一、準備工作和先決條件
(1)被部署的實例,需要安裝codedeploy-agent,安裝方法
git clone https://github.com/aws/aws-codedeploy-agent.git cd aws-codedeploy-agent/bin ./install auto
或者用我從安裝過程中截獲的rpm包安裝也行,分享給大家wget即可
http://cypay-filesharing.s3.amazonaws.com/public/wangfei/codedeploy-agent-1.0-1.643.noarch.rpm
(2)創建一個存放代碼包的S3 bucket,此例中叫s3://CYPayCodeDeployBucket
,美東地區
(3)創建一個Instance Profile,並使新創建的EC2實例使用該Instance Profile,這個過程中還需要創建個IAM Role,並讓Role與Profile關聯,該過程授權EC2實例內部的CodeDeploy-Agent能從S3下載版本包。然後再創建一個Service Role給Codedeploy服務用,該服務需要一些EC2權限
大概創建過程:創建個IAM Role,授權AssumeRole和訪問版本存放S3,再創建個Instance Profile,然後將之前的Role關聯到Profile上;再創建個Role給CodeDeploy服務用;
具體過程:
創建文件 CodeDeployInstanceProfile-Trust.json
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
再創建一個文件CodeDeployInstanceProfile-Permissions.json
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:Get*", "s3:List*" ], "Effect": "Allow", "Resource":"arn:aws:s3:::CYPayCodeDeployBucket/*" } ] }
然後創建角色叫CodeDeployInstanceRole,並給Role加策略
aws iam create-role \ --role-name CodeDeployInstanceRole \ --assume-role-policy-document file://CodeDeployInstanceProfile-Trust.json aws iam put-role-policy \ --role-name CodeDeployInstanceRole \ --policy-name CDInstanceRole-Permissions \ --policy-document file://CodeDeployInstanceProfile-Permissions.json
然後創建instance profile,並把剛纔創建的Role附加到instance profile上,這樣使用這個instance profile創建的EC2實例,就擁有Role對應的權限和策略
aws iam create-instance-profile \ --instance-profile-name CodeDeployInstanceProfile aws iam add-role-to-instance-profile \ --instance-profile-name CodeDeployInstanceProfile \ --role-name CodeDeployInstanceRole
至此,一個具有codedeploy相關權限的Instance Profile就創建好了,創建自動部署的EC2實例的時候需要使用該Profile
接下來創建一個Service Role 這個是codedeploy服務用來在EC2實例中部署代碼的
創建文件 CodeDeployServiceRole-Trust.json
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "codedeploy.us-east-1.amazonaws.com", "codedeploy.us-west-2.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
再創建一個文件CodeDeployServiceRole-Permissions.json
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "autoscaling:PutLifecycleHook", "autoscaling:DeleteLifecycleHook", "autoscaling:RecordLifecycleActionHeartbeat", "autoscaling:CompleteLifecycleAction", "autoscaling:DescribeAutoscalingGroups", "autoscaling:PutInstanceInStandby", "autoscaling:PutInstanceInService", "ec2:Describe*" ], "Effect": "Allow", "Resource": "*" } ] }
創建一個角色CodeDeployServiceRole,然後將角色策略與角色相關聯
aws iam create-role \ --role-name CodeDeployServiceRole \ --assume-role-policy-document file://CodeDeployServiceRole-Trust.json aws iam put-role-policy \ --role-name CodeDeployServiceRole \ --policy-name CDServiceRole-Permissions \ --policy-document file://CodeDeployServiceRole-Permissions.json
獲取Role的相關信息,複製下來備用
aws iam get-role --role-name CodeDeployServiceRole --query "Role.Arn" --output text arn:aws:iam::154xxxxx7698:role/CodeDeployServiceRole # mark this down
第(3)步總結:
創建兩個Role
CodeDeployInstanceRole
CodeDeployServiceRole
創建一個InstanceProfile
CodeDeployInstanceProfile
注意事項:
Instance Profile必須創建實例的時候選擇,事後暫無辦法讓沒選InstanceProfile的實例使用某個Profile
CodeDeploy-agent目前只在最新版的Amazon Linux,Ubuntu,Windows 上測試過,而且自帶yum源中沒有
二、用CodeDeploy部署個新項目
(1)上一步已經創建好使用CodeDeployInstanceProfile這個Profile的EC2實例,並且打好標籤的(例如Name=cms.front),而且實例上已經裝好了codedeploy-agent
(2)準備代碼,此處用tomcat應用舉例。
解壓代碼,在工程目錄目錄裏添加scripts目錄和一個appspec.yml,例如下面這樣的目錄結構,scripts裏面放部署時使用的腳本,appspec.yml文件定義代碼部署到哪個,用什麼用戶在什麼階段執行什麼腳本
cms.front/ ├── appspec.yml ├── css/ ├── error.jsp ├── fonts/ ├── html/ ├── images/ ├── index.jsp ├── js/ ├── META-INF/ ├── scripts/ ├── static/ └── WEB-INF/
appspec.yml文件內容,格式要求非常嚴格,不允許多餘空白
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/tomcat/webapps/ hooks: BeforeInstall: - location: scripts/check_dependencies.sh timeout: 300 runas: root AfterInstall: - location: scripts/change_permissions.sh timeout: 300 runas: root ApplicationStart: - location: scripts/start_server.sh timeout: 300 runas: ec2-user ApplicationStop: - location: scripts/stop_server.sh timeout: 300 runas: ec2-user
首次部署,需要安裝依賴軟件和環境,之後做代碼更新時就不需要了
可以把啓動腳本寫成重啓腳本
這四個腳本我就不多說了,自定義性比較強
然後重新打包,只包含內容,不要將上級目錄也打進包
cd ~/version/cms.front/ && zip -r cms.front.v1.0.zip *
然後將版本包上傳到上述創建的Bucket裏CYPayCodeDeployBucket
官方文檔中介紹用aws deploy push
上傳,但是報錯了,也沒找到解決辦法,就用aws s3 cp
上傳的
Missing required parameter in input: "UploadId"
Unknown parameter in input: "uploadId", must be one of: Bucket, Key, UploadId
更新aws-cli也無用,有解決此錯誤的請告訴我
然後創建一個Application,理解成一個具有相同功能的一個代碼工程,此例爲cms.front
aws deploy create-application --application-name CMSTomcatApplication
然後將重新打包好的版本包push到S3上(這步報錯了,所以手動傳的)
aws deploy push \ --application-name CMSTomcatApplication \ --s3-location s3://CYPayCodeDeployBucket/cms.front.v1.0.zip \ --ignore-hidden-files
然後創建DeploymentGroup,理解成一組需要被部署相同代碼的EC2實例,此例爲cms.tomcat,按Tag來區分,或則按autoscal組來區分
aws deploy create-deployment-group \ --application-name CMSTomcatApplication \ --deployment-group-name CMSTomcatApplication \ --deployment-config-name CodeDeployDefault.OneAtATime \ --ec2-tag-filters Key=Name,Value=cms.tomcat,Type=KEY_AND_VALUE \ --service-role-arn arn:aws:iam::15xxxxxx698:role/CodeDeployServiceRole
最後一行爲上面創建的ServiceRole(讓吧返回值記錄下來來着,現在用到了)
然後創建一個部署,首次部署,跟代碼更新部署,和回滾部署,本質是一樣,沒區別
aws deploy create-deployment \ --application-name CMSTomcatApplication \ --deployment-config-name CodeDeployDefault.OneAtATime \ --deployment-group-name CMSTomcatApplication \ --s3-location bucket=CYPayCodeDeployBucket,bundleType=zip,key=cms.front.v1.0.zip
返回值
{ "deploymentId": "d-ROL5D7YPZ" }
可以查看該部署的狀態
aws deploy get-deployment --deployment-id d-ROL5D7YPZ --query 'deploymentInfo.status' "InProgress"
等進度從InProgress變成Succeeded就成功了,然後瀏覽器訪問下自己的代碼是否OK
三、 做次代碼更新和回滾
本質是一樣的,只不過版本包不同而已,可以吧首次部署的一些無用腳本刪除,回滾的話,會刪除就得部署新的
命令行的話,還是這樣
aws deploy create-deployment \ --application-name CMSTomcatApplication \ --deployment-config-name CodeDeployDefault.OneAtATime \ --deployment-group-name CMSTomcatApplication \ --s3-location bucket=CYPayCodeDeployBucket,bundleType=zip,key=cms.front.v1.1.zip
區別在於使用的版本包版本不同
版本更新和回退,使用web console用瀏覽器來做最爽
選擇你的Application,進到DeploymentGroup裏,然後選擇Deploy New Revision
此時Application和DeploymentGroup的下拉菜單應該已經都默認選好了,還可以改
選擇Revision Type,可選爲S3或者github,此例爲S3 bucket
Revision Location裏寫上版本包的全路徑,s3://CYPayCodeDeployBucket/cms.front.v1.1.zip
File Type會自動識別,支持zip,tar,tar.gz,別的格式沒試過,war跟zip一樣的吧
Deployment Description寫上版本說明
Deployment Config有三種可選
CodeDeployDefault.AllAtOnce, CodeDeployDefault.HalfAtATime, CodeDeployDefault.AllAtATime.
AllAtOnce:組中所有實例一次部署完(同時併發?),有成功的實例就算此次部署成功,都部署失敗就算此次部署失敗
HalfAtATime:一次部署一半實例,分兩次部署完,一半以上實例成功纔算部署成功,一半以上失敗就算部署失敗
AllAtATime:一次部署一臺,直至全部完成,所有實例都部署成功纔算成功,有失敗的就算部署失敗(這個最符合我的需求,可以在起服腳本中加上sleep來實現一臺一臺來更新,並間隔幾百秒)
點擊Deploy Now來完成部署,等到刷新狀態爲Succeeded就成功了,接下來就是測試
總結:
創建好Application和DeploymentGroup之後,跟配置管理工程師協定好往版本中添加的文件,然後按時間+項目+版本號的方式打包,並上傳到S3上,然後代碼的更新回退,由測試和開發同學在瀏覽器上就能完成,省的自己寫代碼更新平臺了
上新項目的時候,也可以直接利用這個服務來實現,首次部署腳本是得寫的複雜點,裝上依賴軟件和設置環境
用好之後,甚至能不用碰ssh工具就能在瀏覽器或者用代碼把活幹完