Chapter 06

CD環境の構築(Github Actions)

inunekousapion
inunekousapion
2022.10.18に更新

本章ではデプロイをGithub Actionsで自動的に行うための準備をします。

OIDCとポリシーとロールの作成

新しくCDKのStackを追加して、AWSのデプロイをGithubActionsで行えるようにします。

infrastructure/stacks/github_oidc.pyというファイルを作成します。

touch infrastructure/stacks/github_oidc.py
github_oidc.py
import os

import aws_cdk as cdk
from aws_cdk import aws_iam


class OIDCDeployApp(cdk.Stack):
    """
    Using OIDC to run GithubActions
    """

    def __init__(
        self,
        scope,
        id,
        **kwargs,
    ):
        super().__init__(scope, id, **kwargs)

        # Cannot creat the same
        github_id_provider = aws_iam.OpenIdConnectProvider(
            self,
            "githubid-provider",
            url="https://token.actions.githubusercontent.com",
            client_ids=["sts.amazonaws.com"],
        )

        githubactions_role = aws_iam.Role(
            self,
            "oidc-githubactions-role",
            role_name="github-oidc-role",
            assumed_by=aws_iam.FederatedPrincipal(
                github_id_provider.open_id_connect_provider_arn,
                conditions={
                    "ForAnyValue:StringLike": {
                        "token.actions.githubusercontent.com:sub": "repo:<org>/<your-repo>:ref:refs/heads/*"
                    }
                },
                assume_role_action="sts:AssumeRoleWithWebIdentity",
            ),
        )

        deploy_policy = aws_iam.Policy(
            self,
            "deploy-policy",
            policy_name="deploy-policy",
            statements=[
                aws_iam.PolicyStatement(
                    effect=aws_iam.Effect.ALLOW, actions=["*"], resources=["*"]
                ),
            ],
        )
        githubactions_role.attach_inline_policy(deploy_policy)

追加したstackを使えるようにします。

前の章で追加したinfrastructure/app.pyを更新します。

app.py
#!/usr/bin/env python3
import aws_cdk as cdk
from stacks.chaliceapp import ChaliceApp
+from stacks.github_oidc import OIDCDeployApp
from dotenv import load_dotenv


load_dotenv(verbose=True)
aws_env = cdk.Environment(account=os.environ['AWS_ACCOUNT_ID'], region=os.environ['REGION'])
app = cdk.App()
ChaliceApp(app, 'pyproject', env=aws_env)
+OIDCDeployApp(app, "github-oidc", env=aws_env)

app.synth()

早速デプロイをしてしまいましょう。

cd infrastructure
cdk deploy github-oidc

Github Secretsにパラメータを設定する

Githubのリポジトリから
Settings > Secrets > Actions
の順にクリックして、Repository secretsのパラメータに下記を設定してください。

AWS_OIDC_ROLE_ARN:先ほど作成したOIDCのARN
AWS_REGION:デプロイ先のリージョン名
AWS_ACCOUNT_ID:AWSアカウントID(12桁の数字です)
SLACK_WEBHOOK_URL:Slackに通知する場合のWebhookURLです(不要なら削除してください)

Github workflow関連ファイルの作成

GithubActionsでCDKのデプロイをするスクリプトを作成していきます。
内容は下記となっています。

  • developブランチにマージされたら実行します
  • 結果をSlackに通知します

.github/workflows/deploy.ymlというファイルを作成します。
※Slack Notificationは不要なら削除してください。

mkdir .github
mkdir .github/workflows
touch .github/workflows/deploy.yml
deploy.yml
name: deploy
on:
  push:
    branches:
      - "develop"
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'
          cache: 'pip'
      
      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: "14"
      
      - name: Install CDK
        run: npm install -g aws-cdk
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
          aws-region: ${{ secrets.AWS_REGION }}
      - name: Install Library
        working-directory: ./infrastructure
        run: pip install -r requirements.txt
      
      - name: Deploy
        working-directory: ./infrastructure
        run: cdk deploy -require-approval never
        env:
          AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
          REGION: ${{ secrets.AWS_REGION }}
      
      - name: Slack Notification
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,message,commit,author
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: always()

developブランチにプッシュしたときにGithubActionsが動作してデプロイが行われたら成功です。