Terraform环境 - 如何让它变干

Kri*_*zsa 9 amazon-web-services terraform devops

我们正在大量使用Terraform进行AWS Cloud配置.我们的基础terraform结构如下所示:

?? modules
??? x
??? y
?? environments
??? dev
?   ??? main.tf
?   ??? output.tf
?   ??? variables.tf
??? uat
?   ??? main.tf
?   ??? output.tf
?   ??? variables.tf
??? prod
    ??? main.tf
    ??? output.tf
    ??? variables.tf
Run Code Online (Sandbox Code Playgroud)

当我们达到我们有许多模块和许多环境的程度时,代码重复现在变得更加严重,我们希望尽可能多地摆脱它.

我们目前主要关注的是output.tf文件 - 每次扩展现有模块或添加新模块时,我们都需要为它设置特定于环境的配置(这是预期的),但我们仍然需要复制/粘贴所需的部件into output.tf输出配置的结果(如IP地址,AWS ARN等).

有没有办法摆脱重复的output.tf文件?我们是否可以在模块本身中定义所需的输出,并在我们为特定环境运行terraform时查看所有已定义的输出?

Yev*_*man 5

我们构建并开源了Terragrunt来解决这个问题。Terragrunt 的功能之一是能够下载远程 Terraform 配置。这个想法是您只需在单个存储库中为您的基础设施定义一次 Terraform 代码,例如,modules

??? modules
 ??? app
 ?   ??? main.tf
 ??? mysql
 ?   ??? main.tf
 ??? vpc
     ??? main.tf
Run Code Online (Sandbox Code Playgroud)

这个 repo 包含典型的 Terraform 代码,有一个区别:代码中在不同环境之间应该不同的任何内容都应该作为输入变量公开。例如,app 模块可能会公开以下变量:

variable "instance_count" {
  description = "How many servers to run"
}

variable "instance_type" {
  description = "What kind of servers to run (e.g. t2.large)"
}
Run Code Online (Sandbox Code Playgroud)

在一个单独的回购协议,调用,例如,住,可以定义为所有的环境,现在只包含一个的代码.tfvars每个组件文件(例如app/terraform.tfvarsmysql/terraform.tfvars等)。这为您提供以下文件布局:

??? live
    ??? prod
    ?   ??? app
    ?   ?   ??? terraform.tfvars
    ?   ??? mysql
    ?   ?   ??? terraform.tfvars
    ?   ??? vpc
    ?       ??? terraform.tfvars
    ??? qa
    ?   ??? app
    ?   ?   ??? terraform.tfvars
    ?   ??? mysql
    ?   ?   ??? terraform.tfvars
    ?   ??? vpc
    ?       ??? terraform.tfvars
    ??? stage
        ??? app
        ?   ??? terraform.tfvars
        ??? mysql
        ?   ??? terraform.tfvars
        ??? vpc
            ??? terraform.tfvars
Run Code Online (Sandbox Code Playgroud)

请注意.tf任何文件夹中都没有 Terraform 配置(文件)。相反,每个.tfvars文件指定一个terraform { ... }块,指定从何处下载 Terraform 代码,以及该 Terraform 代码中输入变量的特定环境值。例如,stage/app/terraform.tfvars可能如下所示:

terragrunt = {
  terraform {
    source = "git::git@github.com:foo/modules.git//app?ref=v0.0.3"
  }
}

instance_count = 3
instance_type = "t2.micro"
Run Code Online (Sandbox Code Playgroud)

而且prod/app/terraform.tfvars可能是这样:

terragrunt = {
  terraform {
    source = "git::git@github.com:foo/modules.git//app?ref=v0.0.1"
  }
}

instance_count = 10
instance_type = "m2.large"
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Terragrunt 文档


spi*_*eap 3

解决这个问题的一种方法是创建一个base环境,然后对公共元素进行符号链接,例如:

\n\n
\xe2\x94\x9c\xe2\x94\x80 modules\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 x\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 y\n\xe2\x94\x9c\xe2\x94\x80 environments\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 base\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dev\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf -> ../base/output.tf\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf -> ../base/variables.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 uat\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf -> ../base/output.tf\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf -> ../base/variables.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 super_custom\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf # not symlinked\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf # not symlinked\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 prod\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf -> ../base/output.tf\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf -> ../base/variables.tf\n
Run Code Online (Sandbox Code Playgroud)\n\n

output.tf这种方法只有在每个环境的文件variables.tf都相同的情况下才真正有效,尽管您可以有非符号链接的变体(例如super_custom上面的),但这可能会变得令人困惑,因为哪些环境是自定义的,哪些是自定义的,这可能会变得令人困惑。 't。YMMV。我尝试将环境之间的更改限制为.tfvars每个环境的一个文件。

\n\n

Charity Major 关于 tfstate 文件的优秀文章值得一读,它让我走上了这条道路。

\n

  • 感谢您的回答。我想到了符号链接,但并不热衷于这种方法..如果这是唯一的方法,我会接受它。感谢您链接这篇文章,它非常有见地,非常好读! (2认同)