Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

creating CloudFront Distribution: InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain #55

Closed
archenroot opened this issue Nov 26, 2019 · 10 comments

Comments

@archenroot
Copy link

archenroot commented Nov 26, 2019

This has been discussed on closed issues, but I am having issue with terraform to retreive cert from us-east-1 region and apply it with Cloudformation in eu-west-1 region.

My config is like this:

provider "aws" {
  //alias = "ireland"
  version                 = "~> 2.0"
  region                  = var.region
  profile                 = var.profile
  shared_credentials_file = var.shared_credentials_file

}

provider "aws" {
  alias = "virginia"
  version                 = "~> 2.0"
  region                  = "us-east-1" //var.region
  profile                 = var.profile
  shared_credentials_file = var.shared_credentials_file
}

# This is problematic, as I cannot use variables in this block
# Tthere are 2 options, env variables switching and or backend-config block support

terraform {

  backend "s3" {
    bucket = "dip2-terraform-state-xxxxxxxx" //var.terraform_state_s3_bucket
    encrypt = true
    profile = "dip2-devops-dev"
    shared_credentials_file = "~/.aws/credentials"
    key    = "flexportal-www" //var.namespace
    region = "eu-west-1" //var.region
  }
}

NOTE: This query works fine to obtain ARN
data "aws_acm_certificate" "cert_flexportal_dev" {
  domain = "flexportal-www.dev.dip2.alpiq.services"
  statuses = ["ISSUED"]
  provider = aws.virginia

}

module "cloudfront_s3_cdn_waf" {

  source                   = "./../../modules/composites/aws_cloudfront_s3_cdn_waf"
  namespace                = var.namespace
  stage                    = var.stage
  name                     = "dip2"
  //attributes               = {}
  # Certificate
But here it won't create CF distro, it fails on error
  acm_certificate_arn = data.aws_acm_certificate.cert_flexportal_dev.arn //var.acm_public_certificate_arn

  # DNS
  dns_parent_zone_name         = var.dns_public_parent_zone_name
  dns_private_zone             = var.dns_private_zone

  use_regional_s3_endpoint = true
  origin_force_destroy     = true
  cors_allowed_headers     = ["*"]
  cors_allowed_methods     = ["GET", "HEAD", "PUT"]
  cors_allowed_origins     = ["*.alpiq.services"]
  cors_expose_headers      = ["ETag"]
  log_prefix               = var.namespace
  delimiter                = var.delimiter
  bucket_acl               = var.bucket_acl
  aliases = var.cf_dns_aliases




  # We do not deploy code via Terraform, but later inject code into bucket via Jenkins
  //release_artifact_path = ""

}

resource "aws_s3_bucket_object" "index" {
  provider = aws
  bucket       = module.cloudfront_s3_cdn_waf.s3_bucket
  key          = "index.html"
  source       = "${path.module}/index.html"
  content_type = "text/html"
  etag         = md5(file("${path.module}/index.html"))
}

So when Cloudformation request happen I see in the post method in TF_LOG file:
nonearn:aws:acm:us-east-1:account number:certificate/cert number>

And its correct ARN its correct...

@archenroot
Copy link
Author

archenroot commented Nov 26, 2019

I tried to reissue cert, also tried to generate cert via terraform but hit some other bug:
hashicorp/terraform-provider-aws#11024

Still, when I review the cloudfront config, it points to correct ARN in virginia region, but while using eu-west-1 region for cloudfront deploy and use this us-east-1 arn, it fails.....

~ viewer_certificate {
          + acm_certificate_arn            = "arn:aws:acm:us-east-1:387170473300:certificate/b080d944-3501-4451-b452-061f5d3453d5"
          ~ cloudfront_default_certificate = true -> false
            minimum_protocol_version       = "TLSv1"
          + ssl_support_method             = "sni-only"
        }
    }

@swedstrom
Copy link

swedstrom commented Jan 10, 2020

@aknysh
Copy link
Member

aknysh commented Jan 15, 2020

CloudFront certs must be created in the us-east-1 region, even if your origin is in a different one
See https://github.com/cloudposse/terraform-root-modules/blob/master/aws/acm-cloudfront/main.tf for a working example

@x80486
Copy link

x80486 commented Oct 18, 2020

I'm running into a similar issue. I'm using this module to create a static website. This is (an excerpt of) the configuration I have:

resource aws_route53_zone "default" {
  name = var.domain_name

  tags = local.tags
}

module "acm_request_certificate" {
  source = "git::https://github.com/cloudposse/terraform-aws-acm-request-certificate.git?ref=tags/0.7.0"

  depends_on = [aws_route53_zone.default]

  domain_name                       = var.domain_name
  process_domain_validation_options = true
  subject_alternative_names         = ["*.${var.domain_name}"]
  wait_for_certificate_issued       = var.wait_for_certificate_issued
  zone_name                         = var.domain_name

  tags = local.tags
}

module "cloudfront_s3_cdn" {
  source = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=tags/0.35.0"

  acm_certificate_arn      = module.acm_request_certificate.arn
  aliases                  = [var.domain_name, "www.${var.domain_name}"]
  allowed_methods          = ["GET", "HEAD"]
  compress                 = true
  dns_alias_enabled        = true
  error_document           = "not_found.html"
  namespace                = var.company_prefix
  name                     = var.name
  origin_force_destroy     = true
  parent_zone_id           = aws_route53_zone.default.zone_id
  stage                    = var.stage
  use_regional_s3_endpoint = true
  website_enabled          = true

  tags = local.tags
}

It always fails the first time with:

Error: error creating CloudFront Distribution: InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain.
	status code: 400, request id: bfc311ca-052f-5269-92b0-e66070178e7d

  on .terraform/modules/cloudfront_s3_cdn/main.tf line 184, in resource "aws_cloudfront_distribution" "default":
 184: resource "aws_cloudfront_distribution" "default" {

I have to run this always for the second time. I'm using us-east-1 by default on everything:

variable "aws_region" {
  description = "The AWS region to deploy to"
  type        = string
  default     = "us-east-1"
}

@aknysh
Copy link
Member

aknysh commented Oct 18, 2020

@x80486 looks like it's a race condition.
Certificate is not ready yet (issued, but not validated), but terraform thinks it's ready and starts to provision the distribution.
There is not a good way to solve it since it's TF that gets the cert ARN and thinks it's time to start creating the distribution.
If you are using TF 0.13, try to add depends_on to the module "cloudfront_s3_cdn" to depend on module "acm_request_certificate".
Or you can always apply in two stages using -target

@x80486
Copy link

x80486 commented Oct 18, 2020

Why I didn't think about that depends_on! 🥳 ...that did the trick! Thanks, @aknysh!

I'll check the apply in two stages using -target approach.

@sdanieru
Copy link

CloudFront certs must be created in the us-east-1 region, even if your origin is in a different one
See https://github.com/cloudposse/terraform-root-modules/blob/master/aws/acm-cloudfront/main.tf for a working example

@aknysh This link is dead; can you provide a link to a current working example of how to do this?

@sdanieru
Copy link

thanks @aknysh, but it's not clear to me how I can use this example. Forgive me for what is probably a basic question as I'm new to Terraform. I have an existing certificate already in us-east-1 which I would like the module to use, but would like the module to create the rest of the objects (bucket, etc.) to us-west-2.

If I do something like this:

provider "aws" {
  region = "us-west-2"
}

provider "aws" {
  alias = "east"
  region = "us-east-1"
}

module "cloudfront_s3_cdn" {
  source              = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=0.40.0"
  namespace           = "acme"
  stage               = "staging"
  name                = "my-website"
  dns_alias_enabled   = true
  aliases             = ["my-website.example.com"]
  parent_zone_name    = "example.com"
}

How do I then specify for the module that it should use provider = aws.east for the acm certificate, or is there a particular alias I should be using for us-east-1 that the module is expecting to use when it looks for an existing certificate?

@Nuru
Copy link
Contributor

Nuru commented May 14, 2021

Closing as fixed by #26. If people are still having problems with current Terraform providers and Cloud Posse modules, please create a new issue.

@Nuru Nuru closed this as completed May 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants