Nov 3, 2019
I wanted to create a cert in ACM with an associated Subject Alternative Name (SAN) that belonged to a different account.
Here’s an example of part of the config I wrote to do that after getting a bunch
of Access Denied
errors and saying some swear words.
# -- declare provider for dev account
provider "aws" {
max_retries = "5"
# create an alias to differentiate between the two
alias = "dev"
region = "us-west-2"
profile = "dev"
assume_role {
role_arn = "arn:aws:iam::112233445556:role/DevRole"
}
}
# --- declare provider for domains account
provider "aws" {
max_retries = "5"
alias = "route53"
region = "us-west-2"
profile = "route53"
assume_role {
role_arn = "arn:aws:iam::22334455667:role/Route53"
}
}
resource "aws_route53_zone" "zone" {
name = "${var.hosted_zone_name}"
private_zone = false
}
resource "aws_route53_zone" "zone_alt" {
# grab alias to the "domains" account profile
provider = "aws.route53"
name = "example.com"
}
# ---- CERTS -----
resource "aws_acm_certificate" "default" {
# registered in "dev" account
domain_name = "dev.example.com"
validation_method = "DNS"
# --- Here's the "vanity" domain to be associated with this cert.
# This name is registered in "domains" account reached by
# an assumed role
subject_alternative_names = "example.com"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
name = "${aws_acm_certificate.default.domain_validation_options.0.resource_record_name}"
type = "${aws_acm_certificate.default.domain_validation_options.0.resource_record_type}"
zone_id = "${data.aws_route53_zone.zone.id}"
records = ["${aws_acm_certificate.default.domain_validation_options.0.resource_record_value}"]
ttl = 60
}
resource "aws_route53_record" "cert_validation_alt1" {
name = "${aws_acm_certificate.default.domain_validation_options.1.resource_record_name}"
type = "${aws_acm_certificate.default.domain_validation_options.1.resource_record_type}"
zone_id = "${aws_route53_zone.zone_alt.zone_id}"
records = ["${aws_acm_certificate.default.domain_validation_options.1.resource_record_value}"]
ttl = 60
}
resource "aws_acm_certificate_validation" "cert" {
certificate_arn = "${aws_acm_certificate.default.arn}"
validation_record_fqdns = [
"${aws_route53_record.cert_validation.fqdn}",
"${aws_route53_record.cert_validation_alt1.fqdn}",
]
}
Running a terraform plan
and terraform apply
on this config will create a new certificate in the
dev account and validate it with DNS validation. Additionally a CNAME
record will be written into the domains account and that SAN will be
validated, too.
Now we can use a “vanity” CNAME like my-app.example.com to point to a record in the dev account, my-app.dev.example.com. That record is the ALIAS to a load balancer hostname that has the cert created above.
Related tags: