GitHub Actionsを使ってAWS SAMアプリをデプロイする use OpenID Connect
現行、GitHub + CodeBuildでSAMアプリをデプロイしているのですが、CodeBuildをGitHub Actionsに置き換えたらどうなるか試してみました。
GitHub ActionsとAWSの連携は、シークレットをGitHubに保存しなくて済む、OpenID Conncetを使っています。
GitHub ActionsとCodeBuild両方使った感想は、Actionsのほうが機能が多く、複雑なことができるので新規ではじめるならActionsのほうが良いかなぁ、という印象でした。
もっとも、CodeBuildで出来ていることをわざわざActionsに移植しても、あまりメリットを感じないので、現行の環境はCodeBuildのままにしておこうと思いました。
GitHubリポジトリの準備
リポジトリの作成
-
GitHubにログインする
-
GitHub右上の「+」を押して「New Repository」を選択する
-
適当に入力して、新規リポジトリを作成する
-
表示されたリポジトリのURLを控えておく
Personal access tokenの作成
-
右上の自分のアイコンをクリック、Settingsを選択する
-
左メニューからDeveloper settingsを選択する
-
左メニューからPersonal access tokensを選択する
-
Generate New Tokenを選択する
-
パスワードの入力を求められたら、パスワードを入力する
-
下記を入力して「Generate token」を押す。
- Note: 利用目的
- Expiration: 30 days
- Select scopes: repoとworkflowにチェック
Cloud9 環境作成
-
AWSコンソールでCloud9のページを開く
-
「Create Environment」を押す
-
任意の名前を入力して「Next step」を押す
-
スペックを選んで「Next step」を押す
(最低スペックでも問題ないと思うが、筆者はt3.smallインスタンスを選択)
-
確認画面が表示されるので、内容を確認して「Create Envrionment」を押す
-
Cloud9 コンソールで下記コマンドを実行する(名前とメールアドレスは、自分のものを入力)
$ git config --global user.name "hoge fuga" $ git config --global user.email hoge-fuga@example.com $ git config --global init.defaultBranch main
-
Cloud9 コンソールで下記コマンドを実行する
$ git init $ echo ".c9*" >> .gitignore $ git add -A $ git commit -m "initial commit"
-
Cloud9 コンソールで下記コマンドを実行する(リモートURLは、GitHubリポジトリ作成時に控えておいたもを入力。Usernameは、GitHubのログインに使用するものを入力。Passwordは、Personal Access Tokenを入力する)
$ git remote add origin https://github.com/hoge-fuga/actions-sam.git $ git push -u origin main Username for 'https://github.com/hoge-fuga/actions-sam.git': hoge-fuga Password for 'https://hoge-fuga@github.com/hoge-fuga/actions-sam.git': ...
SAMの準備
Lambdaのコードの準備
-
下記コマンドを実行してディレクトリを準備する
$ mkdir lambda $ mkdir lambda/hello_aws $ mkdir lambda/hello_github $ touch lambda/hello_aws/lambda_function.py $ touch lambda/hello_github/lambda_function.py
-
lambda/hello_aws/lambda_function.py を開き下記のようにする
def lambda_handler(event, context): return("hello aws")
-
lambda/hello_github/lambda_function.py を開き下記のようにする
def lambda_handler(event, context): return("hello github")
SAMテンプレートを追加
-
下記コマンドを実行してSAMテンプレートファイルを作成する
$ touch template.yaml
-
template.yamlを開き下記のようにする
AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > GitHub Actions + SAM + Lambda Kensho Globals: Function: Timeout: 60 Resources: ### ### Lambda Fn. ### cfnFunctionHelloAws: Type: AWS::Serverless::Function Properties: CodeUri: lambda/hello_aws/ Handler: lambda_function.lambda_handler Runtime: python3.9 cfnFunctionHelloGithub: Type: AWS::Serverless::Function Properties: CodeUri: lambda/hello_github/ Handler: lambda_function.lambda_handler Runtime: python3.9
-
.gitignoreにsam関連ファイルを追加する
$ echo ".aws-sam/*" >> .gitignore
Python 3.9のインストール
Python 3.9でLambda動かしたいときだけ、実施。バージョンにこだわりがない場合は、template.yamlのRuntime: python3.7 に変更すれば、当手順は省略可能。
-
下記コマンドを実行する
$ sudo yum install gcc openssl-devel bzip2-devel libffi-devel $ cd /opt $ sudo wget https://www.python.org/ftp/python/3.9.12/Python-3.9.12.tgz $ sudo tar xzf Python-3.9.12.tgz $ cd Python-3.9.12 $ sudo ./configure --enable-optimizations $ sudo make altinstall $ sudo rm -f /opt/Python-3.9.12.tgz $ python3.9 -V Python 3.9.12
SAM Configの作成
-
下記コマンドのようにsam build、sam deploy --guidedを途中まで実行することによって、SAM Configファイルの作成までを行う
$ cd ~/environment/ $ sam build $ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: actions-test AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: y #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]: ... Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: N
-
作成された samconfig.tomlの内容を確認する
version = 0.1 [default] [default.deploy] [default.deploy.parameters] stack_name = "actions-test" s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-<ランダムな値>" s3_prefix = "actions-test" region = "ap-northeast-1" confirm_changeset = true capabilities = "CAPABILITY_IAM" image_repositories = []
OIDCプロバイダ、IAMロールの作成
GitHub Actions用OIDCプロバイダの作成
-
下記コマンドを実行して、Cloudformationテンプレート用ファイルを作成する
$ cd ~/environment/ $ mkdir cloudformation $ cd cloudformation/ $ touch iam-oidc.yml
-
iam-oidc.ymlの中を下記のように編集する
AWSTemplateFormatVersion: "2010-09-09" Description: > GitHub Actions Kensho IAM OIDC Provider for GitHub Resources: cfnIamOidcGithub: Type: AWS::IAM::OIDCProvider Properties: Url: https://token.actions.githubusercontent.com ClientIdList: - sts.amazonaws.com ThumbprintList: # Fixed Value - 6938fd4d98bab03faadb97b34396831e3780aea1 Outputs: OidcGithub: Value: !GetAtt cfnIamOidcGithub.Arn Export: Name: OidcGithub
-
下記コマンドを実行して、Cloudformationスタックを作成する
$ CFN_TEMPLATE="iam-oidc.yml" $ CFN_STACK_NAME="github-actions-kensho-iam-oidc" $ aws cloudformation deploy --stack-name ${CFN_STACK_NAME} \ --template-file ${CFN_TEMPLATE}
GitHub Actions用IAMロール、ポリシーの作成
-
下記コマンドを実行して、Cloudformationテンプレート用ファイルを作成する
$ touch iam-role.yml $ touch iam-role-policy.yml
-
iam-role-policy.ymlの中を下記のように編集する
AWSTemplateFormatVersion: "2010-09-09" Description: > GitHub Actions Kensho IAM Role and Policy for GitHub Parameters: GithubOrg: Type: String RepositoryName: Type: String Resources: cfnIamRoleGithub: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Action: sts:AssumeRoleWithWebIdentity Principal: Federated: - !ImportValue OidcGithub Condition: StringLike: token.actions.githubusercontent.com:sub: !Sub repo:${GithubOrg}/${RepositoryName}:* RoleName: github-actions-kensho ManagedPolicyArns: - !Ref cfnIAMPolicyGithub cfnIAMPolicyGithub: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Sid: S3ObjectPolicy Effect: Allow Action: - s3:* Resource: - arn:aws:s3:::aws-sam-cli-managed-default-*/* - arn:aws:s3:::aws-sam-cli-managed-default-* - Sid: CF Effect: Allow Action: - cloudformation:* Resource: - arn:aws:cloudformation:*:*:stack/* - arn:aws:cloudformation:*:aws:transform/Serverless-2016-10-31 - Sid: IAM Effect: Allow Action: - iam:* Resource: - arn:aws:iam::*:role/* - Sid: Lambda Effect: Allow Action: - lambda:* Resource: - arn:aws:lambda:*:*:function:* ManagedPolicyName: github-actions-kensho
- 下記コマンドを実行して、Cloudformationスタックを作成する
$ GithubOrg=<GitHubのOrganization名> $ RepositoryName=<GitHubのRepository名> $ CFN_TEMPLATE="iam-role-policy.yml" $ CFN_STACK_NAME="github-actions-kensho-iam-role" $ aws cloudformation deploy --stack-name ${CFN_STACK_NAME} \ --template-file ${CFN_TEMPLATE} \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides \ GithubOrg=${GithubOrg} \ RepositoryName=${RepositoryName}
GitHub Actionsの作成と実行
GitHub Actionsの実行
-
Actionsのワークフローファイルを作成する
$ cd ~/environment/ $ mkdir -p .github/workflows $ cd .github/workflows/ $ touch sam-build-and-deploy.yml
-
sam-build-and-deploy.yml の中を下記のようにする
name: OIDC SAM Kensho on: push: branches: - main permissions: id-token: write contents: read jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::<AWSアカウントID>:role/github-actions-kensho aws-region: ap-northeast-1 - uses: actions/setup-python@v2 with: python-version: '3.9' - uses: aws-actions/setup-sam@v1 - run: sam build - run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
Actions の実行
-
コードをコミット、プッシュする
$ git add -A $ git commit -m "add-sam-lambda" $ git push
-
GitHubのActionsの画面から実行結果を確認する
-
Lambda関数が作成されていることを確認する
Discussion