Terraform按顺序创建资源



需要使用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_resourcetriggers参数,它增加了一个由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中任何值的更新视为对资源的替换。

最新更新