Terraform无trigger选项时如何定义执行顺序?是否遵循main.tf编写顺序?
嘿,我来帮你理清这两个问题:
1. Terraform是否按main.tf的编写顺序执行?
答案是否定的。Terraform不会严格按照你代码里的编写顺序来执行资源操作,它的执行逻辑是基于资源间的依赖关系构建的依赖图,然后按照拓扑排序的顺序来执行。比如,如果你先写了EC2实例,再写它依赖的VPC,Terraform依然会先创建VPC,再创建EC2——因为它能自动识别这种隐式依赖。
只有当资源之间没有任何隐式依赖时,Terraform才可能按照编写顺序执行,但这是不确定的,绝对不能依赖这种行为来控制执行流程。
2. 如何控制data "external"这类资源的执行顺序?
虽然data "external"没有triggers选项(你提到的应该是针对其他资源的触发机制),但我们可以通过两种可靠的方式来控制它的执行顺序:
方式一:利用隐式依赖(推荐)
如果后续资源需要用到data "external"的输出结果,Terraform会自动推断依赖关系,先执行data资源,再处理依赖它的资源。
比如你的例子中,假设EC2实例需要用到get_my_public_ip的结果:
data "external" "get_my_public_ip" { program = ["sh", "get_public_ip.sh"] } resource "aws_instance" "ec2" { # 引用data资源的结果,自动触发依赖 tags = { SourceIP = data.external.get_my_public_ip.result.ip } # 其他EC2配置... }
这样Terraform会先执行get_my_public_ip,再创建EC2实例。
方式二:显式声明depends_on(无引用时使用)
如果后续资源不需要引用data资源的结果,但你依然需要先执行data资源,就可以用depends_on来显式声明依赖。
比如你希望test_http_status这个data资源在db创建完成后再执行:
resource "aws_db_instance" "db" { # DB配置... } data "external" "test_http_status" { # 显式声明依赖于DB资源 depends_on = [aws_db_instance.db] program = ["sh", "check_http_status.sh"] }
针对你的目标顺序的完整示例
按照get_my_public_ip → ec2 → db → test_http_status的顺序,你可以这样配置:
# 1. 先执行获取公网IP的data资源 data "external" "get_my_public_ip" { program = ["sh", "get_public_ip.sh"] } # 2. 依赖get_my_public_ip,创建EC2 resource "aws_instance" "ec2" { # 隐式依赖:引用data的结果 tags = { PublicIP = data.external.get_my_public_ip.result.ip } # 其他EC2配置:比如AMI、实例类型等 ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" } # 3. 依赖EC2,创建DB resource "aws_db_instance" "db" { # 显式依赖EC2(如果不需要引用EC2属性的话) depends_on = [aws_instance.ec2] # DB配置:比如引擎、实例类等 engine = "mysql" instance_class = "db.t2.micro" allocated_storage = 20 db_name = "mydb" username = "admin" password = "password" skip_final_snapshot = true } # 4. 依赖DB,执行HTTP状态测试 data "external" "test_http_status" { # 显式依赖DB depends_on = [aws_db_instance.db] program = ["sh", "-c", "curl -s -o /dev/null -w '%{http_code}' http://${aws_db_instance.db.endpoint}:8080"] }
这样配置后,Terraform就会严格按照你期望的顺序执行:先获取公网IP,再创建EC2,接着创建DB,最后执行HTTP状态测试。
内容的提问来源于stack exchange,提问作者negabaro

