如何获取重新构建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。
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-element" {
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}";
aws deploy create-deployment --application-name <appName> --s3-location <s3 location> --deployment-group-name <group name>;
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]
}
}
}
注意:TTBOMK,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 文件的任何更改都会正确暂存到 S3,然后重新部署到现有 EC2 实例。
但是,如果我必须仅对 EC2 实例进行更改,例如对 userdata
进行更改,则
EC2 实例会正确重建,但 AWS CodeDeploy 不会重新应用到重建的 EC2 实例.
将
id
资源的
time_sleep
嵌入到 appspec.yml
文件中的注释中。此 id
将在 local-exec
执行期间填充。然后,在 template_dir
资源中,使用
depends_on = time_sleep.ec2_instance_delay]
资源的 id
参数,将显式 time_sleep
更改为对 vars
资源 template_dir
的隐式依赖关系。由于 time_sleep
资源会在
EC2 instance.arn
上触发,因此只要 ec2_instance.arn
发生变化,它就会重新生成。这将导致 local-exec
重新生成、暂存并重新部署到具有适当匹配标签的所有 EC2 实例。 代码
appspec.yml
# ${time_stamp}
main.tf
template_dir {
// Replace explicit dependency with an implicit dependency
vars = merge({
time_stamp = time_sleep.ec2_instance_delay.id
})
...
}