acm (terraform)

Sample: Domains for Cloudfront & ELBs

Eg: strategies

<env>/main.tf

provider "aws" { # Provider for AWS ACM certificates needed by Cloudfront

  alias = "us_east_1"

  default_tags {

    tags = {

      env       = local.env

      ci        = local.ci

      department= local.department

      program   = local.program

    }

  }

  region = "us-east-1"

}


# ACM

module "acm" {

  source = "../modules/acm"

  providers = {

    aws.nvirginia = aws.us_east_1

  }


  create_custom_domain = local.acm_tls_certificate_creation

  cf_fqdn  = local.acm_cf_fqdn

  cf_sans  = local.acm_cf_sans

  elb_fqdn = local.acm_elb_fqdn

  elb_sans = local.acm_elb_sans

}

<env>/output.tf

output "cf_certificate_validation_data" {

  value       = module.acm.cf_certificate_domain_validation_options

  description = "Data for validating the certificate via DNS CNAME record"

}


output "lb_certificate_validation_data" {

  value       = module.acm.lb_certificate_domain_validation_options

  description = "Data for validating the certificate via DNS CNAME record"

}

modules/acm/variables.tf

variable "create_custom_domain" {}


#Cloudfront

variable "cf_fqdn" {

  description = "CloudFront Fully qualified domain name"

  type        = string

  nullable    = false

}


# ELBs

variable "elb_fqdn" {

  description = "ELB Fully qualified domain name"

  type        = string

  nullable    = false

}

modules/acm/cert-cf.tf

# Amazon Certificate Manager (acm)

# ################################



terraform {

  required_providers {

    aws = {

      source                = "hashicorp/aws"

      configuration_aliases = [aws.nvirginia]

    }

  }

}



# Create certificate for CloudFront

resource "aws_acm_certificate" "cloudfront" {

  provider = aws.nvirginia

  lifecycle {

    create_before_destroy = true

  }

  count = var.create_custom_domain ? 1 : 0


  domain_name = var.cf_fqdn

  #subject_alternative_names = var.sans #(Optional) Set of domains that should be SANs in the issued certificate. To remove all elements of a previously configured list, set this value equal to an empty list ([]) or use the terraform taint command to trigger recreation

  validation_method = "DNS"

}


# Represents a successful validation of an ACM certificate (needs Route 53 record configured)

resource "aws_acm_certificate_validation" "cloudfront" {

  provider = aws.nvirginia

  timeouts {

    create = "5m" # Default 75m

  }

  count = var.create_custom_domain ? 1 : 0


  certificate_arn = aws_acm_certificate.cloudfront[0].arn

}

modules/acm/cert-lb.tf

# Amazon Certificate Manager (acm)

# ################################


# Create certificate for ELBs

resource "aws_acm_certificate" "elbs" {

  # provider = aws.default

  lifecycle {

    create_before_destroy = true

  }

  count = var.create_custom_domain ? 1 : 0


  domain_name = var.elb_fqdn

  #subject_alternative_names = var.sans #(Optional) Set of domains that should be SANs in the issued certificate. To remove all elements of a previously configured list, set this value equal to an empty list ([]) or use the terraform taint command to trigger recreation

  validation_method = "DNS"

}


# Represents a successful validation of an ACM certificate (needs Route 53 record configured)

resource "aws_acm_certificate_validation" "elbs" {

  timeouts {

    create = "5m" # Default 75m

  }

  count = var.create_custom_domain ? 1 : 0


  certificate_arn = aws_acm_certificate.elbs[0].arn

}

modules/acm/output.tf

#CloudFront certificate

output "cf_certificate_domain_validation_options" {

  value       = try(aws_acm_certificate.cloudfront[0].domain_validation_options, "")

  description = "Certificate domain name validation options"

}


output "cf_certificate_arn" {

  value       = try(aws_acm_certificate_validation.cloudfront[0].certificate_arn, "")

  description = "Certificate ARN"

}



#Load Balancers certificate

output "lb_certificate_domain_validation_options" {

  value       = try(aws_acm_certificate.elbs[0].domain_validation_options, "")

  description = "Certificate domain name validation options"

}

output "lb_certificate_arn" {

  value       = try(aws_acm_certificate_validation.elbs[0].certificate_arn, "")

  description = "Certificate ARN"

}



Sample: Domain & subject alternate names for Cloundfront

Eg: otvalidation

<env>/main.tf

  acm_tls_certificate_creation = true

  acm_cf_fqdn                    = "whatever.domain.int"

  acm_cf_sans                    = ["another.domain.int"]

  acm_elb_fqdn                    = "api.whatever.domain.int"

  acm_elb_sans                    = ["api.another.domain.int"]

<env>/output.tf

output "certificate_arn" {

  value       = try(aws_acm_certificate_validation.validation[0].certificate_arn, "")

  description = "Certificate ARN"

}


output "certificate_domain_validation" {

  value       = try(aws_acm_certificate.certificate[0].domain_validation_options, "")

  description = "Certificate domain name validation options"

}

modules/acm/variables.tf

variable "create_custom_domain" {}

variable "fqdn" {

  description = "Fully qualified domain name"

  type        = string

  nullable    = false

}

variable "sans" {}

modules/acm/acm.tf

# Amazon Certificate Manager (acm)

# ################################


provider "aws" {

  region = "us-east-1" #Cloudfront requires certificate in us-east-1

}


# Create Certificate

resource "aws_acm_certificate" "certificate" {

  lifecycle {

    create_before_destroy = true

  }

  count                     = var.create_custom_domain ? 1 : 0


  domain_name = var.fqdn

  subject_alternative_names = var.sans #(Optional)

  validation_method = "DNS"

}


# Represents a successful validation of an ACM certificate (needs Route 53 record configured)

resource "aws_acm_certificate_validation" "validation" {

  timeouts {

    create = "1m" # Default 75m

  }


  count           = var.create_custom_domain ? 1 : 0


  certificate_arn = aws_acm_certificate.certificate[0].arn

}

modules/acm/output.tf

output "certificate_arn" {

  value       = try(aws_acm_certificate_validation.validation[0].certificate_arn, "")

  description = "Certificate ARN"

}


output "certificate_domain_validation" {

  value       = try(aws_acm_certificate.certificate[0].domain_validation_options, "")

  description = "Certificate domain name validation options"

}