需要使用Terraform创建一个AWS安全组规则,然后触发一个空资源。
如
- health_blue。(aws_security_group_rule)
- wait_for_healthcheck。(null_resource)
我已经尝试在安全组规则和null资源之间添加依赖关系,但是null资源并不总是被触发,或者在规则创建或销毁之前没有被触发。
在创建、修改或销毁安全组规则时需要触发null资源。
配置如下:
resource "aws_security_group_rule" "health_blue" {
count = data.external.blue_eks_cluster.result.cluster_status == "online" ? 1 : 0
description = "LB healthchecks to blue cluster"
cidr_blocks = values(data.aws_subnet.eks_gateway).*.cidr_block
from_port = 80
protocol = "tcp"
security_group_id = data.aws_security_group.blue_cluster_sg[0].id
to_port = 80
type = "ingress"
}
resource "null_resource" "wait_for_healhtcheck" {
triggers = {
value = aws_security_group_rule.health_blue[0].id
}
provisioner "local-exec" {
command = "echo 'Waiting for 25 seconds'; sleep 25"
}
depends_on = [aws_security_group_rule.health_blue]
}
任何提示或指针将不胜感激:~)
使用这里展示的配置,null_resource.wait_for_healhtcheck
依赖于aws_security_group_rule.health_blue
。
(您目前已经冗余地指定了该依赖关系:triggers
中对aws_security_group_rule.health_blue
的引用已经建立了依赖关系,因此depends_on
参数在这里没有任何作用,我建议删除它。)
Terraform中依赖的一般含义是对依赖对象采取的任何操作必须发生在对其依赖对象采取的任何操作之后。在您的案例中,Terraform保证在创建计划之后,如果有任何针对这两个资源的操作计划,那么在应用步骤中,为aws_security_group_rule.health_blue
计划的操作将始终首先发生。
你正在使用null_resource
的triggers
参数,它增加了一个由hashicorp/null
提供程序而不是由Terraform Core本身实现的额外行为:在规划期间,null_resource
将比较来自先前状态的triggers
值与当前配置中的triggers
值,如果它们不同,那么它将提出替换(纯粹概念性的)null_resource
对象的行动。
因为triggers
包含aws_security_group_rule.health_blue[0].id
,所以每次计划创建或替换安全组时,triggers
将使用一个新值。因此总的来说,你的配置声明如下:
- 0或1个
aws_security_group_rule.health_blue
对象 - 每当安全组的
id
属性发生变化时,必须替换null_resource.wait_for_healhtcheck
。 - 每当创建或替换
null_resource.wait_for_healhtcheck
时,运行给定的提供程序。 - 因此,如果安全组的
id
属性发生变化,总是会有创建(或替换)aws_security_group_rule.health_blue
的计划和替换null_resource.wait_for_healhtcheck
的计划。依赖规则意味着安全组的创建将发生在null_resource
的创建之前,因此在运行提供程序之前。
因此,您的配置似乎符合您所述的要求。但是,它确实有一个可能导致问题的不一致:您没有考虑到如果没有aws_security_group_rule.health_blue
实例应该发生什么。在这种情况下,aws_security_group_rule.health_blue[0].id
无效,因为没有该资源的第0个实例可以引用。
为了解决这个问题,我建议简化一下:null_resource
资源并没有真正在这里添加任何你不能直接使用aws_security_group_rule
资源做的事情:
resource "aws_security_group_rule" "health_blue" {
count = data.external.blue_eks_cluster.result.cluster_status == "online" ? 1 : 0
description = "LB healthchecks to blue cluster"
cidr_blocks = values(data.aws_subnet.eks_gateway).*.cidr_block
from_port = 80
protocol = "tcp"
security_group_id = data.aws_security_group.blue_cluster_sg[0].id
to_port = 80
type = "ingress"
provisioner "local-exec" {
command = "echo 'Waiting for 25 seconds'; sleep 25"
}
}
资源的提供程序作为该资源的创建操作的一部分运行,并且更改安全组规则的配置应该导致重新创建该资源,因此使用上述配置,sleep 25
命令将在每次创建安全组规则实例时运行,而不需要单独的资源。
此解决方案假设您只需要在创建(或替换)安全组规则时运行sleep 25
。如果目标是运行提供程序以响应更新其他资源,则需要null_resource
方法,因为在这种情况下,null_resource
资源将充当一种适配器,允许将triggers
中任何值的更新视为对资源的替换。