こんにちは。SREの川野です。
今回は、AWS Lambda Functionをデプロイする際に使用したApexというツールについてご紹介します!
Apexとは
AWS Lambda Functionを簡単に構築・デプロイ・管理するツールです。
※ 悲しいことに2019年6月25日で「No longer maintained」となってしまいました・・・。
主な特徴は以下です。
- ロールバック、メトリクスの確認、ログの確認、テスト実行などの機能の提供
- Lambda Functionで公式にサポートされていない言語の使用が可能
- AWSコンポーネントを管理するためのTerraformのラッパー機能の提供
TerraformでLambdaリソースを作成しようとすると、関数のコードをzipに固めてアップロードするので、関数のコードに変更がなくてもtfstateに差分が出てしまいます。そういった場合にApexを使うことで、tfstateの管理を適切に行うことができます。
インストール
GitHubのReleaseから使用したいバージョンと使用しているOSに合わせたバイナリをダウンロードします。
https://github.com/apex/apex/releases
例:macOS(64bit)の場合
$ wget https://github.com/apex/apex/releases/download/v0.15.0/apex_darwin_amd64
$ mv apex_darwin_amd64 /usr/local/bin/apex
$ chmod +x /usr/local/bin/apex
$ apex version
Apex version 0.15.0
補足:最新の0.16.0は認証情報の拾い方についてIssueが上がっています。そのため今回のこれから説明する手順については、0.15.0で行いました。
AWS認証情報を設定
AWS CLIをインストールして、以下の認証と設定ファイルをそれぞれ作成します。
(参考: AWS CLIのインストール https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html)
~/.aws/credenticals
[default]
aws_access_key_id=[AWSアクセスキー]
aws_secret_access_key=[AWSシークレットキー]
~/.aws/config
[default]
output=[出力データ形式]
region=[AWSリージョン]
次はapex
コマンドの使い方の説明をします。
初期化
apex init
と実行すると、Project name:
と Project description:
の入力を求められるので、適当に入力します。
今回は以下のように入力しました。Project name: apex-lambda
Project description:
すると、以下の初期化処理が実行されます。
1. Lambda Functionを実行するためのロールとポリシーを作成しそれらをアタッチ
2. Lambda Functionの環境設定ファイルproject.json
を作成
3. サンプル(hello/index.js)を含んだ、実装コードを配置するディレクトリfunctions
を作成
実際の画面
~/apex_project$ apex init
_ ____ _______ __
/ \ | _ \| ____\ \/ /
/ _ \ | |_) | _| \ /
/ ___ \| __/| |___ / \
/_/ \_\_| |_____/_/\_\
Enter the name of your project. It should be machine-friendly, as this
is used to prefix your functions in Lambda.
Project name: apex-lambda
Enter an optional description of your project.
Project description:
[+] creating IAM apex-lambda_lambda_function role
[+] creating IAM apex-lambda_lambda_logs policy
[+] attaching policy to lambda_function role.
[+] creating ./project.json
[+] creating ./functions
Setup complete, deploy those functions!
$ apex deploy
ディレクトリ構成は以下のようになっています。
.
├── functions
│ └── hello
│ └── index.js
└── project.json
関数のリスト表示
apex list
と入力すると、先ほどの apex init
コマンドで自動作成されたサンプル関数が表示されます。
~/apex_project$ apex list
hello (not deployed)
runtime: nodejs6.10
memory: 128mb
timeout: 5s
role: arn:aws:iam::572183290275:role/test-apex_lambda_function
handler: index.handle
~/apex_project$ cat functions/hello/index.js
console.log('starting function')
exports.handle = function(e, ctx, cb) {
console.log('processing event: %j', e)
cb(null, { hello: 'world' })
}
Apexでは、関数ディレクトリごとに環境設定を書くことができます。./functions/hello/function.json
を作成すれば、./project.json
の環境設定をオーバーライドします。
実行環境とハンドラーの設定を書く場合は以下のようにします。
(今回はPythonで関数を実装しようと思います。)
ハンドラーは、[関数ファイル名.呼び出す関数]という形式になっています。
~/apex_project$ cat functions/hello/function.json
{
"runtime": "python3.7",
"handler": "lambda_function.lambda_handler"
}
再度確認してみると、function.json
の環境設定を読み込んだ関数が表示されていることがわかります。
~/apex_project$ apex list
hello (not deployed)
runtime: python3.7
memory: 128mb
timeout: 5s
role: arn:aws:iam::572183290275:role/apex-lambda_lambda_function
handler: lambda_function.lambda_handler
実行環境とハンドラーの設定を書き換えたので、古い関数ファイル(index.js)を削除して、新しい関数ファイル(lambda_function.py)を以下のように作成します。
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
現在のディレクトリ構成は以下のようになっています。
.
├── functions
│ └── hello
│ ├── function.json
│ └── lambda_function.py
└── project.json
関数のデプロイ
実装した関数のコードをデプロイします。
~/apex_project$ apex deploy
• creating function env= function=hello
• created alias current env= function=hello version=1
• function created env= function=hello name=apex-lambda_hello version=1
関数の呼び出し
AWSコンソール画面を直接操作しなくても apex invoke
コマンドを使用すれば関数を呼び出すことができます。
~/apex_project$ apex invoke hello
{"statusCode": 200, "body": "\"Hello from Lambda!\""}
AWSコンポーネントの管理
apex infra
がterraform
コマンドのラッパーになっています。 apex_function_関数名
でARNを取得できるので、Apexで作成したLambdaFunctionをTerraformのコードから参照することができます。この参照を使用している際に、terraform
コマンドを使用するとARNが取得できないエラーが表示されるので注意が必要です。
(詳細:https://github.com/apex/apex/blob/master/docs/infra.md)
Terraformのコードは、./infrastructure
ディレクトリを作成してその中にtfファイルを作成します。
.
├── functions
│ └── hello
│ ├── function.json
│ └── lambda_function.py
├── infrastructure
│ ├── backend.tf
│ ├── main.tf
│ └── variables.tf
└── project.json
実行する際は、infrastructure
ディレクトリに移動して下記のように行います。
~/apex_project/infrastructure$ apex infra plan
~/apex_project/infrastructure$ apex infra apply
おわりに
今回の説明は以上になります。
Apexは「No longer maintained」となってしまいましたが、Issueをみてみると2.0としてリリースされる可能性は僅かですがありそうな感じです!
また、類似ツールとしてupというものがあるようなので次の機会に使ってみたいと思います!