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

如何让重建的EC2实例触发新的AWS CodeDeploy部署?

问题

如何让重建后的EC2实例触发新的AWS CodeDeploy部署?

说明:问题并非出在EC2实例的首次部署阶段,而是在EC2实例被重建并重新部署时出现。

问题描述

在将AWS CodeDeploy部署到一组EC2实例时遇到循环依赖问题。AWS AppSpec元素的更新会按预期重新部署到现有EC2实例上,但如果仅对EC2实例进行修改(不会导致AWS CodeDeploy发生任何变化),当EC2实例重启并完成重新初始化后,AWS CodeDeploy并不会被重新应用到新的EC2实例上。

背景信息

基础设施通过Terraform部署。EC2实例完成初始化大约需要15分钟,因此任何AWS CodeDeploy操作都必须等待这15分钟才能在EC2实例上启动。因此,在AWS CodeDeploy配置中添加了depends_on依赖于Terraform的time_sleep资源,等待EC2实例完全启动后再尝试执行实际的AWS CodeDeploy部署。

Terraform伪代码

aws_instance "ec2_instance" {}
time_sleep "ec2_instance_delay" {
    create_duration = var.ec2_creation_delay
    triggers = {
        instance_arn = aws_instance.ec2_instance.arn
    }
}
template_dir {
    depends_on = [time_sleep.ec2_instance_delay]
    provisioner "local-exec" {
        interpreter = ["/bin/bash", "-c"]
        command     = <<EOC
true;
export AWS_ACCESS_KEY_id=${};
export AWS_SECRET_ACCESS_KEY=${};
export AWS_SESSION_TOKEN=${};
aws deploy push --application-name ${aws_codedeploy_app.my_app.name} --description ${} --s3-location <s3-location> --source "${template_dir.appspec[count.index].destination_dir}";
deploy_id=$(aws deploy create-deployment --application-name <appName> --s3-location <s3 location> --deployment-group-name <group name> --query 'deploymentId' --output text);
aws deploy wait deployment-successful --deployment-id $deploy_id;
EOC
    }
}
aws_codedeploy_app "my_app" {}
aws_codedeploy_deployment_group "my_app_group" {
    deployment_config_name = "CodeDeploymentDefault.AllAtOnce"
    ec2_tag_set {
        ec2_tag_filter {
            key   = "Name"
            type  = "KEY_AND_VALUE"
            value = aws_instance.ec2_instance.tags["Name"]
        }
    }
}

说明:Terraform没有aws_codedeploy_deployment资源,因此使用template_dir的appspec结合provisioner "local-exec"生成实际部署操作,最终命令行类似:

aws deploy create-deployment --application-name <appName> --s3-location <s3 location> --deployment-group-name <group name>

当前配置在部署脚本或AppSpec.yml文件更改时能正常工作,但仅修改EC2实例(比如修改userdata)时,EC2重建后CodeDeploy不会重新应用。


解决方案

1. 让部署触发资源感知EC2实例变化

当前template_dir仅在AppSpec内容变化时触发,需将EC2实例的ARN加入其触发器,确保EC2重建(ARN更新)时自动执行部署命令:

template_dir {
    triggers = {
        instance_arn = aws_instance.ec2_instance.arn
        appspec_hash = filemd5("${path.module}/appspec.yml")
    }
    depends_on = [time_sleep.ec2_instance_delay]
    provisioner "local-exec" {
        # 原有命令逻辑不变
    }
}

2. 修正CodeDeploy部署组标签匹配逻辑

检查aws_codedeploy_deployment_group中的标签配置(原伪代码存在语法错误:tags["Name]需修正为tags["Name"]),确保新重建的EC2实例标签与部署组过滤条件完全匹配。建议使用固定环境标签(如Environment: Production)替代实例名称,避免名称变动导致匹配失败。

3. 在EC2用户数据中主动触发部署

在EC2的userdata中添加初始化完成后的触发脚本,由实例自身主动发起CodeDeploy部署:

#!/bin/bash
# 等待实例初始化完成(根据实际调整时长)
sleep 900

# 确保CodeDeploy Agent已安装并运行
sudo yum install -y aws-codedeploy-agent
sudo service codedeploy-agent start

# 触发部署(需EC2实例IAM角色具备CodeDeploy操作权限)
aws deploy create-deployment --application-name <appName> --deployment-group-name <group name> --s3-location <s3 location>

4. 使用null_resource替代template_dir

null_resource更适合执行无状态本地命令,触发器配置更灵活:

null_resource "codedeploy_deployment" {
    triggers = {
        instance_arn = aws_instance.ec2_instance.arn
        appspec_hash = filemd5("${path.module}/appspec.yml")
        deployment_group_id = aws_codedeploy_deployment_group.my_app_group.id
    }

    depends_on = [time_sleep.ec2_instance_delay]

    provisioner "local-exec" {
        interpreter = ["/bin/bash", "-c"]
        command     = <<EOC
export AWS_ACCESS_KEY_ID=${var.aws_access_key}
export AWS_SECRET_ACCESS_KEY=${var.aws_secret_key}
export AWS_SESSION_TOKEN=${var.aws_session_token}

aws deploy push --application-name ${aws_codedeploy_app.my_app.name} --description "Deploy for instance ${aws_instance.ec2_instance.id}" --s3-location <s3-location> --source "${path.module}/deploy-source"

deploy_id=$(aws deploy create-deployment --application-name ${aws_codedeploy_app.my_app.name} --deployment-group-name ${aws_codedeploy_deployment_group.my_app_group.name} --s3-location <s3-location> --query 'deploymentId' --output text)

aws deploy wait deployment-successful --deployment-id $deploy_id
EOC
    }
}

内容的提问来源于stack exchange,提问作者A. Rick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:56