我正在编写一些代码来描述AWS上的基础架构,并且正在遵循Terraform最佳实践。为了使我的代码更具可重用性和面向未来,我正在使用模块。最后,我的代码可能如下所示:
├── modules
│ └── aws_vpc
│ ├── main.tf
│ └── vars.tf
├── prod
│ ├── main.tf
│ └── variables.tf
├── terraform.tfstate
└── terraform.tfstate.backup
为简单起见,我不使用terraform-workspace。
问题是,如果无法在模块中重用variables.tf
的Terraform root
目录,它的目的是什么?
想法是每个环境dev
,prod
和qa
都有单独的目录,在这里我可以重用modules
目录中定义的所有模块,并使用定义的特定于环境的变量在env
目录中。
在Terraform Github pages上也有类似的讨论,但是正如我所看到的,不鼓励这种用法。
因此,如果以后无法在模块中重用variables.tf
的Terraform根目录的用途是什么?
我知道有一个Terragrunt充当Terraform的包装,但是我只想坚持使用Terraform。
答案 0 :(得分:0)
在任何给定的 Terraform 目录中,我不认为任何.tf
文件具有任何特定功能,除了可以使您了解如何分解资源和/或安排您的代码。这样main.tf
和variables.tf
可以合并为1个文件,而不会损失任何功能。
在您的设置中,您的variables.tf
将具有一组变量,每个变量都具有一个default
值(否则,terraform x
命令将提示输入它们的值)。另外,您可以省略default
值,而创建一个terraform.tfvars
文件来为每个变量设置值。
在针对每个环境(产品,测试,开发等)具有单独目录的此设置中,我更喜欢使用terraform.tfvars
,因为我发现进行差异比较容易,而且我知道我唯一需要的是用任何给定的env修改的是terraform.tfvars
文件。
例如,cidr_block
可以是您为每个env指定的变量,然后传递给aws_vpc
模块。 prod 可能是192.168.0.0/16,而 test 可能是10.1.0.0/16。
对于模块,虽然看起来所有的var都是环境dirs中的代码的重复/重复,但这不是给定的。例如,您的env代码中可能有一个var,它是一个布尔值,该布尔值作为输入传递到模块中,然后模块使用该输入来做出某些“决定”。
答案 1 :(得分:0)
模块具有输入和输出。您可以多次调用该模块,但是每次都必须提供所需的输入...您不能简单地依赖在调用上下文中设置的变量(尽管您可以将这些值作为参数传递)。
将模块视为函数,而不是include
。您必须传递参数。模块 not 不能访问全局范围。通常,这是一种良好的编程习惯。全局变量会导致意大利面条式代码并产生意想不到的后果。不错的读物here。
您的模块正在由环境目录./prod/
中的Terraform代码调用,该环境目录本身在variable
中具有./prod/variables.tf
声明。由于要在每个环境中创建目录,因此在此顶级环境中共享数据或资源的唯一方法是复制/粘贴或符号链接文件,如下所示:
├── 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。我曾经使用具有默认值而不是本地变量的变量,但是如果该值在该环境中永远不变,那么使用本地变量是有意义的。