🧚♂️
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