Files
terraform-foundation/terraform/modules/acm-certificate/main.tf
Greg Hendrickson 6136cde9bb feat: Terraform Foundation - AWS Landing Zone
Enterprise-grade multi-tenant AWS cloud foundation.

Modules:
- GitHub OIDC for keyless CI/CD authentication
- IAM account settings and security baseline
- AWS Config Rules for compliance
- ABAC (Attribute-Based Access Control)
- SCPs (Service Control Policies)

Features:
- Multi-account architecture
- Cost optimization patterns
- Security best practices
- Comprehensive documentation

Tech: Terraform, AWS Organizations, IAM Identity Center
2026-02-02 02:57:23 +00:00

164 lines
4.5 KiB
HCL

################################################################################
# ACM Certificate Module
#
# SSL/TLS certificates with:
# - DNS or email validation
# - Automatic Route53 validation records
# - SAN (Subject Alternative Names) support
# - Wildcard certificates
#
# Usage:
# module "cert" {
# source = "../modules/acm-certificate"
#
# domain_name = "example.com"
# zone_id = "Z1234567890"
#
# subject_alternative_names = [
# "*.example.com",
# "api.example.com"
# ]
# }
################################################################################
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
variable "domain_name" {
type = string
description = "Primary domain name for the certificate"
}
variable "subject_alternative_names" {
type = list(string)
default = []
description = "Additional domain names (SANs) for the certificate"
}
variable "zone_id" {
type = string
default = null
description = "Route53 zone ID for DNS validation (null for email validation)"
}
variable "validation_method" {
type = string
default = "DNS"
description = "Validation method: DNS or EMAIL"
validation {
condition = contains(["DNS", "EMAIL"], var.validation_method)
error_message = "Must be DNS or EMAIL"
}
}
variable "wait_for_validation" {
type = bool
default = true
description = "Wait for certificate validation to complete"
}
variable "validation_timeout" {
type = string
default = "45m"
description = "Timeout for certificate validation"
}
variable "tags" {
type = map(string)
default = {}
}
################################################################################
# ACM Certificate
################################################################################
resource "aws_acm_certificate" "main" {
domain_name = var.domain_name
subject_alternative_names = var.subject_alternative_names
validation_method = var.validation_method
lifecycle {
create_before_destroy = true
}
tags = merge(var.tags, { Name = var.domain_name })
}
################################################################################
# DNS Validation Records
################################################################################
resource "aws_route53_record" "validation" {
for_each = var.validation_method == "DNS" && var.zone_id != null ? {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
} : {}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = var.zone_id
}
################################################################################
# Certificate Validation
################################################################################
resource "aws_acm_certificate_validation" "main" {
count = var.wait_for_validation ? 1 : 0
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = var.validation_method == "DNS" && var.zone_id != null ? [for record in aws_route53_record.validation : record.fqdn] : null
timeouts {
create = var.validation_timeout
}
}
################################################################################
# Outputs
################################################################################
output "certificate_arn" {
value = aws_acm_certificate.main.arn
description = "ARN of the certificate"
}
output "certificate_domain_name" {
value = aws_acm_certificate.main.domain_name
description = "Primary domain name"
}
output "certificate_status" {
value = aws_acm_certificate.main.status
description = "Certificate status"
}
output "validation_records" {
value = var.validation_method == "DNS" ? {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
type = dvo.resource_record_type
value = dvo.resource_record_value
}
} : null
description = "DNS validation records (if using DNS validation without auto Route53)"
}
output "validated_certificate_arn" {
value = var.wait_for_validation ? aws_acm_certificate_validation.main[0].certificate_arn : aws_acm_certificate.main.arn
description = "ARN of the validated certificate"
}