使用模块时 Terraform 根目录中 variables.tf 的用途是什么?

What is the purpose of variables.tf in Terraform root directory when using modules?

我正在编写一些代码来描述 AWS 上的基础设施,并且我正在遵循 Terraform 最佳实践。为了使我的代码更具可重用性和面向未来的证明,我使用了模块。最后,我的代码可能是这样的:

├── modules
│   └── aws_vpc
│       ├── main.tf
│       └── vars.tf
├── prod
│   ├── main.tf
│   └── variables.tf
├── terraform.tfstate
└── terraform.tfstate.backup

为了简单起见,我没有使用 terraform-workspace。

问题是,如果我不能在模块中重复使用 Terraform root 目录,variables.tf 的目的是什么?

想法是为每个环境 devprodqa 设置单独的目录,我可以在其中重用 modules 目录中定义的所有模块并使用特定环境env 目录中定义的变量。

Terraform Github pages 上也有类似的讨论,但据我所知,不鼓励这样使用。

那么,如果我以后不能在模块中重用它们,那么在 Terraform 根目录中 variables.tf 的目的是什么?

我知道有一个 Terragrunt 充当 Terraform 的包装器,但我只想坚持使用 Terraform。

在任何给定的 Terraform 目录中,我不认为任何 .tf 文件具有任何特定功能,除了让您了解您如何分解你的资源 and/or 整理你的代码。因此 main.tfvariables.tf 可以合并为 1 个文件而不会丢失任何功能。

在您的设置中,您的 variables.tf 将有一组变量,每个变量都有一个 default 值(否则 terraform x 命令会提示输入它们的值)。或者,您可以省略 default 值,而是创建一个 terraform.tfvars 文件来设置每个变量的值。

在这个设置中,每个环境(生产、测试​​、开发等)都有单独的目录,我更喜欢使用 terraform.tfvars,因为我发现它更容易进行差异化,而且我知道唯一我需要修改任何给定的环境是 terraform.tfvars 文件。

比如cidr_block可能是你为每个env指定的一个变量,然后传给aws_vpc模块。 prod 可能是 192.168.0.0/16 而 test 可能是 10.1.0.0/16。

至于模块,虽然看起来所有的变量都是 repeats/duplicates 环境目录中的代码,但这不是给定的。例如,您的 env 代码中可能有一个 var,它是一个布尔值,作为输入传递到您的模块中,然后模块使用该输入来确定 'decisions'.

模块有输入和输出。您可以多次调用该模块,但每次都必须提供所需的输入……您不能简单地依赖调用上下文中设置的变量(尽管您可以将这些值作为参数传递)。

将模块想象成函数,而不是 include。你必须传递参数。模块 可以访问全局范围。这通常是一个很好的编程习惯......全局变量导致意大利面条代码和意想不到的后果。一些不错的阅读 here.

您的模块正在被环境目录 ./prod/ 中的 Terraform 代码调用,该目录本身在 ./prod/variables.tf 中有 variable 声明。由于您要为每个环境创建一个目录,因此在此顶层共享数据或资源的唯一方法是 copy/paste,或像这样的符号链接文件:

├── modules
│   └── aws_vpc
│       ├── main.tf
│       └── vars.tf
├── prod
│   ├── global_variables.tf (symlink from ./shared/global_variables.tf)
│   ├── main.tf
│   └── variables.tf
├── shared
│   └── global_variables.tf
├── terraform.tfstate
└── terraform.tfstate.backup

请注意,除非您真的想在运行时使用 -var-var-file 更改这些值,否则您可能实际上想要使用 locals。我曾经使用具有默认值的变量而不是本地变量,但是如果该值永远不会因该环境而改变,那么使用本地变量是有意义的。