Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform AWS ACM certificates in us-east-1 for resources in eu-west-1

I have a terraform module that provisions resources primarily in eu-west-1. I need an ACM certificate to attach to a Cloudfront distribution. The certificate must be provisioned in us-east-1.

I have thus configured two providers:

provider "aws" {
  version = "~> 1.0"
  region = "eu-west-1"
}

provider "aws" {
  version = "~> 1.0"
  region = "us-east-1"
  alias = "us-east-1"
}

In my module, I provision the certificate like so:

resource "aws_acm_certificate" "cert" {
  provider = "aws.us-east-1"
  domain_name = "${var.domain_name}"
  validation_method = "DNS"
  tags = "${var.tags}"

  lifecycle {
    create_before_destroy = true
  }
}

Problem #1: I tried to import my existing ACM certificate using:

terraform import module.mymod.aws_acm_certificate.cert arn:aws:acm:us-east-1:xyz:certificate/uuid

This fails with: "Could not find certificate with id". Is terraform looking in the wrong region? I confirmed with the aws CLI that the certificate does indeed exist (e.g. no typos in the ARN).

Ok, so I figured I could just create new certificate. This does work, and I now have two certificates, but I then run into problem #2:

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.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl = 60
}

This attempts to set up DNS validation for ACM. The hosted zone exists in eu-west-1, so I'm expecting problems here. However, this still fails with "Could not find certificate ...", and I'm assuming terraform gets confused about regions. I tried adding provider = "aws.us-east-1" to this resource as well, but it still fails the same way.

So, no matter what I do, Terraform is unable to locate my certificate, even it has created it itself. Am I doing something wrong?

like image 742
Christian Johansen Avatar asked Aug 23 '18 14:08

Christian Johansen


People also ask

How do I use ACM certificates in different regions?

Resolution. You can't migrate an existing certificate in ACM from one AWS Region to another. Instead, you must import or create a certificate in the target Region. To associate an ACM certificate with a CloudFront distribution, you must import or create the certificate in US East (N.

Are AWS certificates region specific?

Short description. You can't export an ACM certificate from one AWS Region to another or from one AWS account to another. This is because the default AWS Key Management Service (AWS KMS) key used to encrypt the private key of the certificate is unique for each AWS Region and AWS account.

Is ACM a global service?

Proven Global Expertise Since 1975, ACM Global Laboratories has been a recognized leader in global clinical trial testing services. Through wholly-owned facilities and partner laboratories, we support clinical trials in more than 65 countries around the globe.


2 Answers

Turns out my problem was with aws_acm_certificate_validation. By specifying the provider in the same region as the certificate, it was all resolved.

resource "aws_acm_certificate_validation" "cert" {
  provider = "aws.us-east-1" # <== Add this
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}
like image 96
Christian Johansen Avatar answered Nov 11 '22 15:11

Christian Johansen


Since Terraform 0.12.14 Quoted references are deprecated. So the accepted answer above should be like this if you're using a version >= 0.12.14 or Terraform 1.x

resource "aws_acm_certificate_validation" "cert" {
  provider = aws.us-east-1 # <== Add this without quotes
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}

To avoid a Warning like this:

Warning: Quoted references are deprecated

52: provider = "aws.us-east-1"

In this context, references are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted references are now deprecated and will be removed in a future version of Terraform. Remove the quotes surrounding this reference to silence this warning.

(and one more similar warning elsewhere)

For more info, see the release notes discussions at hashicorp: https://discuss.hashicorp.com/t/terraform-0-12-14-released/3898

like image 25
roxx0r.munich Avatar answered Nov 11 '22 16:11

roxx0r.munich