我已经能够通过Gitlab-CI完全构建和测试我的应用程序。
如何使用CodeDeploy和CodePipeline从Gitlab-CI将应用程序部署到Amazon EC2?
请看下面的指南。
本指南假定以下内容:
提供的 .gitlab-ci.yml
示例基于 Java/Scala + Gradle 项目。该脚本提供了一个通用示例,当通过此方法实现持续交付时,需要根据您的具体需求进行调整。
本指南假定用户具有关于AWS服务和执行必要任务的基本知识。
注意:此示例提供的指南使用AWS控制台执行任务。虽然这里执行的任务可能有CLI等效,但本指南不会覆盖它们。
创建这些脚本和部署指南的动机来自于缺乏适当的教程,展示如何使用Gitlab和AWS EC2实现持续交付。 Gitlab通过与Digital Ocean合作引入了他们免费的CI引擎,使用户存储库可以免费受益于高质量的CI。
使用Gitlab的主要优势之一是他们提供内置的持续集成容器,用于运行各个步骤并验证构建。 不幸的是,Gitlab和AWS都没有提供一种集成方式,以便在通过构建后执行持续交付。
本指南和脚本(https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/)提供了我为成功使用Gitlab和AWS EC2进行CI和CD所采取的步骤的简化版本,可以帮助任何其他人开始使用这种类型的实现。
确保成功进行持续交付的第一步是在AWS上设置必要的对象,以便允许部署过程成功。
最初的要求将是设置IAM用户:
https://console.aws.amazon.com/iam/home#users
Attach the following permissions:
Inline Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:*",
"codedeploy:*",
"ec2:*",
"elasticloadbalancing:*",
"iam:AddRoleToInstanceProfile",
"iam:CreateInstanceProfile",
"iam:CreateRole",
"iam:DeleteInstanceProfile",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:GetInstanceProfile",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListInstanceProfilesForRole",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:RemoveRoleFromInstanceProfile",
"s3:*"
],
"Resource": "*"
}
]
}
Generate security credentials
https://console.aws.amazon.com/iam/home#roles
创建一个新角色,分配给你的EC2实例,以便访问S3,https://console.aws.amazon.com/ec2/v2/home
点击 启动实例
并按照以下步骤操作:
Amazon Linux AMI 2016.03.3 (HVM), SSD Volume Type
IAM 角色
为 MyDeploymentAppRole
(基于上一部分创建的名称)
MyApp-Production-Instance
)
您将有可能生成或使用 SSH 密钥。请选择适当的方法。
安装 CodeDeploy Agent
登录到您新创建的 EC2 实例并按照说明操作:
CodeDeploy重要路径:
/opt/codedeploy-agent/deployment-root/
/var/log/aws/codedeploy-agent/codedeploy-agent.log
提示:运行tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log
以实时跟踪部署。
安装项目的先决条件 如果您的项目有任何运行先决条件,请确保在运行部署之前安装这些内容,否则您的启动脚本可能会失败。
https://console.aws.amazon.com/s3/home
在这一步中,您需要创建一个 S3 存储桶来存储部署文件。创建存储桶
my-app-codepipeline-deployment
)属性
版本控制
菜单启用版本控制
https://console.aws.amazon.com/codedeploy/home#/applications
现在基本元素已经设置好,我们准备在CodeDeploy中创建部署应用程序。https://console.aws.amazon.com/codepipeline/home#/dashboard
下一步是创建CodePipeline,它负责在S3存储桶和CodeDeploy过程之间建立连接。Create Pipeline
MyAppDeploymentPipeline
)
Source Provider
设为 Amazon S3
Amazon S3 location
设置为您的存储桶和目标部署文件的地址 (例如:s3://my-app-codepipeline-deployment/myapp.zip
)Build Provider
设为 None
- 这已经由 Gitlab-CI 处理,稍后会介绍
Deployment Provider
设为 AWS CodeDeploy
Application Name
设为您的 CodeDeploy 应用程序名称 (例如:MyApp-Production
)Deployment Group
设为您的 CodeDeploy 部署组名称 (例如:MyApp-Production-Fleet
)Create Pipeline
现在AWS环境已经准备好接收应用程序部署,我们可以开始设置CI环境和设置,以确保使用S3、CodeDeploy和CodePipeline将代码构建并部署到EC2实例。
为了使部署工作正常,我们需要在项目存储库中设置一些环境变量。
在您的Gitlab项目中,导航到项目的变量
区域,并设置以下变量:
AWS_DEFAULT_REGION
=> 您的AWS区域AWS_SECRET_ACCESS_KEY
=> 您的AWS用户凭证密钥(生成用户凭证时获取)AWS_ACCESS_KEY_ID
=> 您的AWS用户凭证密钥ID(生成用户凭证时获取)AWS_S3_LOCATION
=> 部署zip文件的位置(例如:s3://my-app-codepipeline-deployment/my_app.zip
)这些变量将由Gitlab-CI容器执行的脚本访问。
提供了一个简单的启动脚本(https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/blob/master/deploy/extras/my_app.sh),以便进行以下任务:
您可以在deploy/extras/my_app.sh
下找到此脚本。
gitlab-ci.yml
文件负责执行与给定提交相关的持续集成任务。它充当一组简化的shell脚本,这些脚本按阶段组织,这些阶段对应于您的持续集成步骤中的不同阶段。
有关详细信息和参考,请参阅以下两个链接:
你可以使用以下工具随时验证你的gitlab-ci.yml
文件的语法: https://gitlab.com/ci/lint
为了部署的目的,我们将仅涵盖本指南提供的示例的最后一部分。deploy-job:
# Script to run for deploying application to AWS
script:
- apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
- pip install -U pip # pip update
- pip install awscli # AWS CLI installation
- $G build -x test -x distTar # # Build the project with Gradle
- $G distZip # creates distribution zip for deployment
- aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
# requires previous CI stages to succeed in order to execute
when: on_success
stage: deploy
environment: production
cache:
key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME"
untracked: true
paths:
- build/
# Applies only to tags matching the regex: ie: v1.0.0-My-App-Release
only:
- /^v\d+\.\d+\.\d+-.*$/
except:
- branches
- triggers
# Script to run for deploying application to AWS
script:
- apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
- pip install -U pip # pip update
- pip install awscli # AWS CLI installation
- $G build -x test -x distTar # # Build the project with Gradle
- $G distZip # creates distribution zip for deployment
- aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
pip
。需要使用pip
来安装AWS CLI,以便将部署文件上传到AWS S3。$G
定义);Gradle提供了一个模块来自动压缩部署文件。根据您正在部署的项目类型,生成分发zip文件my_app.zip
的方法将有所不同。
aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION
命令将分发zip文件上传到我们之前定义的Amazon S3位置。然后,该文件将被CodePipeline自动检测、处理并发送到CodeDeploy。最后,CodeDeploy通过appspec.yml
文件指定的CodeDeploy代理执行必要的任务。appspec.yml
appspec.yml
定义了CodeDeploy在收到部署文件后要遵循的行为。appspec.yml
文件的详细信息: http://docs.aws.amazon.com/codedeploy/latest/userguide/app-spec-ref.html
生成部署Zip文件appspec.yml
=> CodeDeploy部署说明
- 部署阶段脚本
- 提供的示例将放置在zip文件中的scripts
目录中,需要在应用程序目录的根目录(即my_app
目录在zip中)添加my_app.sh
脚本。
- 发布代码-在我们的示例中,它将位于my_app
目录下。
像Gradle和Maven这样的工具能够通过对zip生成过程进行某些更改来生成分发zip文件。如果您不使用这样的工具,您可能需要指示Gitlab-CI以不同的方式生成此zip文件;这种方法超出了本指南的范围。
本指南的最后一步是执行成功的部署。
持续集成的阶段由gitlab-ci.yml
中设置的规则定义。本指南提供的示例将为与以下正则表达式匹配的任何参考启动部署:/^v\d+\.\d+\.\d+-.*$/
。
在这种情况下,通过git将标签v1.0.0-My-App-Alpha-Release
推送到您的远程Gitlab将启动部署过程。您可以根据项目要求调整这些规则。
当检测到标签v1.0.0-My-App-Alpha-Release
时,gitlab-ci.yml
提供的示例将执行以下作业:
一旦分发压缩包被上传到Amazon S3,以下步骤将会发生:
appspec.yml
的files
部分定义的部署位置成功部署的截图:
The deployment failed because a specified file already exists at this location : /path/to/file
。这是因为我已经有文件在该位置上,因为我正在使用一个已存在的实例,并且服务器已经在运行中。.gitlab-ci.yml
中,我做了如下更改:deploy:
stage: deploy
script:
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" # Downloading and installing awscli
- unzip awscliv2.zip
- ./aws/install
- aws deploy push --application-name App-Name --s3-location s3://app-deployment/app.zip # Adding revision to s3 bucket
- aws deploy create-deployment --application-name App-Name --s3-location bucket=app-deployment,key=app.zip,bundleType=zip --deployment-group-name App-Name-Fleet --deployment-config-name CodeDeployDefault.OneAtATime --file-exists-behavior OVERWRITE # Ordering the deployment of the new revision
when: on_success
only:
refs:
- dev
--file-exists-behavior
的aws deploy create-deployment
行。有三个选项可用,OVERWRITE
是我需要的选项,我无法通过CodePipeline设置此标志,因此我选择了cli选项。aws deploy push
命令,在s3存储桶上为我创建.zip。