LambdaからAPI Gateway(IAM認可)へのアクセス方法 [Python版]


AWS上でServerlessかつMicroservicesな構成の場合、Lambda内から別サービスのAPI Gatewayにアクセスすることがある。
API GatewayがIAMでアクセス制限がかかっている場合のアクセス方法が分からなかったので調査した。

※ Node.js版はこちら

前提

  • Lambda (Python 3.7)
  • LambdaにIAM Role付与済み
  • API Gateway(IAM認可)作成済み

※ API Gatewayの設定方法やIAM Roleの内容などはここでは取り扱わない

結論

botocoreのSigV4Authで署名する。

lambda_function.py
import os
import urllib.request
from botocore.credentials import Credentials
from botocore.awsrequest import AWSRequest
from botocore.auth import SigV4Auth

def lambda_handler(event):
    ENDPOINT = "https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/STAGE"
    PATH = "/YOUR/RESOURCE"

    awsreq = AWSRequest(method="GET", url=ENDPOINT+PATH)

    # Sign
    credentials = Credentials(
        os.environ["AWS_ACCESS_KEY_ID"],
        os.environ["AWS_SECRET_ACCESS_KEY"],
        os.environ["AWS_SESSION_TOKEN"])
    SigV4Auth(credentials, "execute-api", os.environ["AWS_REGION"]).add_auth(awsreq)

    # Request
    req = urllib.request.Request(awsreq.url, method=awsreq.method,
                                 headers=awsreq.headers)
    with urllib.request.urlopen(req) as res:
        body = res.read()

    # Do something 

SigV4Auth で AWSRequest を署名する。
⇒ 下記のようなHeadersが設定される

req.headers
X-Amz-Date: 20190701T020706Z
X-Amz-Security-Token: AgoJb3JpZ3luX2VjEBgaDmFwLW6vcnRoZWFzdC0xIkcwRQIgXKqUW7xJYR7xjI8r3A8867/J/258UZa3dVZTZXJhZdoCIQCtfBGGCJQR2RIGAaFMUzXdr4MXYzVapq0dUV8tN6QWGSqAAghhEAIaDDM1OTAzMDQzODQ5MSIMuUdqb7U/zKQD0S6GKt0BOkhXekZuxE8LCL9u8ktGjEeQJGHXiRvyfQ8ohzGRlWzmql66Ao1ArjTjYB1Bw7hbnFs4EUylvwc1XBvbEG/OEyWm1rpbZqe5U5Jg0Z9HY8UvJ2wrjKTH4OBMIYMXk4ZdHu9djIx+6d1Ap0E2F2SAtyMsaG75gFuNOx6frG7T0ZFj9t/pT+5HfxE5349VbxaBX6PvRvOIDfLXqv2UacY9eq3gRkkCNOlBm/4Z+iHyQLkWxkOeG05YIx2r7oeeBqN/459KeKU/pDJMcc/QbnTilCQx+oedEmlV+HRfVIswmPbY6AU6tAHD/gc0T1Rszlg1QgZ7aytsID5JvZCaO6/0SYx0C6mx2G/vrQQivQlxCkK396anWK+sVu69goOxay8cs+wov5+TVtL+1ybPYsMJIv6Pb0/zNS82jyh2Va1YOZ8Ep/i/VHrvPVgVLL1419Ly92MhkPZqMecDiniomEzfBchLYpB+eZ/+B+8+SnqOBuooz+QiF+y8doSBMj24ahhEaa7ErGC/rTI1VuT0GSN8a43N1hpkZ7O9Vlg=
Authorization: AWS4-HMAC-SHA256 Credential=ASIAVHFXXXXXXXXXXXXX/20190701/ap-northeast-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=ac00aaab0b00fe0a000000e0fd0a00c00aab00000b0000a0a000bddb0b000d

AWSRequest 自体はリクエストを発行してくれないので、別途urllibやrequestsなどでリクエストを送る必要がある。

参考

https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html
https://dev.classmethod.jp/cloud/aws/botocore-signed-process/
https://qiita.com/paper2/items/cea6021512132f070403
https://qiita.com/toshihirock/items/a92cbda51d5f469bb0ac
https://qiita.com/crifff/items/6dff429555c898a19758