🚨 CMMC Phase One started November 10! Here's everything you need to know →

How to Configure Cloud Storage to Protect CUI at Rest: Terraform and Policy Examples for NIST SP 800-171 REV.2 / CMMC 2.0 Level 2 - Control - SC.L2-3.13.16

Practical, step-by-step Terraform and policy examples to enforce cryptographic protection of CUI at rest for NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 compliance.

•
April 13, 2026
•
5 min read

Share:

Schedule Your Free Compliance Consultation

Feeling overwhelmed by compliance requirements? Not sure where to start? Get expert guidance tailored to your specific needs in just 15 minutes.

Personalized Compliance Roadmap
Expert Answers to Your Questions
No Obligation, 100% Free

Limited spots available!

This post explains how small businesses can configure cloud storage to meet NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 control SC.L2-3.13.16 — which requires using cryptographic mechanisms to protect Controlled Unclassified Information (CUI) at rest — and includes actionable Terraform examples and policy snippets for AWS, Azure, and Google Cloud.

Understanding SC.L2-3.13.16: objectives and practical scope

SC.L2-3.13.16 requires that organizations apply cryptographic controls to protect the confidentiality of CUI when it is stored. For small businesses this means: identify all cloud buckets/volumes that may hold CUI, ensure server-side or client-side encryption is enabled with appropriate key management, enforce encryption policy automatically (deny unencrypted uploads), protect and audit keys, and document processes for key rotation and access control. The goal is not only to encrypt data, but to ensure encryption is consistently applied, auditable, and tied to strong key management policies.

Practical cloud configuration patterns

AWS: S3 + KMS + bucket policy + Terraform

Common pattern: enable SSE-KMS on S3 buckets, create a dedicated KMS key with key rotation enabled, restrict KMS key usage via a tight key policy, and add a bucket policy that denies PutObject if encryption headers are missing or not using the required algorithm. Example Terraform resources below demonstrate these elements for a small business that wants one KMS key per environment and denies unencrypted uploads.

# AWS: create KMS key and S3 bucket with default encryption and deny unencrypted uploads
resource "aws_kms_key" "cui" {
  description             = "CUI encryption key for production S3"
  enable_key_rotation     = true
  deletion_window_in_days = 30
}

resource "aws_s3_bucket" "cui" {
  bucket = "acme-cui-prod-bucket"
  acl    = "private"
  force_destroy = false

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm     = "aws:kms"
        kms_master_key_id = aws_kms_key.cui.key_id
      }
    }
  }
}

# Bucket policy: deny PutObject if the request does not specify SSE-KMS
resource "aws_s3_bucket_policy" "deny_unencrypted" {
  bucket = aws_s3_bucket.cui.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "DenyUnEncryptedObjectUploads"
        Effect    = "Deny"
        Principal = "*"
        Action    = "s3:PutObject"
        Resource  = "${aws_s3_bucket.cui.arn}/*"
        Condition = {
          StringNotEquals = {
            "s3:x-amz-server-side-encryption" = "aws:kms"
          }
        }
      }
    ]
  })
}

Azure: Storage Account with customer-managed key (CMK) in Key Vault

Use an Azure Key Vault key as a customer-managed key (CMK) for storage account encryption and enable system-assigned identity so the storage account can access the key. Enforce HTTPS-only and enable diagnostic logs for auditability. This Terraform snippet shows the core pieces; for production add RBAC on the Key Vault and soft-delete/ purge protection.

# Azure: Key Vault key and storage account using CMK
resource "azurerm_key_vault" "kv" {
  name                = "acme-cui-kv"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  tenant_id           = data.azurerm_client_config.current.tenant_id
  sku_name            = "standard"
  soft_delete_enabled = true
  purge_protection_enabled = true
}

resource "azurerm_key_vault_key" "cui_key" {
  name         = "cui-storage-key"
  key_vault_id = azurerm_key_vault.kv.id
  key_type     = "RSA"
  key_size     = 2048
}

resource "azurerm_storage_account" "cui" {
  name                     = "acmecuistorage"
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  account_tier             = "Standard"
  account_replication_type = "GRS"
  enable_https_traffic_only = true

  identity {
    type = "SystemAssigned"
  }

  encryption {
    services {
      blob  = { enabled = true }
      file  = { enabled = true }
      queue = { enabled = true }
    }
    key_source     = "Microsoft.Keyvault"
    key_vault_key_id = azurerm_key_vault_key.cui_key.id
  }
}

GCP: Cloud Storage with CMEK and Terraform

For Google Cloud, use Cloud KMS keys (CMEK) and set the bucket's default_kms_key_name so all new objects are encrypted with the CMEK. Also enable Bucket Lock and uniform bucket-level access for predictable ACL behavior and enable audit logs. The example below assumes you already have a KMS key ring.

# GCP: KMS CryptoKey and GCS bucket with default KMS key
resource "google_kms_crypto_key" "cui_key" {
  name            = "cui-key"
  key_ring        = google_kms_key_ring.ring.id
  rotation_period = "7776000s" # 90 days
}

resource "google_storage_bucket" "cui" {
  name                        = "acme-cui-prod-bucket"
  location                    = "US"
  uniform_bucket_level_access = true
  force_destroy               = false

  encryption {
    default_kms_key_name = google_kms_crypto_key.cui_key.id
  }
}

Compliance tips and best practices for small businesses

Actionable tips: (1) Create an inventory of buckets/disks and tag those that may hold CUI; (2) Enforce encryption in IaC (Terraform) and block unencrypted resource creation via policies or pipeline guardrails (e.g., Terraform checks, tfsec, pre-commit hooks, or cloud-native policy engines); (3) Use customer-managed keys (CMK/CMEK) where feasible so you control rotation and access; (4) Harden key policies: enforce least privilege, restrict principals and services that can use the key, and require separate IAM roles for key administration vs. day-to-day use; (5) Enable audit logging (CloudTrail, Azure Monitor, GCP Audit Logs) and S3/Blob access logging so you can prove encryption and access patterns for assessments.

Real-world scenarios and small-business examples

Example 1: A small engineering firm storing specification PDFs for DoD subcontractors. Tag buckets as "CUI", enforce SSE-KMS, and set Terraform plan checks so developers cannot create unencrypted buckets. Example 2: A vendor that shares CUI with partners — implement per-partner KMS keys and key usage policies, rotate keys quarterly (or enforced rotation), and require key approval workflows for granting decryption rights. Example 3: Legacy backups on object storage — run an inventory and migrate non-encrypted objects into new encrypted buckets using a batch job that reads and re-writes objects under the correct keys, then disable public access and add retention rules.

Risks of not implementing SC.L2-3.13.16 controls

Failing to implement these controls exposes CUI to unauthorized disclosure and increases risk of data breaches, contract noncompliance, loss of DoD or federal contracts, fines, and reputational damage. Operationally, unencrypted or inconsistently encrypted storage makes incident response and forensic validation harder: you can't prove data was protected, and you may be required to notify customers and regulators. From a security perspective, weak key management (shared accounts, no rotation, broad key policies) effectively nullifies encryption.

In summary, meeting SC.L2-3.13.16 for NIST SP 800-171 Rev.2 / CMMC 2.0 Level 2 is achievable for small businesses by combining strong key management, enforcing encryption through Terraform and cloud-native policies, and operationalizing audit and rotation processes. Use the provided Terraform patterns as a baseline, integrate policy checks into CI/CD, document key administration and rotation procedures, and regularly audit your inventory so CUI stays encrypted and auditable at rest.

 

Quick & Simple

Discover Our Cybersecurity Compliance Solutions:

Whether you need to meet and maintain your compliance requirements, help your clients meet them, or verify supplier compliance we have the expertise and solution for you

 CMMC Level 1 Compliance App

CMMC Level 1 Compliance

Become compliant, provide compliance services, or verify partner compliance with CMMC Level 1 Basic Safeguarding of Covered Contractor Information Systems requirements.
 NIST SP 800-171 & CMMC Level 2 Compliance App

NIST SP 800-171 & CMMC Level 2 Compliance

Become compliant, provide compliance services, or verify partner compliance with NIST SP 800-171 and CMMC Level 2 requirements.
 HIPAA Compliance App

HIPAA Compliance

Become compliant, provide compliance services, or verify partner compliance with HIPAA security rule requirements.
 ISO 27001 Compliance App

ISO 27001 Compliance

Become compliant, provide compliance services, or verify partner compliance with ISO 27001 requirements.
 FAR 52.204-21 Compliance App

FAR 52.204-21 Compliance

Become compliant, provide compliance services, or verify partner compliance with FAR 52.204-21 Basic Safeguarding of Covered Contractor Information Systems requirements.
 
Hello! How can we help today? 😃

Chat with Lakeridge

We typically reply within minutes