【问题标题】:How to share Terraform variables across workpaces/modules?如何跨工作区/模块共享 Terraform 变量?
【发布时间】:2020-05-03 14:55:39
【问题描述】:

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 个工作区)。 有没有办法做到这一点?

或者正确的做法是将“数据库”和“应用程序”定义为一个Module,然后使用Workspaces(DEV、QA、PROD)进行编排?

【问题讨论】:

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


    【解决方案1】:

    在 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(当然,您需要手动设置它来引导,而不是让它自行管理),那么您可以将 var.common_environment_variables 配置为该工作区上的敏感变量。

    如果您改为通过传递到 provider "azurerm" 块中的 Terraform 变量来设置它(如您在示例中所示),那么您强制运行配置的任何人或系统直接填充这些变量,强制他们使用服务主体 vs . 其他机制之一并阻止 Terraform 自动获取使用 az login 设置的凭据。 Terraform 配置通常应该只描述 Terraform 管理的内容,而不是与运行 Terraform 或运行 Terraform 的位置相关的设置。

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

    【讨论】:

    • 我将无法在我的项目中使用 Enterprise,但没关系。您对环境配置的补充是一个很大的优势,我只是在研究它,因为通过查看它我知道那些配置不应该存在。
    猜你喜欢
    • 2020-08-25
    • 2017-05-23
    • 2018-12-15
    • 2016-07-07
    • 2014-03-11
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    相关资源
    最近更新 更多