GitHub Actions+AWS SAMでCI/CD構築
はじめに
GitHub Actions+AWS SAMでCI/CD構築してみました。
構築・設定手順の備忘です。
前提条件
- AWS SAM テンプレート作成
- GitHub環境(アカウント作成・リポジトリ作成など)
全体イメージ
GitHubの特定のリポジトリのmainブランチにpushされたらAWS SAMのテンプレートを使用してAWSリソースをデプロイします。
構築手順
IDプロバイダの追加
IDプロバイダを追加します。
- タイプ:OpenID Connect
- URL:https://token.actions.githubusercontent.com
- 対象者:sts.amazonaws.com
上記の通りに入力後、「サムプリントを取得」をクリックして、サムプリントが表示されたら、「プロバイダを追加」をクリックして、IDプロバイダを作成します。
※サーバー証明書のサムプリントは、OpenID Connectプロバイダがキーを利用できるようにするドメインで使用されるX.509証明書の16進でエンコードされたSHA-1ハッシュ値です。
IAMロールの作成
GitHub ActionsでかぶるIAMロールを作成します。
IAMロールには、以下の2つを設定します。
- 許可ポリシー
AWSリソースへのアクセス許可ポリシー - 信頼ポリシー
このロールを引き受けることができるエンティティの条件を指定します。
まず、許可ポリシーに設定するポリシーを作ります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"s3:*",
"apigateway:*",
"cloudformation:*",
"dynamodb:*",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:PassRole",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"lambda:*",
"cognito-idp:*",
"iam:GetRolePolicy"
],
"Resource": "*"
}
]
}
今回、必要なサービス(Cognito User Pools、API Gateway、Lambda、DynamoDB、S3)の全リソースへの全アクションを許可しています。
※全許可で動くことを確認してから個々のアクション、リソースを指定します。
ポリシーエディタでもしっかりと怒られてます。
できました。これを、この後作成するロールにアタッチします。
GitHub ActionsでかぶるIAMロールを作成します。エンティティタイプは、ウェブアイデンティティですね。プロバイダーと、オーディエンスは先ほど作成済みのIDプロバイダーを指定します。
先ほど作成した許可ポリシーをアタッチします。
ここの「ステップ1:信頼されたエンティティを選択する」でこのロールを引き受けることができるエンティティの条件を指定します。
編集ボタンから編集します。
!!!???
と、思ったのですが、この選択画面に行ってしまい、編集できないですね。
ひとまず、ロール作成してしまいます。
その後、できたロールを選択して、「信頼ポリシーを編集」から編集します。
Principalは自動で入っているフェデレーテッドユーザーのままで良いです。
Conditionに以下を追加します。
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:{GitHubユーザー名}/sample-git-repository:*"
}
「ポリシーを更新」をクリック
できました。
GitHub Actions Secrets設定
GitHub Actions Secretsを設定します。
IAM_ROLE_ARN:先ほど作成したGitHub ActionsがかぶるIAMロールのARN
AWS_REGION:AWSのリージョン 例:ap-northeast-1
これらのシークレットキーを次の手順のワークフローファイルで参照する設定を入れます。
GitHub Actionsのワークフローファイル作成
GitHub Actionsのワークフローファイルを作成します。
ワークフロー構文
リポジトリの .github/workflows/ 配下に YML 形式で保存します。
例では、.github/workflows/deploy.yamlです。
name: Deploy-AWS-todo-app
on:
push:
branches:
- 'main'
workflow_dispatch:
env:
TEMPLATE_FILE: template.yaml
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup python
uses: actions/setup-python@v3
with:
python-version: '3.9'
- name: Setup aws-sam
uses: aws-actions/setup-sam@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
aws-region: ${{secrets.AWS_REGION}}
role-to-assume: ${{secrets.IAM_ROLE_ARN}}
- run: aws sts get-caller-identity
- name: Build & Deploy Cloudformation stacks
run: |
sam build --template-file ${TEMPLATE_FILE}
sam deploy --template-file ${TEMPLATE_FILE}
permission: ではジョブに対して、IDトークンの書き込み権限を割り当てています。
ワークフローがGitHub OIDCのトークンを要求するために必要になります。
このテンプレートファイルをmainブランチにプッシュします。
すると、すぐに、始まりました!
むむ!失敗したようです。
エラーの詳細を見ていくと、
デプロイ中の質問に答えられずに中止されてしまったようです。
以下のファイルを修正します。
samconfig.toml
[default.deploy.parameters]
confirm_changeset = false
テンプレートファイルに「echo 'y'」入れるなどの対策があるようです。今回はこちらの対応で行きます。
※confirm_changesetオプション(デフォルトfalse)は、デプロイ前に変更セットを作成してからデプロイするかどうかの設定です。予期しないリソース置換を防ぐ事ができるため、trueが推奨です。
そして、Action実行!
右上「Run workflow」から実行できます。workflow_dispatch
も対象にしているため。
お、おぉぉぉぉ!成功しました。
この後、AWSマネジメントコンソールで確認しましたが、各リソースが正常にデプロイされていました。めでたしめでたし。
最後に
と、思ったのですが、デプロイ後のLambda関数の実行ログで以下のエラーが出てしまいアプリケーションが動作しませんでした(毎回)。現在まだ原因は特定できていません。
[ERROR] Runtime.ImportModuleError: Unable to import module 'app': No module named 'awsgi' Traceback (most recent call last):
ローカル環境からsam deploy
でデプロイすると、起きないエラーです。
requirement.txtにaws-wsgi
を記載していますが、構築時に失敗してしまうのでしょうか。
あと、ローカルからsam deploy
でデプロイすると、
となるのですが、GitHub Actionsからデプロイすると、コードが見えるのですよね。上がるものが違う?
進捗あり次第、追記します。
Discussion