3分で作る、スケジュール実行するLambda
スケジュール実行するLambdaを、AWS製の Chalice というサーバーレスアプリケーションフレームワークを使ってサクッと構築したいと思います。Chalice はPython製のツールで開発言語もPythonに限られますが、軽量なフレームワークとなっており、学習コストが低くとっつきやすくなっています。API Gatewayと一緒に使われることが多いかと思いますが、各種イベントソースとの連携にも使えます。
環境
- macOS Catalina 10.15.4
- Python 3.7.7
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.4 BuildVersion: 19E287 $ python3 -VV Python 3.7.7 (default, Mar 10 2020, 15:43:33) [Clang 11.0.0 (clang-1100.0.33.17)]
やってみる
仮想環境の作成
今回は Python で標準機能の venv
を利用します。
$ mkdir chalice-example && cd chalice-example $ python3 -m venv venv
仮想環境の有効化
$ source ./venv/bin/activate (venv) $
Chaliceのインストール
(venv) $ pip install chalice
Boto3のインストール
今回は処理の中で使用しますので、boto3をインストールします。
(venv) $ pip install boto3
プロジェクトの作成
new-project
コマンドを利用してプロジェクトの雛形を作成します。schedule-lambda フォルダが作成され、各種ファイルが作成されています。
(venv) $ chalice new-project schedule-lambda
ファイルの確認します。app.py
に処理内容をコーディングしていきます。
(venv) $ cd schedule-lambda (venv) $ tree -a . ├── .chalice │ └── config.json ├── .gitignore ├── app.py └── requirements.txt
コード
app.py
の内容を下記のようにします。処理内容は見ての通りで、リージョンの一覧を出力しています。処理内容に実務的な意味はありません。@app.schedule
にてスケジュール実行することを指定しています。簡単ですね。今回は最短で確認したいので、1分ごとに実行します。
import logging import boto3 from chalice import Chalice, Rate app = Chalice(app_name='schedule-lambda') app.log.setLevel(logging.INFO) ec2 = boto3.client('ec2') @app.schedule(Rate(1, unit=Rate.MINUTES)) def regions(event): response = ec2.describe_regions() app.log.info(response['Regions'])
必要なライブラリの設定
実行に必要なライブラリを requirements.txt
に記載します。これによりデプロイ時に一緒にアップロードされます。
(venv) $ pip freeze | grep boto3 >> requirements.txt (venv) $ cat requirements.txt boto3==1.12.39
デプロイ
下記のコマンドでデプロイします。
(venv) $ chalice deploy --stage dev Creating deployment package. Creating IAM role: schedule-lambda-dev Creating lambda function: schedule-lambda-dev-regions Resources deployed: - Lambda ARN: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXXX:function:schedule-lambda-dev-regions
以上でスケジュール実行するLambdaが作成できました。
作成されたものを確認
Lambda
デコレータをつけた関数がそれぞれLambdaとして作成されています。
プロジェクト名、環境名、関数名というルールで作成されています。トリガーがCloudWatch Eventsになっていることや、ハンドラがそれぞれ設定されていることが分かります。
IAMロール
マネジメントコンソールで、schedule-lambda-dev ロールのポリシーを確認します。
特にポリシーの設定はしていませんが、ec2:DescribeRegions
が追加されています。Chaliceではソースコードを解析し、必要な権限を自動で付与してくれます。これが非常に便利でいちいちソースコードを調べる必要がありませんし、面倒だからといって必要以上に大きな権限を付与する必要がありません。
今回はリージョンの一覧を取得する処理だったので、必要な権限が付与されていることが分かります。
ただ、自動で付与されるのは boto3.client
を使用した場合で、boto3.resource
を使った場合は手動で付与する必要があります。その場合は、別途ポリシーJsonを用意しておきます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeRegions" ], "Resource": [ "*" ], "Sid": "7bd95f2e3b7744e9938edf34bb28ec66" }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" } ] }
CloudWatch Events ルール
1分間隔で実行するルールが作成されています。
実行ログの確認
正しく実行されているか確認します。マネジメントコンソールにログインし、/aws/lambda/schedule-lambda-dev-regions
というロググループが作成されていますので確認します。
正しく実行されていることが確認できました。
ログはコマンドでも確認することができます。--name
には関数名を指定します。
(venv) $ chalice logs --name regions
後片付け
次のコマンドで作成したリソースが削除できます。ロググループは削除されないので手動で消す必要があります。
(venv) $ chalice delete --stage dev
スケジュール実行の指定方法
文字列で指定する方法と、クラスを使用する方法があり、どちらの方法でも下記のルールに従っています。
Schedule Expressions for Rules - Amazon CloudWatch Events
固定レートの場合
文字列で指定する方法。単数形と複数形を使い分ける必要があります。
# 1時間ごと (単数形になっていることに注意) @app.schedule('rate(1 hour)') def every_hour(event): pass # 2時間ごと (複数形になっていることに注意) @app.schedule('rate(5 hours)') def every_two_hours(event): pass
クラスを使用する方法。こちらは複数形しか使用しないのでより安全です。
# 1時間ごと @app.schedule(Rate(1, unit=Rate.HOURS)) def every_hour(event): print(event.to_dict()) # 2時間ごと @app.schedule(Rate(2, unit=Rate.HOURS)) def every_two_hours(event): print(event.to_dict())
cronの場合
# 文字列指定 @app.schedule('cron(15 10 ? * 6L 2002-2005)') def cron_handler(event): pass # クラス指定 @app.schedule(Cron(15, 10, '?', '*', '6L', '2002-2005')) def cron_obj_handler(event): pass
その他できること
サポートしているイベントソース
IaCツールとの連携
CloudFormation、Terraformと連携してデプロイを管理することもできます。
- AWS CloudFormation Support
- Terraform Support
- Deploying AWS Chalice application using AWS Cloud Development Kit | AWS Developer Blog
その他
- 認証
- Websockets (Experimental APIs)
最後に
要件がシンプルな場合や、検証のためにサクッとLambdaを作りたいといったときには有用なツールだと感じました。
Serverlessのほうが機能が豊富で同じくらい簡単にスケジュール実行するLambdaを作成することができますが、ポリシーの自動生成とデプロイ時にCloudFormationを使用しないので、デプロイが即時に行われるところがメリットかと思います。要件によって使い分けていただければと思います。