以下の内容はhttps://so-wh.at/entry/2026/03/01/133535より取得しました。


API GatewayからStep Functionsを実行する

terraformのコードが以下の通り。

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"}



以上の内容はhttps://so-wh.at/entry/2026/03/01/133535より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14