最近あるLambda関数から別のLambda関数を呼び出す処理をする際に少し調べたのでメモ。
環境
ランタイム | Python 3.9 |
---|
今回の想定ケース
特定のLambdaから別のLambdaをまるごと呼び出す処理を想定。
今回は、以下のtestFunction01
からtestFunction02
を呼び出すような処理を実現していく。
def lambda_handler(event, context):
print('[testFunction01] testFunction01')
def lambda_handler(event, context):
print('[testFunction02] Called by testFunction01')
return {'message': 'called by testFunction01'}
実現方法
基本的にはinvokeを呼び出してあげることで実現可能。
IAMロールの修正
invokeを呼び出すことができるように、lambda:InvokeFunction
アクションを実行できるようなポリシーを作成し、呼び出し元Lambda関数に紐づけているIAMロールに許可を追加する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:*:[AWSアカウントID]:function:*"
}
]
}
コードの修正
boto3
を使用してLambdaのクライアントを作成し、invokeを実行する。
import boto3
def lambda_handler(event, context):
print('[testFunction01] testFunction01')
# 別Lambda関数の呼び出し
response = boto3.client('lambda').invoke(
FunctionName = 'testFunction02',
InvocationType='RequestResponse'
)
print(response)
上記のコードを実行し、testFunction02のCloudWatch Logsを確認すると、呼び出されていることが確認できる。
また、呼び出した側には以下のような出力が出ている。
[testFunction01] testFunction01
{'ResponseMetadata': {'RequestId': 'XXX', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Thu, 29 Dec 2022 00:28:12 GMT', 'content-type': 'application/json', 'content-length': '4', 'connection': 'keep-alive', 'x-amzn-requestid': 'XXX', 'x-amzn-remapped-content-length': '0', 'x-amz-executed-version': '$LATEST', 'x-amzn-trace-id': 'root=XXX'}, 'RetryAttempts': 0}, 'StatusCode': 200, 'ExecutedVersion': '$LATEST', 'Payload': <botocore.response.StreamingBody object at 0x7f17bf8e0970>}
responseのbody(testFunction02
の実行結果)を取得したい場合は以下のようにJSONでコードして値を取り出すようにすれば良い。
import json
body = json.loads(response['Payload'].read())
print(body)
補足(1) : InvocationType
InvocationTypeにはEventとRequestResponseの2種類があるので、用途に応じて使い分ける。
InvocationType | 用途 |
---|---|
RequestResponse | 同期処理 |
Event | 非同期処理 |
補足(2) : 呼び出されるLambdaに値を渡したい場合
invokeにはPayloadを渡すことができる口があるので、そこを使うことで呼び出されるLambdaに値を渡すことができる。
payload = {"one": 1, "two": 2, "three": 3}
response = boto3.client('lambda').invoke(
FunctionName = 'testFunction02',
InvocationType='RequestResponse',
Payload = payload
)
渡されたPayloadはeventに入る。