hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.79k stars 9.14k forks source link

[Bug]: aws_api_gateway_domain_name: unable to convert an EDGE type to REGIONAL #28059

Open riastrad opened 1 year ago

riastrad commented 1 year ago

Terraform Core Version

v1.3.5

AWS Provider Version

4.34.0

Affected Resource(s)

Expected Behavior

I am attempting to update an API Gateway that has previously been deployed with an endpoint configuration type EDGE (by default). I want to update this API Gateway to instead be type REGIONAL.

I expect changing the following configuration details to result in successfully updating the API Gateway instance:

Actual Behavior

The changes mentioned above result in an AWS API error instead.

Relevant Error/Panic Output Snippet

│ Error: BadRequestException: /endpointConfiguration/types/0 Invalid request input
│ 
│   with aws_api_gateway_domain_name.domain,
│   on domain-name.tf line 3, in resource "aws_api_gateway_domain_name" "domain":
│    3: resource "aws_api_gateway_domain_name" "domain" {

Terraform Configuration Files

Relevant API Gateway resources

resource "aws_api_gateway_rest_api" "company-api" {
  name        = "CompanyAPIGateway-${var.deployment_stage}"
  description = "API Gateway for all Company APIs"
  api_key_source = "AUTHORIZER"

  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

resource "aws_api_gateway_domain_name" "domain" {
  domain_name = "api-${var.deployment_stage}.test-domain.com"
  regional_certificate_arn  = var.certificate_arn == "" ? one(aws_acm_certificate_validation.cert_validation1).certificate_arn : var.certificate_arn

  endpoint_configuration {
      types = ["REGIONAL"]
  }
}

resource "aws_route53_record" "dns-api" {
  name    = aws_api_gateway_domain_name.domain.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.zone.id

  alias {
    evaluate_target_health = true
    # name = aws_api_gateway_domain_name.domain.regional_domain_name
    # zone_id = aws_api_gateway_domain_name.domain.regional_zone_id

    # Not pretty, but it might work?
    name = replace(aws_api_gateway_deployment.company-api.invoke_url, "/${var.deployment_stage}", "")
    zone_id = data.aws_route53_zone.zone.zone_id
  }
}
Other potentially relevant resources

resource "aws_acm_certificate" "cert" {
  count = var.certificate_arn == "" ? 1 : 0

  domain_name               = "api-${var.deployment_stage}.test-domain.com"
  subject_alternative_names = var.deployment_stage == "prod" ? ["*.domain.com"] : null
  validation_method         = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_acm_certificate_validation" "cert_validation1" {
  count = var.certificate_arn == "" ? 1 : 0

  certificate_arn = one(aws_acm_certificate.cert).arn
  validation_record_fqdns = var.deployment_stage == "prod" ? [
    one(aws_route53_record.cert_validation_dns1).fqdn,
    one(aws_route53_record.cert_validation_dns2).fqdn
  ] : [ one(aws_route53_record.cert_validation_dns1).fqdn]
}

Steps to Reproduce

  1. Deploy an API Gateway configuration that relies on the default "EDGE" endpoint configuration and uses a custom domain name
  2. Change the API Gateway and Route53 resources to use a "REGIONAL" endpoint configuration
  3. Attempt to run terraform apply

Debug Output

tf_debug.txt

Panic Output

No response

Important Factoids

The API Gateway has previously been deployed as an "EDGE-OPTIMIZED" type and this error appears when attempting to update the resource to be "REGIONAL" instead.

The original error I encountered was due to the fact that the regional_domain_name and regional_zone_id fields do not populate for the aws_api_gateway_domain_name resource after switching it to endpoint_configuration: { types = ["REGIONAL"] }.

When I hard code the values in my Route53 record resource instead of referencing them the domain_name resource (as shown in the configuration above) I receive the AWS error that's shared here and I believe this to be closer to the root cause of the issue.

References

No response

Would you like to implement a fix?

No response

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

riastrad commented 1 year ago

I went digging in the AWS API documentation and realized that this isn't necessarily a bug in the provider, but due to the fact that AWS's UpdateDomainName endpoint doesn't support replace operations for the endpointConfiguration[^1]:

image

I'll leave this ticket open because it would be nice if the CLI caught this in the terraform plan or terraform apply commands before trying to make an invalid patch. A "updating this resource is not possible because x" could potentially save folks a lot of time when they try to implement in the future.

[^1]: image is a screenshot from these docs