【发布时间】:2019-12-08 22:10:20
【问题描述】:
我在 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"
}
}
如果我想申请 dev 环境,我必须将 Az Cli 切换到 sub-dev。同样,对于生产,我将不得不使用 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 环境是由第 3 方配置的)或者 Terraform 是否支持这种让您的状态文件处于不同订阅设置下的方式?
【问题讨论】:
-
您不希望只有一个状态文件用于 dev 和 prod。如果你以不同的方式应用它们(例如
terraform apply dev和terraform apply production或类似的),那么你绝对需要两个不同的状态文件,否则部署第二个将覆盖第一个,破坏第一个中的所有内容。而且您也不希望同时应用开发和生产。 -
我正在使用工作区(开发和产品),所以我可以使用单状态文件。要使用不同的状态文件,我应该在后端定义中添加一些条件值吗?
-
我不建议将工作空间用于静态环境。它们增加了事物的复杂性,使您更难从代码/文件结构的一瞥中看到您已部署的内容,因此您错过了 IaC 的一大优势。
-
那么,您是否建议拥有两个具有相同 tf 文件(参数化资源组名称)和不同后端配置的不同目录(dev 和 prod)?
-
是的。我会使用模块或符号链接来保持干燥,只通过不同的 tfvars 文件和提供程序配置文件更改您需要的内容。关于如何在 SO 上构建它,还有许多其他问题和答案。
标签: azure terraform terraform-provider-azure