AWS Lambda から IAM 認証のかかった API を呼び出したいという場合があります。
この場合、Lambda に適切な IAM ロール(ポリシー)を付与し、かつ API 呼び出し時に署名を行う必要があります。
Python では、aws-requests-auth というライブラリを使用すると簡単に署名を行うことができます。
API の準備
IAM 認証のかかった API を用意します。リージョンは ap-northeast-1 と仮定します。
今回は GET /hoge
を叩くと {"message": "hoge"}
が返ってくるように設定しました。
この API に IAM 認証をかけ、デプロイしておきます。
ステージ名は api
としました。
黒く塗りつぶしている箇所は API ID です。
Lambda 関数の作成
API を呼び出す Lambda 関数を作成します。
ロールには基本的なポリシーに加え、以下のようなポリシーを設定します。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:(アカウントID):(API ID)/api/*"
}
}
Resource は arn:aws:execute-api:(リージョン):(アカウントID):(API ID)/(ステージ)/(メソッド)/(リソースパス)
のような形式で指定します。
今回であれば arn:aws:execute-api:ap-northeast-1:(アカウントID):(API ID)/api/GET/hoge
のように細かく指定することも、
あるいは arn:aws:execute-api:*:*:*
のようにワイルドカードを利用して大雑把に指定することもできます。
Lambda 関数のデプロイ
API を呼び出す Lambda 関数を書いていきます。
使用するライブラリは aws-requests-auth と requests です。
import requests
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
def lambda_handler(event, context):
region = "ap-northeast-1"
# XXXXXXXXXX のところは API ID
host = "XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com"
auth = BotoAWSRequestsAuth(
aws_host=host,
aws_region=region,
aws_service="execute-api",
)
stage = "api"
url = f"https://{host}/{stage}/hoge"
response = requests.get(url, auth=auth)
return response.json()
ライブラリを含むので zip なり S3 経由なりでデプロイします。
テスト
実際に API を呼び出せるかテストしてみます。
API にアクセスできることが確認できました。