Day 19 完整驗證
昨天我們在 region ap-northeast-2
用 terraform 建立起一套 infrastructure,現在要從 Gitlab deploy Laravel web application 上去確認 web 跟 deployment 都能正常運作。(本日程式碼)
修改 Gitlab Pipeline & CI/CD Variable
換了 region,ECR repository 的 URI 會不同,我們要修改 Gitlab CI/CD variable 的 ECR_BASE
為 xxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com
。
還有 .gitlab-ci.yml
的這行:
1 | aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $ECR_BASE |
把寫死的 ap-northeast-1
改成 $AWS_DEFAULT_REGION
,然後在 CI/CD variable 設定變數值為 ap-northeast-2
。
增加 push image 到首爾的 IAM policy
記得在 push docker image 上 ECR 時有設定一組 AWS credential 來 push image 到 ECR repository 嗎?我們要找到那個 IAM user(可以用 AWS key id 直接在 IAM user 介面搜尋),幫他的 policy 加上可以 push image 到 ap-northeast-2
的 ECR repo,這部份的 policy 會變成像這樣:
1 | ...(ignore) |
這些修改完成後就能夠從 Gitlab trigger pipeline 啦~
觀察 CodePipeline
Gitlab 成功推 image 上 ap-northeast-2
的 ECR repository 後,我們觀察 CodePipeline 的運作:
嗯,毫無反應,就是個不會動的 CodePipeline。
為什麼勒~?
CodePipeline 是什麼時候要開始做事?當然是 ECR repository 有新的 image 的時候~那 CodePipeline 又是怎麼知道要開始做事呢?顯然 ECR repository 跟 CodePipeline 之間有某種魔法機制讓 CodePipeline 知道 ECR repository 有新的 image、可以開始進行 deploy。
這個機制就是 EventBridge(以前叫 CloudWatch Event),它可以建立 event rule,在收到 AWS service 的 event 時去做某些事情。讓我們回到東京 region 偷看(?) EventBridge 的 rules:
web console 自動建立了一個 rule,從描述看起來是在 ECR image tag 改變的時候會去 trigger CodePipeline 開始做事。進去可以看到 event pattern:
1 | { |
這段 event pattern 的意思是 ECR repository my-app
的 image tag latest
被 push 成功時,會觸發這個 event rule 去 trigger 另一個動作。event rule 會 trigger 誰、做什麼動作由 target 設定:
這邊的 target 當然是 CodePipeline 了~
用 Terraform 在首爾建立 EventBridge rule
知道機制後,要在 terraform configuration 補上 EventBridge 的 rule。(對辣~就是 import resource 的時候又漏了辣~)
首先是 target 需要的 IAM role 及 policy:
1 | resource "aws_iam_role" "codepipeline_trigger" { |
接著是 event rule 跟 target:
1 | resource "aws_cloudwatch_event_rule" "codepipeline_trigger" { |
apply 這些 resource 上去,Gitlab pipeline 再執行一次,發現 CodePipeline 開始動了!🥳
然後它就壞掉了 😐
點進去看它又怎麼了,在 phase details 看到:
看起來是 codebuild 對存放 artifact 的 s3 bucket 缺乏權限,這邊 artifact 的觀念跟 Gitlab pipeline 的一樣,是 pipeline 過程中產生的各種產出物,codebuild project 會把 artifact 放在 s3 某個 bucket。我們在 resource aws_iam_policycode_build_project
幫它補上:
1 | ... |
接著從 CodePipeline 按右上角的 Release change 讓它重跑,因為這邊跟 Gitlab Pipeline 無關了,我們重跑 CodePipeline 就可以了:
終於成功!
確認 ECS service 正常運作
終於來到最後確認——確定 ECS service 正常運作、可以看到 Laravel 歡迎頁。
把 aws_autoscaling_group.asg
的 desired_capacity
、max_size
跟 min_size
都設成 1,還有 aws_ecs_service.service
的 desired_count
也設成 1 然後 apply。
一樣到 ECS service 的 deployment 觀察 service 的 deploy 狀況,service 穩定之後就可以用 ALB 的 DNS name 看看是不是能看到 Laravel 歡迎頁囉!
如果可以看到 Laravel 歡迎頁,表示我們的 terraform 是正確的,可喜可賀可口可樂!
刪除首爾 region 的 resource 們
測試完當然要把首爾 region 的 resource 刪掉啦~用 terraform 就非常簡單,只要下 terraform destroy
指令並且 yes
即可!
會出現 error 的常常是 s3 bucket 跟 ECR repository,它們會說 bucket 或 repository 不是空的所以刪不掉,這種時候筆者通常手動把東西砍了再跑一次 destroy。