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

Terraform module to create AWS API Gateway v2 (HTTP/WebSocket) πŸ‡ΊπŸ‡¦
https://registry.terraform.io/modules/terraform-aws-modules/apigateway-v2/aws
Apache License 2.0
148 stars 200 forks source link

Can't use multiple authorizers of different types #95

Closed paul-rafferty-marina closed 10 months ago

paul-rafferty-marina commented 11 months ago

Description

I cannot deploy and API Gateway that has authorizers of different types (eg: REQUEST and JWT), or Terraform throws this error telling me that attribute types must all match for conversion to map. This happens because the map must contain different types, since REQUEST and JWT have different parameters. Some of these parameters are required by one authorizer type, but are not supported at all by the other authorizer type.

Example: cannot use parameter enable_simple_responses

I cannot use this parameter on my REQUEST authorizer without also using it on the JWT authorizer, or I get the above message, that attribute types must all match for conversion to map. But if I set the JWT authorizer's value to any boolean, I get the error EnableSimpleResponses can only be set for REQUEST authorizer.

Workaround: do not use this parameter anywhere.

Example: cannot use different authorizer types due to authorizer_payload_format_version

This is worse because there is no workaround. On my REQUEST authorizer, I must set this or I get the message AuthorizerPayloadFormatVersion is a required parameter for REQUEST authorizer. But I cannot give this parameter any value on my JWT authorizer or I get the error: AuthorizerPayloadFormatVersion can only be set for REQUEST authorizer. Obviously I cannot set it to 'null' either or I get the original error.

NOTE: not the same as issue 89

The error message is similar to https://github.com/terraform-aws-modules/terraform-aws-apigateway-v2/issues/89 Indeed, the underlying cause is Terraform's handling of maps.

Versions

locals { domain_name = "terraform-aws-modules.modules.tf" # trimsuffix(data.aws_route53_zone.this.name, ".") subdomain = "complete-http" }

###################

HTTP API Gateway

###################

module "api_gateway" { source = "../../"

name = "http" description = "HTTP API Gateway with two authorizer types" 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 = [""] }

domain_name = local.domain_name domain_name_certificate_arn = module.acm.acm_certificate_arn

default_route_settings = { detailed_metrics_enabled = true throttling_burst_limit = 100 throttling_rate_limit = 100 }

authorizers = { "cognito" = { authorizer_type = "JWT" identity_sources = "$request.header.Authorization" name = "cognito" audience = ["d6a38afd-45d6-4874-d1aa-3c5c558aqcc2"] issuer = "https://${aws_cognito_user_pool.this.endpoint}" } "lambda" = { authorizer_type = "REQUEST" identity_sources = "$request.header.Authorization" name = "lambda" authorizer_payload_format_version = "2.0" } }

integrations = {

"ANY /" = {
  lambda_arn             = module.lambda_function.lambda_function_arn
  payload_format_version = "2.0"
  timeout_milliseconds   = 12000
}

}

data "aws_route53_zone" "this" { name = local.domain_name }

module "acm" { source = "terraform-aws-modules/acm/aws" version = "~> 3.0"

domain_name = local.domain_name zone_id = data.aws_route53_zone.this.id subject_alternative_names = ["${local.subdomain}.${local.domain_name}"] }

module "lambda_function" { source = "terraform-aws-modules/lambda/aws" version = "~> 3.0"

function_name = "${random_pet.this.id}-lambda" description = "My awesome lambda function" handler = "index.lambda_handler" runtime = "python3.8"

publish = true

create_package = false local_existing_package = local.downloaded

allowed_triggers = { AllowExecutionFromAPIGateway = { service = "apigateway" source_arn = "${module.api_gateway.apigatewayv2_api_execution_arn}//" } } }

resource "aws_cognito_user_pool" "this" { name = "user-pool-${random_pet.this.id}" }


Steps to reproduce the behavior:
* I am not using workspaces
* I have cleared the local cache

## Expected behavior
The module should be able to handle multiple authorizers of different types

## Actual behavior
When I try apply the module using two authorizers (REQUEST and JWT) I get this error:

Error: Invalid value for input variable on ../../../../../modules/api_gateway/api_gateway.tf line 36, in module "api_gateway": 36: authorizers = local.authorizers

The given value is not suitable for module.api_gateway.module.api_gateway.var.authorizers declared at .terraform/modules/api_gateway.api_gateway/variables.tf:204,1-23: attribute types must all match for conversion to map. "

github-actions[bot] commented 10 months ago

This issue has been automatically marked as stale because it has been open 30 days with no activity. Remove stale label or comment or this issue will be closed in 10 days

github-actions[bot] commented 10 months ago

This issue was automatically closed because of stale in 10 days

github-actions[bot] commented 9 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.