[AWS] Lambda 関数を AWS CLI を使ってデプロイする


はじめに

AWS Lambda を使ってサーバレスな環境での処理を実施出来るのは良いが、毎回 AWS マネジメントコンソール からメンテナンスするのも億劫だし、できれば Lambda 関数のコードは Git 等で管理したい。

というわけで、Lambda 関数のコードはローカルでメンテナンスを行い、AWS CLI を使ってデプロイする方法について見ていく。

前提条件

本記事における前提条件は以下の 4 点。

  1. デプロイ対象の Lambda 関数がすでに存在していること
    • つまり
      • aws iam create-role でロール作成を事前に行うのではなく
      • aws lambda create-function で Lambda 関数を作成するのでもない
  2. 既存の Lambda 関数に対する 更新 を行うことが目的となる
  3. AWS CLI がインストールされていること
  4. AWS CLI を実行するためのユーザがいること

作業環境

本記事の作業は EC2 インスタンス上で実施している。

前準備

AWS CLI を使うには、前提条件 でも挙げた次の 2 点が必要なので、そのための確認と前準備を行う。

  • AWS CLI がインストールされていること
  • AWS CLI を実行するためのユーザがいること

AWS CLI の確認

繰り返しとなるが、本記事では AWS CLI の実行と確認を EC2 インスタンス上で行っている。
EC2 インスタンスでは予め AWS CLI がインストールされているため、当該ツールのインストールは行っていない。
念の為、インストールされているかの確認とバージョンの確認をしておく。

# 所在確認
$ which aws
/usr/bin/aws

# (一応)バージョン確認
$ aws --version
aws-cli/1.14.9 Python/2.7.13 Linux/4.9.81-35.56.amzn1.x86_64 botocore/1.8.13

AWS CLI の設定

AWS CLI ユーザ

「アクセスの権限」に「プログラムによるアクセス」のみを選択してユーザを作成。ユーザ名は aws-cli とした。
以下のロールを持つグループ Aws-Cli を作成し、作成したユーザに紐付けた。権限は持たせ過ぎかも。

アカウント グループ ロール
aws-cli Aws-Cli EC2FullAccess, S3FullAccess, LambdaFullAccess

で、大事なポイント。
作成後に発行されるクレデンシャルは AWS CLI の設定を行う際に必要になる。必ずメモ、もしくは csv でダウンロードしておくこと。
ここで保存しておかないと、もう手に入れる術が無いらしい。

補足

  • 紛失したり忘れたりした場合は再作成できる
  • IAM ユーザーのアクセスキーの管理 の 「アクセスキーの管理 (コンソール) > 別の IAM ユーザーのアクセスキーを作成、変更、または削除するには (コンソール)」 を参照

AWS CLI の設定

aws configure コマンドで設定を行う。設定項目は多くないので敷居は全然高くない。
設定については公式の 設定ファイルと認証情報ファイルの設定 を参照。

$ aws configure
AWS Access Key ID [None]: ${Access Key}            # <- AWS CLI ユーザ作ったときの Access Key
AWS Secret Access Key [None]: ${Secret Access Key} # <- AWS CLI ユーザ作ったときの Secret Access Key
Default region name [None]: ${Region Name}         # <- デプロイ対象のリージョン, 東京の場合は `ap-northeast-1`
Default output format [None]: json                 # <- json/yaml/txt/table を選択できる

ここで Access KeySecret Access Key を指定することでデプロイ先が決まる、つまり 指定したキーに紐づくユーザが存在する環境に対してデプロイされる、ということになる。この辺はしっかりと理解しておきたい。

AWS CLI によるデプロイ

前準備が整ったので、実際に AWS CLI を使って Lambda 関数のデプロイを行っていく。

環境変数の設定

環境変数の適用コマンド

もし Lambda 関数に対して環境変数を設定したい場合、以下のコマンドで設定できる。

$ aws lambda update-function-configuration --function-name Hogehoge --environment Variables={KeyName1=string,KeyName2=string}

参考: update-function-configuration

デプロイ

デプロイコマンド

デプロイは対象のリソースを zip で固めてコマンドを実行するだけで良い。

$ zip -r lambda.zip .
$ aws lambda update-function-code --function-name Hogehoge --zip-file fileb://lambda.zip

このとき zip で固めるのは Lambda 関数のコードがあるディレクトリ。

参考: update-function-code

デプロイの例

ディレクトリ構造が以下の場合( Python で Lambda 関数を実装 )

git-repository/
+ src/
    + functions/
        + Hogehoge/
        |   + conf/
        |   |   + Hogehoge.conf
        |   + lambda_function.py
        + Piyopiyo/
            + conf/
            |   + Piyopiyo.conf
            + lambda_function.py

Hogehoge をデプロイしたければ

  1. cd git-repository/src/function/HogehogeHogehoge/ まで移動
  2. zip -r lambda.zip .Hogehoge 以下を固める
  3. で、aws lambda update-function-code ~ を実行してデプロイする

流れとなる。

環境変数の適用例

説明が前後するが、conf/Hogehoge.cong の中身に Lambda 関数の環境変数を次のような形で定義していた場合、

HOGE=hogeeeeee
PIYO=poiyooooo
Bar=Barrrrrrrr

環境変数の設定 で挙げたコマンドを以下のようにすることで、ファイルの中身を環境変数に反映させることも出来る。

cd git-repository/src/function/Hogehoge

# 1. ファイル末尾の空行を削除
# 2. ファイルの改行コードを `,` に置換
# 3. ファイル末尾にできた `,` を `` に置換(トリムする)
# 4. 上記工程を `Variables={}` の中で行った後、環境変数を Lambda に適用
aws lambda update-function-configuration  --function-name Hogehoge --environment Variables={`cat conf/Hogehoge.conf | tr -s "\n" | tr '\n' ',' | sed s/,$//`}

おまけ

Jenkins からのデプロイ

AWS CLI を使って Jenkins ジョブから Lambda 関数のデプロイも簡単にできたので、その手順も備忘録としてあげておく。

なお今回、 Jenkins は EC2 で構築しているので、AWS CLI のインストールは行っていない。

Jenkins ジョブの作成

任意のジョブ名を入力して「フリースタイル・プロジェクトのビルド」を選択する。

ビルドパラメータの設定

「説明」には本ジョブに関する説明を記入する。

それから、後述の ソースコード管理の選択 で Git を選択するので、入力された文字列をデプロイ対象のブランチとする べく

  • 「ビルドのパラメータ化」にチェックを入れ
  • 「名前」と「デフォルト値」を入力する

ソースコード管理の選択

ここでは GitHub のリポジトリを扱いたいので

  • Git を選択
  • リポジトリ URL には GitHub のURL を入力
  • 認証情報は、有れば入力
  • ブランチ指定子は ビルドパラメータの設定 で入力した文字列を $ を接頭辞につけて指定する

ビルド処理

シェルの実行を選択

AWS CLI を使用して Lambda 関数をデプロイしたいので、ビルド処理では「シェルの実行」を選択する。

ビルドシェル

ビルドシェルは以下の通り。

で指定したリポジトリはジョブ実行時に $WORKSPACE 配下にクローンされてくる。
で、$WORKSPACE 配下の __デプロイしたい Lambda 関数のソースコードがあるところまで移動 し、AWS CLI によるデプロイ で示したように aws lamda コマンドから環境変数の適用とデプロイを行う。

#!/bin/bash
#
# Hogehoge
#

# ここで Lambda 関数としてデプロイしたいディレクトリまで移動する
cd $WORKSPACE/src/function/Hogehoge

# 環境変数の適用
## 1. ファイル末尾の空行を削除
## 2. ファイルの改行コードを `,` に置換
## 3. ファイル末尾にできた `,` を `` に置換(トリムする)
## 4. 上記工程を `Variables={}` の中で行った後、環境変数を Lambda に適用
aws lambda update-function-configuration  --function-name Hogehoge --environment Variables={`cat conf/Hogehoge.conf | tr -s "\n" | tr '\n' ',' | sed s/,$//`}

# デプロイ
## デプロイ対象のリソースを zip で固めたうえで
zip -r lambda.zip .

## AWS CLI でデプロイする
### function-nameはlambda上の上書き対象の関数名
aws lambda update-function-code --function-name Hogehoge --zip-file fileb://lambda.zip

exit

まとめにかえて

所感

AWS CLI からコマンドを実行する際、どこに対してデプロイするのか を CLI を実行するときに指定しないのが気持ち悪かった。

当初、「デプロイ先を指定しないでどこにデプロイするんだ ?」と疑問だったのだが、手順を調べていくなかで aws configure で CLI の設定を行うことを知った。

で、aws configure を実行した際に AWS CLI ユーザの Access KeySecret Access Key を設定することでデプロイ先が決まるんだな、ということで腹に落ちた。

この辺、なんとなくで使っているとモヤモヤ感が残るので、しっかり理解して使っていきたい。

このあと試したいこと

今回は Lambda 関数が既に AWS 上に存在する前提で、それに対するデプロイを AWS CLI から行えることを確認した。
が、Lambda 関数が存在しない状態でもデプロイが出来るようにしてみたい。

に書いたように aws iam create-roleaws lambda create-function を組み合わせることで対応はできるが、以下の記事によると SAM を利用することでも実現できる様子。

なので、そのうちこちらも試してみたい。

参考

AWS 本家

上記以外