Deploy Vue3 to S3
IAM User, Role, Policy
設置順序是:
-
創建 S3 Policy (為了有存S3的權限)
-
創建 IAM Role 並附加該 Policy (為了限制特定角色能擁能擁有存S3的權限)
-
設置信任關係,允許特定 User 擔任此 Role (為了確認該用戶是否具備該角色的權限)
這兩個方向的權限設置必須同時滿足,用戶才能成功擔任角色。這是 AWS 的一種安全機制,確保角色和用戶雙方都同意這種權限委派關係。
User
name: github-actions-user
添加 assume-role-policy 這個政策
AWS CLI確認該 User 相關權限
{
"AttachedPolicies": [
{
"PolicyName": "assume-role-policy",
"PolicyArn": "arn:aws:iam::my-id:policy/assume-role-policy"
}
]
}
Role
name: GitHubActionsS3Role
Trust relationships
新版的 AWS SDK 和 GitHub Actions 用到了 OIDC 驗證中的 session tagging 功能
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GitHubActionsS3RoleTaskV2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::my-id:user/github-actions-user"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
增加角色的最大會話持續時間
Policy
- name: assume-role-policy
GitHub Action使用 aws s3 sync 時可能還需要 s3:ListBucket 和 s3:DeleteObject(因為有 --delete 選項)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::fedoubt-prod-web-assets/task/v2/*",
"arn:aws:s3:::fedoubt-prod-web-assets"
]
}
]
}
- name: s3-put-policy
新版的 AWS SDK 和 GitHub Actions 用到了 OIDC 驗證中的 session tagging 功能
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AssumeRolePolicy",
"Effect": "Allow",
"Action": [
"sts:AssumeRole",
"sts:TagSession"
],
"Resource": "arn:aws:iam::my-id:role/GitHubActionsS3Role"
}
]
}
## S3 Bucket Policy
CloudFront 和 GitHub Actions 分成兩個獨立的 **Statement**
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::fedoubt-prod-web-assets/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::my-id:distribution/E2BB5HJ93U5T36"
}
}
},
{
"Sid": "AllowGithubActions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::my-id:role/GitHubActionsS3Role"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::fedoubt-prod-web-assets/task/v2/*"
}
]
}
GitHub Actions
# 生成 AWS 認證
aws iam create-access-key --user-name github-actions-user
# 複製 AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY
New repository secret
進入 GitHub Repository → Settings → Secrets and variables → Actions → New repository secret,新增:
| key | value |
|---|---|
| AWS_ACCESS_KEY_ID | AKIAEXAMPLE123456 |
| AWS_SECRET_ACCESS_KEY | wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
### **.github/workflows/deploy.yml** |
GitHub Actions只會執行存在於當前分支上的workflow檔案。
確認在對的分支上創建workflow檔案:
name: Deploy Vue3 to S3
on:
push:
branches:
- task-vue # 只在 push 到 main 分支時觸發
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # 啟用 OIDC 驗證
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
working-directory: ./task-vue/my-vue-app # 完整路徑到Vue項目目錄
run: npm install
- name: Build project
working-directory: ./task-vue/my-vue-app # 完整路徑到Vue項目目錄
run: npm run build
# ... AWS credential setup ...
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # 這是 User 的憑證
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 這是 User 的憑證
role-to-assume: arn:aws:iam::my-id:role/GitHubActionsS3Role-task-v2
aws-region: ap-southeast-2
role-duration-seconds: 900 # 將此值減小,例如設為15分鐘
- name: Deploy to S3
run: aws s3 sync ./task-vue/my-vue-app/dist s3://fedoubt-prod-web-assets/task/v2 --delete