terraformのコードが以下の通り。
##################################################################### # API Gateway ##################################################################### resource "aws_apigatewayv2_api" "apigw2sfn" { name = "apigw2sfn" protocol_type = "HTTP" } resource "aws_apigatewayv2_stage" "apigw2sfn_main" { api_id = aws_apigatewayv2_api.apigw2sfn.id name = "main" auto_deploy = true } resource "aws_apigatewayv2_route" "apigw2sfn_post_root" { api_id = aws_apigatewayv2_api.apigw2sfn.id route_key = "POST /" target = "integrations/${aws_apigatewayv2_integration.apigw2sfn.id}" } resource "aws_apigatewayv2_integration" "apigw2sfn" { api_id = aws_apigatewayv2_api.apigw2sfn.id integration_type = "AWS_PROXY" integration_subtype = "StepFunctions-StartExecution" credentials_arn = aws_iam_role.apigw2sfn_role.arn request_parameters = { Input = "$request.body" StateMachineArn = aws_sfn_state_machine.my_sfn_sleep.arn } } resource "aws_iam_role" "apigw2sfn_role" { name = "apigw2sfn-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "sts:AssumeRole" Principal = { Service = "apigateway.amazonaws.com" } } ] }) } resource "aws_iam_role_policy" "apigw2sfn_start_sfn" { role = aws_iam_role.apigw2sfn_role.name name = "start-sfn" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "states:StartExecution" Resource = aws_sfn_state_machine.my_sfn_sleep.arn } ] }) } ##################################################################### # Step Functions ##################################################################### resource "aws_sfn_state_machine" "my_sfn_sleep" { name = "my-sfn-sleep" role_arn = aws_iam_role.my_sfn_role.arn definition = jsonencode({ QueryLanguage = "JSONata" StartAt = "Wait" States = { Wait = { Type = "Wait" Seconds = 60 Next = "Exit" } Exit = { Type = "Succeed" } } }) } resource "aws_iam_role" "my_sfn_role" { name = "my-sfn-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "sts:AssumeRole" Principal = { Service = "states.amazonaws.com" } } ] }) }
curlからPOSTするとすぐにレスポンスが返ってくる。
% curl -XPOST -d '{"hello":"world"}' https://xxx.execute-api.ap-northeast-1.amazonaws.com/main/ {"executionArn":"arn:aws:states:ap-northeast-1:123456789012:execution:my-sfn-sleep:7af667d7-16f8-4435-8ce5-f3500a878a32","startDate":1.772339363814E9}
リクエストボディがStateへの入力になる。


認証を追加
LambdaのAuthorizerを追加する。
resource "aws_apigatewayv2_route" "apigw2sfn_post_root" { # ... # 追加 authorization_type = "CUSTOM" authorizer_id = aws_apigatewayv2_authorizer.apigw2sfn.id } ##################################################################### # Authorizer ##################################################################### resource "aws_apigatewayv2_authorizer" "apigw2sfn" { api_id = aws_apigatewayv2_api.apigw2sfn.id authorizer_type = "REQUEST" identity_sources = ["$request.header.Authorization"] name = "authorizer" authorizer_payload_format_version = "2.0" enable_simple_responses = true authorizer_uri = aws_lambda_function.apigw2sfn_authorizer.invoke_arn authorizer_result_ttl_in_seconds = 0 } resource "lambdazip_file" "apigw2sfn_authorizer" { output = "apigw2sfn-authorizer.zip" contents = { "index.mjs" = <<-EOT export const handler = async (event) => { console.log(event); return { isAuthorized: true, context: {}, // コメントアウトしてもよい }; }; EOT } } resource "aws_lambda_function" "apigw2sfn_authorizer" { filename = lambdazip_file.apigw2sfn_authorizer.output function_name = "apigw2sfn-authorizer" role = aws_iam_role.lambda_apigw2sfn_authorizer_role.arn handler = "index.handler" source_code_hash = lambdazip_file.apigw2sfn_authorizer.base64sha256 runtime = "nodejs22.x" } # NOTE: apigw2sfn_roleへの権限の付与は不要っぽい resource "aws_lambda_permission" "authorizer" { statement_id = "AllowExecutionFromAPIGateway" action = "lambda:InvokeFunction" function_name = aws_lambda_function.apigw2sfn_authorizer.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_apigatewayv2_api.apigw2sfn.execution_arn}/authorizers/${aws_apigatewayv2_authorizer.apigw2sfn.id}" } resource "aws_iam_role" "lambda_apigw2sfn_authorizer_role" { name = "lambda-apigw2sfn-authorizer-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { Service = "lambda.amazonaws.com" } Action = "sts:AssumeRole" } ] }) } resource "aws_iam_role_policy_attachment" "lambda_apigw2sfn_authorizer_role" { role = aws_iam_role.lambda_apigw2sfn_authorizer_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" }
curlにAuthorizationヘッダをつけてリクエストを送る
% curl -H "Authorization: secret" -XPOST -d '{"hello":"world"}' https://xxx.execute-api.ap-northeast-1.amazonaws.com/main/
2026-03-01T05:18:57.786000+00:00 2026/03/01/[$LATEST]adc7c386f6284871bec443ce118165e0 INIT_START Runtime Version: nodejs:22.v72 Runtime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:d16c83c0a8a33f01d0039330bdf4f8f429ff40686e670a93d7fbf2b2d77cb783
2026-03-01T05:18:57.949000+00:00 2026/03/01/[$LATEST]adc7c386f6284871bec443ce118165e0 START RequestId: 23221b22-ee34-4a2c-ac2d-9ccde5bc0475 Version: $LATEST
2026-03-01T05:18:57.952000+00:00 2026/03/01/[$LATEST]adc7c386f6284871bec443ce118165e0 2026-03-01T05:18:57.952Z 23221b22-ee34-4a2c-ac2d-9ccde5bc0475 INFO {
version: '2.0',
type: 'REQUEST',
routeArn: 'arn:aws:execute-api:ap-northeast-1:123456789012:xxx/main/POST/',
identitySource: [ 'secret' ],
routeKey: 'POST /',
rawPath: '/main/',
rawQueryString: '',
headers: {
accept: '*/*',
authorization: 'secret',
'content-length': '17',
'content-type': 'application/x-www-form-urlencoded',
host: 'xxx.execute-api.ap-northeast-1.amazonaws.com',
'user-agent': 'curl/8.7.1',
'x-amzn-trace-id': 'Root=1-69a3cc41-6fb73814690fbe6a00877c63',
'x-forwarded-for': 'xxx.xxx.xxx.xxx',
'x-forwarded-port': '443',
'x-forwarded-proto': 'https'
},
requestContext: {
// ...
}
}
2026-03-01T05:18:58.009000+00:00 2026/03/01/[$LATEST]adc7c386f6284871bec443ce118165e0 END RequestId: 23221b22-ee34-4a2c-ac2d-9ccde5bc0475
2026-03-01T05:18:58.010000+00:00 2026/03/01/[$LATEST]adc7c386f6284871bec443ce118165e0 REPORT RequestId: 23221b22-ee34-4a2c-ac2d-9ccde5bc0475 Duration: 59.51 ms Billed Duration: 219 ms Memory Size: 128 MB Max Memory Used: 74 MB Init Duration: 158.59 ms
isAuthorizedをfalseにするとブロックされる。
% curl -H "Authorization: secret" -XPOST -d '{"hello":"world"}' https://rthl7n1u4a.execute-api.ap-northeast-1.amazonaws.com/main/ {"message":"Forbidden"}