如何在每次Terraform Apply时运行Connection Provisioner且不重建EC2资源
解决方案:让null_resource的Provisioner每次Apply都运行
要让null_resource的connection和所有provisioner每次执行terraform apply都运行,且不重建依赖的EC2,核心是让null_resource每次apply都触发重建——因为provisioner仅在资源创建/重建时执行,而connection是provisioner执行前的前置步骤,只要资源重建,就会重新建立连接并执行所有provisioner。
你当前的代码里已经加了always_run = timestamp()到triggers,但可能没生效或者误解了taint的作用。以下是修正后的完整配置和说明:
修正后的代码
resource "null_resource" "resource_null" { depends_on = [aws_instance.public-ec2] triggers = { # 每次apply时timestamp()都会生成新值,触发null_resource重建 always_run = timestamp() # 保留必要的依赖值,确保EC2状态变化时也能触发 aws_public_ip = aws_instance.public-ec2.public_ip aws_ec2_key_pair = tls_private_key.tls_pk.private_key_pem } connection { type = "ssh" host = self.triggers.aws_public_ip user = "ec2-user" password = "" private_key = self.triggers.aws_ec2_key_pair } provisioner "file" { source = "./myKey.pem" destination = "/tmp/myKey.pem" } provisioner "remote-exec" { inline = ["sudo chmod 400 /tmp/myKey.pem"] } }
关键说明
timestamp()触发重建:triggers里的always_run = timestamp()会在每次terraform apply时生成新的时间戳,导致null_resource的触发器值变化,Terraform会自动销毁旧的null_resource并创建新的,此时所有provisioner会重新执行,connection也会在provisioner执行前重新建立。- 无需手动taint:手动标记taint确实会触发资源重建,但你的情况中可能因为
connection配置的引用问题导致未执行?用timestamp()的方式更可靠,无需手动操作。 - 保留依赖值:
aws_public_ip和aws_ec2_key_pair留在triggers里,确保当EC2的公网IP或密钥变化时,也能触发null_resource的重建和provisioner执行。
验证方法
执行terraform apply后,你会看到Terraform提示null_resource.resource_null将被替换,随后会建立SSH连接,执行file和remote-exec provisioner。
内容的提问来源于stack exchange,提问作者chetan
相关产品推荐
相关产品推荐

