CI/CD:CodePipeline vs GitHub Actions
你的 code push 了,然後手動 SSH 進去拉 code、重啟服務?都 2026 年了,該自動化了。
先講結論
AWS 的 CI/CD 全家桶是 CodePipeline + CodeBuild + CodeDeploy,跟 AWS 服務整合最深但學習曲線陡。GitHub Actions 更靈活、社群生態更好、大多數場景也更便宜。如果你的 code 在 GitHub 上,用 GitHub Actions + 部署到 AWS 是 2026 年的最佳選擇。
方案一:GitHub Actions(推薦)
基本流程
git push → GitHub Actions →
build Docker image →
push to ECR →
update ECS service
ECR:你的 Docker image 倉庫
# 建立 ECR Repository
aws ecr create-repository --repository-name web-app \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256
# 設定 Lifecycle Policy(保留最近 20 個 image)
aws ecr put-lifecycle-policy --repository-name web-app \
--lifecycle-policy-text '{
"rules": [{
"rulePriority": 1,
"description": "Keep last 20 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 20
},
"action": {"type": "expire"}
}]
}'
# 登入 ECR
aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.comGitHub Actions Workflow
# .github/workflows/deploy.yml
name: Deploy to ECS
on:
push:
branches: [main]
env:
AWS_REGION: ap-northeast-1
ECR_REPOSITORY: web-app
ECS_CLUSTER: prod-cluster
ECS_SERVICE: web-app
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
permissions:
id-token: write # OIDC
contents: read
steps:
- uses: actions/checkout@v4
# 用 OIDC 連 AWS(不需要 Access Key)
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
aws-region: ${{ env.AWS_REGION }}
# 登入 ECR
- uses: aws-actions/amazon-ecr-login@v2
id: ecr-login
# Build + Push
- name: Build and push image
env:
ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
# 更新 ECS Service
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster $ECS_CLUSTER \
--service $ECS_SERVICE \
--force-new-deploymentGitHub Actions + OIDC:不要用 Access Key
# 在 AWS 建立 OIDC Provider(給 GitHub)
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1
# 建立 IAM Role(給 GitHub Actions 用)
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}
}]
}
EOF
aws iam create-role --role-name github-actions-deploy \
--assume-role-policy-document file://trust-policy.json用 OIDC 取代 Access Key 是安全最佳實踐。Access Key 放在 GitHub Secrets 裡仍然有洩漏風險,OIDC 完全不需要存 credential。
方案二:AWS CodePipeline
什麼時候選 CodePipeline
- Code 在 CodeCommit(AWS 的 git,注意:CodeCommit 自 2024 年 7 月起已停止接受新客戶,建議使用 GitHub 或 GitLab)上
- 需要跟 AWS 服務深度整合(CodeDeploy blue/green)
- 企業合規要求全在 AWS 內完成
- 不想依賴第三方 CI 服務
CodePipeline + CodeBuild + CodeDeploy
# 1. 建立 CodeBuild Project
aws codebuild create-project --name web-app-build \
--source type=GITHUB,location=https://github.com/your-org/web-app \
--artifacts type=NO_ARTIFACTS \
--environment type=LINUX_CONTAINER,computeType=BUILD_GENERAL1_SMALL,image=aws/codebuild/amazonlinux2-x86_64-standard:5.0,privilegedMode=true \
--service-role arn:aws:iam::123456789012:role/codebuild-role
# buildspec.yml# buildspec.yml
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Building Docker image...
- docker build -t $REPOSITORY_URI:$IMAGE_TAG .
- docker tag $REPOSITORY_URI:$IMAGE_TAG $REPOSITORY_URI:latest
post_build:
commands:
- echo Pushing image...
- docker push $REPOSITORY_URI:$IMAGE_TAG
- docker push $REPOSITORY_URI:latest
- printf '[{"name":"app","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json多環境部署
分支策略
main → production
staging → staging
feature/* → 不部署(只跑 test)
GitHub Actions 多環境
# deploy-staging.yml
on:
push:
branches: [staging]
jobs:
deploy:
environment: staging # GitHub Environment(有 approval 機制)
# ... 同上,但 ECS_CLUSTER/ECS_SERVICE 用 staging 的值
# deploy-production.yml
on:
push:
branches: [main]
jobs:
deploy:
environment: production # 需要手動 approve
# ...Rollback
# 快速 rollback:把 ECS service 的 Task Definition 指回上一版
aws ecs update-service --cluster prod-cluster \
--service web-app \
--task-definition web-app:42 # 上一個版本號
# 或者直接 revert git commit 讓 CI/CD 重跑
git revert HEAD && git push origin mainGitHub Actions vs CodePipeline
| GitHub Actions | CodePipeline | |
|---|---|---|
| 學習曲線 | 低(YAML 清楚) | 高(三個服務要串) |
| 免費額度 | 2000 分鐘/月(public repo 無限) | 每個 pipeline $1/月 |
| 社群 Action | 超多 | 幾乎沒有 |
| AWS 整合 | OIDC + CLI | 原生 |
| 自建 Runner | 支援 | CodeBuild(AWS 管) |
| Approval | GitHub Environment | Manual Approval stage |
| 缺點 | 依賴 GitHub | 三個服務要串、Debug 痛苦 |
自架 vs AWS
| 面向 | 自架(GitLab CI) | GitHub Actions | CodePipeline |
|---|---|---|---|
| Runner | 自己管 GitLab Runner | GitHub 管 / Self-hosted | CodeBuild(AWS 管) |
| Registry | Harbor | ECR | ECR |
| 部署 | SSH + docker-compose | ECS update / kubectl | CodeDeploy |
| 費用 | Runner 機器費 | 免費/按分鐘 | 按 pipeline + build 分鐘 |
如果你讀過 CD 和 CD 模板,GitHub Actions 的概念一模一樣——只是語法和生態不同。
K8s 映射
| AWS CI/CD | K8s 對應 |
|---|---|
| CodePipeline | Tekton Pipelines |
| CodeBuild | Kaniko(in-cluster build) |
| CodeDeploy (blue/green) | Argo Rollouts |
| GitHub Actions → ECS | GitHub Actions → kubectl / ArgoCD |
| ECR | Harbor / DockerHub |
如果你用 EKS,最佳搭配是 GitHub Actions build image → push to ECR → ArgoCD 偵測到新 image → 自動部署。詳見 K8s GitOps。
系列導覽
| 上一篇 | 下一篇 |
|---|---|
| EventBridge | FinOps |
好的 CI/CD 讓你有信心在週五下午部署——壞的 CI/CD 讓你週五下午不敢碰任何東西。