モチベーション
AWSコンソールを開いたり、AWS CLIを使わずに、gitの操作だけでAWS Lambda関数のデプロイを完了します。
近年、Github AcitonsというGithub純正のCI/CDツールがリリースされました。
これを使って、Githubで管理しているAWS Lambda関数の変更を、AWSに反映します。
前提条件
今回はRubyで作成されたAWS Lambda関数を更新します。
Lambda関数とデプロイスクリプトが同じ言語だとメンテナンスが楽なので、デプロイにもRubyを使います。
先駆者
検索すると、AWS Lambda関数をデプロイするGithub Acitonsがいくつか公開されているのが見つかります。1
例えば Deploy AWS Lambda function のソースコードを見てみましょう。aws-sdk
を使っているのがわかります。2
その中でもupdate_function_code
メソッドを使っています。3
引数にはZipファイルを指定しています。
AWSコンソールでAWS Lambda関数を更新するときと同様に、zipファイルを作って更新すれば良さそうです。
Ruby用のaws-sdk-lambda gemを使います。
準備
IAMユーザー
万が一、AWSのIDとパスワードが漏れたときに、該アカウントだけを停止できるように、AWS上にdeploy専用のIAMユーザーを作成します。
必要なIAMポリシーは次のとおりです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lambda:UpdateFunctionCode",
"Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXX:function:tange"
}
]
}
Action
には今回使いたいupdate_function_code
メソッドを表すlambda:UpdateFunctionCode
を指定します。
Resource
には、更新対象のLambda関数のARN
の値を指定します。ここでは
arn:aws:lambda:ap-northeast-1:XXXXXXX:function:tange
を指定しました。
Github Secrets
Github Actionsには、リポジトリに設定されたパスワードのような秘密情報を参照する機能があります。
IAMのaccess_key_id
とsecret_access_key
をGithub Actionsから参照するのに使います。
手順は暗号化されたシークレットの作成と利用 - GitHub ヘルプを参照してください。
Github Actions
完成形
最初に完成形を示します。これをLambda関数を管理しているリポジトリに追加すると、Github Acitonsは動作します。
name: Ruby
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Ruby 2.5の環境を作る
uses: actions/setup-ruby@v1
with:
ruby-version: 2.5.x
- name: 依存gemをダウンロード
run: |
gem install bundler
bundle config set deployment 'true'
bundle install
- name: zip圧縮
run: |
zip deploy_package lambda_function.rb -r vendor
- name: AWSにアップロード
env:
access_key_id: ${{ secrets.access_key_id }}
secret_access_key: ${{ secrets.secret_access_key }}
run: |
gem install aws-sdk-lambda
bin/deploy
各ジョブの解説
リポジトリへのpushに応じてGithub Actionsを起動する
on: [push]
onには色々なトリガーが指定できます。
詳しくはワークフローをトリガーするイベント - GitHub ヘルプを見てください。
ソースコードをチェックアウトする
- uses: actions/checkout@v1
Ruby 2.5の環境を作る
AWS Lambdaはruby 2.5をサポートしています。4
- name: Ruby 2.5の環境を作る
uses: actions/setup-ruby@v1
with:
ruby-version: 2.5.x
依存gemをダウンロード
- name: bundle install
run: |
gem install bundler
bundle config set deployment 'true'
bundle install
AWS Lambdaでは、関数は実行可能は状態でアップロードする必要があります。
つまりアップロードzipファイルには依存ライブラリも入れる必要があります。
zipファイルに入れやすくするため、依存gemをローカルディレクトリにインストールします。
bundle config set deployment 'true'
を設定すると、依存ライブラリはvendor
ディレクトリ配下に格納されます。
zip圧縮
zipコマンドで必要なファイルを1つのzipファイルに纏めます。
- name: Zip
run: |
zip deploy_package lambda_function.rb -r vendor
deploy_package
は作成するzipファイル名です。
lambda_function.rb
はzipファイルに含めるファイル名です。
AWS LambdaでRubyランタイムを使うときのデフォルトファイル名がlambda_function.rb
です。
他に必要なファイルがあれば、空白で区切って続けて書いてください。
-r vendor
はbundle install
コマンドで保存した依存ライブラリをzipファイルに入れるためにつけています。
他に必要なディレクトリがあれば追加してください。
AWSにアップロード
- name: Deploy
env:
access_key_id: ${{ secrets.access_key_id }}
secret_access_key: ${{ secrets.secret_access_key }}
run: |
gem install aws-sdk-lambda
bin/deploy
Github Secretsに設定した秘密情報を読み込みます。
env:
access_key_id: ${{ secrets.access_key_id }}
secret_access_key: ${{ secrets.secret_access_key }}
${{ secrets.access_key_id }}
がGithub Secretsを参照している箇所です。
デプロイに必要なaws-sdk-lambda
gemをインストールして、デプロイを実行します。
run: |
gem install aws-sdk-lambda
bin/deploy
bin/deploy
はRubyスクリプトです。
#!/usr/bin/env ruby
require "aws-sdk-lambda"
client = Aws::Lambda::Client.new region: "ap-northeast-1",
access_key_id: ENV["access_key_id"],
secret_access_key: ENV["secret_access_key"]
zip_file = File.open "deploy_package.zip", "r"
client.update_function_code function_name: "tange", zip_file: zip_file
Aws::Lambda::Client#update_function_codeを使って、AWS Lambda関数を更新します。
-
https://github.com/marketplace?utf8=%E2%9C%93&type=actions&query=lambda ↩
-
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L4 ↩
-
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L34 ↩
-
https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html ↩