如果有人在2023年使用Terraform和OpenAPI配置寻找一个例子,这是我使用的内容。
resource "aws_api_gateway_rest_api" "MyApi" {
name = "${var.name}-${var.environment}"
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"AWS" : aws_iam_role.api-gateway-access-role.arn
},
"Action" : "execute-api:Invoke",
"Resource" : "arn:aws:execute-api:${var.aws_region}:${var.aws_account_id}:*/*/*/*"
"Condition" : {
"StringEquals" : {
"aws:SourceVpc" : data.terraform_remote_state.vpc.outputs.vpc_id
}
}
}
]
})
body = jsonencode({
"openapi" : "3.0.1",
"info" : {
"title" : "MyApi",
"version" : "0.1.0"
},
"paths" : {
"/my-in-principle" : {
"post" : {
"x-amazon-apigateway-auth" : {
"type" : "AWS_IAM"
},
"x-amazon-apigateway-integration" : {
"uri" : "arn:aws:apigateway:${var.aws_region}:sns:path/${aws_sns_topic.my-request.arn}?Action=Publish&TopicArn=${aws_sns_topic.my-request.arn}",
"passthroughBehavior" : "when_no_templates",
"credentials" : aws_iam_role.sns-access-role.arn,
"httpMethod" : "POST",
"type" : "aws",
"requestTemplates" : {
"application/json" : "{\"Message\": $input.json('$')}"
},
"requestParameters" : {
"integration.request.querystring.Message" : "method.request.body"
}
"responses" : {
"400" : {
"statusCode" : "400",
"contentHandling" : "CONVERT_TO_TEXT"
"responseTemplates" : {
"application/json" : "$input.json('$')"
},
},
"500" : {
"statusCode" : "500",
"contentHandling" : "CONVERT_TO_TEXT"
"responseTemplates" : {
"application/json" : "$input.json('$')"
},
},
"200" : {
"statusCode" : "200",
"contentHandling" : "CONVERT_TO_TEXT"
"responseTemplates" : {
"application/json" : "$input.json('$')"
},
}
}
},
"responses" : {
"200" : {
"description" : "Successful Response"
},
"400" : {
"description" : "Bad Request"
},
"500" : {
"description" : "Internal Server Error"
}
}
}
}
}
})
endpoint_configuration {
types = ["PRIVATE"]
vpc_endpoint_ids = [data.aws_vpc_endpoint.execute-api.id]
}
}
resource "aws_sns_topic_policy" "my-request-topic-policy" {
arn = aws_sns_topic.my-request.arn
policy = jsonencode({
Version = "2012-10-17",
Id = "default",
Statement = [
{
Sid = "AllowAPIGatewayToPublish",
Effect = "Allow",
Principal = {
Service = "apigateway.amazonaws.com"
},
Action = "sns:Publish",
Resource = aws_sns_topic.my-request.arn,
Condition = {
ArnEquals = {
"aws:SourceArn" = "arn:aws:execute-api:${var.aws_region}:${var.aws_account_id}:${aws_api_gateway_rest_api.MyApi.id}/*/*/*"
}
}
}
]
})
}
resource "aws_iam_role" "sns-access-role" {
name = "sns-access-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "apigateway.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
inline_policy {
name = "sns-publish-policy"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"sns:Publish"
],
Resource = [
aws_sns_topic.my-request.arn
]
}
]
})
}
}
resource "aws_api_gateway_method_settings" "MyMethodSettings" {
rest_api_id = aws_api_gateway_rest_api.MyApi.id
stage_name = aws_api_gateway_stage.MyApiStage.stage_name
method_path = "*/*"
settings {
throttling_rate_limit = "5"
throttling_burst_limit = "20"
}
}
resource "aws_api_gateway_deployment" "MyDeployment" {
rest_api_id = aws_api_gateway_rest_api.MyApi.id
triggers = {
redeployment = sha1(jsonencode([
aws_api_gateway_rest_api.MyApi.body,
aws_api_gateway_rest_api.MyApi.policy
]))
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "MyApiStage" {
rest_api_id = aws_api_gateway_rest_api.MyApi.id
stage_name = "v1"
deployment_id = aws_api_gateway_deployment.MyDeployment.id
xray_tracing_enabled = true
}
resource "aws_lambda_permission" "MyLambdaInvokePermission" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.Async-Lambda.function_name
principal = "apigateway.amazonaws.com"
# More: http:
source_arn = "arn:aws:execute-api:${var.aws_region}:${var.aws_account_id}:${aws_api_gateway_rest_api.MyApi.id}/*/*/*"
}