🧚♂️
【Github Actions】静的サイトをS3 + CloudFrontへ環境毎にデプロイする🛩️
🛝 実現すること
- S3 と CloudFront で公開されている静的サイトのデプロイを Github Actions で自動化する
- develop,production 環境に分けてデプロイする
🎣 手順
- Github Actions で OIDC を使用して AWS 認証を行う
1.1. Github OIDC Provider 作成する
1.2. Github OIDC ID プロバイダーの IAM ロールを作成する - Github Secrets で環境変数を設定
- Github Actions の Workflow を定義
🦚Github Actions で OIDC を使用して AWS 認証を行う
OpenID Connect(以下: OIDC)を使用すると、Github Actions のワークフロー内で AWS リソースアクセス出来るようになります
🐬Github OIDC Provider 作成する
AWS コンソール → IAM → ID プロバイダ → プロバイダを追加
各項目に以下の値を入力
項目 | 値 | 備考 |
---|---|---|
プロバイダの設定 | OpenID Connect | - |
プロバイダの URL | https://token.actions.githubusercontent.com |
- |
対象者 | sts.amazonaws.com |
aws official actionを使用する場合に使用 |
入力後に「サムプリントを取得」をクリックし「プロバイダを追加」
🧊Github OIDC ID プロバイダーの IAM ロールを作成する
ロール → ロールを作成
以下の値を入力して次へ
項目 | 値 | 備考 |
---|---|---|
信頼されたエンティティタイプ | ウェブアイデンティティ | - |
アイデンティティプロバイダー | token.actions.githubusercontent.com |
- |
Audience | sts.amazonaws.com |
- |
Github 組織 | {Github 組織名} | またはユーザー名 |
Github リポジトリ | {Github リポジトリ名} | - |
カスタム信頼ポリシーを設定する場合(ウェブアイデンティティで設定済の場合スキップ)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::{AWSのアカウントID}: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:{Githubのユーザー名}/{Githubリポジトリ名}:*"
}
}
}
]
}
もし、ブランチを制限したい場合は Condition を下記のように設定します
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:{Githubのユーザー名}/{Githubリポジトリ名}:ref:refs/heads/{ブランチ}"
}
}
次に、許可ポリシー追加の画面になるが、インラインポリシーで追加するためスキップ
ロール名を入力し、ロールを作成
ロールの一覧から作成されたロールを選択 → 許可を追加 → インラインポリシーを作成
以下を追加して作成
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:DeleteObject", "s3:PutObject"],
"Resource": ["arn:aws:s3:::{バケット名}", "arn:aws:s3:::{バケット名}/*"]
}
]
}
🎾Github Secrets で環境変数を設定する
Github Actions で使用する際の環境変数を保管する
対象のリポジトリに移動し、Settings > Security > Actions へ移動し、
「New repository secret」をクリック
以下の値を入力し追加
アカウント ID は IAM ダッシュボードから確認出来ます
Name | Secret |
---|---|
AWS_ACCOUNT_ID_DEV | {dev 環境の AWS アカウント ID} |
S3_BUCKET_DEV | {dev 環境のバケット名} |
AWS_ACCOUNT_ID_MAIN | {production 環境の AWS アカウント ID} |
S3_BUCKET_MAIN | {production 環境のバケット名} |
🛼Github Actions の Workflow を定義
🌱 ブランチとデプロイ
- develop ブランチに push すると、develop 環境にデプロイされる
- main ブランチに push すると、production 環境にデプロイされる
🪼 作成するファイル
ファイル名 | 役割 | 備考 |
---|---|---|
deploy.yml |
デプロイ共通処理 | - |
deploy_develop.yml |
develop の環境変数 | - |
deploy_main.yml |
production の環境変数 | - |
deploy_develop.yml
定義した環境変数をdeploy.yml
に渡し、deploy.yml
を実行する流れとなります。
🕸️ サイトの構成
.
├── .github
├── README.md
├── images
├── index.html
├── js
└── styles
🐣 成果物
deploy_develop.yml
name: deploy to develop
on:
push:
branches:
- develop
# 以下のいずれかが変更された場合に実行される
paths:
- "images/**"
- "js/**"
- "styles/**"
- index.html
jobs:
deploy:
# deploy.ymlを再利用する
uses: {Github組織(ユーザー)名}/{Githubリポジトリ名}/.github/workflows/deploy.yml@develop
# deploy.ymlに渡す環境変数を定義
secrets:
AWS_ROLE_ARN: arn:aws:iam::${{secrets.AWS_ACCOUNT_ID_DEV}}:role/{作成したAWSロール名}
AWS_S3_BUCKET: ${{ secrets.S3_BUCKET_DEV }}
deploy_main.yml
name: deploy to main
on:
push:
branches:
- main
# 以下のいずれかが変更された場合に実行される
paths:
- "images/**"
- "js/**"
- "styles/**"
- index.html
jobs:
deploy:
# deploy.ymlを再利用する
uses: {Github組織(ユーザー)名}/{Githubリポジトリ名}/.github/workflows/deploy.yml@main
# deploy.ymlに渡す環境変数を定義
secrets:
AWS_ROLE_ARN: arn:aws:iam::${{secrets.AWS_ACCOUNT_ID_MAIN}}:role/{作成したAWSロール名}
AWS_S3_BUCKET: ${{ secrets.S3_BUCKET_MAIN }}
deploy.yml
name: deploy
on:
# 別のworkflow(deploy_develop.yml, deploy_main.yml)からの呼び出しをトリガーにする
workflow_call:
# 呼び出し元で定義した環境変数を受け取る
secrets:
AWS_ROLE_ARN:
required: true
AWS_S3_BUCKET:
required: true
# 共通の環境変数
env:
AWS_REGION: ap-northeast-1
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
# 認証情報を取得しAWSにアクセス可能にする
- name: Configure AWS credentials from IAM Role
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
# sync: ディレクトリ内のファイルをS3のディレクトリに同期させる
# cp: ファイルをS3のバケットにコピーする
- name: Upload files to S3
run: |
aws s3 sync --delete images/ s3://${{ secrets.AWS_S3_BUCKET }}/images/
aws s3 sync --delete js/ s3://${{ secrets.AWS_S3_BUCKET }}/js/
aws s3 sync --delete styles/ s3://${{ secrets.AWS_S3_BUCKET }}/styles/
aws s3 cp index.html s3://${{ secrets.AWS_S3_BUCKET }}/index.html
以上です!最後までありがとうございました!🧝🧝♀️🧝♂️
Discussion