AWS CodeDeploy将代码自动部署至Amazon EC2

AWS CodeDeploy是完全托管的部署服务,可将代码部署到EC2实例,Fargate,Lambda及本地服务器。使用AWS CodeDeploy通过自动化部署的方式,减少部署时的停机时间并提高工作效率。

这次有机会使用CodeDeploy服务,在这里总结一下使用的经验。

CodeDeploy的源可指定如下资源。

  • S3
  • GitHub

CodeDeploy部署目标为如下。

  • Amazon EC2
  • AWS Fargate
  • AWS Lambda
  • 本地服务器

CodeDeploy能做什么?

CodeDeploy能做的事情很多,但是对于我来说感到最大魅力的有以下3点。

  1. 执行Shell Script
    不是单纯地执行 git pull origin master,还可以执行Shell Script清除缓存,进行服务重启等,实际上什么都可以做。

  2. 管理ELB下的EC2群
    当把代码部署到ELB下的EC2时,自动从ELB移除EC2,完成部署后重新添加到ELB。

  3. 部署触发器
    将代码代码发布到Master分支时,触发自动部署。

CodeDeploy的机制

说安装过程之前,简要解释CodeDeploy的工作方式。

以Amazon EC2为例首先安装并启动CodeDeploy Agent,CodeDeploy Agent的作用是定期向AWS查询有没有部署指令。如果有deploy指令,将根据指令开始部署。

接下来以Amazon Linux为例介绍CodeDeploy的使用方法。

配置CodeDeploy

在AWS管理页面配置CodeDeploy之前需要做如下准备。

  1. 创建IAM Role
  2. 在Amazon EC2安装CodeDeploy Agent
  3. 创建appspec.yml

1. 创建IAM Role

需给Amazon EC2Deploy Group赋予的IAM Role,赋予的策略是AWS管理策略

  • EC2的IAM Role需要AmazonEC2RoleforAWSCodeDeploy策略
  • Deploy Group的IAM Role需要AWSCodeDeployRole策略

2. 在Amazon EC2安装CodeDeploy Agent

需要 aws cliRuby,因Amazon Linux已安装aws cli,在这里仅安装Ruby。

# yum install ruby
# cd /tmp
# aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
# chmod +x ./install
# ./install auto

安装CodeDeploy Agent后确认,服务状态。

# service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 7412

3. 创建appspec.yml

在GitHub的Repository的根目录下创建appspec.yml,appspec.yml的内容如下。

version: 0.0
os: linux
files:
  - source: ./
    destination: /tmp/demo
hooks:
  BeforeInstall:
    - location: scripts/before.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/after.sh
      timeout: 300
      runas: root

version指定部署版本。

os指定部署环境系统,Amazon Linux或Ubuntu Server时为linux,Windows Server时指定windows。

files指定CodeDeploy安装在EC2实例上的文件或目录。 将应用程序修订版中的文件或目录复制到实例上的特定位置。设置源对和目标,可以指定多个。

源(source)指定修订版本复制的文件或目录,可以指定以下格式。该路径是修订版本根目录的相对路径。

  • 指定文件名时,复制该文件到目标路径
  • 指定目录名时,将复制目录及目录中的所有文件
  • 如果指定/,将复制修订版的所有文件及目录

目标(destination)指定保存文件的绝对路径。

hooks可以在部署的任何阶段执行脚本。 可以设置location(脚本位置),timeout(脚本执行超时)和runas(执行脚本的用户)。

上面的图面来自AWS官网,示意CodeDeploy的生命周期。左侧图为无ELB右侧图为ELB下的部署,右侧图因有从ELB移除及添加的操作所以步骤比左侧图多一些。黑色的部分为执行Shell Script。

简单介绍一下生命周期。

Action 内容
ApplicationStop 停止应用程序的处理
DownloadBundle CodeDeployAgent将应用程序Revision文件复制到一个临时位置
BeforeInstall 在安装之前执行的处理,用于预安装任务,例如创建当前版本的备份
Install CodeDeployAgent将Revision文件复制到指定目录
AfterInstall 安装后的处理,可用于配置应用程序和更改文件权限之类的任务
ApplicationStart 启动在ApplicationStop停止的应用程序
ValidateService 确认部署状态
BeforeBlockTraffic 从ELB移除之前的处理
BlockTraffic 从ELB移除
AfterBlockTraffic 从ELB移除后的处理
BeforeAllowTraffic 添加到ELB之前的处理
AllowTraffic 添加到ELB
AfterAllowTraffic 添加到ELB后的处理

配置CodeDeploy

创建Application

AWS管理页面访问CodeDeploy,选择Deploy下的Applications后点击 Create application。

输入 Application Name 和 Compute Platform 后点击 Create application。

Compute Platform 可选择的有以下3种。

  • EC2/On-premises
  • AWS Lambda
  • Amazon ECS

接下来点击 Create deployment group。

创建Deployment Group

输入Deployment group名称及赋予CodeDeploy的IAM的ARN。

部署环境选择 Amazon EC2 instances后,设定tag。

在这里部署方式选择 CodeDeployDefault.OneAtAtime。

默认部署方式有以下3种。

  • CodeDeployDefault.OneAtATime
  • CodeDeployDefault.HalfAtATime
  • CodeDeployDefault.AllAtOnce

也可点击 Create deployment configuration进行自定义。

在这里不使用ELB,因此不勾选 Enable load balancing。

可选择ALB及NLB及Classic Load Balancer。

高级选项使用默认值,点击Create deployment group。

进行部署

在这里S3作为源,首先把ihack.zip保存到S3上。该文件包含 appspec.yml 文件及 App 文件夹。appspec.yml 内容如下,把该文件夹的所有文件及文件夹部署到服务器的 /tmp/demo 目录下。

version: 0.0
os: linux
files:
   - source: /
     destination: /tmp/demo

选择 Deployments Tab后,点击 Create deployment。

deployment group选择在上面创建的 demoDeploymentGroup,Revision Type选择 S3 后,输入ihack.zip文件在S3上的路径。

勾选 Fail the deployment 后,点击 Create deployment。

显示部署成功。

登录服务器后,cd至 /tmp/demo 目录后,执行 tree 命令查看部署情况。