AWS CodeDeploy I

AWS CodeDeploy 将程序部署到各种计算资源,例如EC2、Fargate、Lambda或on-premise机器上。使用CodeDeploy可以将软件部署过程自动化,减少人工部署的出错风险

在本节我们使用CodeDeploy部署WAR包到EC2上,为了简化实验,只会部署到一台机器上。在生产环境要把它部署在多台机器上并使用ELB做负载均衡

内容分为两部分,在第一部分我们先创建一台EC2,在第二部分使用CodeDeploy将程序部署到EC2并在浏览器中查看效果

progress-diagram-codedeploy.png (699×429)

创建EC2 Role

CodeDeploy使用SSM(AWS System Manager)来将它的agent安装到EC2上,所以在创建EC2前,先准备好对应的Role。

进入IAM页面,点击Create role

image-20220312142057008

选择EC2,并进入下一步:

image-20220312142114428

首先添加AmazonSSMManagedInstanceCore权限:

image-20220312142149254

再添加AmazonS3ReadOnlyAccess权限,此权限用于EC2后面从S3下载WAR文件并进行部署:

image-20220312142217687

为Role命名为ec2-role-for-codedeploy, 并保存:

image-20220312142253328

创建EC2机器

接下来我们将创建一台EC2,用于部署web程序。

在EC2页面,点击Launch Instances

image-20220312104239745

使用新版创建EC2 的UI:

image-20220312142335206


第一步添加标签,点击Add additional tags

添加两个标签,Name => webserver, role => webserver, 在后面CodeDeploy将使用role=>webserver这个标签,决定将程序部署到哪些机器上。

image-20220312104719019

创建新的密钥对:

image-20220312104509775

为密钥对命名并创建:

image-20220312104519783

在网络设置部分,放开80和443端口,用于后面在浏览器中访问部署的Web应用:

image-20220312104604828

在高级设置部分,选择上一步创建好的Role,绑定到EC2上

image-20220312142438564

点击Launch Instance创建机器。

创建CodeDeploy的部署脚本

CodeDeploy将使用代码库下的脚本来执行详细的部署命令,所以我们先提前准备好,并提交到代码仓库里。

切换到Cloud 9, 在项目目录下创建scripts文件夹,并在里面创建install_dependencies.sh文件,内容如下:

#!/bin/bash
sudo yum install tomcat -y
sudo yum -y install httpd
sudo cat << EOF > /etc/httpd/conf.d/tomcat_manager.conf
<VirtualHost *:80>
    ServerAdmin root@localhost
    ServerName app.wildrydes.com
    DefaultType text/html
    ProxyRequests off
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/unicorn-web-project/
    ProxyPassReverse / http://localhost:8080/unicorn-web-project/
</VirtualHost>
EOF

image-20220310115937622

scripts文件夹继续创建start_server.sh文件,内容如下:

#!/bin/bash
sudo systemctl start tomcat.service
sudo systemctl enable tomcat.service
sudo systemctl start httpd.service
sudo systemctl enable httpd.service

scripts文件夹创建stop_server.sh文件,内容如下:

#!/bin/bash
isExistApp=pgrep httpd
if [[ -n $isExistApp ]]; then
sudo systemctl stop httpd.service
fi
isExistApp=pgrep tomcat
if [[ -n $isExistApp ]]; then
sudo systemctl stop tomcat.service
fi

CodeDeploy使用appspec.yml文件来指定部署时要运行哪些脚本,在项目根目录下创建此文件,内容如下:

version: 0.0
os: linux
files:
  - source: /target/unicorn-web-project.war
    destination: /usr/share/tomcat/webapps/
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root

CodeDeploy将使用S3中构建完成的zip包进行部署,所以要将上面创建的这些文件一起打包到zip中,更新buildspec.yml:

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto8
  build:
    commands:
      - echo Build started on `date`
      - mvn test
  post_build:
    commands:
      - echo Build completed on `date`
      - mvn package
artifacts:
  files:
    - target/unicorn-web-project.war
    - appspec.yml
    - scripts/**/*
  discard-paths: no

将代码提交到CodeCommit:

cd ~/environment/unicorn-web-project
git add *
git commit -m "Adding CodeDeploy files"
git push -u origin main

切换到CodeCommit页面,点击Start build,重新构建一遍项目,将我们上面添加的文件打包到新的zip包里:

image-20220312150642995