こちらは今年もやるよ!AWS Lambda縛り Advent Calendar 2015の16日の記事ですが、随時更新してます(最終更新: 2016-07-15)
はじめに
なお、記載されている情報は全て2015-07-15現在のものです。
開発は随時行っているため変わる可能性があります。
Lamveryとは?
いいからソース
コチラになります
https://github.com/marcy-terui/lamvery
概要
Lambda functionのデプロイやFunctionそのものを含めた周辺機能の設定・管理を支援するツールです。
Python製で自分自身主にPythonで使っていますが、Node.jsも一応対応していて、最低限の動作確認もしてます。
User-friendly deploy and management tool for AWS Lambda function
というコンセプトの元、一つのFunctionを如何に楽に便利に扱うかと実践的なデプロイフローの確率に主眼を置いて開発しており、あくまでフレームワークではなくツールという位置づけです。
また、こういったツールはFunctionのdeployにフックしないと実現できないような付加機能を付けられることに価値があると思っていて、そういったものを積極的に追加しているのが特長です。
読み方
作者は「らんべりー」と読んでます。
語源
元々はAWSのドキュメントに書いているPythonコードのデプロイ方法があまりにも面倒で、これをなんとかできないかなと思って作ったので、「Lam bda + v irtual e nv + p y thon」1と適当にピックアップして繋げた感じですが、今ではもうちょと短くてかっこ良い名前が良かったなとか思わなくもないですw
何故他のような同じようなツールとの比較
lambda-uploader, Kappa等
- 設定ファイルがJSON(YAMLの方がマシ)
- 設定ファイルとコマンドラインオプションの切り分けが不明確
- virtualenvのライブラリのパスがベタ書きだったり、格納効率が悪くてデプロイパッケージ(zip)が肥大化する
-
.py
,.pyc
の区別がなく、片方あれば良いのに全てアーカイブに含まれる2
-
Apex
こちらをご確認ください。特にrollbackの仕様は一目見て「あ、これダメなやつだ」って分かったので注意した方が良いです。
http://qiita.com/marcy-terui/items/db8dae512af3c553fe72
上記を使わずにLamveryを作ったのはなぜか?
- 扱いやすい設定ファイルが欲しかった
- 設定ファイルはYAML、さらにjinja2 templateとして解釈されるためコードや変数の埋め込みができる
- 多くのツールが実践を意識したパラメータやオプション設計がなされていない
- 私的な基準ではありますが、設定ファイルとコマンドラインオプションを以下の様なポリシーで分けています
- 設定ファイル=バージョン管理されるべきもの
- コマンドオプション=一時的に使用するもの
- 実践的なデプロイフローの確率
- Pythonおよびvirtualenvの仕様にあったデプロイパッケージ作成
-
.py
はアーカイブに格納せず.pyc
のみ格納など3
-
などなど、手に馴染んで実践的に使えるツールが欲しかったのと、使っていく中で色々欲しくなりそうだったのでいっその事自分で作っちゃおうかなと。
ざっくり特長とできること一覧
- YAML + Jinja2テンプレートによる設定記述
- 格納効率に優れたパッケージ作成(Pythonのみ)
- 安全なデプロイおよびロールバック
- デプロイフック
- 環境変数の受け渡し
- KMSを用いた機密情報の受け渡し
- KMSを用いた機密ファイルの受け渡し
- API GatewayへのAPIデプロイおよび管理
- CloudWatch Eventsによるスケジュール実行の設定と管理
- CloudWatch Logsログ閲覧
使い方
インストール
- PyPI
アーカイブの効率が悪くなりますし、ディレクトリが汚くなるのでFunction本体を置くディレクトリ自体ではなくサブディレクトリにvirtualenv仮想環境を展開することをオススメします。
virtualenv -p <path-to-python2.7> .venv
. .venv/bin/activate
pip install lamvery
- Apt
echo "deb https://dl.bintray.com/willyworks/deb trusty main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install lamvery
export PATH=/opt/lamvery/bin:$PATH
- Yum
echo "
[bintraybintray-willyworks-rpm]
name=bintray-willyworks-rpm
baseurl=https://dl.bintray.com/willyworks/rpm/centos/\$releaserver/\$basearch/
gpgcheck=0
enabled=1
" | sudo tee -a /etc/yum.repos.d/bintray-willyworks-rpm.repo
sudo yum install lamvery
export PATH=/opt/lamvery/bin:$PATH
設定方法
まず、以下のコマンドで設定ファイルの雛形を作成します。
lamvery init
いくつかの設定ファイルの雛形が出来上がるので、それを編集します。
上述のとおり、jinja2 templateとして解釈されるため{{ }}
で囲むと変数展開、{% %}
で囲むとコードの埋め込みができます。
また、よく使われると思われる環境変数については簡潔に書けるようenv
という変数に入れておきました。
以下、設定例です。
基本設定
profile: private
region: us-east-1
versioning: true
default_alias: test
clean_build: false
configuration:
name: lamvery-test
runtime: python2.7
role: {{ env['AWS_LAMBDA_ROLE'] }}
handler: lambda_function.lambda_handler
description: This is sample lambda function.
timeout: 10
memory_size: 128
vpc_config:
subnets:
- subnet-cadf2993
security_groups:
- sg-4d095028
イベント(CloudWatch Events)設定
rules:
- name: foo
description: bar
schedule: 'rate(5 minutes)'
targets:
- id: test-target-id
input:
this:
- is: a
- sample: input
機密情報(KMS)に関する設定
key_id: xxxx-yyyy-zzzz
cipher_texts: {}
secret_files: {}
除外リスト
- ^\.lamvery\.yml$
- ^\.lamvery\.event\.yml$
- ^\.lamvery\.secret\.yml$
- ^\.lamvery\.exclude\.yml$
アクションフック
build:
pre:
- pip install -r requirements.txt -t ./
post: []
API Gateway
api_id: myipugal74
stage: dev
cors:
origin: '*'
methods:
- GET
- OPTION
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
configuration:
swagger: '2.0'
info:
title: Sample API
schemes:
- https
paths:
/:
get:
produces:
- application/json
parameters:
- name: sample
in: query
required: false
type: string
responses:
'200':
description: 200 response
schema:
$ref: '#/definitions/Sample'
definitions:
Sample:
type: object
設定項目
基本設定
- profile
aws configure --profile hoge
で設定するhoge
の部分です。
Credential情報やRegionの設定が入るやつです。
http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html
指定しない場合(null
と書く or 項目ごと削除)はAWS SDK(boto3)
の挙動に準じます(EC2上ならIAM Role、ローカルだとAWS_SECRET_KEY
等の環境変数とか) - region
そのまんまリージョン名 - versioning
バージョニングの有効(true
)、無効(false
) - default_alias
オプションで指定しない場合のエイリアス - clean_build
デプロイパッケージ作成時にソースコードをテンポラリのディレクトリに移動した上でパッケージを作成します。ビルドにフックしてライブラリなどをインストールしてデプロイしたい場合などに作業ディレクトリを汚さずに済みます(フックについては後述) - configuration
基本的にLambdaの設定項目そのままです。- name
Functionの名前です。APIでFunctionの特定に使われるため重複不可。 - runtime
Functionのランタイム。現状はpython2.7
ornodejs
をサポートしています。 - role
Lambda実行時に与えるIAM RoleのARN。 - handler
Functionのエントリーポイントとなる関数の名前空間。 - description
Functionの説明。 - timeoute
Functionの最大実行時間(秒) - memory_size
Function(のコンテナ)に与えるメモリサイズ(MB) - vpc_config
VPC内で動かすための設定
subnets
にサブネットID,security_groups
にセキュリティグループのIDをそれぞれリストで指定します。
- name
イベント(CloudWatch Events)設定
- name
Eventの一意なルール名 - description
ルールの説明 - targets
Eventのターゲット(複数可)- id
ターゲットの一意なID - input
ターゲットに渡す入力(Functionのevent
引数)に入る - input_path
input
との併用不可。JSONPath形式で、input
を指定しない場合にデフォルトで渡される引数の中から任意の部分だけ扱いたい場合に使用する
- id
機密情報に関する設定
- key_id
KMSの秘密鍵ID(ARNではなくIDの部分だけ) - cipher_texts
特定の文字列をKMSによって暗号化された暗号文が入ります。基本的にコマンドから設定するため、この項目を手動で書くことはまず無いです。
ここに入った情報がFunctionへ渡され、機密情報を安全に受け渡すことができます(詳しくは後述) - secret_files
特定のファイルの中身をKMSによって暗号化された暗号文とが入ります。基本的にコマンドから設定するため、この項目を手動で書くことはまず無いです。
ここに入った情報がFunctionへ渡され、機密情報が含まれたファイルを安全に受け渡すことができます(詳しくは後述)
除外リスト
ただひたすら正規表現で除外したいファイルのパスを列挙する
アクションフック
現状は build
のみサポートします。 build
はデプロイパッケージを作成する処理です。
pre
に前、 post
に後に実行させたいコマンドを列挙します。
API Gateway
- api_id
API GatewayにおけるAPIのID(rest-api-id)です。
api
コマンドでAPIを初回作成する際に-w
オプションを付けると自動で記入されます。 - stage
APIをデプロイするステージ名です。api
コマンド実行時にオプションで指定されない場合に使用されます。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/stages.html - cors
APIの各リソースに自動的に付与したいCORS (Cross-Origin Resource Sharing)オプションを指定します。- origin
Access-Control-Allow-Origin
に指定するオプション - headers
Access-Control-Allow-Headers
に指定するオプション - methods
Access-Control-Allow-Methods
に指定するオプション
- origin
- configuration
Swagger形式でAPIの設定を記述します。
Lambdaファンクションを実行するためやCORSの設定等に必要なx-amazon-apigateway-integration
の内容は、設定ファイルに明示的に記載されていない場合は自動的に付与されます。Mapping Templateも全てのパラメータを渡すものを自動で設定します(この挙動はオプションで抑制可能です)
コマンド
コマンドライン引数については、よく使用するもののみは記載しています。
全てを知りたい場合はREADMEからご確認ください。
init
$ lamvery init -h
usage: lamvery init [-h] [-c CONF_FILE]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
各種設定ファイルの雛形を作成するインストール後に最初に実行するコマンドです。
generate
$ lamvery generate -h
usage: lamvery generate [-h] [-c CONF_FILE] -k KIND
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-k KIND, --kind KIND The kind of the file # accepts "function"
各種プログラムの雛形を生成するコマンドです。
-k
で生成するファイルの種別を指定しますが現状は function
でFunctionの雛形のみ生成可能です。
build
$ lamvery build -h
usage: lamvery build [-h] [-c CONF_FILE] [-s] [-l] [-e ENV]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-s, --single-file Only use the main lambda function file
-l, --no-libs Archiving without all libraries
-e ENV, --env ENV Environment variables that pass to the function
ソースコードとライブラリのアーカイブ(ZIP)ファイルを作成します。
確認用や変則的なフローを組む場合向け。
ファイル名はFunction名.zip
となります。設定ファイルがない場合などは実行したディレクトリ名.zip
です。
deploy
$ lamvery deploy -h
usage: lamvery deploy [-h] [-a ALIAS] [-c CONF_FILE] [-d] [-s] [-l] [-p]
[-e ENV]
optional arguments:
-h, --help show this help message and exit
-a ALIAS, --alias ALIAS
Alias for a version of the function
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-d, --dry-run Dry run
-s, --single-file Only use the main lambda function file
-l, --no-libs Archiving without all libraries
-p, --publish Publish the version as an atomic operation
-e ENV, --env ENV Environment variables that pass to the function
以下の全てをまとめて行います。
- ソースコードとライブラリのアーカイブを作成
- アーカイブの中に機密情報の暗号文を埋め込む
- アーカイブの中にオプションで指定された環境変数を埋め込む
- Lambdaの実行設定を更新
- アーカイブをアップロード
- 前のバージョンに別のエイリアスを付ける(指定されている場合)
- 新しいバージョンにエイリアスを付ける(指定されている場合)
また、日頃お世話になっているcodenize.toolsで重宝しているDry run(更新せずに差分だけ表示する)オプションを付けました。-d
または--dry-run
となっています。
-e
または --env
で環境変数を指定できます。
rollback
$ lamvery rollback -h
usage: lamvery rollback [-h] [-a ALIAS] [-c CONF_FILE] [-v VERSION]
optional arguments:
-h, --help show this help message and exit
-a ALIAS, --alias ALIAS
Alias for a version of the function
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-v VERSION, --version VERSION
Version of the function
deploy
の巻き戻しを行います。Dry runにも対応しています。
Rollbackの仕様についてはこちらに記載しています。
configure
$ lamvery configure -h
usage: lamvery configure [-h] [-c CONF_FILE] [-d]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-d, --dry-run Dry run
ソースコードの更新は行わず、Functionの設定のみ更新します。もちろんDry run対応。
ただし、バージョニングしている場合は新しいバージョンを発行するまで設定は反映されませんので注意してください。
デプロイ時にも設定を同期するので、ほぼバージョニングしない場合にしか使えないコマンドですw
set-alias
$ lamvery set-alias -h
usage: lamvery set-alias [-h] [-a ALIAS] [-c CONF_FILE] [-d] [-v VERSION]
[-t TARGET]
optional arguments:
-h, --help show this help message and exit
-a ALIAS, --alias ALIAS
Alias for a version of the function
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-d, --dry-run Dry run
-v VERSION, --version VERSION
Version of the function
-t TARGET, --target TARGET
The alias of the version that is targeted for setting
alias
エイリアスを設定します。こちらもDry run対応。
-a
or --alias
でエイリアス名、-v
or --version
でエイリアスを付けるバージョンを指定します。
encrypt
$ lamvery encrypt -h
usage: lamvery encrypt [-h] [-c CONF_FILE] [-n SECRET_NAME] [-s] text
positional arguments:
text The text value to encrypt
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-n SECRET_NAME, --secret-name SECRET_NAME
The name of the secret value
-s, --store Store encripted value to the configuration file
(default: .lamvery.secret.yml)
KMSを使って与えられた値を暗号化します。
-n
or --name
で取り出す際に使用する名前を指定し、-s
or --store
を付けるとその名前で設定ファイルに暗号文が登録されます。
encrypt-file
$ lamvery encrypt-file -h
usage: lamvery encrypt-file [-h] [-c CONF_FILE] -p PATH [-s] file
positional arguments:
file The file path to encrypt
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-p PATH, --path PATH The path to put the decrypted file in the function
-s, --store Store encripted value to the configuration file
(default: .lamvery.secret.yml)
KMSを使って指定ファイルを暗号化します。
-n
or --name
でFunctionで扱う際に使用するファイル名前を指定し、-s
or --store
を付けるとその名前で設定ファイルに暗号文とファイル名が登録されます。
decrypt
$ lamvery decrypt -h
usage: lamvery decrypt [-h] [-c CONF_FILE] [-n SECRET_NAME]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-n SECRET_NAME, --secret-name SECRET_NAME
The name of the secret value
設定ファイル内の暗号文を復号します。
-n
or --name
で暗号化時に決めた名前を指定します。
decrypt-file
は元ファイル見ればええやんって話なので実装してませんw
events
CloudWatch Eventsの設定を行います。もちろんDry run対応です。
差分更新となっており、Event設定がない場合は作成、あれば更新します。
Functionに紐づくEventの中で記述されていないものは削除されますが、別のFunctionに紐づくものはTargetから外すのみで削除は行いません。
lamvery events [-k]
invoke
$ lamvery invoke -h
usage: lamvery invoke [-h] [-a ALIAS] [-c CONF_FILE] [-v VERSION] json
positional arguments:
json The JSON string or file that pass to the function
optional arguments:
-h, --help show this help message and exit
-a ALIAS, --alias ALIAS
Alias for a version of the function
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-v VERSION, --version VERSION
Version of the function
Functionを起動します。
起動した結果のLogは標準出力に吐かれます。
引数で入力を指定します。JSONフォーマットで渡せばそのまま渡され、JSONの書かれたファイルのパスを指定するとその中身を渡します
バージョン指定(-v
)やエイリアス指定(-a
)もできます。
logs
$ lamvery logs -h
usage: lamvery logs [-h] [-c CONF_FILE] [-f] [-F FILTER] [-i INTERVAL]
[-s START]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-f, --follow Watch the log events and updates the display (like
`tail -f`)
-F FILTER, --filter FILTER
Filtering pattern for the log messages
-i INTERVAL, --interval INTERVAL
Intervals(seconds) to watch the log events
-s START, --start START
Time to start the log events watching
CloudWatch Logsに吐かれるfunctionのログを閲覧します。
-f
で tail -f
的に流し続けたり、-s
で開始日時を指定して閲覧できます。
api
$ lamvery api -h
usage: lamvery api [-h] [-c CONF_FILE] [-d] [-n] [-r] [-s STAGE] [-w]
optional arguments:
-h, --help show this help message and exit
-c CONF_FILE, --conf-file CONF_FILE
Configuration YAML file (default: .lamvery.yml)
-d, --dry-run Dry run
-n, --no-integrate Without automatic integration
-r, --remove Remove your API
-s STAGE, --stage STAGE
The name of the stage in API Gateway
-w, --write-id Write the id of your API to the configuration file
(default: .lamvery.api.yml)
API GatewayにAPIをデプロイします。-r
を付けると削除します。
-n
で x-amazon-apigateway-integration
等を自動設定する挙動を抑制し、設定ファイルに書かれたそのままでデプロイできます。
機密情報を使用するLambda functionの作成の流れ(参考)
1. KMSで秘密鍵を作ります。
2. Function実行時のIAM Roleに以下の権限を追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:us-east-1:<your-account-number>:key/<your-key-id>"
]
}
]
}
3. 設定ファイルやFunctionの雛形を生成します
lamvery init
lamvery generate -k function
4. 以下のように設定ファイルに1で作った鍵のIDを設定します
profile: default
region: us-east-1
configuration:
name: sample_lambda_function
runtime: python2.7 # or nodejs
role: arn:aws:iam::000000000000:role/lambda_basic_execution
handler: lambda_function.lambda_handler
description: This is sample lambda function.
timeout: 10
memory_size: 128
key_id: a5ed61a9-fa57-4ebf-9b3f-457b95de05ce # <-ここ!!!
cipher_texts: {}
5. 機密情報を暗号化して保存します
lamvery encrypt -s -n foo "This is a secret"
6. ソースを書きます
import lamvery
def lambda_handler(event, context):
print(lamvery.secret.get('foo'))
var lamvery = require('./lamvery.js');
exports.lambda_handler = function(event, context) {
lamvery.secret.get('foo', function(err, data) {
console.log(data);
});
}
7. Deploy!!
lamvery deploy
8. Functionを起動
lambery invoke {}
以下のように復号された結果が得られます。
START RequestId: 13829c9c-9f13-11e5-921b-6f048cff3c2d Version: $LATEST
This is a secret
END RequestId: 13829c9c-9f13-11e5-921b-6f048cff3c2d
最後に
かなり機能は充実してきましたが、まだまだ色々追加する予定です!
良かったら使ってみてフィードバックをいただけると嬉しいです :-)
フィードバックはコチラから↓
https://github.com/marcy-terui/lamvery
-
Pythonのライブラリ等が隔離された仮想環境を提供するライブラリ
https://pypi.python.org/pypi/virtualenv ↩ -
.py
は素のソース、.pyc
はコンパイル済みのソース ↩ -
ベンチとってないのでアレですが、コンパイルが短縮されるので起動時間がごくわずかですが向上するかも? ↩