Terraform с проблемой взаимозависимости API-Gateway, Route53 и SSL-сертификации - PullRequest
2 голосов
/ 06 марта 2019

Не получается получить сертификат SSL от ACM, работающего на API-шлюзе Route53 с использованием terraform. Кажется, существует проблема взаимозависимости.

data "aws_route53_zone" "root_domain" {
  name         = "${var.route53_root_domain_name}"
  private_zone = false
}

# The domain name to use with api-gateway
resource "aws_api_gateway_domain_name" "domain_name" {
  domain_name = "${var.route53_sub_domain_name}"

  certificate_arn = "${aws_acm_certificate.cert.arn}"
}

resource "aws_route53_record" "sub_domain" {
  name    = "${var.route53_sub_domain_name}"
  type    = "A"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"

  alias {
    name                   = "${aws_api_gateway_domain_name.domain_name.cloudfront_domain_name}"
    zone_id                = "${aws_api_gateway_domain_name.domain_name.cloudfront_zone_id}"
    evaluate_target_health = false
  }
}

resource "aws_acm_certificate" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"
  domain_name       = "${var.route53_sub_domain_name}"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "cert_validation" {
  name    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${aws_route53_record.sub_domain.zone_id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"

  certificate_arn         = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}

Проблема в том, что:

  1. aws_api_gateway_domain_name требуется aws_acm_certificate
  2. aws_acm_certificate должен быть проверен, поэтому шаг 3
  3. aws_route53_record.cert_validation требует aws_route53_record.sub_domain
  4. aws_route53_record.subdomain требуется имя_ aws_api_gateway_domain_name
  5. Перейти к 1

Каждый раз, когда я пытаюсь использовать данную конфигурацию, я получаю следующую ошибку:

aws_api_gateway_domain_name.domain_name: Ошибка при создании шлюза API Имя домена: BadRequestException: Невозможно связать сертификат arn: aws: acm: us-east-1: yyyy: сертификат / zzzz с CloudFront. это ошибка может помешать использованию доменного имени audit-log.taspli.com в API Gateway до 40 минут. Пожалуйста, убедитесь, что сертификат доменное имя соответствует запрашиваемому доменному имени, и что этот пользователь имеет разрешение на вызов облачного фронта: UpdateDistribution на ресурсах '*'. код состояния: 400, идентификатор запроса: хххх

1 Ответ

0 голосов
/ 10 марта 2019

Кажется, я исправил проблему, добавив записи проверки сертификатов в корневой домен, а не в поддомен.Следовательно, нарушение циклической зависимости.

Проблема заключается в том, что поддомен не может быть создан без сертификата, а сертификат не может быть проверен без поддомена.Так что ситуация застряла и неразрешима.

Вы можете вручную создать поддомен, но тогда какой смысл в автоматизации, если вам приходится прилагать усилия вручную для решения проблем.

Поэтому я попытался добавить записи проверки сертификата в корневой каталог.Внезапно он начинает работать, потому что корневой домен - это то, что создается снаружи для проекта.Этакий глобальный инфраструктурный проект, который может быть реализован извне.Тогда ваши отдельные проекты могут зависать от этой инфраструктуры в каждом конкретном случае.

Вот конфигурация terraform, которая сработала:

data "aws_route53_zone" "root_domain" {
  name         = "${var.route53_root_domain_name}"
  private_zone = false
}

# The domain name to use with api-gateway
resource "aws_api_gateway_domain_name" "domain_name" {
  domain_name = "${var.route53_sub_domain_name}"

  certificate_arn = "${aws_acm_certificate.cert.arn}"
}

resource "aws_route53_record" "sub_domain" {
  name    = "${var.route53_sub_domain_name}"
  type    = "A"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"

  alias {
    name                   = "${aws_api_gateway_domain_name.domain_name.cloudfront_domain_name}"
    zone_id                = "${aws_api_gateway_domain_name.domain_name.cloudfront_zone_id}"
    evaluate_target_health = false
  }
}

resource "aws_acm_certificate" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"
  domain_name       = "${var.route53_sub_domain_name}"
  validation_method = "DNS"
}

resource "aws_route53_record" "cert_validation" {
  name    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"

  certificate_arn         = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]

  timeouts {
    create = "45m"
  }
}
...