2019/05/31

Build AWS EC2 for CodeDeploy

最後更新時間:2019/05/31


文章開頭先謝謝 ellery 大大,沒有你提醒,我大概會繼續通靈 debug 幾個禮拜 XD


先說明 CodeDeploy 大概的運作機制:
  1. 先設定好 EC2 的基本權限 (IAM)
  2. 要支援 CodeDeploy 的 EC2 instance 必須安裝 CodeDeploy agent (很重要,EC2 上 trigger event 都是靠這個 agent)
  3. 設定 CodeDeploy 上 Application 對應到的 EC2 instances
  4. User 先將打包好的 code 送到 S3 上存放
  5. 接下來 trigger application 上特定的  deploy-er,將特定版本的 code 從 S3 上派送到 EC2 instance 上
  6. EC2 instance 的 CodeDeploy agent 收到 event 以後,會按照 appspec.yml 中指定的動作來動作,操作完成會回傳 status 給 CodeDeploy。
  7. CodeDeploy 會在 pannel 顯示 deploy 的進度和狀態。

TL;DR




接下來這邊會用較為簡單的方法 (但不安全 XD) 的說明,來建立支援 CodeDeploy 的 EC2 instance,並做一次 deployment。操作、設定會幾乎按照 AWS 的 document 上的進行,但會調整一些順序讓操作比較順暢。


IAM

該做的還是要做,逃也逃不掉。要先幫 EC2 建立一個支援 CodeDeploy 的 Role,EC2 需要從 S3 上面拉檔案,所以除了 CodeDeploy 的權限以外,也要開 S3 的權限。

這邊用最寬鬆的權限來做 demo,若需要更安全、仔細的設定說明,請參考 AWS docs

圖 1-1:這個 role 是要給 EC2 用的,所以建立時要先選 EC2


圖 1-2:要支援自動部屬的 EC2 需要這二個 policy


接下來,CodeDeploy 的 deploy-er 也需要權限,所以要建立一個 Role 給 Deploy-er 使用。這個就比較簡單,直接使用 CodeDeploy 的 policy 即可。


圖 1-3:建立 CodeDeploy 用的 role


圖 1-4:這邊就只有一個 policy 沒得挑



S3 bucket


前文有提到,會把要 deploy 的檔案先放在 S3 上,所以需要開一個 bucket 供 CodeDeploy 存放檔案用。

按照一般步驟建立一個 s3 bucket,除了 bucket name 不要 conflict 以外,其他選項都用預設值即可。我這邊用的名稱是「deploy-for-qwe」:

圖 N-M:我還沒想到要打什麼註解 ....





EC2 設定

EC2 其實沒有太複雜的設定,主要就是需要安裝 CodeDeploy agent 而已。

在開機器時,要留意幾個地方,第一個是 instance 的 IAM role 必須是上一步驟建立給 EC2 可以 deploy 的 role:

圖 2-1:建立 EC2 instance 時要加上 role


圖 2-2:幫 EC2 加個 tag,之後操作會比較方便。可以隨意命名。


再來要幫 EC2 instance 安裝 CodeDeploy agent,這邊可以直接參考 AWS install the CodeDeploy agent 的文件說明。


CodeDeploy

切換到 CodeDeploy 的 console,直接按下「Create application」就對了:

圖 3-1:建立 application,供之後為不同 application 設定不同的操作


圖 3-2:CodeDeploy 支援不同的 platform,我這邊使用 EC2


接著建立 deployment group,這邊要選擇前面建立的 CodeDeployRole:

圖 3-3:記得要選擇 role


最後選擇預計要被 deployed 的 instance,這個時候建立 EC2 設定的 tag 就很有用了,可以一次選擇多個 instance 或是不同的群組:

圖 3-4:透過 tag 來選擇要 deploy 的 EC2 instance:佈署到「usage」為「deploy」的所有 instance




appsepec.yml


這個檔案主要用來記錄、控制佈署時要做的動作,包括停止服務、刪除 cache、把新的程式移動到指定的位置、initialize .... 等等。

appspec.yml 檔案必須放在專案的根目錄,appspec.yml 的撰寫方法可以參考 AWS - AppSpec File Example

這邊不自己寫 appspec.yml,直接從 AWS 提供的 example 來測試即可。開啟 download resource kit file 頁面,為意選擇一個 example 下載並解壓縮,目錄看起來會像下面這個樣子:
$ tree
.
├── appspec.yml
├── index.html
├── LICENSE.txt
└── scripts
    ├── install_dependencies
    ├── start_server
    └── stop_server


appspec.yml 的檔案內容如下:
version: 0.0
os: linux
files:
  - source: /index.html
    destination: /var/www/html/
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies
      timeout: 300
      runas: root
    - location: scripts/start_server
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server
      timeout: 300
      runas: root

「version」這個 key 是必要的,其他的 key 看不同的部屬環境而有不同。

這邊要 deploy 到 EC2 instance 上,所以改寫 appspec.yml 到最簡單的寫法:
version: 0.0
os: linux

files:
    - source: index.html
      destination: /var/www/html/

接著,透過 aws-cli 下指令將 source code 打包上傳到 s3 的 bucket 上:
aws deploy push \
  --application-name hello-world \
  --s3-location s3://deploy-for-qwe/hello.zip \
  --source .

藍色標記是需要依照前文自行設定的資料自行修改的文字。

指令成功執行以後,應會看到以下的 response:
To deploy with this revision, run:
aws deploy create-deployment --application-name hello-world --s3-location bucket=deploy-for-qwe,key=hello.zip,bundleType=zip,eTag=0bd6b5414d8315a960ab1256d33b4e9b --deployment-group-name <deployment-group-name> --deployment-config-name <deployment-config-name> --description <description>


既然 AWS 都要你照做了,就不用多想跟著下指令:
aws deploy create-deployment \
--application-name hello-world \
--s3-location bucket=deploy-for-qwe,key=hello.zip,bundleType=zip,eTag=0bd6b5414d8315a960ab1256d33b4e9b \
--deployment-group-name tmp-group

# 後半段非必要參數,所以我刪掉了

指令成功,會回傳 JSON data:
{   
    "deploymentId": "d-SDXUUDKFZ"
}

這個時候打開 CodeDeploy 的 Deployments,就會看到有 deploy 正在進行:

圖 4-1:透過指令送出的 deployment 需求正在進行中

執行完成,連到 EC2 instance 上,就可以看到 /var/www/html/ 目錄下多了一個 index.html 的檔案了,deploy 成功!

回到 local 端,對 index.html 的內容做個調整,再做一次 aws deploy push,這次回傳結果也差不多,不過注意紅色標記的部份:
To deploy with this revision, run:
aws deploy create-deployment --application-name hello-world --s3-location bucket=deploy-for-qwe,key=hello.zip,bundleType=zip,eTag=085f6c6ca293276a3072be2e8a5a7870 --deployment-group-name <deployment-group-name> --deployment-config-name <deployment-config-name> --description <description>


「eTag」的 hash 值已經和前一次不同了!

CodeDeploy 上,eTag 的值相當於 product version,不同的值代表不同的版本,所以有必要時可以快速透過 eTag 在個版本之間做切換:
圖 4-2:在 pannel 會自動帶出可以 deploy 的版本


希望這篇說明,可以幫你快速了解 AWS CodeDeploy 的功能以及設定、操作方式。

沒有留言:

張貼留言

除非必要,請不要在回覆時留下您的敏感資訊 (電話、email、地址等)