Skip to content
On this page

📆 2023-03-05

CloudFront + S3 へのデプロイを GitHub Actions で自動化した

#GitHub Actions #AWS #CloudFront #S3

はじめに

ブログサイトを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 を指定すると書いてある。

IDプロバイダを追加

ロール作成

GitHub Actions が Assume Role するロールを作成する。

AWS コンソール > IAM > ロール からロールを作成する。

  • 信頼されたエンティティタイプ: ウェブアイデンティティ
  • アイデンティティプロバイダー: https://token.actions.githubusercontent.com
  • Audience: sts.amazonaws.com

ロールを作成

  • ポリシーは後からつけるのでこの画面では付けなかった。
  • ロール名は github-actions-role で作成した。

ロールにポリシーを追加

作成したロールに次のようなポリシーをインラインポリシーで追加した。

json
{
  "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 の条件を追加した。

json
{
	"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 ファイルを作成する。

yaml
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_IDAWS_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_ID
  • AWS_TARGET_S3_BUCKET

GitHub Actions 実行

ワークフローのトリガーに workflow_dispatch を入れているので手動でも起動ができる。

GitHub リポジトリ > Actions > deploy blog site > Run workflow からワークフローを実行すると、無事に Huge によるビルドと S3 へのアップロードができた。

通常は main ブランチにプッシュすることでデプロイが始まる。

おわりに

AWSの IDプロバイダ周りの設定は初めてで、心理的なハードルが高かったが、やってみれば簡単だった。

早い段階でデプロイ自動化できた。これでブログ更新が捗ると良いな。

参考

Released under the MIT License.