GitHub ActionsでOpenID Connectを使用してAWS CDKのデプロイを実行してみた

2022.02.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

昨年にGitHub ActionsでのOpenID Connect(OIDC)がサポートされるようになりました。

これにより、AWSやAzure、Google Cloudなどの各種プロバイダーと連携してWorkflowの実行時にクレデンシャルを発行し、クラウドへのシステムのデプロイ時の認証に使用することができるようになります。このクレデンシャルは一時的にしか使用できないため、パーマネントなアクセスキーを使用する場合に比べて、漏洩時に悪用されるリスクを大きく軽減することができます。

今回は、GitHub ActionsでOpenID Connectを使用してAWS CDKのデプロイを実行してみました。

やってみた

IDプロバイダの追加

Create Identity Providerで次のように指定して、IDプロバイダを作成します。

  • Provider type:OpenID Connect
  • Provider URL:https://token.actions.githubusercontent.com
  • Audience:sts.amazonaws.com

IAMロールの作成

GitHub Actions Workflowで使用するIAMロールを作成します。

作成したIAMロールに、CDKによるデプロイが行えるポリシーをアタッチします。必要な権限はCDKでどのリソースを作成するかによりけりですが、必要に応じて絞ってください。今回はすべてのリソースの作成に対応できるように*を指定しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}

信頼ポリシーを次のように編集して、特定のGitHubリポジトリのブランチでのアクション時にのみ、IDプロバイダを信頼するようにします。Federatedには先程作成したIDプロバイダのArnを指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "<IDプロバイダArn>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:<GitHubアカウント名>/<GitHubリポジトリ名>:ref:refs/heads/*"
        }
      }
    }
  ]
}

参考

GitHub Actions Workflowファイルの作成

GitHub Actions Workflowファイルを次のように作成します。今回はブランチPush時にCDKデプロイが行われるようにしています。

.github/workflows/app-cd.yml

name:
  app cd

on:
  push

env:
  AWS_ROLE_ARN: arn:aws:iam::XXXXXXXXXXXX:role/GitHubActionsOIDC

permissions:
  id-token: write
  contents: read

jobs:
  aws-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ env.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1
      - run: npm install
      - run: npm run deploy

また、npm scriptでnpm run deployにより手動承認なしでCDKデプロイを実行できるようにしています。

package.json

{
  "name": "aws-cdk-app",
  "version": "0.1.0",
  "bin": {
    "aws-cdk-app": "bin/aws-cdk-app.js"
  },
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest --silent",
    "cdk": "cdk",
    "deploy": "cdk deploy --require-approval never"
  },
  //略
}

念の為、ディレクトリ構造はこんな感じです。

ブランチをpushすると、CDKデプロイを実行することができました!

ハマったところ

IAMロールの信頼ポリシーのConditionで、ワイルドカードを使用しているにも関わらず、演算子にStringEqualsを使用していたため、aws-actions/configure-aws-credentials@v1による認証がNot authorized to perform sts:AssumeRoleWithWebIdentityとなりハマりました。正しくはStringLikeを使用します。

うまく動かない

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "<IDプロバイダArn>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:sub": "repo:<GitHubアカウント名>/<GitHubリポジトリ名>:ref:refs/heads/*"
        }
      }
    }
  ]
}

おわりに

GitHub ActionsでOpenID Connectを使用してAWS CDKのデプロイを実行してみました。

聞いていた通り非常に便利でしたので、CI/CDツールにGitHub Actionsを採用する際はぜひとも利用したいと思いました。

参考

以上