我在基础架构中使用了许多通用模块。我最近遇到了一个问题。我将简化并解释一个这样的实例。
一个代码段
module "ec2-instance" {
source = "../common-modules/ec2-instance/"
aws_instance="monitoring"
region="ap-south-1"
subnets=["subnet-a979cb"]
ami_id="ami-34b4c05b"
instance_type="t2.medium"
instance_count=1
security_group= "sg-aac36ab3"
}
我正在十个地方使用代码段中使用的模块(../common-modules/ec2-instance/
)。
现在,在十种用法之一(ec2实例)中,我想添加标签/ userdata /任何新属性,但不添加其他属性,即我不想编辑我的模块源代码,因为它会弄乱我称为模块的其他9个地方。
能请你帮我实现这个目标吗?
答案 0 :(得分:2)
模块应按原样使用;在使用它们的任何地方,行为和选项都应该相同。但是,您试图做的是为模块引入更多的变量,而不会导致模块的任何实例发生变化,除了实际使用变量的实例。
除了将现有值用作默认值,然后在模块上提供变量以允许这些默认值被覆盖(仅在您希望发生这种情况的地方)(例如,每10个模块中有一个),就没有通用答案。您提到的示例(标签,用户数据等)在Terraform行为上都非常不同,因此需要自定义解决方案。
我们来看一下您给出的示例:
1)变量标记:Terraform 0.12.0-alpha1引入了dynamic block feature,该标记使您可以在所有资源上使用完全为零的标记,除了您实际为其提供的标记之外,通过变量(例如地图列表)。
示例:
您的模块将具有一个名为tags
的变量,默认情况下可以为空列表。在模块资源中,您将实现以下内容(未经测试,仅是Git链接中示例的解释):
dynamic "tags" {
for_each = var.tags
tag {
key = tags.key
value = tags.value
}
}
2)可变用户数据
向您的模块添加一个user_data
变量,默认值为空字符串(Terraform 0.12.0据说具有本机null支持,但是我在与用户数据结合使用方面没有经验;仍然是AFAIK用户数据字符串必须至少为1个字符)。
分配用户数据时添加一些插值:
user_data = "${var.user_data == "" ? data.template_file.existing_user_data.rendered : var.user_data}"
显然,现有的用户数据应该是您在9个模块实例上不应该更改的数据。通过将此设置为默认设置,除了在实际上已传递自定义用户数据的模块上,将不会应用任何更改,从而采用覆盖策略。
3)任何新属性
与上述示例相同;找到一种方法来将当前值作为默认值,这样,除非通过自定义变量输入应用更改,否则任何模块都不会看到更改。
答案 1 :(得分:0)
如果您无法使现有模块同时适用于两种用途,则可以制作模块的新版本,并将其中一种指向新模块版本,将另一种指向旧版本。 Module versioning。您无法即时更改模块定义