UPD: updated apigw-lambda to support multiple resources (aka part_path). also added support for regional apigw

This commit is contained in:
xpk 2024-03-05 11:50:02 +08:00
parent 906b04cffa
commit 09f4a5fb4e
Signed by: xpk
GPG Key ID: CD4FF6793F09AB86
4 changed files with 62 additions and 32 deletions

View File

@ -23,7 +23,7 @@ No modules.
|------|------|
| [aws_api_gateway_deployment.apigw-deployment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_deployment) | resource |
| [aws_api_gateway_integration.api-integration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_integration) | resource |
| [aws_api_gateway_integration_response.MyDemoIntegrationResponse](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_integration_response) | resource |
| [aws_api_gateway_integration_response.integration-response](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_integration_response) | resource |
| [aws_api_gateway_method.api-method](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_method) | resource |
| [aws_api_gateway_method_response.response_200](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_method_response) | resource |
| [aws_api_gateway_method_settings.apigw-method-settings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_method_settings) | resource |
@ -51,6 +51,7 @@ No modules.
|------|-------------|------|---------|:--------:|
| apigw-security-group-id | Security group id of apigateway | `string` | n/a | yes |
| apigw-subnet-ids | Subnet IDs of apigateway | `list(string)` | n/a | yes |
| apigw-type | Type of apigateway: private or regional | `string` | n/a | yes |
| apigw-vpc-id | VPC id of apigateway | `string` | n/a | yes |
| apigw-vpc-link-target-arns | Target arns for apigateway VPC link | `list(string)` | `[]` | no |
| cloudwatchlog-retention | Cloudwatch log group retention days | `number` | `14` | no |
@ -61,8 +62,8 @@ No modules.
| lambda-main-function-name | Main python file without the .py extension | `string` | n/a | yes |
| lambda-runtime-version | Lambda runtime version | `string` | `"python3.12"` | no |
| name | Name of apigateway | `string` | n/a | yes |
| path\_part | Last path segment of this API resource | `string` | n/a | yes |
| stages | apigateway stages | `map` | n/a | yes |
| resources | Apigateway resources (path\_part) | `map(any)` | n/a | yes |
| stages | apigateway stages | `map(any)` | n/a | yes |
## Outputs

View File

@ -2,9 +2,12 @@ resource "aws_api_gateway_rest_api" "api" {
name = var.name
description = var.description
endpoint_configuration {
types = ["PRIVATE"]
vpc_endpoint_ids = [aws_vpc_endpoint.apigw-vpcep.id]
dynamic "endpoint_configuration" {
for_each = [1]
content {
types = var.apigw-type == "private" ? ["PRIVATE"] : ["REGIONAL"]
vpc_endpoint_ids = var.apigw-type == "private" ? [aws_vpc_endpoint.apigw-vpcep[0].id] : null
}
}
}
@ -14,6 +17,7 @@ resource "aws_api_gateway_rest_api" "api" {
data "aws_region" "current" {}
resource "aws_vpc_endpoint" "apigw-vpcep" {
count = var.apigw-type == "private" ? 1 : 0
private_dns_enabled = false
security_group_ids = [var.apigw-security-group-id]
service_name = "com.amazonaws.${data.aws_region.current.name}.execute-api"
@ -30,48 +34,58 @@ resource "aws_api_gateway_vpc_link" "api-vpc-link" {
target_arns = var.apigw-vpc-link-target-arns
}
# The resource for the endpoint
# Apigw resources, integration, method, responses
resource "aws_api_gateway_resource" "api-res" {
path_part = var.path_part
depends_on = [aws_api_gateway_rest_api_policy.api-policy]
for_each = var.resources
path_part = each.key
parent_id = aws_api_gateway_rest_api.api.root_resource_id
rest_api_id = aws_api_gateway_rest_api.api.id
}
resource "aws_api_gateway_method" "api-method" {
depends_on = [aws_api_gateway_resource.api-res]
for_each = var.resources
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.api-res.id
http_method = "POST"
authorization = "NONE"
resource_id = aws_api_gateway_resource.api-res[each.key].id
http_method = each.value["method"]
authorization = each.value["authorization"]
}
# non-proxy integration
resource "aws_api_gateway_integration" "api-integration" {
depends_on = [aws_api_gateway_method.api-method]
for_each = var.resources
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.api-res.id
http_method = aws_api_gateway_method.api-method.http_method
integration_http_method = "POST"
type = "AWS"
content_handling = "CONVERT_TO_TEXT"
resource_id = aws_api_gateway_resource.api-res[each.key].id
http_method = aws_api_gateway_method.api-method[each.key].http_method
integration_http_method = each.value["method"]
type = each.value["integration-type"]
content_handling = each.value["content-handling"]
uri = aws_lambda_function.function.invoke_arn
}
resource "aws_api_gateway_method_response" "response_200" {
depends_on = [aws_api_gateway_method.api-method]
for_each = var.resources
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.api-res.id
http_method = aws_api_gateway_method.api-method.http_method
resource_id = aws_api_gateway_resource.api-res[each.key].id
http_method = aws_api_gateway_method.api-method[each.key].http_method
status_code = "200"
}
resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" {
resource "aws_api_gateway_integration_response" "integration-response" {
depends_on = [aws_api_gateway_integration.api-integration]
for_each = var.resources
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.api-res.id
http_method = aws_api_gateway_method.api-method.http_method
status_code = aws_api_gateway_method_response.response_200.status_code
resource_id = aws_api_gateway_resource.api-res[each.key].id
http_method = aws_api_gateway_method.api-method[each.key].http_method
status_code = aws_api_gateway_method_response.response_200[each.key].status_code
}
# apigw deployment and stage
resource "aws_api_gateway_deployment" "apigw-deployment" {
depends_on = [aws_api_gateway_integration.api-integration]
rest_api_id = aws_api_gateway_rest_api.api.id
triggers = {
@ -85,7 +99,7 @@ resource "aws_api_gateway_deployment" "apigw-deployment" {
resource "aws_api_gateway_stage" "apigw-stage" {
for_each = var.stages
depends_on = [aws_cloudwatch_log_group.this]
depends_on = [aws_api_gateway_rest_api_policy.api-policy, aws_cloudwatch_log_group.this]
deployment_id = aws_api_gateway_deployment.apigw-deployment.id
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = each.key
@ -113,6 +127,7 @@ resource "aws_api_gateway_stage" "apigw-stage" {
}
resource "aws_api_gateway_method_settings" "apigw-method-settings" {
depends_on = [aws_api_gateway_rest_api_policy.api-policy]
for_each = aws_api_gateway_stage.apigw-stage
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = each.value.stage_name

View File

@ -1,7 +1,7 @@
output apigw-id {
output "apigw-id" {
value = aws_api_gateway_rest_api.api.id
}
output apigw-vpc-endpoints {
value = aws_vpc_endpoint.apigw-vpcep.*.dns_entry[0].*.dns_name
output "apigw-vpc-endpoints" {
value = try(aws_vpc_endpoint.apigw-vpcep.*.dns_entry[0].*.dns_name, null)
}

View File

@ -8,18 +8,32 @@ variable "description" {
description = "Description of apigateway"
}
variable "path_part" {
variable "apigw-type" {
type = string
description = "Last path segment of this API resource"
description = "Type of apigateway: private or regional"
validation {
condition = can(regex("^(private|regional)$", var.apigw-type))
error_message = "Invalid apigw type, only allowed types are: 'private', 'regional'"
}
}
variable "resources" {
type = map(any)
description = "Apigateway resources (path_part)"
}
#variable "path_part" {
# type = string
# description = "Last path segment of this API resource"
#}
#variable "stage-name" {
# type = string
# description = "Apigateway stage name"
#}
variable stages {
type = map
variable "stages" {
type = map(any)
description = "apigateway stages"
}