GitHub Push → GitHub Actions 觸發 → OIDC 驗證 → Assume Role → Deploy Lambda
流程已經只剩下最後一步:部署 Lambda
前篇已經成功讓 GitHub Actions 透過 OIDC 登入 AWS,接下來只需要撰寫一個 自動部署 Lambda 的 workflow 定義檔。
GitHub Actions 會依照 .yml 的指令逐步執行:
打包程式碼、上傳至 AWS、再透過 CLI 呼叫 update-function-code
完成部署。
# ==========================================================
# GitHub Actions workflow:自動部署 AWS Lambda
# ----------------------------------------------------------
# 當 develop 分支有 push 時,自動:
# 1. 取得 OIDC 驗證登入 AWS
# 2. 打包整個專案成 zip
# 3. 更新指定的 Lambda 函數程式碼
# ==========================================================
name: Deploy Lambda # 工作流程名稱,會顯示在 Actions 頁面上
on:
push:
branches:
- develop # 僅當推送到 develop 分支時觸發部署流程
jobs:
deploy: # Job 名稱,可自訂(例如 deploy、build 等)
runs-on: ubuntu-latest # 使用 GitHub 提供的 Ubuntu Runner 執行環境
permissions:
id-token: write # 允許 Actions 產生 OIDC token 以登入 AWS
contents: read # 允許讀取 Repository 內容
steps:
# Step 1. 取出最新的原始碼
- name: Checkout source
uses: actions/checkout@v4 # 官方 action,用來抓取專案內容到 Runner
# Step 2. 使用 OIDC 登入 AWS
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4 # AWS 官方 action
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }} # 要 Assume 的 IAM Role
aws-region: ${{ secrets.AWS_REGION }} # 目標 AWS 區域
# Step 3. 打包 Lambda 原始碼
- name: Zip Lambda function
run: |
zip -r function.zip . # 將目前資料夾內容壓縮成 function.zip
# Step 4. 確認壓縮結果
- name: List files after zip
run: ls -R # 列出所有檔案,確認 zip 包含的內容
# Step 5. 更新 Lambda 函數程式碼
# Lambda 函數名稱(從 Secrets 讀取)
# 指定上傳 zip 作為新版本程式碼
- name: Deploy to Lambda
run: |
aws lambda update-function-code \
--function-name ${{ secrets.LAMBDA_FUNCTION_NAME }} \
--zip-file fileb://function.zip
雖然現在的版本已經可以使用,但在部署及檢視 Log 的過程中,發現還有許多改善空間。
Run zip -r function.zip . # 將目前資料夾內容壓縮成 function.zip
adding: .git/ (stored 0%)
adding: .git/HEAD (stored 0%)
adding: .git/shallow (stored 0%)
adding: .git/refs/ (stored 0%)
adding: .git/refs/remotes/ (stored 0%)
adding: .git/refs/remotes/origin/ (stored 0%)
adding: .git/refs/remotes/origin/develop (stored 0%)
adding: .git/refs/tags/ (stored 0%)
...
從 Log 發現 zip 打包時居然包含了 80 多個檔案... 這是因為 YAML 中沒有指定排除路徑,所以才把 .git/
、.github/
通通打包進去了。
ITHome-ironman-2025/ # 專案資料夾
├── .lambdaignore # 打包 Lambda zip 時要略過的檔案清單
├── lambda_function.py # 程式碼
├── bedrock_service.py
├── ....py
├── requirements.txt # 引入套件清單
└── .github/ # GitHub 用設定檔路徑
└── workflows/ # GitHub Actions workflow 的預設讀取路徑
└── deploy-lambda.yml # yaml 設定檔案
# Git / GitHub
.git/*
.github/*
.gitignore
# Python build / cache
__pycache__/
*.pyc
*.pyo
*.pyd
*.egg-info/
build/
dist/
# Local environment
.env
venv/
.venv/
# System files
.DS_Store
Thumbs.db
# IDE configs
.vscode/
.idea/
# Logs
*.log
# 壓縮檔本身
*.zip
# Step 3. 打包 Lambda 原始碼
- name: Zip Lambda function
run: |
- zip -r function.zip .
+ zip -r function.zip . -x@.lambdaignore
這樣就乾淨多啦!
不管系統開發、部署、測試,環境變數設定錯誤都可以算是常見問題。
在 workflow 中加入適當的 Log,有助於開發人員迅速確認是否有設定變數值。
steps:
+ # Step 0. 輸出參數設定
+ - name: check deploy infos
+ run: |
+ if [ -z "${{ secrets.AWS_ROLE_ARN }}" ]; then
+ echo "AWS_ROLE_ARN is missing!"
+ else
+ echo "AWS_ROLE_ARN is set (value masked)."
+ fi
+ if [ -z "${{ secrets.AWS_REGION }}" ]; then
+ echo "AWS_REGION is missing!"
+ else
+ echo "AWS_REGION is set (value masked)."
+ fi
+ if [ -z "${{ secrets.LAMBDA_FUNCTION_NAME }}" ]; then
+ echo "LAMBDA_FUNCTION_NAME is missing!"
+ else
+ echo "LAMBDA_FUNCTION_NAME is set (value masked)."
+ fi
目前這個 workflow 會在每次
對 develop 分支做 push 時觸發,但實務上,遇到只是修改 README 或調整說明文件,並不需要對 Lambda 做重新部署。
如果想避免重複部署的問題,可以在條件式中加入檔案篩選:
on:
push:
branches:
- develop
paths:
- 'lambda_function.py'
- 'bedrock_service.py'
# 總之就是直接列出有異動就需要部署的檔案
對!所以還有另一種更保險的作法:
利用 paths-ignore
屬性,列出異動也不需要部署的檔案就可以了。
on:
push:
branches:
- develop # 僅當推送到 develop 分支時觸發部署流程
paths-ignore:
- 'README.md'
- '.gitignore'
- '.lambdaignore'
- '.github/**'
這樣設定後,如果 commit 只修改了被列在 paths-ignore 的檔案,就不會觸發整個自動部署流程。
就算少列了檔案,最多只是重複部署,而不會影響服務的可用性。
其實調整 yaml file 不只節省空間
在部署的時候,避免打包不需要的檔案除了可以加快速度外,還有一個額外的好處。部署至 Lambda 的 ZIP 檔案是有大小限制的。
根據官方文件:Lambda 配額,zip 的檔案大小不能 > 50 MB。
畢竟 Lambda 本來就是為了快速且短期運算的任務設計,天生就不適用於一整套的複雜系統。
為什麼輸出 Log 的時候,不直接把 secret 設定值印出來就好?
我也想...所以一開始的 yaml 調整其實是這樣的:
steps:
+ # Step 0. 輸出參數設定
+ - name: deploy infos
+ run: |
+ echo "Deploying to Lambda: ${{ secrets.LAMBDA_FUNCTION_NAME }}"
+ echo "Region: ${{ secrets.AWS_REGION }}"
# Step 1. 取出最新的原始碼
- name: Checkout source
uses: actions/checkout@v4 # 官方 action,用來抓取專案內容到 Runner
執行結果
被遮蔽啦!
然而,官方文件 Using secrets in GitHub Actions 中其實有提及這個情形。
為了避免機敏資料被意外輸出,GitHub 會自動遮掉 Log 中的 secrets 資訊喔!