将Terraform天蓝色状态文件置于不同的订阅下

时间:2019-07-31 11:41:02

标签: azure terraform terraform-provider-azure

我在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"
  • 我为tfstate存储帐户生成了一个SAS令牌,并添加了sas_token配置值(已删除resource_group_name

,但徒劳无功,并得到相同的错误。

我尝试登录az logout,但是terraform要求我先登录。我是否必须以某种方式调整Azure端的权限(这很难,因为Azure环境是由第三方来配置的),或者Terraform是否完全支持这种状态文件处于不同订阅设置下的状态?

2 个答案:

答案 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)