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で署名する。
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が設定される
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