如何在工作区/模块之间共享Terraform变量?

时间:2020-01-16 17:44:01

标签: terraform terraform-provider-azure terraform-cloud

Terraform Cloud Workspaces允许我定义变量,但是我无法找到一种在多个工作空间之间共享变量的方法。

在我的示例中,我有两个工作区:

  • 数据库
  • 应用程序

在两种情况下,我将使用相同的AzureRM凭据进行连接。以下是工作区用于连接到我的Azure订阅的常用值:

provider "azurerm" {
  subscription_id = "00000000-0000-0000-0000-000000000000"
  client_id       = "00000000-0000-0000-0000-000000000000"
  client_secret   = "00000000000000000000000000000000"
  tenant_id       = "00000000-0000-0000-0000-000000000000"
}

重复值没有任何意义(在我的情况下,我可能会有10个工作区)。 有办法吗?

还是正确的方法是将“数据库”和“应用程序”定义为模块,然后使用工作区(DEV,QA,PROD)进行编排?

enter image description here

1 个答案:

答案 0 :(得分:2)

在Terraform Cloud中,Workspace对象当前是最不精确的位置,您可以在其中直接指定变量值。没有内置的机制可以在工作空间之间共享变量值。

但是,一种解决方法是使用Terraform本身来管理Terraform Cloud。 The tfe provider(由于历史原因以Terraform Enterprise命名,因为它是在Terraform Cloud启动之前构建的),将允许Terraform管理Terraform Cloud工作区及其相关变量。

variable "workspaces" {
  type = set(string)
}

variable "common_environment_variables" {
  type = map(string)
}

provider "tfe" {
  hostname = "app.terraform.io" # Terraform Cloud
}

resource "tfe_workspace" "example" {
  for_each = var.workspaces

  organization = "your-organization-name"
  name         = each.key
}

resource "tfe_variable" "example" {
  # We'll need one tfe_variable instance for each
  # combination of workspace and environment variable,
  # so this one has a more complicated for_each expression.
  for_each = {
    for pair in setproduct(var.workspaces, keys(var.common_environment_variables)) : "${pair[0]}/${pair[1]}" => {
      workspace_name = pair[0]
      workspace_id   = tfe_workspace.example[pair[0]].id
      name           = pair[1]
      value          = var.common_environment_variables[pair[1]]
    }
  }

  workspace_id = each.value.workspace_id

  category  = "env"
  key       = each.value.name
  value     = each.value.value
  sensitive = true
}

通过上述配置,您可以设置var.workspaces包含要Terraform管理的工作空间的名称,并var.common_environment_variables包含要为其全部设置的环境变量。


请注意,要在提供程序上设置凭据,建议的方法是在环境变量而不是Terraform变量中设置它们,因为这会使Terraform配置本身与如何获取这些凭据无关。通过与Azure CLI身份验证的集成,您可以潜在地在本地(Terraform Cloud外部)应用相同的Terraform配置,而Terraform Cloud执行环境通常会使用服务主体。

因此,要在Terraform Cloud环境中提供凭据,请在var.common_environment_variables中放置以下环境变量:

  • ARM_CLIENT_ID
  • ARM_TENANT_ID
  • ARM_SUBSCRIPTION_ID
  • ARM_CLIENT_SECRET

如果您使用Terraform Cloud本身在此管理Terraform Cloud的工作空间上运行操作(自然,您需要手动设置该选项以进行引导,而不是对其进行自我管理),则可以配置{{1} }作为该工作区上的敏感变量。

如果您改为通过传递到var.common_environment_variables块中的Terraform变量进行设置(如示例中所示),那么您将强制运行配置的任何人或系统直接填充这些变量,从而迫使他们使用服务主体与其他机制之一进行比较,并防止Terraform自动获取使用az login设置的凭据。 Terraform配置通常只应描述Terraform所管理的内容,而不应描述与谁在运行Terraform或在哪里运行Terraform有关的设置。

请注意,尽管Terraform Cloud自我管理工作区的状态将包括 这些凭据的副本(对于Terraform正在管理的对象来说是正常的),因此应适当设置the permissions on this workspace以限制对其的访问。