GitHub Actions で S3 デプロイ

Study

概要

GitHub Actions を使用して、S3 に Web ページコンテンツをデプロイする。

説明

GitHub Actions は、CI/CD ツールの一種。
GitHub のイベントをトリガとして、ビルド、デプロイ等の操作を自動化することができる。

リポジトリ内の .github ディレクトリの中に、workflows というファイルを作成し、どのイベントをトリガとしてどのような動作を行うかを記述する。

詳しくは公式ページを参照。

GitHub Actions を理解する - GitHub Docs
コア概念や重要な用語など、GitHub Actions の基本について説明します。

もともと、S3 による静的 Web サイトホスティングを使用して Web ページを公開していた。
今回、S3 へのコンテンツアップロードを自動化できないかと思い、試してみた。

内容

下準備?

Windows で WSL を使用しているが、Git 操作をするたびにアクセストークンを聞かれていて、さすがに面倒くさい。
そこで、Git Credential Manager を使用する。

WSL2でGit認証を毎回聞かれないようにする

また、日本語ファイルについて、git status 等の出力の文字化け対策も行った。

https://dev.classmethod.jp/articles/git-avoid-illegal-charactor-tips/

AWS 側の設定

GitHub Actions で S3 にファイルを配置するため、GitHub 上のサーバから S3 にアクセスする必要がある。

GitHub の設定で、IAM ユーザの認証情報をシークレットとして設定する方法が考えられる。
(単に触ってみるくらいの時はそうしていた。)
だが、セキュリティ的には、一時的な認証情報を使用する IAM ロールを使用する方が望ましい

そこで、今回は IAM ロールを使用した方法を試した。
次のような記事を参考にして進めた。

アマゾン ウェブ サービスでの OpenID Connect の構成 - GitHub Docs
ワークフロー内で OpenID Connect を使用して、アマゾン ウェブ サービスで認証を行います。
GitHub ActionsにAWSクレデンシャルを直接設定したくないのでIAMロールを利用したい | DevelopersIO
OIDCプロバイダとIAMロールを利用して、セキュアなAWSクレデンシャルを取り扱おう!
GitHub Actions で OIDC を使用して AWS 認証を行う

まず、IAM にて ID プロバイダの設定を追加。

次に、IAM ロールを作成。
信頼されたエンティティの設定は次の通り。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::AccountId:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:sub": "repo:UserName/RepositoryName:ref:refs/heads/BranchName",
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

ポリシーの設定は次の通り。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::BucketName",
                "arn:aws:s3:::BucketName/*"
            ]
        }
    ]
}

今回、aws s3 sync でのアップロードを想定しているため、GetObjectListBucketPutObject の3つの権限を設定した。

GitHub 側の設定

冒頭にも書いた通り、.github/workflows に設定を記述するだけで良い。

S3 にファイルをアップロードする際の設定例があったので、ほぼそのまま利用した。

GitHub - aws-actions/configure-aws-credentials: Configure AWS credential environment variables for use in other GitHub Actions.
Configure AWS credential environment variables for use in other GitHub Actions. - aws-actions/configure-aws-credentials

実際に使用した .github/workflows ファイルの設定内容は次の通り。

name: Deploy to S3

on:
  push:
    branches: "BranchName"

env:
  AWS_REGION: ap-northeast-1
  BUCKET_TO_SYNC: BucketName
  ROLE_TO_ASSUME: arn:aws:iam::AccountId:role/RoleName

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    name: Deploy files to AWS S3
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: ${{ env.ROLE_TO_ASSUME }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Upload objects with awscli
      run: |
        : # Sync to S3 without ".git/*", ".github/*", and "README.md"
        aws s3 sync . s3://${BUCKET_TO_SYNC} \
          --exclude ".git/*" \
          --exclude ".github/*" \
          --exclude "README.md"

トラブルと解決

Credentials could not be loaded, …

GitHub Actions 実行時に次のエラーが発生。
Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers

確認したところ .github/workflows の設定が誤っており、権限設定の部分に id-token: write の記述が不足していた。

No OpenIDConnect provider found …

続いて別のエラーが発生。
No OpenIDConnect provider found in your account for https://token.actions.githubusercontent.com

IAM の ID プロバイダの設定をよく確認すると、https://token.actions.githubusercontent.com と設定すべきところで、最後に / が入っていた。

コンテンツにアクセスすると…

S3 にアップロードした Web ページにアクセスすると、index.html がダウンロードされてしまい、表示ができなかった。

これに関しては、キャッシュを消去することで解決した。

他の原因として、S3 上で認識されているファイル形式によって、挙動が変わってしまうということもあるらしい。

S3に置いたhtmlファイルがブラウザダウンロードされてしまう時 - Qiita
現象静的サイトとして設定しているS3に置いたHTMLが、アクセスするとダウンロードコンソールが表示されるようになっていた。調査ブラウザでアクセスし、開発ツールでネットワーク等でファイルタイプを…

まとめ

GitHub Actions を使用して、S3 へのファイルアップロードを自動化してみた

今回は、AWS の認証に IAM ロールを使用した設定を行ってみた。

感想

今回使用した Web ページのコンテンツファイルは、HTML、CSS、JavaScript を使用したものなので、ビルドが必要なものに比べれば得られる恩恵は少ないのかも。
でも、マージしてプッシュするだけでアップロードできるようになったのでかなり楽になった。

あと、GitHub Actions の設定ファイルについても完全に理解できているわけじゃないから、使いこなすにはもっとちゃんと勉強する必要がある。

AWS の Code 系サービスを使うという手もあったんだけど、今回はコスト面を考えて GitHub Actions を採用した。また今度、Code 系も触ってみたいな。

参考

s3 syncに必要なアクセス権限 - Qiita
経緯ポリシー内で指定できるアクセス権限周りは下記があり、syncに必要な権限は何か確認した。オブジェクトオペレーションに対するアクセス権限バケットオペレーションに関連するアクセス権限バケット…
S3 sync を使用して ListObjectsV2 のアクセス拒否エラーを解決する
Amazon Simple Storage Service (Amazon S3) バケットとの間でオブジェクトのコピーを実行するために、aws s3 sync コマンドを使用しています。しかし、ListObjectsV2 オペレーションを...
GitHub Actions の YAML で RUN にコメントを入れる - Qiita
Workflow の RUN 内でコメント行を入れたいGitHub Actions の Workflow で、YAML の run ディレクティブ(指示子)でコメントを入れたい(# コメント 行を…
タイトルとURLをコピーしました