我正在尝试防止标记值的更改导致 terraform 计划发生更改。
tag {
key = "Name"
value = "${var.stage}-${var.name}"
propagate_at_launch = true
}
tag {
key = "commit_location"
value = data.aws_ssm_parameter.commit_location.value
propagate_at_launch = true
}
lifecycle {
ignore_changes = [
tag["commit-location"]
]
}
terraform 计划导致错误:
│ on ../modules/ec2/asg.tf line 61, in resource "aws_autoscaling_group" "asg":
│ 61: tag["commit_location"]
│
│ Block type "tag" is represented by a set of objects, and set elements do not have addressable keys. To find elements matching specific criteria, use a "for" expression with an "if" clause.
我期望对此标签的更改(即对 data.aws_ssm_parameter.commit_location.value 的值的更改)不会导致 terrazform 计划中此资源的更改。
我注意到 AWS 提供商 v5 中的标签/标签块的行为似乎发生了变化,这可能会导致此问题。 我读过几个错误报告,但他们似乎在 12 个多月后没有得到答案。
你是对的,因为我相信 AWS 提供商 v5,
tag
块被视为一组对象,这意味着您无法使用像 tag["commit_location"]
这样的键引用单个标签。要解决此问题,您需要调整 Terraform 中处理标签的方式。
您不能像
ignore_changes
那样直接引用 tag["commit_location"]
块中的特定标记,因为正如错误所示,集合没有可寻址键。以下是我解决这个问题的方法:
如果您可以忽略对此资源的all标签的更改,则可以使用以下命令:
lifecycle {
ignore_changes = [tags]
}
这将防止对
tags
的任何更改触发 Terraform 计划的更改。
如果您只想忽略对特定标签的更改(例如,
commit_location
),您可以使用更动态的方法。由于标签现在是一个集合,因此您可以应用 for_each
循环来定义标签。
例如:
resource "aws_autoscaling_group" "asg" {
# Define tags as a map
dynamic "tag" {
for_each = {
Name = "${var.stage}-${var.name}"
commit_location = data.aws_ssm_parameter.commit_location.value
}
content {
key = tag.key
value = tag.value
propagate_at_launch = true
}
}
lifecycle {
# Use the 'for_each' approach to manage tags dynamically
ignore_changes = [
tags[*].value if tag.key == "commit_location"
]
}
}
这里,
for_each
块动态生成标签,并且ignore_changes
用于使用commit_location
循环忽略对特定for_each
标签的更改。
任一选项“应该”防止对标签值进行不必要的更改,从而触发 Terraform 计划中的更改。