编辑通过模块创建的资源

时间:2018-12-12 09:54:00

标签: terraform terraform-provider-aws

我在基础架构中使用了许多通用模块。我最近遇到了一个问题。我将简化并解释一个这样的实例。

一个代码段

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个地方。

能请你帮我实现这个目标吗?

2 个答案:

答案 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。您无法即时更改模块定义