概要
GitHub Actions を使用して、S3 に Web ページコンテンツをデプロイする。
説明
GitHub Actions は、CI/CD ツールの一種。
GitHub のイベントをトリガとして、ビルド、デプロイ等の操作を自動化することができる。
リポジトリ内の .github
ディレクトリの中に、workflows
というファイルを作成し、どのイベントをトリガとしてどのような動作を行うかを記述する。
詳しくは公式ページを参照。
もともと、S3 による静的 Web サイトホスティングを使用して Web ページを公開していた。
今回、S3 へのコンテンツアップロードを自動化できないかと思い、試してみた。
内容
下準備?
Windows で WSL を使用しているが、Git 操作をするたびにアクセストークンを聞かれていて、さすがに面倒くさい。
そこで、Git Credential Manager を使用する。
また、日本語ファイルについて、git status 等の出力の文字化け対策も行った。
AWS 側の設定
GitHub Actions で S3 にファイルを配置するため、GitHub 上のサーバから S3 にアクセスする必要がある。
GitHub の設定で、IAM ユーザの認証情報をシークレットとして設定する方法が考えられる。
(単に触ってみるくらいの時はそうしていた。)
だが、セキュリティ的には、一時的な認証情報を使用する IAM ロールを使用する方が望ましい。
そこで、今回は IAM ロールを使用した方法を試した。
次のような記事を参考にして進めた。
まず、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
でのアップロードを想定しているため、GetObject
、ListBucket
、PutObject
の3つの権限を設定した。
GitHub 側の設定
冒頭にも書いた通り、.github/workflows
に設定を記述するだけで良い。
S3 にファイルをアップロードする際の設定例があったので、ほぼそのまま利用した。
実際に使用した .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 上で認識されているファイル形式によって、挙動が変わってしまうということもあるらしい。
まとめ
GitHub Actions を使用して、S3 へのファイルアップロードを自動化してみた。
今回は、AWS の認証に IAM ロールを使用した設定を行ってみた。
感想
今回使用した Web ページのコンテンツファイルは、HTML、CSS、JavaScript を使用したものなので、ビルドが必要なものに比べれば得られる恩恵は少ないのかも。
でも、マージしてプッシュするだけでアップロードできるようになったのでかなり楽になった。
あと、GitHub Actions の設定ファイルについても完全に理解できているわけじゃないから、使いこなすにはもっとちゃんと勉強する必要がある。
AWS の Code 系サービスを使うという手もあったんだけど、今回はコスト面を考えて GitHub Actions を採用した。また今度、Code 系も触ってみたいな。