Terraform最佳实践 - 避免重复

4
我考虑将一些基础设施代码迁移到Terraform上,因为我们在使用AWS CloudFormation时遇到了一些问题。
让我举个例子,我有一个ECS集群,可以运行约10个不同的任务定义。每个任务定义包含几乎相同的配置,为避免代码重复,我正在构建可重用模块。
据我所知,有三种主要方法来组织terraform目录。
1:
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"传递它,然后在我的main.tf中,我需要将变量传递给modules/ecs/task/main.tf,这似乎是一种冗长的方式,需要很多步骤才能将变量传递到ecs/task/main.tf。
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中,你需要从例如stage中的main.tf开始,该文件调用了modules/ecs/main.tf。然后通过/modules/ecs/main.tf应用到/modules/ecs/task/main.tf中。
这种方法的问题是每当我添加一个新模块时,都必须将其添加到所有不同环境的main.tf中。
3.
project
├── modules
|         ├── ecs
|       ├── main.tf
|       ├── variables.tf
|       ├── task
|            ├── main.tf
|                    ├── variables.tf
|
|
|
|
|──  main.tf 
|── variable.tf

使用terraform工作区,我可以在modules/ecs/task/variables.tf中使用locals来确定我正在构建的环境。像这样:

modules/ecs/task.variables.tf

locals {

env="${terraform.workspace}"

masterAccountIDS = {

"default"="12121212"

"dev"="84848484"

}



masterAccountID="${lookup(local.masterAccountIDS, local.env)}"

}

但这将要求我每次添加一个新环境时都要浏览所有的variables.tf文件,并添加一个名为“stage”的新条目。

我无法想出一种方法,允许我不复制粘贴代码或在添加新环境时插入新内容,并使其全部位于一个位置,以便我可能只需要编辑一个文件。

1个回答

0

目前来说,使用工作区是最好的选择。我正在使用类似下面这样的方式来管理所有变量:

defaults.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)])}"
}

现在你可以在主定义中调用上述变量 - main.tf -
module "s3" {
  source = "s3"
  tags = "${local.tags}"
  meta = "${local.meta}"
  workspace = "${local.workspace}"
  workspace_list = "${local.workspace_list}"
}

现在你可以按照以下方式调用模块中定义的变量 -
"${var.workspace["environ"]}"

PS - 这是一个解决方法,但目前来看效果非常好。Terraform应该提供一些开箱即用的工具来管理它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接