Skip to content

terraform-aws-modules/terraform-aws-apigateway-v2

AWS API Gateway v2 (HTTP/Websocket) Terraform module

Terraform module which creates API Gateway v2 resources with HTTP/Websocket capabilities.

This Terraform module is part of serverless.tf framework, which aims to simplify all operations when working with the serverless in Terraform.

Usage

HTTP API Gateway

module "api_gateway" {
  source = "terraform-aws-modules/apigateway-v2/aws"

  name          = "dev-http"
  description   = "My awesome HTTP API Gateway"
  protocol_type = "HTTP"

  cors_configuration = {
    allow_headers = ["content-type", "x-amz-date", "authorization", "x-api-key", "x-amz-security-token", "x-amz-user-agent"]
    allow_methods = ["*"]
    allow_origins = ["*"]
  }

  # Custom domain
  domain_name = "terraform-aws-modules.modules.tf"

  # Access logs
  stage_access_log_settings = {
    create_log_group            = true
    log_group_retention_in_days = 7
    format = jsonencode({
      context = {
        domainName              = "$context.domainName"
        integrationErrorMessage = "$context.integrationErrorMessage"
        protocol                = "$context.protocol"
        requestId               = "$context.requestId"
        requestTime             = "$context.requestTime"
        responseLength          = "$context.responseLength"
        routeKey                = "$context.routeKey"
        stage                   = "$context.stage"
        status                  = "$context.status"
        error = {
          message      = "$context.error.message"
          responseType = "$context.error.responseType"
        }
        identity = {
          sourceIP = "$context.identity.sourceIp"
        }
        integration = {
          error             = "$context.integration.error"
          integrationStatus = "$context.integration.integrationStatus"
        }
      }
    })
  }

  # Authorizer(s)
  authorizers = {
    "azure" = {
      authorizer_type  = "JWT"
      identity_sources = ["$request.header.Authorization"]
      name             = "azure-auth"
      jwt_configuration = {
        audience         = ["d6a38afd-45d6-4874-d1aa-3c5c558aqcc2"]
        issuer           = "https://sts.windows.net/aaee026e-8f37-410e-8869-72d9154873e4/"
      }
    }
  }

  # Routes & Integration(s)
  routes = {
    "POST /" = {
      integration = {
        uri                    = "arn:aws:lambda:eu-west-1:052235179155:function:my-function"
        payload_format_version = "2.0"
        timeout_milliseconds   = 12000
      }
    }

    "GET /some-route-with-authorizer" = {
      authorizer_key = "azure"

      integration = {
        type = "HTTP_PROXY"
        uri  = "some url"
      }
    }

    "$default" = {
      integration = {
        uri = "arn:aws:lambda:eu-west-1:052235179155:function:my-default-function"
      }
    }
  }

  tags = {
    Environment = "dev"
    Terraform   = "true"
  }
}

Multiple Subdomains

API Gateway v2 supports wildcard custom domains which allow users to map multiple subdomains to the same API Gateway. This is useful when you have multiple customers and you want to provide them with a custom domain for their API endpoint and possibly use that for header based routing/rules.

module "api_gateway" {
  source = "terraform-aws-modules/apigateway-v2/aws"

  ...
  domain_name = "*.mydomain.com"
  subdomains  = ["customer1", "customer2"]
  ...
}

This will create records that allow users to access the API Gateway using the following subdomains:

  • customer1.mydomain.com
  • customer2.mydomain.com

Specific Hosted Zone

If you want to create the domain name in a specific hosted zone, you can use the hosted_zone_name input parameter:

module "api_gateway" {
  source = "terraform-aws-modules/apigateway-v2/aws"

  ...
  hosted_zone_name = "api.mydomain.com"
  domain_name      = "prod.api.mydomain.com"
  ...
}

Conditional Creation

The following values are provided to toggle on/off creation of the associated resources as desired:

module "api_gateway" {
  source = "terraform-aws-modules/apigateway-v2/aws"

  # Disable creation of the API and all resources
  create = false

  # Disable creation of the domain name and API mapping
  create_domain_name = false

  # Disable creation of Route53 alias record(s) for the custom domain
  create_domain_records = false

  # Disable creation of the ACM certificate for the custom domain
  create_certificate = false

  # Disable creation of the routes and integrations
  create_routes_and_integrations = false

  # Disable creation of the stage
  create_stage = false

  # ... omitted
}

Examples

  • Complete HTTP - Create API Gateway, authorizer, domain name, stage and other resources in various combinations
  • HTTP with VPC Link - Create API Gateway with VPC link and integration with resources in VPC (eg. ALB)
  • Websocket - Create Websocket API

Requirements

Name Version
terraform >= 1.3
aws >= 5.37

Providers

Name Version
aws >= 5.37

Modules

Name Source Version
acm terraform-aws-modules/acm/aws 5.0.1

Resources

Name Type
aws_apigatewayv2_api.this resource
aws_apigatewayv2_api_mapping.this resource
aws_apigatewayv2_authorizer.this resource
aws_apigatewayv2_deployment.this resource
aws_apigatewayv2_domain_name.this resource
aws_apigatewayv2_integration.this resource
aws_apigatewayv2_integration_response.this resource
aws_apigatewayv2_route.this resource
aws_apigatewayv2_route_response.this resource
aws_apigatewayv2_stage.this resource
aws_apigatewayv2_vpc_link.this resource
aws_cloudwatch_log_group.this resource
aws_route53_record.this resource
aws_route53_zone.this data source

Inputs

Name Description Type Default Required
api_key_selection_expression An API key selection expression. Valid values: $context.authorizer.usageIdentifierKey, $request.header.x-api-key. Defaults to $request.header.x-api-key. Applicable for WebSocket APIs string null no
api_mapping_key The API mapping key string null no
api_version A version identifier for the API. Must be between 1 and 64 characters in length string null no
authorizers Map of API gateway authorizers to create
map(object({
authorizer_credentials_arn = optional(string)
authorizer_payload_format_version = optional(string)
authorizer_result_ttl_in_seconds = optional(number)
authorizer_type = optional(string, "REQUEST")
authorizer_uri = optional(string)
enable_simple_responses = optional(bool)
identity_sources = optional(list(string))
jwt_configuration = optional(object({
audience = optional(list(string))
issuer = optional(string)
}))
name = optional(string)
}))
{} no
body An OpenAPI specification that defines the set of routes and integrations to create as part of the HTTP APIs. Supported only for HTTP APIs string null no
cors_configuration The cross-origin resource sharing (CORS) configuration. Applicable for HTTP APIs
object({
allow_credentials = optional(bool)
allow_headers = optional(list(string))
allow_methods = optional(list(string))
allow_origins = optional(list(string))
expose_headers = optional(list(string), [])
max_age = optional(number)
})
null no
create Controls if resources should be created bool true no
create_certificate Whether to create a certificate for the domain bool true no
create_domain_name Whether to create API domain name resource bool true no
create_domain_records Whether to create Route53 records for the domain name bool true no
create_routes_and_integrations Whether to create routes and integrations resources bool true no
create_stage Whether to create default stage bool true no
credentials_arn Part of quick create. Specifies any credentials required for the integration. Applicable for HTTP APIs string null no
deploy_stage Whether to deploy the stage. HTTP APIs are auto-deployed by default bool true no
description The description of the API. Must be less than or equal to 1024 characters in length string null no
disable_execute_api_endpoint Whether clients can invoke the API by using the default execute-api endpoint. By default, clients can invoke the API with the default {api_id}.execute-api.{region}.amazonaws.com endpoint. To require that clients use a custom domain name to invoke the API, disable the default endpoint bool null no
domain_name The domain name to use for API gateway string "" no
domain_name_certificate_arn The ARN of an AWS-managed certificate that will be used by the endpoint for the domain name. AWS Certificate Manager is the only supported source string null no
domain_name_ownership_verification_certificate_arn ARN of the AWS-issued certificate used to validate custom domain ownership (when certificate_arn is issued via an ACM Private CA or mutual_tls_authentication is configured with an ACM-imported certificate.) string null no
fail_on_warnings Whether warnings should return an error while API Gateway is creating or updating the resource using an OpenAPI specification. Defaults to false. Applicable for HTTP APIs bool null no
hosted_zone_name Optional domain name of the Hosted Zone where the domain should be created string null no
mutual_tls_authentication The mutual TLS authentication configuration for the domain name map(string) {} no
name The name of the API. Must be less than or equal to 128 characters in length string "" no
protocol_type The API protocol. Valid values: HTTP, WEBSOCKET string "HTTP" no
route_key Part of quick create. Specifies any route key. Applicable for HTTP APIs string null no
route_selection_expression The route selection expression for the API. Defaults to $request.method $request.path string null no
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
stage_access_log_settings Settings for logging access in this stage. Use the aws_api_gateway_account resource to configure permissions for CloudWatch Logging
object({
create_log_group = optional(bool, true)
destination_arn = optional(string)
format = optional(string)
log_group_name = optional(string)
log_group_retention_in_days = optional(number, 30)
log_group_kms_key_id = optional(string)
log_group_skip_destroy = optional(bool)
log_group_class = optional(string)
log_group_tags = optional(map(string), {})
})
{} no
stage_client_certificate_id The identifier of a client certificate for the stage. Use the aws_api_gateway_client_certificate resource to configure a client certificate. Supported only for WebSocket APIs string null no
stage_default_route_settings The default route settings for the stage
object({
data_trace_enabled = optional(bool, true)
detailed_metrics_enabled = optional(bool, true)
logging_level = optional(string)
throttling_burst_limit = optional(number, 500)
throttling_rate_limit = optional(number, 1000)
})
{} no
stage_description The description for the stage. Must be less than or equal to 1024 characters in length string null no
stage_name The name of the stage. Must be between 1 and 128 characters in length string "$default" no
stage_tags A mapping of tags to assign to the stage resource map(string) {} no
stage_variables A map that defines the stage variables for the stage map(string) {} no
subdomain_record_types A list of record types to create for the subdomain(s) list(string)
[
"A",
"AAAA"
]
no
subdomains An optional list of subdomains to use for API gateway list(string) [] no
tags A mapping of tags to assign to API gateway resources map(string) {} no
target Part of quick create. Quick create produces an API with an integration, a default catch-all route, and a default stage which is configured to automatically deploy changes. For HTTP integrations, specify a fully qualified URL. For Lambda integrations, specify a function ARN. The type of the integration will be HTTP_PROXY or AWS_PROXY, respectively. Applicable for HTTP APIs string null no
vpc_link_tags A map of tags to add to the VPC Links created map(string) {} no
vpc_links Map of VPC Link definitions to create
map(object({
name = optional(string)
security_group_ids = optional(list(string))
subnet_ids = optional(list(string))
tags = optional(map(string), {})
}))
{} no

Outputs

Name Description
acm_certificate_arn The ARN of the certificate
api_arn The ARN of the API
api_endpoint URI of the API, of the form https://{api-id}.execute-api.{region}.amazonaws.com for HTTP APIs and wss://{api-id}.execute-api.{region}.amazonaws.com for WebSocket APIs
api_execution_arn The ARN prefix to be used in an aws_lambda_permission's source_arn attribute or in an aws_iam_policy to authorize access to the @connections API
api_id The API identifier
authorizers Map of API Gateway Authorizer(s) created and their attributes
domain_name_api_mapping_selection_expression The API mapping selection expression for the domain name
domain_name_arn The ARN of the domain name
domain_name_configuration The domain name configuration
domain_name_hosted_zone_id The Amazon Route 53 Hosted Zone ID of the endpoint
domain_name_id The domain name identifier
domain_name_target_domain_name The target domain name
integrations Map of the integrations created and their attributes
routes Map of the routes created and their attributes
stage_access_logs_cloudwatch_log_group_arn Arn of cloudwatch log group created
stage_access_logs_cloudwatch_log_group_name Name of cloudwatch log group created
stage_arn The stage ARN
stage_domain_name Domain name of the stage (useful for CloudFront distribution)
stage_execution_arn The ARN prefix to be used in an aws_lambda_permission's source_arn attribute or in an aws_iam_policy to authorize access to the @connections API
stage_id The stage identifier
stage_invoke_url The URL to invoke the API pointing to the stage
vpc_links Map of VPC links created and their attributes

Authors

Module managed by Anton Babenko. Check out serverless.tf to learn more about doing serverless with Terraform.

Please reach out to Betajob if you are looking for commercial support for your Terraform, AWS, or serverless project.

License

Apache 2 Licensed. See LICENSE for full details.