You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在销毁EC2资源前执行命令?Terraform远程执行需求咨询

实现Terraform销毁VM/EC2前执行命令的方法

方法一:使用Terraform的destroy-time provisioner(通过remote-exec执行)

Terraform支持在资源销毁阶段触发provisioner,只需显式指定when = "destroy"。针对EC2实例,配置示例如下:

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0" # 替换为你的目标AMI
  instance_type = "t2.micro"

  # 销毁前执行的清理命令
  provisioner "remote-exec" {
    when        = "destroy"
    inline = [
      "echo 'Instance is being destroyed, running cleanup...'",
      # 替换为你需要执行的具体命令,比如备份数据、停止服务等
      "sudo systemctl stop my_app_service",
      "aws s3 sync /app/data s3://my-backup-bucket/instance-${self.id}-backup"
    ]

    connection {
      type        = "ssh"
      user        = "ec2-user" # 根据AMI调整,Ubuntu为ubuntu,CentOS为centos
      private_key = file("~/.ssh/id_rsa")
      host        = self.public_ip
    }
  }
}

注意事项:

  • 确保销毁时Terraform能连通实例:安全组需允许SSH(Windows用WinRM)访问,实例公/私网IP对Terraform运行环境可达,密钥对有效。
  • 若实例部署在私有网络,需Terraform环境能访问私网(比如通过跳板机、VPN),否则连接失败会导致销毁流程中断。
  • 若provisioner执行失败,Terraform会终止销毁,需手动处理后重新执行terraform destroy。

方法二:利用EC2生命周期钩子+SSM Run Command(无Terraform依赖场景)

如果担心Terraform销毁时无法连接实例,可通过AWS原生服务触发清理:

实现步骤:

  1. 创建IAM角色,允许Lambda调用SSM SendCommand,并拥有EC2实例的访问权限。
  2. 编写Lambda函数,捕获EC2终止事件,通过SSM在目标实例执行命令:
import boto3

ssm = boto3.client('ssm')

def lambda_handler(event, context):
    instance_id = event['detail']['instance-id']
    try:
        ssm.send_command(
            InstanceIds=[instance_id],
            DocumentName='AWS-RunShellScript',
            Parameters={
                'commands': [
                    'echo "Termination detected, starting cleanup"',
                    'sudo rm -rf /tmp/temp_work_dir',
                    'sudo tar -czf /var/log/app_backup.tar.gz /var/log/my_app'
                ]
            }
        )
    except Exception as e:
        print(f"Failed to send command: {str(e)}")
        raise e
  1. 创建CloudWatch Event规则,捕获EC2的Instance Terminate事件,触发上述Lambda函数。
  2. 确保目标EC2实例已安装SSM Agent(Amazon Linux 2默认预装,其他系统需手动安装)。

注意事项:

  • 生命周期钩子有默认300秒超时限制,需确保清理命令能在超时前完成。
  • 此方法不依赖Terraform连接,适合网络隔离或Terraform环境无法访问实例的场景。

方法三:实例内监听终止信号(本地可靠方案)

在EC2实例内部,通过监听元数据的终止通知触发本地脚本:

  1. 编写后台监听脚本/usr/local/bin/termination-cleanup.sh:
#!/bin/bash
while true; do
    # 检查是否收到终止通知
    if curl -s http://169.254.169.254/latest/meta-data/spot/termination-time > /dev/null; then
        echo "Termination signal received, executing cleanup..."
        # 执行清理操作
        sudo systemctl stop my_app
        aws s3 cp /app/config s3://my-config-bucket/instance-backup/$(hostname)
        break
    fi
    sleep 5
done
  1. 将脚本注册为系统服务,确保实例启动时自动运行:
sudo tee /etc/systemd/system/termination-cleanup.service <<EOF
[Unit]
Description=Run cleanup on instance termination

[Service]
ExecStart=/usr/local/bin/termination-cleanup.sh
Restart=always
User=root

[Install]
WantedBy=multi-user.target
EOF

sudo chmod +x /usr/local/bin/termination-cleanup.sh
sudo systemctl daemon-reload
sudo systemctl enable termination-cleanup.service

注意事项:

  • 适用于所有EC2实例(按需/Spot),无需外部服务依赖。
  • 需给实例附加IAM角色,赋予S3等服务的访问权限(如需上传备份)。

内容的提问来源于stack exchange,提问作者Dhananjay Gahiwade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:40:39