Apexは、いくつもの言語をサポートしていますが、今回はPythonを用いたパターンでサクッとLambdaファンクションをデプロイして実行してみるところまでをやってみます。
1. Apexをインストールする
使用する環境は以下のとおりです。
- OS: OS X EL Capitan
- Apex : v0.10.2
- python: v2.7.10
インストール
以下のコマンドを実行します。
curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
動作確認を兼ねて、以下のコマンドでバージョンを確認します。
apex version
Apex version 0.10.2
2. AWSのクレデンシャルを設定する
Apexのりようには、AWS CLIと同様にAWSのクレデンシャル情報を指定する必要があります。
[default]
output = json
region = ap-northeast-1
[default]
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXX
3. Apexプロジェクトを作成する
プロジェクトの雛形作成
Apexのプロジェクトジェネレーターを使って、プロジェクトの雛形を作成します。
mkdir apex-sample
cd apex-samle
apex init
最初に、Project name
とProject description
を入力します。
_ ____ _______ __
/ \ | _ \| ____\ \/ /
/ _ \ | |_) | _| \ /
/ ___ \| __/| |___ / \
/_/ \_\_| |_____/_/\_\
Enter the name of your project. It should be machine-friendly, as this
is used to prefix your functions in Lambda.
Project name: apex-sample
Enter an optional description of your project.
Project description: apex-sample
処理が完了すると、デプロイコマンドが表示されます。
[+] creating IAM hoge-tes_lambda_function role
[+] creating IAM hoge-tes_lambda_logs policy
[+] attaching policy to lambda_function role.
[+] creating ./project.json
[+] creating ./functions
Setup complete, deploy those functions!
$ apex deploy
プロジェクトのディレクトリ
ジェネレーターで作成されるプロジェクトの雛形は以下の通りです。
デフォルトで、node.jsのファンクション(hello)が作成されます。
.
|-- functions
| `-- hello
| `-- index.js
`-- project.json
4. ファンクションを実装する
スクリプトの作成
mkdir function/python_lambda
vi function/python_lambda/main.py
今回は以下のスクリプトを用意します。
"""
Lambda example with external dependency
"""
import logging
import requests
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def handle(event, context):
"""
Lambda handler
"""
logger.info("%s - %s", event, context)
url = "https://api.ipify.org?format=json"
raw = requests.get(url)
logger.info("%s", raw)
result = raw.json()
logger.info("Lambda IP: %s", result['ip'])
注記の設定
ファンクションの注記を設定します。これは、AWS マネジメントコンソール上でLambdaファンクションの一覧に表示されます。下記のfunction.json
をpython_lambda
フォルダの直下に置きます。
{
"description": "Example with python"
}
依存ライブラリのダウンロード
以下のコマンドでスクリプトの中で利用するライブラリをプロジェクトの中にダウンロードします。
pip install requests -t functions/python_lambda
依存ライブラリのダウンロード後のプロジェクトは、以下の様になります。
.
|-- function.json
|-- main.py
|-- requests
| |-- __init__.py
| |-- __init__.pyc
| |-- adapters.py
| |-- adapters.pyc
| |-- api.py
| |-- api.pyc
| |-- auth.py
| |-- auth.pyc
| |-- cacert.pem
| |-- certs.py
| |-- certs.pyc
| |-- compat.py
| |-- compat.pyc
| |-- cookies.py
| |-- cookies.pyc
| |-- exceptions.py
| |-- exceptions.pyc
| |-- hooks.py
| |-- hooks.pyc
| |-- models.py
| |-- models.pyc
| |-- packages
| | |-- __init__.py
| | |-- __init__.pyc
| | |-- chardet
| | | |-- __init__.py
| | | |-- __init__.pyc
| | | |-- big5freq.py
| | | |-- big5freq.pyc
| | | |-- big5prober.py
| | | |-- big5prober.pyc
| | | |-- chardetect.py
| | | |-- chardetect.pyc
| | | |-- chardistribution.py
| | | |-- chardistribution.pyc
| | | |-- charsetgroupprober.py
| | | |-- charsetgroupprober.pyc
| | | |-- charsetprober.py
| | | |-- charsetprober.pyc
| | | |-- codingstatemachine.py
| | | |-- codingstatemachine.pyc
| | | |-- compat.py
| | | |-- compat.pyc
| | | |-- constants.py
| | | |-- constants.pyc
| | | |-- cp949prober.py
| | | |-- cp949prober.pyc
| | | |-- escprober.py
| | | |-- escprober.pyc
| | | |-- escsm.py
| | | |-- escsm.pyc
| | | |-- eucjpprober.py
| | | |-- eucjpprober.pyc
| | | |-- euckrfreq.py
| | | |-- euckrfreq.pyc
| | | |-- euckrprober.py
| | | |-- euckrprober.pyc
| | | |-- euctwfreq.py
| | | |-- euctwfreq.pyc
| | | |-- euctwprober.py
| | | |-- euctwprober.pyc
| | | |-- gb2312freq.py
| | | |-- gb2312freq.pyc
| | | |-- gb2312prober.py
| | | |-- gb2312prober.pyc
| | | |-- hebrewprober.py
| | | |-- hebrewprober.pyc
| | | |-- jisfreq.py
| | | |-- jisfreq.pyc
| | | |-- jpcntx.py
| | | |-- jpcntx.pyc
| | | |-- langbulgarianmodel.py
| | | |-- langbulgarianmodel.pyc
| | | |-- langcyrillicmodel.py
| | | |-- langcyrillicmodel.pyc
| | | |-- langgreekmodel.py
| | | |-- langgreekmodel.pyc
| | | |-- langhebrewmodel.py
| | | |-- langhebrewmodel.pyc
| | | |-- langhungarianmodel.py
| | | |-- langhungarianmodel.pyc
| | | |-- langthaimodel.py
| | | |-- langthaimodel.pyc
| | | |-- latin1prober.py
| | | |-- latin1prober.pyc
| | | |-- mbcharsetprober.py
| | | |-- mbcharsetprober.pyc
| | | |-- mbcsgroupprober.py
| | | |-- mbcsgroupprober.pyc
| | | |-- mbcssm.py
| | | |-- mbcssm.pyc
| | | |-- sbcharsetprober.py
| | | |-- sbcharsetprober.pyc
| | | |-- sbcsgroupprober.py
| | | |-- sbcsgroupprober.pyc
| | | |-- sjisprober.py
| | | |-- sjisprober.pyc
| | | |-- universaldetector.py
| | | |-- universaldetector.pyc
| | | |-- utf8prober.py
| | | `-- utf8prober.pyc
| | `-- urllib3
| | |-- __init__.py
| | |-- __init__.pyc
| | |-- _collections.py
| | |-- _collections.pyc
| | |-- connection.py
| | |-- connection.pyc
| | |-- connectionpool.py
| | |-- connectionpool.pyc
| | |-- contrib
| | | |-- __init__.py
| | | |-- __init__.pyc
| | | |-- appengine.py
| | | |-- appengine.pyc
| | | |-- ntlmpool.py
| | | |-- ntlmpool.pyc
| | | |-- pyopenssl.py
| | | |-- pyopenssl.pyc
| | | |-- socks.py
| | | `-- socks.pyc
| | |-- exceptions.py
| | |-- exceptions.pyc
| | |-- fields.py
| | |-- fields.pyc
| | |-- filepost.py
| | |-- filepost.pyc
| | |-- packages
| | | |-- __init__.py
| | | |-- __init__.pyc
| | | |-- ordered_dict.py
| | | |-- ordered_dict.pyc
| | | |-- six.py
| | | |-- six.pyc
| | | `-- ssl_match_hostname
| | | |-- __init__.py
| | | |-- __init__.pyc
| | | |-- _implementation.py
| | | `-- _implementation.pyc
| | |-- poolmanager.py
| | |-- poolmanager.pyc
| | |-- request.py
| | |-- request.pyc
| | |-- response.py
| | |-- response.pyc
| | `-- util
| | |-- __init__.py
| | |-- __init__.pyc
| | |-- connection.py
| | |-- connection.pyc
| | |-- request.py
| | |-- request.pyc
| | |-- response.py
| | |-- response.pyc
| | |-- retry.py
| | |-- retry.pyc
| | |-- ssl_.py
| | |-- ssl_.pyc
| | |-- timeout.py
| | |-- timeout.pyc
| | |-- url.py
| | `-- url.pyc
| |-- sessions.py
| |-- sessions.pyc
| |-- status_codes.py
| |-- status_codes.pyc
| |-- structures.py
| |-- structures.pyc
| |-- utils.py
| `-- utils.pyc
`-- requests-2.10.0.dist-info
|-- DESCRIPTION.rst
|-- INSTALLER
|-- METADATA
|-- RECORD
|-- WHEEL
|-- metadata.json
`-- top_level.txt
5. Lambdaファンクションのデプロイする
Lambdaファンクションの準備ができたら、以下のコマンドでAWSへデプロイします。--profile <name>
でプロフィルを切り替えることが可能です(本番/開発の切り替えなど)。
apex deploy
• creating function function=python_lambda
• created alias current function=python_lambda version=1
• function created function=python_lambda name=apex-sample_python_lambda version=1
AWSにLambdaファンクションが作成されます。
6. Lambdaファンクションを実行してみる
デプロイした後、以下のコマンドでLambdaファンクションを実行することができます。
apex invoke python_lambda
続いて以下のコマンドで実行結果を確認すると、動作したことが確認できます。LambdaのIPが取得できていることがわかると思います。
apex logs python_lambda
/aws/lambda/apex-sample_python_lambda START RequestId: 2e61ed55-49d5-11e6-a09e-59cea9415cc8 Version: 1
/aws/lambda/apex-sample_python_lambda [INFO] 2016-07-14T15:11:05.301Z 2e61ed55-49d5-11e6-a09e-59cea9415cc8 {} - <__main__.LambdaContext object at 0x7f3ef89d7850>
/aws/lambda/apex-sample_python_lambda [INFO] 2016-07-14T15:11:05.336Z 2e61ed55-49d5-11e6-a09e-59cea9415cc8 Starting new HTTPS connection (1): api.ipify.org
/aws/lambda/apex-sample_python_lambda [INFO] 2016-07-14T15:11:06.119Z 2e61ed55-49d5-11e6-a09e-59cea9415cc8 <Response [200]>
/aws/lambda/apex-sample_python_lambda [INFO] 2016-07-14T15:11:06.119Z 2e61ed55-49d5-11e6-a09e-59cea9415cc8 Lambda IP: 52.196.95.168
/aws/lambda/apex-sample_python_lambda END RequestId: 2e61ed55-49d5-11e6-a09e-59cea9415cc8
/aws/lambda/apex-sample_python_lambda REPORT RequestId: 2e61ed55-49d5-11e6-a09e-59cea9415cc8 Duration: 819.04 ms Billed Duration: 900 ms Memory Size: 128 MB Max Memory Used: 39 MB
7. Lambdaファンクションのバージョン確認
尚、以下のコマンドを実行するとデプロイされたLambdaファンクションのバージョンが確認できます。
apex list
python_lambda
description: Example with python
runtime: python2.7
memory: 128mb
timeout: 5s
role: arn:aws:iam::XXXXXXXXXXXX:role/apex-sample_lambda_function
handler: main.handle
current version: 1
所感
この様に、サクッとできました。Apexの開発者の言う通り、Lambdaのユーザビリティーの不満はだいぶ解決されるのではないでしょうか。
Apexにはその他にも便利な機能がたくさんあるので、Lambdaの開発には大変便利なものだと思います。
参考
http://dev.classmethod.jp/cloud/aws/how-to-manage-aws-lambda-functions-with-apex/
https://github.com/apex/apex