当我使用 CloudFormation 预置 Amazon EC2 实例时,如何确保部署 CodeDeploy 代理?

上次更新日期: 2022 年 3 月 11 日

我正在使用 AWS CloudFormation 预置我的基础设施和 AWS CodeDeploy 资源。如何确保在我的 Amazon Elastic Compute Cloud (Amazon EC2) 实例上安装并运行 CodeDeploy 代理?

简短描述

如果您创建以下任一资源作为 CodeDeploy 部署的目标,请使用 cfn-initcfn-signal 帮助程序脚本:

  • AWS::EC2::Instance
  • AWS::AutoScaling::AutoScalingGroup

在您预置基础设施部署之前,可以使用帮助程序脚本,通过 CodeDeploy 代理完全预置目标实例。

解决方法

要使用 cfn-initcfn-signal 帮助程序脚本部署 CodeDeploy 代理,请完成以下步骤以正确配置 AWS CloudFormation 模板。

1.    在代码编辑器中,创建 JSON 或 YAML 文件,以便为您的资源使用 AWS CloudFormation 模板。

2.    对于 Metadata 密钥,使用 AWS::CloudFormation::Init 类型,以便为您的实例或启动配置包含元数据。

使用 AWS::CloudFormation::Init 类型的元数据密钥示例

"SampleLinuxInstance" : {
            "Type" : "AWS::EC2::Instance",
            "Metadata" : {
                "AWS::CloudFormation::Init" : {
                    "config" : {
                        "packages" : {
                            "yum" : {
                                "ruby" : []
                            }
                        },
                        "files" : {
                            "/home/ec2-user/install" : {
                                "source" : {"Fn::Join" : ["", ["https://aws-codedeploy-", {"Ref" : "AWS::Region"}, ".s3.amazonaws.com/latest/install"]]},
                                "mode" : "000755"
                            }
                        },
                        "commands" : {
                            "00-install-agent" : {
                                "command" : "./install auto",
                                "cwd" : "/home/ec2-user/"
                            },
                            "01-cfn-signal" : {
                                "command" : {"Fn::Join" : ["", ["/opt/aws/bin/cfn-signal -e 0 --stack ", { "Ref": "AWS::StackName" }, " --resource SampleLinuxInstance --region ", { "Ref" : "AWS::Region" }]]}
                            }
                        }
                    }
                }
            },
            "Properties" : {
                ...
            }
        }

注意: AWS::CloudFormation::Init 类型包括 CodeDeploy 代理的安装步骤。它还包含在您完成以下步骤后向 CloudFormation 堆栈返回信号的命令。

3.    设置 UserData 属性以调用 cfn-init 脚本。

调用 cfn-init 脚本的 UserData 属性示例

"Properties" : {
                "InstanceType" : "t2.micro",
                "ImageId" : {"Ref" : "AMI"},
                "IamInstanceProfile" : {"Ref" : "SampleInstanceProfile"},
                "KeyName" : {"Ref" : "SSHKey"},
                "UserData" :  {"Fn::Base64" : {
                    "Fn::Join" : ["", [
                        "#!/bin/bash\n",
                        "yum -y update\n",
                        "yum -y install cfn-bootstrap\n",
                        "/opt/aws/bin/cfn-init -v",
                        " --stack ", { "Ref" : "AWS::StackName" },
                        " --resource SampleLinuxInstance",
                        " --region ", { "Ref" : "AWS::Region" }, 
                        "\n"
                    ]]
                }},
                "Tags" : [
                    {
                        "Key" : {"Ref" : "InstanceTagKey"},
                        "Value" : {"Ref" : "InstanceTagValue"}
                    }
                ]
            }

4.    对于实例资源,配置 CreationPolicy 属性以执行以下操作: 要求 Amazon EC2 实例或 Amazon EC2 Auto Scaling 组在指定时段内发送成功信号到 CloudFormation。

CreationPolicy 属性示例,该属性要求 Amazon EC2 实例在指定时间段内发送成功信号到 CloudFormation

"SampleLinuxInstance" : {
            "Type" : "AWS::EC2::Instance",
            "CreationPolicy" : {
                "ResourceSignal" : {
                    "Count" : "1",
                    "Timeout" : "PT5M"
                }
            },

5.    要为 Amazon EC2 实例或 Amazon EC2 Auto Scaling 组上的部署组资源创建显式依赖关系,使用 DependsOn 属性

为部署组资源创建显式依赖关系的 DependsOn 属性示例

"SampleLinuxCDDeploymentGroup" : {
            "Type" : "AWS::CodeDeploy::DeploymentGroup",
            "DependsOn" : "SampleLinuxInstance",
            "Properties" : {
                "ApplicationName" : {"Ref" : "SampleCDApp"},
                "ServiceRoleArn" : {"Ref" : "ServiceRole"},
                "Ec2TagFilters" : [
                    {
                        "Key" : {"Ref" : "InstanceTagKey"},
                        "Value" : {"Ref" : "InstanceTagValue"},
                        "Type" : "KEY_AND_VALUE"
                    }
                ],
                "Deployment" : {
                    "Revision" : {
                        "RevisionType" : "S3",
                        "S3Location" : {
                            "Bucket" : {"Ref" : "BucketName"},
                            "BundleType" : {"Ref" : "BundleType"},
                            "Key" : {"Ref" : "BundleKey"}
                        }
                    }
                }
            }
        }

6.    要完成 CloudFormation 模板,将任何其他附加资源、属性或您的环境所需的输出包括在内。

7.    使用已完成的模板创建 CloudFormation 堆栈