У меня был похожий сценарий, и ключом к его решению было использование localals и flatten () . Этот подход также должен работать для вас, так что вам не нужно два прохода для создания ресурсов.
В этом сценарии есть несколько доменов, каждый из которых имеет дочерние домены, которые будут отображаться в разделе subjectAltName сертификата. Например:
├── preview.example.com
│ ├── app.preview.example.com
│ └── www.preview.example.com
├── demo.example.com
│ ├── app.demo.example.com
│ └── www.demo.example.com
├── staging.example.com
│ ├── app.staging.example.com
│ └── www.staging.example.com
└── example.com
├── app.example.com
└── www.example.com
Для этого мы сначала устанавливаем некоторые переменные:
variable "domains" {
type = "list"
default = [
"demo.example.com",
"preview.example.com",
"staging.example.com",
"example.com"
]
}
variable "subdomains" {
type = "list"
default = [
"app",
"www"
]
}
Затем мы создадим ресурсы сертификата, которые содержат субдомены как SAN.
resource "aws_acm_certificate" "cert" {
count = "${length(var.domains)}"
domain_name = "${element(var.domains, count.index)}"
validation_method = "DNS"
subject_alternative_names = ["${
formatlist("%s.%s",
var.subdomains,
element(var.domains, count.index)
)
}"]
}
Далее нам понадобится локальная переменная, чтобы сгладить результирующий набор доменов и поддоменов.
Это необходимо, поскольку terraform не поддерживает синтаксис вложенных списков начиная с версии 0.11.7.
через element()
интерполяцию или `list [count].
locals {
dvo = "${flatten(aws_acm_certificate.cert.*.domain_validation_options)}"
}
Далее нам понадобится поиск зоны Route 53, которую мы можем использовать в последующих записях Route 53:
data "aws_route53_zone" "zone" {
count = "${length(var.domains) > 0 ? 1 : 0}"
name = "example.com."
private_zone = false
}
Затем мы создаем DNS-записи Route 53, которые будут заполняться данными из сертификата.
ресурс для проверки DNS. Мы добавляем один к поддоменам, чтобы у нас также был
запись для базового домена, не включенного в список поддоменов.
resource "aws_route53_record" "cert_validation" {
count = "${length(var.domains) * (length(var.subdomains) + 1)}"
zone_id = "${data.aws_route53_zone.zone.id}"
ttl = 60
name = "${lookup(local.dvo[count.index], "resource_record_name")}"
type = "${lookup(local.dvo[count.index], "resource_record_type")}"
records = ["${lookup(local.dvo[count.index], "resource_record_value")}"]
}
Наконец, мы создаем ресурс проверки сертификата, который будет ждать, пока сертификат будет
выдано.
resource "aws_acm_certificate_validation" "cert" {
count = "${length(var.domains) * (length(var.subdomains) + 1)}"
certificate_arn = "${element(aws_acm_certificate.cert.*.arn, count.index)}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.*.fqdn}"]
}
Единственное предостережение для этого последнего ресурса состоит в том, что он будет создавать один экземпляр ресурса для каждого
сертификат запрошен, но каждый экземпляр будет зависеть от всех FQDN во всех доменах и
субдомены. Это ни на что не повлияет в AWS, но код terraform не будет продолжен / завершен
пока не будут выданы все сертификаты.
Это должно работать за один запуск приложения без необходимости -target
каких-либо ресурсов за первый проход,
хотя, по-видимому, существует известная проблема около , сколько времени требуется для проверки
завершить когда
выполняется через terraform, и по этой причине может потребоваться второй проход, хотя и без изменения кода или планирования / применения вызова.