GithubActions 用 OpenID Connect 方式部署 S3

412 阅读2分钟

背景

通常我们会使用AWS提供的 key/secret 模式来从AWS外部调用AWS的服务,比如以 S3 为例,我们需要有 Bucket 写入权限的 key/secret。

然而 AWS 推荐使用 AssumeRole 的方式,具体原因看参考文档,通过OpenID Connect方式来申请一个临时的角色来获得权限。

接来下就描述这种方式的步骤

注意:以下内容中出现 123456789012 表示 AWS 的账号

步骤

  1. AWS Console 配置 Identify providers

进入 Console > IAM > Identify providers,点击 Add provider

然后点击底下的 Add provider 添加

  1. AWS Console 配置 Role

进入 Console > IAM > Role,点击 Create role

下一步,然后 Create Policy,在JSON栏填入

{

    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0", // 随意
            "Effect": "Allow", // 填允许
            "Action": "sts:AssumeRole", // 行为是 AssumeRole
            
            // 访问的资源,这里和最后的角色名称要一致
            "Resource": "arn:aws:iam::123456789012:role/githubactions", 

            "Condition": {
                // Like 表示可以使用 * 号
                "StringLike": {
                    // key是固定的,value的 user/repo 按照github repo的名称填
                    "token.actions.githubusercontent.com:sub": "repo:user/repo:*"
                }
            }
        }
    ]
}

最后到 Review

Create role 完毕

  1. Github Actions workflow

在项目的 .github/workflows/xxx.yml 里填入工作流的代码,具体请看

name: Deploy to S3

on:
  workflow_dispatch:

env:
  BUCKET_NAME : "bucket-name"
  AWS_REGION : "region-name"

permissions:
  id-token: write
  contents: read

jobs:
  build-deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [12.x]

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - run: npm install
    - run: npm run build
    - run: npm test

    - name: Configure aws credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: arn:aws:iam::123456789012:role/githubactions
        role-session-name: githubactions
        aws-region: ${{ env.AWS_REGION }}

    - name: Deploy to S3
      run: aws s3 sync ./build s3://${{ env.BUCKET_NAME }}/

大概意思就是:

  • Git clone 代码
  • Build 代码到 build 目录
  • Test 验证
  • aws-actions/configure-aws-credentials@v1 通过 assume role 获得权限
  • 有权限后使用 aws sync 到 bucket
  1. 配置 bucket Policy

去到你的 bucket 的 permission 栏,编辑 Policy,例子如下:

(bucket-name改为真实bucket的名称)

{

    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Edit",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    // 重点在这,允许前面配置的角色访问 bucket
                    "arn:aws:iam::123456789012:role/githubactions",
                    "arn:aws:iam::123456789012:root"
                ]
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3::: bucket-name/*"
            ]
        },

        {

            "Sid": "Read",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}

完成了

总结

总的来说就通过 OpenID Connect 的方式,仅授权 Github 来申请使用角色,该角色最后在bucket下给了write权限,使得部署成功;这样完成了不需要向 Github 填入 secret 之类的。

参考文档

Configuring OpenID Connect in Amazon Web Services - GitHub Docs

github.com/aws-actions…