代码之家  ›  专栏  ›  技术社区  ›  Casper

地形最佳实践-避免重复

  •  3
  • Casper  · 技术社区  · 6 年前

    我正在考虑将我们的一些基础设施代码切换到Terraform,因为我们在AWS CloudFormation上遇到了一些麻烦。

    根据我收集到的信息,有3种主要的方法来构建你的地形目录。

    project
    ├── modules
    |      ├─ ecs
    |            ├── main.tf
    |            ├── variables.tf
    |            ├── task
    |                 ├── main.tf
    |                 ├── variables.tf
    |
    |
    └── env
    |       ├─── dev.tfvars
    |       ├─── prod.tfvars
    |       ├─── stage.tfvars
    |       ├─── 10+   
    |
    |
    |── main.tf 
    |── variable.tf
    

    使用这种结构,我必须从env文件夹中获取变量,并将其传递给 -var-files="env/dev.tfvars"

    2

    project
    ├── modules
    |       ├─ ecs
    |            ├── main.tf
    |            ├── variables.tf
    |            ├── task
    |                ├── main.tf
    |                ├── variables.tf
    |
    |
    └── stage
    |    ├─── main.tf    
    |    ├─── variable.tf
    |    ├─── stage.tfvars 
    |
    └── dev
    |    ├─── main.tf    
    |    ├─── variable.tf
    |    ├─── dev.tfvars
    |
    └── 10+
    |   ├─── main.tf    
    |   ├─── variable.tf
    |   ├─── X.tfvars
    

    如果希望将基于环境的变量应用于 modules/ecs/task/main.tf ,你必须从 main.tf 例如,在调用 modules/ecs/main.tf /modules/ecs/main.tf 然后应用到 /modules/ecs/task/main.tf

    这种方法的问题还在于,每当我添加一个新模块时,我都必须将它添加到所有不同环境中主.tf

    三。

    project
    ├── modules
    |         ├── ecs
    |       ├── main.tf
    |       ├── variables.tf
    |       ├── task
    |            ├── main.tf
    |                    ├── variables.tf
    |
    |
    |
    |
    |──  main.tf 
    |── variable.tf
    

    通过使用terraform工作区,我可以在modules/ecs/task中使用局部变量/变量.tf来确定我在营造什么样的环境。这样地:

    modules/ecs/task.variables.tf

    locals {
    
    env="${terraform.workspace}"
    
    masterAccountIDS = {
    
    "default"="12121212"
    
    "dev"="84848484"
    
    }
    
    
    
    masterAccountID="${lookup(local.masterAccountIDS, local.env)}"
    
    }
    

    但这需要每次我添加一个新的环境时,我都要经历所有的过程变量.tf文件,并添加一个名为“stage”的新条目。

    我想不出一种方法可以让我不复制粘贴代码,或者在添加新环境时不插入新内容,或者将所有内容都放在一个地方,所以我可能只需要编辑一个文件。

    1 回复  |  直到 6 年前
        1
  •  0
  •   vivekyad4v    6 年前

    使用工作区是目前最好的选择。我使用下面的方法在一个地方管理所有变量-

    默认值.tf

    /* DEFAULT VARIABLES */
    
    locals {
      tags = {
          Project = "${var.project}"
          Contact = "vivek@vivekyadav.me"
          Requester = "Vivek"
          Creator = "Vivek"
          ManagedBy = "TF"
          Environ = "${local.workspace["environ"]}"
       }
    }
    
    locals {
      meta = {
          name_prefix = "hpy-${local.workspace["environ"]}-${local.workspace["project_name"]}"
          account_id = "${local.workspace["account_id"]}"
          region_name = "${local.workspace["region_name"]}"
       }
    }
    
    /* CUSTOM VARIABLES - ENVIRONMENT SPECIFIC */
    
    ################  DEFAULT LOCALS - DEFINE ENV VARIABLES FOR APP  #################
    locals {
      env = {
        default = {
          project_name = "${var.project}"
          region_name = "${var.region}"
          environ = "dev"
          account_id = "356******001"
        }
        default_list = {
        }
    
    ################  DEV LOCALS - DEFINE ENV VARIABLES FOR APP  #################
    
        dev = {
          environ = "dev"
        }
        dev_list = {
        }
    
    ################  UAT LOCALS - DEFINE ENV VARIABLES FOR APP  #################
    
        uat = {
          environ = "uat"
        }
        uat_list = {
        }
    
    ################  PREP LOCALS - DEFINE ENV VARIABLES FOR APP  #################
    
        prep = {
          environ = "prep"
        }
        prep_list = {
        }
    
    ################  PRD LOCALS - DEFINE ENV VARIABLES FOR APP  #################
    
        prod = {
          environ = "prod"
          account_id = "3621****8334"
        }
        prod_list = {
        }
    
      }
    
    ################  EXPORTING ENV/WORKSPACE VARIABLES FOR APP  #################
    
      workspace = "${merge(local.env["default"], local.env[terraform.workspace])}"
      workspace_lists= "${merge(local.env["default_list"], local.env[format("%v_list",terraform.workspace)])}"
    }
    

    现在可以在主定义中调用上述变量-

    主.tf -

    module "s3" {
      source = "s3"
      tags = "${local.tags}"
      meta = "${local.meta}"
      workspace = "${local.workspace}"
      workspace_list = "${local.workspace_list}"
    }
    

    现在您可以调用模块中定义的变量,如下所示-

    "${var.workspace["environ"]}"
    

    PS-这是一个解决办法,但工作非常好,如果现在。Terraform应该提供一些现成的东西来管理它。