我在Azure中有两个订阅。我们称它们为sub-dev和sub-prod。在sub-dev下,我有用于开发的资源(在资源组rg-dev中),在sub-prod下有用于生产的资源(在资源组rg-prod中)。
现在,我只想为dev和prod拥有一个状态文件。我可以使用Terraform工作区(开发和生产)来做到这一点。在子开发(rg-dev)下有一个名为tfsate的存储帐户。它有一个容器等。Azure后端的配置如下:
terraform {
backend "azurerm" {
resource_group_name = "rg-dev"
storage_account_name = "tfstate"
container_name = "tfcontainer"
key = "terraform.tfstate"
}
}
如果要应用到开发环境,则必须将Az Cli切换到子开发。同样,对于生产,我将不得不使用sub-prod。我使用az cli切换默认订阅:
az account set -s sub-prod
问题是状态的存储帐户在sub-dev下,而不在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"
sas_token
配置值(已删除resource_group_name
),但徒劳无功,并得到相同的错误。
我尝试登录az logout
,但是terraform要求我先登录。我是否必须以某种方式调整Azure端的权限(这很难,因为Azure环境是由第三方来配置的),或者Terraform是否完全支持这种状态文件处于不同订阅设置下的状态?
答案 0 :(得分:0)
不管是好是坏(我没有尝试过其他组织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交互的人员的上下文通过z CLI向远程后端进行身份验证。该人员需要对存储帐户具有“读取器和数据访问”角色,以便在运行时动态检索存储帐户密钥。
配置了上述状态文件后,将执行Terraform
az login
az account -s "<name of subscription where you want to create resources>"
terraform init
terraform plan
terraform apply
答案 1 :(得分:0)
还有另一种方法可以做到这一点。您可以在其他订阅上使用与存储帐户关联的访问密钥,并将其导出为环境变量。 重击:
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)