【问题标题】:Terraform environment specific variablesTerraform 环境特定变量
【发布时间】:2018-01-17 03:48:48
【问题描述】:

有人知道是否有办法根据环境/工作空间在 Terraform 中填充变量吗?最好是一个

  • 填充 var 命名空间(即不是外部数据源),
  • 不需要包装器
    • 点赞tf(){ terraform --var-file=$(get_tf_env).tfvars
  • 通过更改 terraform env/workspace 生效,无需任何额外的手动步骤(即不通过运行 terraform env 触发的步骤)?

【问题讨论】:

    标签: terraform


    【解决方案1】:

    填充 var 命名空间,不需要包装器,通过更改工作空间生效(Terraform 0.12 代码):

    variable "ami_id" {
      type = map(string)
    
      default = {
        stg = "ami-foo28929"
        prd = "ami-bar39b12"
      }
    }
    
    resource "aws_instance" "this" {
      ami = var.ami_id[terraform.workspace]
      (...)
    }
    

    【讨论】:

    • 有点骇人听闻,但我想这是最干净的解决方案,直到添加对此类内容的本机支持。
    【解决方案2】:

    Terraform workspaces

    工作空间是 Terraform 状态的命名容器。对于多个工作区,一个 Terraform 配置目录可用于管理多个不同的基础设施资源集。

    在 Terraform 版本的 0.9 行中,这个概念被称为“环境”。它在 0.10 中根据有关 Terraform 本身和使用 Terraform 的组织内部“环境”一词超载引起的混淆的反馈进行了重命名。

    引用当前工作区对于基于工作区更改行为很有用。例如,对于非默认工作区,启动较小的集群大小可能很有用。例如:

    resource "aws_instance" "example" {
      count = "${terraform.workspace == "default" ? var.default : var.min}"
    
      # ... other arguments
    }
    

    【讨论】:

    • 我使用如上所述的工作空间,以及允许您根据环境(工作空间)名称为各种资源保留不同变量的变量映射。然后将像这样查找资源:“${lookup(var.vpc_cidr, terraform.workspace)}”。这将为您提供来自 varialbe 映射“vpc_cidr”的值与等于工作区名称的键的值,例如 ecommerce-dev
    • 这个答案不是一个好方法。它将值直接放在代码中,而不是放在代码使用的数据中。 Mattec 对此答案的改进是有效的,就像使用从 terraform apply 命令加载 WORKSPACE.tfvars 文件的包装器一样。
    • @EricM.Johnson 您可以扩展“使用从 terraform apply 命令加载 WORKSPACE.tfvars 文件的包装器”吗?我更喜欢production.tfvarsstaging.tfvars ...等并能够加载
    • @theartofbeing 我的意思是像这样调用 Terraform:terraform apply -var-file=tfvars/${ENVIRONMENT}.tfvars,在 variable 块中声明这些变量,然后使用像 '"${var.foo}" 这样的变量。跨度>
    【解决方案3】:

    据我所知,没有一种使用 Terraform 的本地方法。如果您四处搜索,您会发现很多人的 TF 配置入口点都有不同的文件夹结构,每个不同的文件夹在 tfvars 文件中可以有不同的值。使用 0.10 中引入的 Terraform Workspaces 可能会让您有所了解。

    我已经实现了类似于您使用OctopusDeploy 建议的功能。如果您以前没有使用过,Octopus 可以很好地管理环境特定的变量。我在每个环境中都有一个默认的 tfvars 文件和 Octopus 中相应变量值的列表。

    我有一个基本步骤,它遍历 tfvars 中的每个变量并查找具有相同名称的 Octopus 变量,如果找到则替换它。

    我发现这是一种不错的工作方式,因为它很好地分离了 Terraform tfvars 文件(需要什么值)和 Octopus 中的变量值(实际值是什么)。

    例如如果我有一个包含

    的 tfvars 文件
    instance_size = "Medium"
    

    我在 Octopus 中有 2 个环境,Staging 和 Production。我可以向 Octopus 添加一个名为“instance_size”的变量,并为每个环境设置不同的值(例如分别为“Big”和“Biggest”)。

    我编写的步骤模板将为“instance_size”找到一个对应的值,因此这意味着当我运行它进行暂存时,我会得到:

    instance_size = "Big"
    

    用于生产

    instance_size = "Biggest"
    

    【讨论】:

    • 谢谢费尔明;我特别想避免使用任何形式的包装器;我已经有文件夹/符号链接农场设置,但这样我可以有不同的模块集(实现相同的界面)影响操作。在这种情况下,我们的 AWS 东西被排除在外,因此可以使用 Azure 或 GCE 中的等价物来实现。工作区本质上是以前版本中所谓的环境的 0.10 版本。如果 terraform 0.10.0 有一种反映工作区名称的方法会很有用,但我认为没有。
    • 我将 Octopus 步骤作为部署管道的一部分,因此不要将其视为包装器本身。不确定我是否理解具有相同接口的不同模块的含义 - 相同的参数要求但在 Azure/AWS 之间切换实现?
    【解决方案4】:

    我建议您为 Terraform 项目采用基于“堆栈”的方法,以便您可以配置和管理每个工作区(也称为环境)的“堆栈”和远程状态。从风险的角度来看,这限制了更改的影响范围,简化了工作流程,还提供了更清洁、更易于维护的代码库。

    什么会让你的一天变得更好?

    • 一种客观简单的设计,让您可以对平台及其移动部件进行推理。 (又名堆栈)
    • 一种为您提供灵活性同时限制更改风险的实施。 (又名限制爆炸半径)
    • 一种解决方案,在今天创造价值,并在建立长期发展势头的同时不断改进。 (又名模式,工作流程)

    以下是良好做法的快速列表

    • 跨“工作区”分别管理“堆栈”的“状态”

    • 实施“堆栈”以实现跨“工作区”的一致“配置”

    • 通过良好的“模式”和“工作流程”保持客观和简单。

    使用基于堆栈的方法的示例 Terraform 项目

    /
      /scripts
         <shell scripts>
         <terraform wrapper functions>
    
      /stacks
        /application_1   # Provisions Application 1 and its dependencies
        /application_2   # Provisions Application 2 and its dependencies
        /application_n   # Provisions Application N and its dependencies
            backend.tf       # Remote State
            data.tf          # Data Sources
            stack.tf         # Stack Variables and Defaults
            aws_resource.tf 
            ...
            ...    
        /network    # Provisions VPC, Subnets, Route Tables, Route53 Zones
        /security   # Provisions Security Groups, Network ACLs, IAM Resources
        /storage    # Provisions Storage Resources like S3, EFS, CDN
    
      global.tf     # Global Variables
      dev.tfvars    # Development Environment Variables
      tst.tfvars    # Testing Environment Variables
      stg.tfvars    # Staging Environment Variables
      prd.tfvars    # Production Environment Variables
      terraform.sh  # Wrapper Script for Executing Terraform (Workflow)
    

    还有一些想法

    随着您的实施增长,将未来的需求合并到现有堆栈中或作为新堆栈(如果它们是共享依赖项)将变得更加简单。

    Terraform 允许将远程状态用作数据源。为每个堆栈配置您自己的输出变量可以更简洁地配置和使用导出的资源属性。

    设置您的项目,以便您可以在堆栈级别定义变量和合理的默认值,您可以根据需要在工作空间级别覆盖它们,以满足不同环境(例如开发、测试、生产等)的要求。同时保持配置一致,并且每个环境单独管理远程状态。

    这些是我们在团队中开发和部署的一些实践,以改善我们使用 Terraform 管理 AWS 平台的体验。

    干杯!

    【讨论】:

    • 这非常好。但只是其他人不会像我一样被抓到,Terraform Enterprise 因为遥控器不允许这样做 - 不支持像“TF_...”这样的 tfvars 和 envvars。但对于 S3 状态等 - 太棒了
    【解决方案5】:

    Handling environmental variables in Terraform Workspaces -Taking Advantage of Workspaces,Miles Collier 2019 年清楚地解释了这是如何工作的。这只是一个摘要。

    在parameters.tf中:

    locals {
       env = {
          default = {
             instance_type  = "t2.micro"
             ami            = "ami-0ff8a91507f77f867"
             instance_count = 1
          }
          dev = {
             instance_type  = "m5.2xlarge"
             ami            = "ami-0130c3a072f3832ff"
          }
          qa = {
             instance_type  = "m5.2xlarge"
             ami            = "ami-00f0abdef923519b0"
             instance_count = 3
          }
          prod = {
             instance_type  = "c5.4xlarge"
             ami            = "ami-0422d936d535c63b1"
             instance_count = 6
          }
       }
    environmentvars = "${contains(keys(local.env), terraform.workspace)}" ? terraform.workspace : "default"
       workspace       = "${merge(local.env["default"], local.env[local.environmentvars])}"
    }
    

    要引用变量,请添加到本地变量或将其传递给模块:

    instance_type = "${local.workspace["instance_type"]}"
    

    这将使用来自所选工作区的值,或者如果没有为该工作区定义变量,或者没有选择工作区,则使用默认值。如果没有定义默认值,它会优雅地失败。

    使用terraform workspace select dev 选择开发工作区。

    【讨论】:

      猜你喜欢
      • 2022-08-17
      • 2020-11-12
      • 1970-01-01
      • 2019-06-25
      • 2014-11-13
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      相关资源
      最近更新 更多