在不同的订阅下拥有 Terraform 天蓝色状态文件
Having the Terraform azure state file under different subscription
我在 Azure 中有两个订阅。我们称它们为子开发和子产品。在 sub-dev 下,我有开发资源(在资源组 rg-dev 中),在 sub-prod 下有生产资源(在资源组 rg-prod 中)。
现在,我只想为开发人员和生产人员准备一个状态文件。我可以这样做,因为我正在使用 Terraform 工作区(开发和生产)。 sub-dev (rg-dev) 下有一个名为 tfsate 的 Storage Account。它有一个容器等。Azure后端配置如下:
terraform {
backend "azurerm" {
resource_group_name = "rg-dev"
storage_account_name = "tfstate"
container_name = "tfcontainer"
key = "terraform.tfstate"
}
}
如果我想申请开发环境,我必须将 Az Cli 切换到子开发环境。同样,对于生产,我将不得不使用子产品。我使用 az cli 切换默认订阅:
az account set -s sub-prod
问题是状态的存储帐户在 sub-dev 而不是 sub-prod 下。当默认订阅设置为 sub-prod.
时,我尝试 terraform init
(或应用)时会出现访问错误
Error: Failed to get existing workspaces: Error retrieving keys for Storage Account "tfstate": storage.AccountsClient#ListKeys: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'user@example.com' with object id '<redacted>' does not have authorization to perform action 'Microsoft.Storage/storageAccounts/listKeys/action' over scope '/subscriptions/sub-prod/resourceGroups/rg-dev/providers/Microsoft.Storage/storageAccounts/tfstate' or the scope is invalid. If access was recently granted, please refresh your credentials."
我尝试了一些事情:
- 我加了
subscription_id = "sub-dev"
- 我为 tfstate 存储帐户生成了一个 SAS 令牌并添加了
sas_token
配置值(删除了 resource_group_name
)
但徒劳无功并得到同样的错误。
我尝试 az logout
但 terraform 要求我先登录。我是否必须以某种方式调整 Azure 端的权限(这很难,因为 Azure 环境是由第 3 方配置的)或者 Terraform 是否支持这种在不同的订阅设置下拥有您的状态文件?
无论好坏(我没有对其他组织 terraform 的方法进行过多试验),我们都按照您描述的方式使用 terraform。状态文件,在远程后端,在对我的资源的不同订阅中。创建工作区以处理部署环境。
我们的状态文件是这样指定的:
terraform {
required_version = ">= 0.12.6"
backend "azurerm" {
subscription_id = "<subscription GUID storage account is in>"
resource_group_name = "terraform-rg"
storage_account_name = "myterraform"
container_name = "tfstate"
key = "root.terraform.tfstate"
}
}
我们将 Terraform 存储帐户保存在与部署完全不同的订阅中,但这不是必需的。
像这样配置状态文件时,它会使用与 CLI 交互的人员的上下文,通过 az CLI 向远程后端进行身份验证。此人需要对存储帐户具有“Reader & 数据访问”角色,以便在运行时动态检索存储帐户密钥。
配置了上述状态文件后,执行 Terraform 将是
az login
az account set -s "<name of subscription where you want to create resources>"
terraform init
terraform plan
terraform apply
还有另一种方法可以做到这一点。您可以使用与另一个订阅上的存储帐户关联的访问密钥,并将其导出为环境变量。
Bash:
export ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
Powershell:
$env:ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
我在 Azure 中有两个订阅。我们称它们为子开发和子产品。在 sub-dev 下,我有开发资源(在资源组 rg-dev 中),在 sub-prod 下有生产资源(在资源组 rg-prod 中)。
现在,我只想为开发人员和生产人员准备一个状态文件。我可以这样做,因为我正在使用 Terraform 工作区(开发和生产)。 sub-dev (rg-dev) 下有一个名为 tfsate 的 Storage Account。它有一个容器等。Azure后端配置如下:
terraform {
backend "azurerm" {
resource_group_name = "rg-dev"
storage_account_name = "tfstate"
container_name = "tfcontainer"
key = "terraform.tfstate"
}
}
如果我想申请开发环境,我必须将 Az Cli 切换到子开发环境。同样,对于生产,我将不得不使用子产品。我使用 az cli 切换默认订阅:
az account set -s sub-prod
问题是状态的存储帐户在 sub-dev 而不是 sub-prod 下。当默认订阅设置为 sub-prod.
时,我尝试terraform init
(或应用)时会出现访问错误
Error: Failed to get existing workspaces: Error retrieving keys for Storage Account "tfstate": storage.AccountsClient#ListKeys: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'user@example.com' with object id '<redacted>' does not have authorization to perform action 'Microsoft.Storage/storageAccounts/listKeys/action' over scope '/subscriptions/sub-prod/resourceGroups/rg-dev/providers/Microsoft.Storage/storageAccounts/tfstate' or the scope is invalid. If access was recently granted, please refresh your credentials."
我尝试了一些事情:
- 我加了
subscription_id = "sub-dev"
- 我为 tfstate 存储帐户生成了一个 SAS 令牌并添加了
sas_token
配置值(删除了resource_group_name
)
但徒劳无功并得到同样的错误。
我尝试 az logout
但 terraform 要求我先登录。我是否必须以某种方式调整 Azure 端的权限(这很难,因为 Azure 环境是由第 3 方配置的)或者 Terraform 是否支持这种在不同的订阅设置下拥有您的状态文件?
无论好坏(我没有对其他组织 terraform 的方法进行过多试验),我们都按照您描述的方式使用 terraform。状态文件,在远程后端,在对我的资源的不同订阅中。创建工作区以处理部署环境。
我们的状态文件是这样指定的:
terraform {
required_version = ">= 0.12.6"
backend "azurerm" {
subscription_id = "<subscription GUID storage account is in>"
resource_group_name = "terraform-rg"
storage_account_name = "myterraform"
container_name = "tfstate"
key = "root.terraform.tfstate"
}
}
我们将 Terraform 存储帐户保存在与部署完全不同的订阅中,但这不是必需的。
像这样配置状态文件时,它会使用与 CLI 交互的人员的上下文,通过 az CLI 向远程后端进行身份验证。此人需要对存储帐户具有“Reader & 数据访问”角色,以便在运行时动态检索存储帐户密钥。
配置了上述状态文件后,执行 Terraform 将是
az login
az account set -s "<name of subscription where you want to create resources>"
terraform init
terraform plan
terraform apply
还有另一种方法可以做到这一点。您可以使用与另一个订阅上的存储帐户关联的访问密钥,并将其导出为环境变量。 Bash:
export ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
Powershell:
$env:ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)