Skip to main content

Terraform for Post-Quantum Cryptography: Migrate TLS and KMS to PQC on AWS

Key Takeaway

Prepare for post-quantum cryptography with Terraform. Configure hybrid TLS policies, KMS key types, ACM certificates, and S3 encryption for NIST PQC standards compliance.

Table of Contents

Post-quantum cryptography (PQC) is one of the most practical security shifts underway in 2026. NIST finalized three PQC standards in 2024 (ML-KEM, ML-DSA, SLH-DSA), and AWS is rolling out PQC-capable services. The migration pressure is real — “harvest now, decrypt later” attacks mean data encrypted today could be vulnerable to future quantum computers.

This guide shows how to use Terraform to start migrating your AWS infrastructure toward quantum-safe cryptography.

The PQC Landscape in 2026

NIST StandardReplacesPurposeAWS Support
ML-KEM (Kyber)RSA, ECDH key exchangeKey encapsulationKMS, ACM, S2N-TLS
ML-DSA (Dilithium)RSA, ECDSA signaturesDigital signaturesComing 2026
SLH-DSA (SPHINCS+)RSA, ECDSA (stateless)Hash-based signaturesLimited

Step 1: TLS Policy with Hybrid PQC

AWS ALBs and CloudFront support hybrid PQC TLS policies that combine classical and post-quantum key exchange:

# ALB with hybrid PQC TLS policy
resource "aws_lb" "main" {
  name               = "app-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = var.public_subnet_ids
}

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.main.arn
  port              = 443
  protocol          = "HTTPS"
  certificate_arn   = aws_acm_certificate.main.arn

  # Hybrid PQC policy — supports ML-KEM + classical ECDH
  ssl_policy = "ELBSecurityPolicy-TLS13-1-3-2024-PQ"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

CloudFront with PQC

resource "aws_cloudfront_distribution" "main" {
  # ...

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate.main.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.3_2024_PQ"  # Hybrid PQC
  }
}

Step 2: KMS Keys for Quantum-Safe Encryption

# Standard KMS key — start tracking which keys need migration
resource "aws_kms_key" "sensitive_data" {
  description             = "Encryption for sensitive data (PQC migration candidate)"
  deletion_window_in_days = 30
  enable_key_rotation     = true

  # Tag keys by sensitivity for PQC migration planning
  tags = {
    DataClassification = "confidential"
    PQCMigration       = "priority-1"     # Highest priority for migration
    EncryptionType     = "symmetric-256"   # AES-256 is quantum-safe for symmetric
  }
}

# Asymmetric key — these are vulnerable to quantum attacks
resource "aws_kms_key" "signing_key" {
  description              = "Code signing key (PQC migration needed)"
  key_usage                = "SIGN_VERIFY"
  customer_master_key_spec = "RSA_4096"  # Will need PQC replacement

  tags = {
    PQCMigration = "priority-1"
    KeyType      = "asymmetric-rsa"
    Warning      = "Vulnerable to quantum — migrate when PQC KMS available"
  }
}

# Symmetric keys (AES-256) are already quantum-safe for encryption
resource "aws_kms_key" "storage_key" {
  description              = "Storage encryption key"
  customer_master_key_spec = "SYMMETRIC_DEFAULT"  # AES-256 — quantum safe
  enable_key_rotation      = true

  tags = {
    PQCMigration = "not-required"  # Symmetric encryption is safe
    KeyType      = "symmetric-aes256"
  }
}

Step 3: S3 Encryption Audit

# Enforce server-side encryption on all S3 buckets
resource "aws_s3_bucket_server_side_encryption_configuration" "sensitive" {
  bucket = aws_s3_bucket.sensitive.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.sensitive_data.arn
    }
    bucket_key_enabled = true  # Reduces KMS API calls
  }
}

# Block unencrypted uploads
resource "aws_s3_bucket_policy" "deny_unencrypted" {
  bucket = aws_s3_bucket.sensitive.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "DenyUnencryptedUploads"
        Effect    = "Deny"
        Principal = "*"
        Action    = "s3:PutObject"
        Resource  = "${aws_s3_bucket.sensitive.arn}/*"
        Condition = {
          StringNotEquals = {
            "s3:x-amz-server-side-encryption" = "aws:kms"
          }
        }
      }
    ]
  })
}

Step 4: VPN with PQC Key Exchange

# AWS Site-to-Site VPN supports hybrid PQC
resource "aws_vpn_connection" "pqc" {
  customer_gateway_id = aws_customer_gateway.main.id
  vpn_gateway_id      = aws_vpn_gateway.main.id
  type                = "ipsec.1"

  # Tunnel options with PQC-capable settings
  tunnel1_ike_versions                 = ["ikev2"]
  tunnel1_phase1_dh_group_numbers      = [21]     # Check AWS docs for PQC DH groups
  tunnel1_phase1_encryption_algorithms = ["AES256-GCM-16"]
  tunnel1_phase1_integrity_algorithms  = ["SHA2-384"]

  tags = {
    PQCStatus = "hybrid-pqc-enabled"
  }
}

Migration Checklist Module

Create a module that audits your infrastructure’s PQC readiness:

# modules/pqc-audit/main.tf
# Tag all cryptographic resources for migration tracking

variable "resources" {
  type = map(object({
    arn             = string
    key_type        = string  # symmetric, rsa, ecdsa, ecdh
    data_sensitivity = string  # public, internal, confidential, restricted
  }))
}

locals {
  # Symmetric AES is quantum-safe, asymmetric is not
  vulnerable_resources = {
    for k, v in var.resources : k => v
    if contains(["rsa", "ecdsa", "ecdh"], v.key_type)
  }

  priority_map = {
    restricted   = "P0-immediate"
    confidential = "P1-high"
    internal     = "P2-medium"
    public       = "P3-low"
  }
}

output "migration_report" {
  value = {
    total_resources    = length(var.resources)
    vulnerable         = length(local.vulnerable_resources)
    quantum_safe       = length(var.resources) - length(local.vulnerable_resources)
    priority_breakdown = {
      for k, v in local.vulnerable_resources :
      k => local.priority_map[v.data_sensitivity]
    }
  }
}

What’s Quantum-Safe vs What Needs Migration

AlgorithmQuantum Safe?Terraform Resources Affected
AES-256 (symmetric)✅ YesS3 SSE, EBS, RDS encryption
SHA-256, SHA-384✅ YesIntegrity checks
RSA-2048/4096❌ NoKMS asymmetric keys, ACM certs
ECDSA P-256/P-384❌ NoKMS signing keys, ACM certs
ECDH (TLS key exchange)❌ NoALB/CloudFront TLS policies
ML-KEM (Kyber)✅ YesNew hybrid TLS policies

Hands-On Courses

Conclusion

Post-quantum migration starts now — not when quantum computers arrive. Use Terraform to audit your cryptographic resources, tag them by migration priority, and start adopting hybrid PQC TLS policies on ALBs and CloudFront. Symmetric encryption (AES-256) is already quantum-safe; focus migration efforts on asymmetric keys (RSA, ECDSA) used for TLS, code signing, and key exchange.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.