Lambda 関数のデプロイに Lamvery を使ってみました

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、菅野です。
最近、Lambda 関数を Python で作る事になった時に、
「毎回毎回ライブラリも含めて zip 圧縮して送るの面倒だなぁ・・・」
ということで探してみたところ「Lamvery」を見つけたので試してみました。
お手軽にデプロイをしたいという要望にぴったりでしたのでご紹介します。

Lamvery のできること

作者の照井さんのブログより抜粋しました

  • YAML + Jinja2テンプレートによる設定記述
  • 格納効率に優れたパッケージ作成(Pythonのみ)
  • 安全なデプロイおよびロールバック
  • デプロイフック
  • 環境変数の受け渡し
  • KMSを用いた機密情報の受け渡し
  • KMSを用いた機密ファイルの受け渡し
  • API GatewayへのAPIデプロイおよび管理
  • CloudWatch Eventsによるスケジュール実行の設定と管理
  • CloudWatch Logsログ閲覧

Mac へのインストール

以下のコマンドを実行するだけです。

$ pip install lamvery

作成の準備

ディレクトリの準備

$ mkdir lamvery-test
$ cd lamvery-test

雛形の作成

init コマンドを実行すると以下のようにいくつかのファイルが作成されます。

$ lamvery init
lamvery: Output initial file: .lamvery.yml
lamvery: Output initial file: .lamvery.exclude.yml
lamvery: Output initial file: .lamvery.secret.yml
lamvery: Output initial file: .lamvery.hook.yml
lamvery: Output initial file: .lamvery.event.yml
lamvery: Output initial file: .lamvery.api.yml

今回はデプロイだけが目的なので、不要なファイルを消します。

rm .lamvery.secret.yml
rm .lamvery.hook.yml
rm .lamvery.event.yml
rm .lamvery.api.yml

ひとまずここまでにして、設定は後ほど行います。

Lambda 関数の作成とライブラリ準備

今回の Lambda 関数は「http://www.google.co.jp」へアクセスしてステータスコードをチェックする内容にします。

Lambda 関数を作成

以下の内容で「lamvery-test.py」ファイルを作成します

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import requests


#【関数】Lambda メイン
def lambda_handler( event, context ):

    # URLを取得
    url = 'http://www.google.co.jp'

    # アクセス
    response = requests.get( url )
    
    # ステータスコードが200なら
    if response.status_code == requests.codes.ok:
        print( 'OK' )
    else:
        print( 'NG' )
        

#【関数】メイン
if __name__ == "__main__":

    # ローカルで実行した時に lambda_handler を実行する
    lambda_handler( {}, {} )

ローカルで実行してみます

$ python ./lamvery-test.py
OK

ライブラリを準備

今回は requests ライブラリを使っていますので、Lambda 関数と同じ階層に準備します。
以下のコマンドでダウンロードしておきます。

$ pip install requests -t ./
Collecting requests
  Downloading requests-2.12.5-py2.py3-none-any.whl (576kB)
    100% |████████████████████████████████| 583kB 1.4MB/s
Installing collected packages: requests
Successfully installed requests-2.12.5

Lambda 関数が使う IAM Role の準備

今回作成する IAM ロールは、ログの操作、S3 オブジェクトの読み書きを可能にしておきます。

  • Amazon マネジメントコンソールで IAM ロールのページを開き、「新しいロールの作成」ボタンをクリックします
    スクリーンショット_2017-01-24_17_27_27
  • ロール名に「lamvery-test」と入力します
  • ロールタイプの選択画面では「AWS Lambda」の「選択」ボタンをクリックします
    スクリーンショット_2017-01-24_17_33_45
  • ポリシーのアタッチのページでは「AWSLambdaExecute」にチェックを入れて次のステップへ移動します
    スクリーンショット_2017-01-24_17_52_01
  • ロールの作成ボタンをクリックします
  • ロールの一覧に「lamvery-test」ロールがありますのでクリックします
  • ここで表示される「ロール ARN」をメモしておきます
    スクリーンショット_2017-01-24_17_58_42

Lamvery の設定

設定ファイル「.lamvery.yml」を修正します

# credential 関係は埋めない
#profile: null
# 東京リージョンを指定
region: ap-northeast-1
# バージョニングしてもらう
versioning: true
# デフォルトのエイリアスを prod とする
default_alias: prod
clean_build: false
configuration:
  name: lamvery-test
  runtime: python2.7
  # 先ほどコピーした IAM Role を貼り付け
  role: arn:aws:iam::************:role/lamvery-test
  # Lambda が実行するハンドラを指定
  handler: lamvery-test.lambda_handler
  # description
  description: lamvery-test function.
  # タイムアウトを30秒に設定
  timeout: 30
  memory_size: 128

Lambda 関数をデプロイできる credential を用意する(~/.aws/credentials)

[default]
region = ap-northeast-1

[DeployUser]
aws_access_key_id = ****
aws_secret_access_key = ****
region=ap-northeast-1

このプロファイルを使うように設定

export AWS_PROFILE=DeployUser

Lambda 関数をデプロイ・・・の前に

Lamvery には --dry-runオプションが用意されていますので試してみましょう。

$ lamvery deploy --dry-run
(Dry run) lamvery: Configuration file ".lamvery.secret.yml" does not exist.
(Dry run) lamvery: Configuration file ".lamvery.secret.yml" does not exist.
(Dry run) lamvery: Configuration file ".lamvery.hook.yml" does not exist.
(Dry run) lamvery: VIRTUAL_ENV environment variable can not be found. Python libraries are not included in the archive.
(Dry run) lamvery: [Function] Create new function "lamvery-test"
(Dry run) lamvery: [Function] description: None -> lamvery-test function.
(Dry run) lamvery: [Function] handler: None -> lamvery-test.lambda_handler
(Dry run) lamvery: [Function] memory_size: None -> 128
(Dry run) lamvery: [Function] timeout: None -> 30
(Dry run) lamvery: [Function] role: None -> arn:aws:iam::731520619447:role/lamvery-test
(Dry run) lamvery: [Function] runtime: None -> python2.7
(Dry run) lamvery: [Function-VPC] subnets: None -> []
(Dry run) lamvery: [Function-VPC] security_groups: None -> []
(Dry run) lamvery: [Function] Capacity: 31,002,309 Bytes -> 32,374,545 Bytes
(Dry run) lamvery: [Alias] prod: None -> $LATEST

特にエラーが無さそうなので、実際にデプロイします。

$ lamvery deploy
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.hook.yml" does not exist.
lamvery: VIRTUAL_ENV environment variable can not be found. Python libraries are not included in the archive.
lamvery: [Function] Create new function "lamvery-test"
lamvery: [Function] description: None -> lamvery-test function.
lamvery: [Function] handler: None -> lamvery-test.lambda_handler
lamvery: [Function] memory_size: None -> 128
lamvery: [Function] timeout: None -> 30
lamvery: [Function] role: None -> arn:aws:iam::731520619447:role/lamvery-test
lamvery: [Function] runtime: None -> python2.7
lamvery: [Function-VPC] subnets: None -> []
lamvery: [Function-VPC] security_groups: None -> []
lamvery: [Function] Capacity: 31,002,309 Bytes -> 32,374,545 Bytes
lamvery: [Alias] prod: None -> $LATEST

--dry-run をつけた時と同じ結果になりました(あたりまえですが)

デプロイの結果を確認

Amazon マネジメントコンソールで確認します。
スクリーンショット_2017-01-24_22_17_10
デプロイされてますので、動くかテストしてみましょう。
「lamvery-test」の行をクリックした後の画面で「Test」ボタンをクリックします。
「Input test event」のポップアップが出たら「Save and test」ボタンをクリックします。
スクリーンショット_2017-01-24_22_22_35
「OK」と表示されていますので、予定通りの結果となっています。
「lamvery deploy」と入力して実行するだけでデプロイ完了です。

もう一度デプロイ

何もせず、もう一度同じコマンドを実行してみます。

$ lamvery deploy
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.hook.yml" does not exist.
lamvery: VIRTUAL_ENV environment variable can not be found. Python libraries are not included in the archive.
lamvery: [Function-VPC] subnets: None -> []
lamvery: [Function-VPC] security_groups: None -> []
lamvery: [Function] Capacity: 32,374,545 Bytes -> 33,060,663 Bytes
lamvery: [Function] Deployed version: 2
lamvery: [Function] Previous version: $LATEST
lamvery: [Alias] prod-pre: None -> $LATEST
lamvery: [Alias] prod: $LATEST -> 2

prod エイリアスのバージョンが2になりました。
Amazon マネジメントコンソールでも確認してみましょう。
スクリーンショット_2017-01-24_22_57_28
prod エイリアスのバージョンが2になっています。

別のエイリアスでデプロイしてみる

では、同じ設定で「dev」エイリアスとしてデプロイしてみましょう。
オプションは「-a」です。

$ lamvery deploy -a dev
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.hook.yml" does not exist.
lamvery: VIRTUAL_ENV environment variable can not be found. Python libraries are not included in the archive.
lamvery: [Function-VPC] subnets: None -> []
lamvery: [Function-VPC] security_groups: None -> []
lamvery: [Function] Capacity: 33,060,663 Bytes -> 33,746,781 Bytes
lamvery: [Function] Deployed version: 3
lamvery: [Alias] dev: None -> 3

dev エイリアスにバージョン3がデプロイされました。
もう一度 Amazon マネジメントコンソールで確認します。
スクリーンショット_2017-01-24_23_08_58
dev エイリアスのバージョンが3、prod エイリアスはバージョン2のままとなっています。
次に、status コードが 200 の時に「OK」ではなく「OK!」と出力するよう修正して dev エイリアスとしてデプロイしてみます。

$ lamvery deploy -a dev
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.secret.yml" does not exist.
lamvery: Configuration file ".lamvery.hook.yml" does not exist.
lamvery: VIRTUAL_ENV environment variable can not be found. Python libraries are not included in the archive.
lamvery: [Function-VPC] subnets: None -> []
lamvery: [Function-VPC] security_groups: None -> []
lamvery: [Function] Capacity: 33,746,781 Bytes -> 34,432,901 Bytes
lamvery: [Function] Deployed version: 4
lamvery: [Function] Previous version: 3
lamvery: [Alias] dev-pre: None -> 3
lamvery: [Alias] dev: 3 -> 4

dev エイリアスのバージョンが上がっただけですね。
この状態で dev エイリアスを指定して実行すると「OK!」と表示されました。
スクリーンショット_2017-01-24_23_56_42
prod エイリアスを指定して実行すると「OK」と表示されます。
スクリーンショット_2017-01-24_23_59_34

ロールバック

「OK!」と表示されるようになった dev エイリアスですが、一つ前のバージョンに戻してみます。

$ lamvery rollback -a dev
lamvery: [Function] Previous version: 3
lamvery: [Alias] dev: 4 -> 3

バージョンが3に戻ったようですので Amazon マネジメントコンソールで実行してみます。
スクリーンショット_2017-01-25_0_06_14
dev エイリアスのバージョンが3に戻り、結果も「OK」になりました。

まとめ

Lamvery を使うことでデプロイが簡単になり、エイリアスの管理やバージョンの管理も行え、
何かあった時のロールバックもコマンド一つで可能となりました。

最後に

いかがでしたでしょうか。
今回社内で使うツールの為に Lambda 関数を作成したのですが、Lamvery のおかげで
デプロイ→テストが手軽に行えたので開発の効率が向上し、時間短縮になりました。
また、インストールや設定も簡単でしたので学習コストもほとんど無く、その点も時間短縮に貢献しています。
皆さんも Python で Lambda 関数を作成する時は Lamvery を一度お試しください。

参考ページ

これらのページを参考にさせていただきました。
ありがとうございました。
AWS Lambda向けデプロイ・管理ツール「Lamvery」について
AWS Lambdaを新機能バージョニングとエイリアスでBlue-Green Deploymentする
AWS Lambda バージョニングの紹介
API GatewayのステージとLambda のエイリアスを対応させる