在 Terraform 中更改 AWS 自定义域的端点配置

问题描述 投票:0回答:1

我正在尝试编写一个 terraform 模块来创建 API 网关和关联的自定义域。

该模块允许消费者为 API 网关指定“端点类型”(即

EDGE
REGIONAL
)。

一开始它工作得很好,但是如果在没有先拆除所有内容的情况下更改端点类型,事情就会开始崩溃。

我已将其缩减为问题所在的

aws_api_gateway_domain_name
资源。

我对此有以下配置:

resource "aws_api_gateway_domain_name" "custom_domain" {
  domain_name     = local.custom_domain
  regional_certificate_arn = local.domain_type == "REGIONAL" ? aws_acm_certificate.regional_domain_cert[0].arn : null
  certificate_arn = local.domain_type == "EDGE" ? aws_acm_certificate.edge_domain_cert[0].arn : null

  endpoint_configuration {
    types = [local.domain_type]
  }

  security_policy = "TLS_1_2"

  depends_on = [
    aws_acm_certificate.edge_domain_cert,
    aws_acm_certificate.regional_domain_cert,
    aws_route53_record.cert_validation_record,
    aws_api_gateway_rest_api.api_gateway,
  ]

  lifecycle {
    create_before_destroy = false
  }
}

我在这里遇到的问题是,

endpoint_configuration
无法就地更新,因为根据其
文档
,AWS不支持此属性的op:replace功能。

导致此错误:

│ Error: updating API Gateway Domain Name (mydomain.testdomain.xyz): operation error API Gateway: UpdateDomainName, https response error StatusCode: 400, RequestID: 29ec3dcd-25c3-40e0-9f3c-0671e1ad7497, BadRequestException: /endpointConfiguration/types/0 Invalid request input
│ 
│   with module.example_api.aws_api_gateway_domain_name.custom_domain[0],
│   on ../../../../../Git/terraform-example/domain.tf line 45, in resource "aws_api_gateway_domain_name" "custom_domain":
│   45: resource "aws_api_gateway_domain_name" "custom_domain" {

因此,我还尝试创建单独的

aws_api_gateway_domain_name.edge_custom_domain
aws_api_gateway_domain_name.regional_custom_domain
资源,我认为我可以拆除自定义域并使用适当的配置创建一个新域。然而,问题是我无法让 Terraform 在启动新域之前销毁现有的 EDGE/REGIONAL 域。

例如,使用以下资源:

resource "aws_api_gateway_domain_name" "edge_custom_domain" {
  count           = local.create_domain && local.domain_type == "EDGE" ? 1 : 0
  domain_name     = local.custom_domain
  certificate_arn = aws_acm_certificate.edge_domain_cert[0].arn

  endpoint_configuration {
    types = ["EDGE"]
  }

  security_policy = "TLS_1_2"

  depends_on = [
    aws_acm_certificate.edge_domain_cert,
    aws_acm_certificate.regional_domain_cert,
    aws_route53_record.cert_validation_record,
  ]

  lifecycle {
    create_before_destroy = false
  }
}

resource "aws_api_gateway_domain_name" "regional_custom_domain" {
  count           = local.create_domain && local.domain_type == "REGIONAL" ? 1 : 0
  domain_name     = local.custom_domain
  regional_certificate_arn = aws_acm_certificate.regional_domain_cert[0].arn

  endpoint_configuration {
    types = ["REGIONAL"]
  }

  security_policy = "TLS_1_2"

  depends_on = [
    aws_acm_certificate.edge_domain_cert,
    aws_acm_certificate.regional_domain_cert,
    aws_route53_record.cert_validation_record,
  ]

  lifecycle {
    create_before_destroy = false
  }
}

给我一个如下错误:

module.example_api.aws_api_gateway_domain_name.edge_custom_domain[0]: Creating...
╷
│ Error: creating API Gateway Domain Name (mydomain.testdomain.xyz): operation error API Gateway: CreateDomainName, https response error StatusCode: 400, RequestID: cb120eb4-dbf0-4424-a218-6a7eab16b7f7, BadRequestException: The domain name you provided already exists.
│ 
│   with module.example_api.aws_api_gateway_domain_name.edge_custom_domain[0],
│   on ../../../../../Git/terraform-example/domain.tf line 1, in resource "aws_api_gateway_domain_name" "edge_custom_domain":
│    1: resource "aws_api_gateway_domain_name" "edge_custom_domain" {

我的具体问题是:实际上有可能做我想做的事情吗?

额外问题:是否有可能

aws_api_gateway_domain_name.regional_custom_domain
aws_api_gateway_domain_name.edge_custom_domain
depends_on
彼此不引入循环?我想表达类似“如果需要的话,等待其他资源被销毁

或者,是否可以以 terraform 式的方式更新

endpoint_configuration
? API 网关配置建议创建新的配置集,然后删除旧的配置集,尽管这对于 Terraform 来说似乎不可能。

amazon-web-services terraform terraform-provider-aws
1个回答
0
投票

对于两种类型的 aws_api_gateway_domain_name 使用相同的资源并使用动态块进行不同的配置怎么样?

例如:

resource "aws_api_gateway_domain_name" "custom_domain" {
  count           = local.create_domain ? 1 : 0
  domain_name     = local.custom_domain

  dynamic "certificate_arn" {
    for_each = local.domain_type == "EDGE" ? ["EDGE"] : []
    content {
      certificate_arn = aws_acm_certificate.edge_domain_cert[0].arn
    }
  }

  dynamic "regional_certificate_arn" {
    for_each = local.domain_type == "REGIONAL" ? ["REGIONAL"] : []
    content {
      regional_certificate_arn = aws_acm_certificate.regional_domain_cert[0].arn
    }
  }

  dynamic "endpoint_configuration" {
    for_each = local.domain_type == "EDGE" ? ["EDGE"] : ["REGIONAL"]
    content {
      types = endpoint_configuration.value
    }
  }

  security_policy = "TLS_1_2"

  depends_on = [
    # aws_acm_certificate.edge_domain_cert, # explicit dependency not needed
    # aws_acm_certificate.regional_domain_cert, # explicit dependency not needed
    aws_route53_record.cert_validation_record,
  ]

  lifecycle {
    create_before_destroy = false
  }
}

我没有时间测试上面的代码。

© www.soinside.com 2019 - 2024. All rights reserved.