はじめに 
ブログサイトを1から作ってみたの続き。
CloudFront + S3 で作ったブログサイトのデプロイを GitHub Actions で自動化してみた。
具体的にはブログサイトの GitHub リポジトリの main ブランチにマークダウンの追加・変更をプッシュしたら、 GitHub Actions で Hugo コマンドを実行して静的サイトを生成し、生成されたファイルを S3 バケットに自動的にアップロードする。
権限周りの準備 
準備として、GitHub の公式ドキュメント Configuring OpenID Connect in Amazon Web Services にしたがって、OIDC provider を登録し IAM ロールを作成する。
この IAM ロールを GitHub Actions で Assume Role することで、S3 へのアクセス権を得る。
GitHub OIDC provider を IAM に追加 
AWS コンソール > IAM > IDプロバイダ からIDプロバイダを追加する。
- プロバイダのタイプ: OpenID Connect
 - プロバイダのURL: 
https://token.actions.githubusercontent.com - 対象者: 
sts.amazonaws.com 
※ Amazon が出している 公式の Action を使う場合は、対象者に sts.amazonaws.com を指定すると書いてある。

ロール作成 
GitHub Actions が Assume Role するロールを作成する。
AWS コンソール > IAM > ロール からロールを作成する。
- 信頼されたエンティティタイプ: ウェブアイデンティティ
 - アイデンティティプロバイダー: 
https://token.actions.githubusercontent.com - Audience: 
sts.amazonaws.com 

- ポリシーは後からつけるのでこの画面では付けなかった。
 - ロール名は 
github-actions-roleで作成した。 
ロールにポリシーを追加 
作成したロールに次のようなポリシーをインラインポリシーで追加した。
{
  "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
            "s3:ListBucket",
            "s3:ListObjectsV2",
            "s3:DeleteObject",
            "s3:PutObject"
        ],
        "Resource": [
          "arn:aws:s3:::{バケット名}",
          "arn:aws:s3:::{バケット名}/*"
        ]
      }
    ]
}
ロールの信頼ポリシーを編集 
作成したロールの信頼ポリシーの Condition に StringLike の条件を追加した。
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"Federated": "arn:aws:iam::{accountId}:oidc-provider/token.actions.githubusercontent.com"
			},
			"Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:nshmura/website:*"
                }
            }
		}
	]
}

GitHub Actions でのデプロイ 
GitHub Actions Workflow ファイルを追加 
.github/workflow/deploy.yaml という名前で Worflow ファイルを作成する。
name: deploy blog site
on:
  push:
    branches:
      - main
    paths:
      - "website/**"
  workflow_dispatch:
env:
  AWS_REGION: ap-northeast-1
  AWS_ROLE_ARN: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role
  AWS_TARGET_S3_BUCKET: ${{ secrets.AWS_TARGET_S3_BUCKET }}
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: "0.110.0"
      - name: Build
        run: |
          cd website
          HUGO_ENV=production hugo --minify
      - name: Configure AWS credentials from IAM Role
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          role-to-assume: ${{ env.AWS_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}
      - name: Upload file to S3
        run: aws s3 sync --delete website/public s3://${{ env.AWS_TARGET_S3_BUCKET }}/website/public
AWS_ACCOUNT_IDとAWS_TARGET_S3_BUCKETはシークレットとした。private リポジトリなのでベタで書いても問題ない気はする。- AWSの権限は、AWS 公式の 
aws-actions/configure-aws-credentials@v1-node16に任せる。 
GitHub Actions Secrets 追加 
GitHub リポジトリ > Settings > Secrets and variables > Actions に進んで「New repository secret」からシークレットを追加する。
AWS_ACCOUNT_IDAWS_TARGET_S3_BUCKET
GitHub Actions 実行 
ワークフローのトリガーに workflow_dispatch を入れているので手動でも起動ができる。
GitHub リポジトリ > Actions > deploy blog site > Run workflow からワークフローを実行すると、無事に Huge によるビルドと S3 へのアップロードができた。
通常は main ブランチにプッシュすることでデプロイが始まる。
おわりに 
AWSの IDプロバイダ周りの設定は初めてで、心理的なハードルが高かったが、やってみれば簡単だった。
早い段階でデプロイ自動化できた。これでブログ更新が捗ると良いな。