TerraformPilot

DevOps

Terraform for Confidential Computing: Deploy Nitro Enclaves and TEEs on AWS

Deploy confidential computing with Terraform on AWS. Provision Nitro Enclaves for data-in-use protection, configure KMS attestation policies

LLuca Berton2 min read

Confidential computing protects data while it's being processed — not just at rest or in transit. Gartner highlights it as a 2026 strategic trend as sensitive AI and analytics workloads move to shared cloud infrastructure. AWS Nitro Enclaves provide hardware-isolated environments where even AWS operators can't access your data during processing.

Why Confidential Computing Matters

#

Traditional encryption protects data at rest (S3, EBS) and in transit (TLS), but data must be decrypted for processing. Confidential computing closes this gap:

Data StateProtectionAWS Service
At restAES-256 encryptionKMS, S3 SSE, EBS
In transitTLS 1.3ALB, CloudFront, VPN
In useHardware isolationNitro Enclaves

EC2 with Nitro Enclaves

#
resource "aws_instance" "confidential" {
  ami           = data.aws_ami.al2023.id
  instance_type = "m5.2xlarge"  # Must support Nitro Enclaves
  subnet_id     = var.private_subnet_id
 
  enclave_options {
    enabled = true  # Enable Nitro Enclaves on this instance
  }
 
  # Allocate resources for the enclave
  user_data = base64encode(<<-EOF
    #!/bin/bash
    # Install Nitro Enclaves CLI
    amazon-linux-extras install aws-nitro-enclaves-cli -y
    yum install aws-nitro-enclaves-cli-devel -y
 
    # Configure enclave allocator
    cat > /etc/nitro_enclaves/allocator.yaml <<'ALLOC'
    memory_mib: 4096
    cpu_count: 2
    ALLOC
 
    # Start the allocator service
    systemctl enable nitro-enclaves-allocator
    systemctl start nitro-enclaves-allocator
    systemctl enable docker
    systemctl start docker
  EOF
  )
 
  metadata_options {
    http_endpoint = "enabled"
    http_tokens   = "required"  # IMDSv2 only
  }
 
  root_block_device {
    encrypted   = true
    volume_size = 50
    volume_type = "gp3"
  }
 
  tags = {
    Name      = "confidential-compute"
    Component = "confidential-computing"
  }
}
 
# Instance types that support Nitro Enclaves
# m5.xlarge, m5.2xlarge, m5.4xlarge, m5.8xlarge, m5.12xlarge, m5.16xlarge, m5.24xlarge
# c5.xlarge+, r5.xlarge+, c6i.xlarge+, m6i.xlarge+, r6i.xlarge+

KMS Key with Attestation Policy

#

KMS can restrict key access to only verified Nitro Enclaves:

resource "aws_kms_key" "enclave_only" {
  description = "Key accessible only from verified Nitro Enclaves"
 
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "RootAccess"
        Effect    = "Allow"
        Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" }
        Action    = "kms:*"
        Resource  = "*"
      },
      {
        Sid       = "EnclaveDecrypt"
        Effect    = "Allow"
        Principal = { AWS = aws_iam_role.enclave.arn }
        Action    = ["kms:Decrypt", "kms:GenerateDataKey"]
        Resource  = "*"
        Condition = {
          StringEqualsIgnoreCase = {
            # Only allow decryption from a specific enclave image
            "kms:RecipientAttestation:PCR0" = var.enclave_pcr0_hash
          }
        }
      }
    ]
  })
 
  tags = {
    Component = "confidential-computing"
    KeyUsage  = "enclave-only"
  }
}
 
resource "aws_kms_alias" "enclave" {
  name          = "alias/enclave-key"
  target_key_id = aws_kms_key.enclave_only.id
}

IAM Role for Enclave Workloads

#
resource "aws_iam_role" "enclave" {
  name = "enclave-workload"
 
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}
 
resource "aws_iam_role_policy" "enclave_kms" {
  name = "enclave-kms-access"
  role = aws_iam_role.enclave.id
 
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["kms:Decrypt", "kms:GenerateDataKey"]
        Resource = aws_kms_key.enclave_only.arn
      },
      {
        Effect   = "Allow"
        Action   = ["s3:GetObject"]
        Resource = "${aws_s3_bucket.encrypted_data.arn}/*"
      }
    ]
  })
}
 
resource "aws_iam_instance_profile" "enclave" {
  name = "enclave-workload"
  role = aws_iam_role.enclave.name
}

Encrypted Data Pipeline

#
# S3 bucket for encrypted input data
resource "aws_s3_bucket" "encrypted_data" {
  bucket = "confidential-data-${data.aws_caller_identity.current.account_id}"
}
 
resource "aws_s3_bucket_server_side_encryption_configuration" "encrypted" {
  bucket = aws_s3_bucket.encrypted_data.id
 
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.enclave_only.arn
    }
    bucket_key_enabled = true
  }
}
 
# VPC endpoint — data never leaves AWS network
resource "aws_vpc_endpoint" "s3" {
  vpc_id       = var.vpc_id
  service_name = "com.amazonaws.${var.region}.s3"
  route_table_ids = var.private_route_table_ids
}
 
resource "aws_vpc_endpoint" "kms" {
  vpc_id              = var.vpc_id
  service_name        = "com.amazonaws.${var.region}.kms"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.private_subnet_ids
  security_group_ids  = [aws_security_group.endpoints.id]
  private_dns_enabled = true
}

Network Isolation

#
resource "aws_security_group" "enclave_instance" {
  name_prefix = "enclave-"
  vpc_id      = var.vpc_id
 
  # No inbound from internet
  # Only outbound to VPC endpoints
  egress {
    from_port       = 443
    to_port         = 443
    protocol        = "tcp"
    security_groups = [aws_security_group.endpoints.id]
    description     = "HTTPS to VPC endpoints only"
  }
 
  tags = { Component = "confidential-computing" }
}

Use Cases for Confidential Computing

#
Use CaseWhat's ProtectedWhy Enclave
AI model inference on private dataPatient records, financial dataData decrypted only inside enclave
Multi-party computationCombined datasets from multiple orgsNo party sees the other's raw data
Private key operationsTLS private keys, signing keysKeys never exist in main memory
Regulated data processingHIPAA, PCI, GDPR workloadsProvable isolation for compliance
Secure credential managementAPI keys, database passwordsCredentials isolated from host OS

Hands-On Courses

#

Conclusion

#

Confidential computing closes the last encryption gap — protecting data while it's being processed. Use Terraform to provision Nitro Enclave-enabled EC2 instances, KMS keys with attestation policies that only allow decryption from verified enclaves, and network isolation via VPC endpoints. Essential for AI inference on sensitive data, multi-party analytics, and regulated workloads.

#Terraform#Security#AWS#Confidential Computing#DevOps

Share this article