From 2cb86afac1e26bae47c2bf943756d171e6fd6b59 Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Sat, 29 Nov 2025 08:17:45 -0600 Subject: [PATCH 1/4] Upgrade AWS provider and min required Terraform version to `6.0` and `1.5.7` respectively --- .pre-commit-config.yaml | 2 +- README.md | 7 +-- docs/UPGRADE-6.0.md | 75 ++++++++++++++++++++++++++++++ examples/complete-http/README.md | 6 +-- examples/complete-http/versions.tf | 4 +- examples/vpc-link-http/README.md | 6 +-- examples/vpc-link-http/versions.tf | 4 +- examples/websocket/README.md | 4 +- examples/websocket/versions.tf | 4 +- versions.tf | 4 +- wrappers/versions.tf | 4 +- 11 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 docs/UPGRADE-6.0.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 71da442..02bf72e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.103.0 + rev: v1.104.0 hooks: - id: terraform_fmt - id: terraform_wrapper_module_for_each diff --git a/README.md b/README.md index eb9dfa2..161e758 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ module "api_gateway" { ``` This will create records that allow users to access the API Gateway using the following subdomains: + - `customer1.mydomain.com` - `customer2.mydomain.com` @@ -184,14 +185,14 @@ module "api_gateway" { | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [aws](#requirement\_aws) | >= 5.96 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.96 | +| [aws](#provider\_aws) | >= 6.0 | ## Modules diff --git a/docs/UPGRADE-6.0.md b/docs/UPGRADE-6.0.md new file mode 100644 index 0000000..6beb111 --- /dev/null +++ b/docs/UPGRADE-6.0.md @@ -0,0 +1,75 @@ +# Upgrade from v5.x to v6.x + +If you have any questions regarding this upgrade process, please consult the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-apigateway-v2/tree/master/examples) directory: +If you find a bug, please open an issue with supporting configuration to reproduce. + +## List of backwards incompatible changes + +- Terraform `v1.5.7` is now minimum supported version +- AWS provider `v6.0` is now minimum supported version + +## Additional changes + +### Added + +- + +### Modified + +- Variable definitions now contain detailed `object` types in place of the previously used any type + +### Variable and output changes + +1. Removed variables: + + - + +2. Renamed variables: + + - + +3. Added variables: + + - + +4. Removed outputs: + + - + +5. Renamed outputs: + + - + +6. Added outputs: + + - + +## Upgrade Migrations + +### Before 5.x Example + +```hcl +module "apigateway" { + source = "terraform-aws-modules/apigateway-v2/aws/" + version = "~> 5.0" + + # Truncated for brevity ... + +} +``` + +### After 6.x Example + +```hcl +module "apigateway" { + source = "terraform-aws-modules/apigateway-v2/aws/" + version = "~> 6.0" + + # Truncated for brevity ... + +} +``` + +### State Changes + +TBD diff --git a/examples/complete-http/README.md b/examples/complete-http/README.md index 082e8f0..6418cc5 100644 --- a/examples/complete-http/README.md +++ b/examples/complete-http/README.md @@ -19,8 +19,8 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [aws](#requirement\_aws) | >= 5.96 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.0 | | [local](#requirement\_local) | >= 2.5 | | [null](#requirement\_null) | >= 2.0 | | [tls](#requirement\_tls) | >= 3.1 | @@ -29,7 +29,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.96 | +| [aws](#provider\_aws) | >= 6.0 | | [local](#provider\_local) | >= 2.5 | | [null](#provider\_null) | >= 2.0 | | [tls](#provider\_tls) | >= 3.1 | diff --git a/examples/complete-http/versions.tf b/examples/complete-http/versions.tf index 61e4e49..3a14bd1 100644 --- a/examples/complete-http/versions.tf +++ b/examples/complete-http/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.3" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.96" + version = ">= 6.0" } local = { source = "hashicorp/local" diff --git a/examples/vpc-link-http/README.md b/examples/vpc-link-http/README.md index 795d199..f193765 100644 --- a/examples/vpc-link-http/README.md +++ b/examples/vpc-link-http/README.md @@ -19,15 +19,15 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [aws](#requirement\_aws) | >= 5.96 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.0 | | [null](#requirement\_null) | >= 2.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.96 | +| [aws](#provider\_aws) | >= 6.0 | | [null](#provider\_null) | >= 2.0 | ## Modules diff --git a/examples/vpc-link-http/versions.tf b/examples/vpc-link-http/versions.tf index 7082bff..736440e 100644 --- a/examples/vpc-link-http/versions.tf +++ b/examples/vpc-link-http/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.3" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.96" + version = ">= 6.0" } null = { source = "hashicorp/null" diff --git a/examples/websocket/README.md b/examples/websocket/README.md index a549ee6..49d2546 100644 --- a/examples/websocket/README.md +++ b/examples/websocket/README.md @@ -50,8 +50,8 @@ connected (press CTRL+C to quit) | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [aws](#requirement\_aws) | >= 5.96 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.0 | ## Providers diff --git a/examples/websocket/versions.tf b/examples/websocket/versions.tf index 97e1864..db13b0a 100644 --- a/examples/websocket/versions.tf +++ b/examples/websocket/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.3" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.96" + version = ">= 6.0" } } } diff --git a/versions.tf b/versions.tf index 97e1864..db13b0a 100644 --- a/versions.tf +++ b/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.3" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.96" + version = ">= 6.0" } } } diff --git a/wrappers/versions.tf b/wrappers/versions.tf index 97e1864..db13b0a 100644 --- a/wrappers/versions.tf +++ b/wrappers/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.3" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.96" + version = ">= 6.0" } } } From ccea02c274b6bfc298d32742a2985aea72aeefb8 Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Sat, 29 Nov 2025 08:38:11 -0600 Subject: [PATCH 2/4] feat: Add support for `region` resource level argument --- README.md | 3 ++- docs/UPGRADE-6.0.md | 2 +- main.tf | 29 +++++++++++++++++++++++++++-- variables.tf | 6 ++++++ wrappers/main.tf | 1 + 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 161e758..81c253e 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ module "api_gateway" { | Name | Source | Version | |------|--------|---------| -| [acm](#module\_acm) | terraform-aws-modules/acm/aws | 5.0.1 | +| [acm](#module\_acm) | terraform-aws-modules/acm/aws | 6.1.1 | ## Resources @@ -249,6 +249,7 @@ module "api_gateway" { | [name](#input\_name) | The name of the API. Must be less than or equal to 128 characters in length | `string` | `""` | no | | [private\_zone](#input\_private\_zone) | Indicates the hosted zone being looked up is private. Certificate validation will fail if this is set to true. | `bool` | `false` | no | | [protocol\_type](#input\_protocol\_type) | The API protocol. Valid values: `HTTP`, `WEBSOCKET` | `string` | `"HTTP"` | no | +| [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | | [route\_key](#input\_route\_key) | Part of quick create. Specifies any route key. Applicable for HTTP APIs | `string` | `null` | no | | [route\_selection\_expression](#input\_route\_selection\_expression) | The route selection expression for the API. Defaults to `$request.method $request.path` | `string` | `null` | no | | [routes](#input\_routes) | Map of API gateway routes with integrations |
map(object({
# Route
authorizer_key = optional(string)
api_key_required = optional(bool)
authorization_scopes = optional(list(string), [])
authorization_type = optional(string)
authorizer_id = optional(string)
model_selection_expression = optional(string)
operation_name = optional(string)
request_models = optional(map(string), {})
request_parameter = optional(object({
request_parameter_key = optional(string)
required = optional(bool, false)
}), {})
route_response_selection_expression = optional(string)

# Route settings
data_trace_enabled = optional(bool)
detailed_metrics_enabled = optional(bool)
logging_level = optional(string)
throttling_burst_limit = optional(number)
throttling_rate_limit = optional(number)

# Stage - Route response
route_response = optional(object({
create = optional(bool, false)
model_selection_expression = optional(string)
response_models = optional(map(string))
route_response_key = optional(string, "$default")
}), {})

# Integration
integration = object({
connection_id = optional(string)
vpc_link_key = optional(string)
connection_type = optional(string)
content_handling_strategy = optional(string)
credentials_arn = optional(string)
description = optional(string)
method = optional(string)
subtype = optional(string)
type = optional(string, "AWS_PROXY")
uri = optional(string)
passthrough_behavior = optional(string)
payload_format_version = optional(string)
request_parameters = optional(map(string), {})
request_templates = optional(map(string), {})
response_parameters = optional(list(object({
mappings = map(string)
status_code = string
})))
template_selection_expression = optional(string)
timeout_milliseconds = optional(number)
tls_config = optional(object({
server_name_to_verify = optional(string)
}))

# Integration Response
response = optional(object({
content_handling_strategy = optional(string)
integration_response_key = optional(string)
response_templates = optional(map(string))
template_selection_expression = optional(string)
}), {})
})
}))
| `{}` | no | diff --git a/docs/UPGRADE-6.0.md b/docs/UPGRADE-6.0.md index 6beb111..16a0e62 100644 --- a/docs/UPGRADE-6.0.md +++ b/docs/UPGRADE-6.0.md @@ -12,7 +12,7 @@ If you find a bug, please open an issue with supporting configuration to reprodu ### Added -- +- Support for `region` parameter to specify the AWS region for the resources created if different from the provider region. ### Modified diff --git a/main.tf b/main.tf index 0b36225..4c1ec12 100644 --- a/main.tf +++ b/main.tf @@ -12,6 +12,8 @@ locals { resource "aws_apigatewayv2_api" "this" { count = var.create ? 1 : 0 + region = var.region + api_key_selection_expression = local.is_websocket ? var.api_key_selection_expression : null body = local.is_http ? var.body : null @@ -54,6 +56,8 @@ resource "aws_apigatewayv2_api" "this" { resource "aws_apigatewayv2_authorizer" "this" { for_each = { for k, v in var.authorizers : k => v if var.create } + region = var.region + api_id = aws_apigatewayv2_api.this[0].id authorizer_credentials_arn = each.value.authorizer_credentials_arn @@ -87,6 +91,8 @@ locals { resource "aws_apigatewayv2_domain_name" "this" { count = local.create_domain_name ? 1 : 0 + region = var.region + domain_name = var.domain_name domain_name_configuration { @@ -112,6 +118,8 @@ resource "aws_apigatewayv2_domain_name" "this" { resource "aws_apigatewayv2_api_mapping" "this" { count = local.create_domain_name && local.create_stage ? 1 : 0 + region = var.region + api_id = aws_apigatewayv2_api.this[0].id api_mapping_key = var.api_mapping_key domain_name = aws_apigatewayv2_domain_name.this[0].id @@ -166,7 +174,9 @@ locals { module "acm" { source = "terraform-aws-modules/acm/aws" - version = "5.0.1" + version = "6.1.1" # TODO - https://github.com/terraform-aws-modules/terraform-aws-acm/pull/167 + + region = var.region create_certificate = local.create_domain_name && var.create_domain_records && local.create_certificate @@ -186,6 +196,8 @@ module "acm" { resource "aws_apigatewayv2_route" "this" { for_each = { for k, v in var.routes : k => v if local.create_routes_and_integrations } + region = var.region + api_id = aws_apigatewayv2_api.this[0].id api_key_required = local.is_websocket ? each.value.api_key_required : null @@ -217,6 +229,8 @@ resource "aws_apigatewayv2_route" "this" { resource "aws_apigatewayv2_route_response" "this" { for_each = { for k, v in var.routes : k => v if local.create_routes_and_integrations && coalesce(v.route_response.create, false) } + region = var.region + api_id = aws_apigatewayv2_api.this[0].id model_selection_expression = each.value.route_response.model_selection_expression response_models = each.value.route_response.response_models @@ -231,8 +245,9 @@ resource "aws_apigatewayv2_route_response" "this" { resource "aws_apigatewayv2_integration" "this" { for_each = { for k, v in var.routes : k => v.integration if local.create_routes_and_integrations } - api_id = aws_apigatewayv2_api.this[0].id + region = var.region + api_id = aws_apigatewayv2_api.this[0].id connection_id = try(aws_apigatewayv2_vpc_link.this[each.value.vpc_link_key].id, each.value.connection_id) connection_type = each.value.connection_type content_handling_strategy = each.value.content_handling_strategy @@ -279,6 +294,8 @@ resource "aws_apigatewayv2_integration" "this" { resource "aws_apigatewayv2_integration_response" "this" { for_each = { for k, v in var.routes : k => v.integration if local.create_routes_and_integrations && v.integration.response.integration_response_key != null } + region = var.region + api_id = aws_apigatewayv2_api.this[0].id integration_id = aws_apigatewayv2_integration.this[each.key].id @@ -324,6 +341,8 @@ locals { resource "aws_apigatewayv2_stage" "this" { count = local.create_stage ? 1 : 0 + region = var.region + api_id = aws_apigatewayv2_api.this[0].id dynamic "access_log_settings" { @@ -383,6 +402,8 @@ resource "aws_apigatewayv2_stage" "this" { resource "aws_apigatewayv2_deployment" "this" { count = local.create_stage && var.deploy_stage && !local.is_http ? 1 : 0 + region = var.region + api_id = aws_apigatewayv2_api.this[0].id description = var.description @@ -414,6 +435,8 @@ resource "aws_apigatewayv2_deployment" "this" { resource "aws_cloudwatch_log_group" "this" { for_each = { for k, v in { "this" = var.stage_access_log_settings } : k => v if local.create_stage && v != null && try(v.create_log_group, true) } + region = var.region + name = coalesce(each.value.log_group_name, "/aws/apigateway/${var.name}/${replace(var.stage_name, "$", "")}") retention_in_days = each.value.log_group_retention_in_days kms_key_id = each.value.log_group_kms_key_id @@ -430,6 +453,8 @@ resource "aws_cloudwatch_log_group" "this" { resource "aws_apigatewayv2_vpc_link" "this" { for_each = { for k, v in var.vpc_links : k => v if var.create } + region = var.region + name = coalesce(each.value.name, each.key) security_group_ids = each.value.security_group_ids subnet_ids = each.value.subnet_ids diff --git a/variables.tf b/variables.tf index 8318104..e948e0d 100644 --- a/variables.tf +++ b/variables.tf @@ -4,6 +4,12 @@ variable "create" { default = true } +variable "region" { + description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" + type = string + default = null +} + variable "tags" { description = "A mapping of tags to assign to API gateway resources" type = map(string) diff --git a/wrappers/main.tf b/wrappers/main.tf index 8deb054..a3c982d 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -29,6 +29,7 @@ module "wrapper" { name = try(each.value.name, var.defaults.name, "") private_zone = try(each.value.private_zone, var.defaults.private_zone, false) protocol_type = try(each.value.protocol_type, var.defaults.protocol_type, "HTTP") + region = try(each.value.region, var.defaults.region, null) route_key = try(each.value.route_key, var.defaults.route_key, null) route_selection_expression = try(each.value.route_selection_expression, var.defaults.route_selection_expression, null) routes = try(each.value.routes, var.defaults.routes, {}) From 61eccd0a701b9f67f72c5d722b164f524bc5889c Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Sat, 29 Nov 2025 08:46:17 -0600 Subject: [PATCH 3/4] chore: Remove upgrade guide since there are no significant user facing changes --- docs/UPGRADE-6.0.md | 75 --------------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 docs/UPGRADE-6.0.md diff --git a/docs/UPGRADE-6.0.md b/docs/UPGRADE-6.0.md deleted file mode 100644 index 16a0e62..0000000 --- a/docs/UPGRADE-6.0.md +++ /dev/null @@ -1,75 +0,0 @@ -# Upgrade from v5.x to v6.x - -If you have any questions regarding this upgrade process, please consult the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-apigateway-v2/tree/master/examples) directory: -If you find a bug, please open an issue with supporting configuration to reproduce. - -## List of backwards incompatible changes - -- Terraform `v1.5.7` is now minimum supported version -- AWS provider `v6.0` is now minimum supported version - -## Additional changes - -### Added - -- Support for `region` parameter to specify the AWS region for the resources created if different from the provider region. - -### Modified - -- Variable definitions now contain detailed `object` types in place of the previously used any type - -### Variable and output changes - -1. Removed variables: - - - - -2. Renamed variables: - - - - -3. Added variables: - - - - -4. Removed outputs: - - - - -5. Renamed outputs: - - - - -6. Added outputs: - - - - -## Upgrade Migrations - -### Before 5.x Example - -```hcl -module "apigateway" { - source = "terraform-aws-modules/apigateway-v2/aws/" - version = "~> 5.0" - - # Truncated for brevity ... - -} -``` - -### After 6.x Example - -```hcl -module "apigateway" { - source = "terraform-aws-modules/apigateway-v2/aws/" - version = "~> 6.0" - - # Truncated for brevity ... - -} -``` - -### State Changes - -TBD From 5c2ca5a1b95d2750246180d6e0cd94dd76c07762 Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Sat, 29 Nov 2025 11:56:01 -0600 Subject: [PATCH 4/4] fix: Use updated ACM module with reduced Terraform version requirement --- README.md | 2 +- main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 81c253e..10be022 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ module "api_gateway" { | Name | Source | Version | |------|--------|---------| -| [acm](#module\_acm) | terraform-aws-modules/acm/aws | 6.1.1 | +| [acm](#module\_acm) | terraform-aws-modules/acm/aws | 6.2.0 | ## Resources diff --git a/main.tf b/main.tf index 4c1ec12..e45a9c0 100644 --- a/main.tf +++ b/main.tf @@ -174,7 +174,7 @@ locals { module "acm" { source = "terraform-aws-modules/acm/aws" - version = "6.1.1" # TODO - https://github.com/terraform-aws-modules/terraform-aws-acm/pull/167 + version = "6.2.0" region = var.region