CodePipeline や CodeBuild を利用したパイプラインの作成記事はよく見ますが、GitHub Actions を利用した日本語記事はあまり見かけないので備忘録として残します。 特に難しいことはしていないのですが、Actions 用の Credential(IAM User)は作成せず、OpenID Connect(OIDC) を利用して AssumeRole(WithWebIdentity) してみました。以下はサンプルのレポジトリです。
1. SAM Application の作成
公式チュートリアルを参考に、sam init
、 sam deploy
を実行します。今回は Python 3.9 で作成しています。
2. Identity provider の作成
GitHub OIDC Provider から AWS に対して Credential を要求するために、AWS 側で OIDC Provider と IAM Role を作成する必要があります。
まずは IAM で OIDC Provider を CloudFormation(template.yaml
) で作成します。AWS マネージメントコンソールと CloudFormation のドキュメント、GitHub のドキュメントを行き来しながら作成しました。
パラメータは以下を指定しました。これは 2022/06/27 時点での情報であり、今後変わる可能性もあるため作成の際は公式ドキュメントを確認するようにしてください。
Key | Value |
---|---|
Provider URL | https://token.actions.githubusercontent.com |
Thumbprints | 6938fd4d98bab03faadb97b34396831e3780aea1 |
Audience | sts.amazonaws.com |
CloudFormation template の記載方法は aws-actions/configure-aws-credentials の README を参考にしました。
3. IAM Role の作成
AWS 側の OIDC Provider で JWT を検証できたら、指定の IAM Role を利用し、一時 Credential を発行して Actions へ渡します。IAM Role には sam deploy
に必要な IAM Policy をアタッチします。
IAM Role と IAM Policy も CloudFormation で作成します。IAM Role の Trust relationships も aws-actions/configure-aws-credentials の README を参考に記載しました。
IAM Role の Trust relationships(信頼関係)は以下のように指定しました。
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "token.actions.githubusercontent.com:sub": "repo:enokawa/sam-cicd-sample:*" } } } ] }
IAM Policy に必要な権限は、前述した通り sam deploy
に必要なものを指定する必要があります。最小権限の原則に則った権限設定を行うことが望ましいですが、今回はおおざっぱな権限を付与しています。詳しくは以下の行を参照してください。プロダクションで利用する場合は、必要な権限やリソースを洗い出して設定するようにしましょう。
必要な権限やリソースの洗い出しにはかなりの労力が必要となりますが、以下のドキュメントが参考になるかもしれません。
4. Secrets の登録
AWS アカウント ID やデプロイ先のリージョン、S3 バケット名など固有のリソース名は他者に知られたくないため、GitHub の Secrets に登録します。今回は Public レポジトリのため以下の設定としていますが、Private レポジトリでも利用した方がよいでしょう。
Key | Value | 用途 |
---|---|---|
AWS_ACCOUNT_ID | 12 桁の AWS アカウント ID | aws-actions/configure-aws-credentials@v1 で IAM Role(role-to-assume ) の ARN を指定する際に利用 |
AWS_REGION | デプロイ先の AWS リージョン名 | aws-actions/configure-aws-credentials@v1 で デプロイ先のリージョン(aws-region )を指定する際に利用 |
AWS_SAM_STACK_NAME | デプロイする SAM の CloudFormation Stack 名 | Integration test 時に Stack 名を指定する際に利用 |
S3_BUCKET_NAME | Lambda のコードや CloudFormation template 保存先の S3 バケット名 | sam deploy 時に S3 バケット名を指定する際に利用 |
5. Workflow の定義
ここまでできたら準備完了です。 .github
ディレクトリ配下に Workflow や Job、Step を定義していきます。今回は、Build 用と Deploy 用で Workflow を分けてみました。YAML を修正しては GitHub に push して Actions がコケてまた YAML を修正して... を繰り返していました。試せていませんが、actionlint や act を使うことでもっとスムーズにデバッグできるかもしれません。
最終的に、以下のように無事 Actions が想定通りに動作することが確認できました。以降は、ローカルではデプロイせずに Actions からデプロイする運用を想定しています。ただ GitHub 側の障害もあり得るため、ローカルからデプロイができるように手順を準備しておいた方がよいかと思います。
まとめ
AWS SAM Application を GitHub Actions + OpenID Connect を利用してデプロイする方法を紹介しました。OIDC の利用は初めてだったのですが、IAM User を作成せずに一時 Credential を発行できるためセキュアに CI/CD パイプラインを構築できてよいですね。