AWS KMS and Terraform Key Lifecycle Management

Managing encryption keys as code requires a clear understanding of how AWS Key Management Service integrates with Terraform, how key policies are expressed, and how multi-region and state encryption scenarios are handled. This article covers the complete lifecycle from initial key creation to policy updates, alias management, and audit alignment, using patterns that keep security consistent with infrastructure as code principles.

Prerequisites and Project Layout

Working with AWS KMS through Terraform assumes a baseline environment that is ready for secure infrastructure provisioning.

  • AWS CLI configured
  • Terraform installed
  • Basic understanding of encryption concepts
  • Resources that need encryption

A typical project structure for a focused KMS workspace is:

aws-kms-terraform/
├── main.tf
├── variables.tf
├── outputs.tf
└── terraform.tfvars

This layout separates provider configuration, key definitions, outputs, and variable values. Keeping the key policy in main.tf with variables for project name and environment enables reuse across teams.

Core KMS Key Resource

AWS Key Management Service is a managed service for creating and controlling encryption keys. Terraform models a key with the awskmskey resource. Common baseline arguments include description, deletionwindowindays, enablekey_rotation, policy, and tags.

A basic configuration defines a key with account root permissions and enables rotation:

```hcl
provider "aws" {
region = var.aws_region
}

resource "awskmskey" "main" {
description = "KMS key for ${var.projectname}"
deletion
windowindays = 7
enablekeyrotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.awscalleridentity.current.account_id}:root"
}
Action = "kms:"
Resource = "
"
}
]
})
tags = {
Environment = var.environment
}
}

resource "awskmsalias" "main" {
name = "alias/${var.projectname}"
target
keyid = awskmskey.main.keyid
}

data "awscalleridentity" "current" {}
```

The alias resource provides a stable name for the key and simplifies references in other services. The caller identity data source injects the current account ID into the policy principal.

For tighter access control, the policy can be built with awsiampolicy_document and restrict actions to specific roles:

```hcl
resource "awskmskey" "example" {
description = "Example KMS key"
policy = data.awsiampolicydocument.example.json
deletion
windowindays = 7
}

data "awsiampolicy_document" "example" {
statement = [
{
effect = "Allow"
actions = [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
]
principals = [{
type = "AWS"
identifiers = ["arn:aws:iam::123456789012:role/example-role"]
}]
resources = ["*"]
},
]
}
```

This configuration ensures that only the specified IAM role can perform encryption and decryption operations on the key.

Multi-Region Keys and Replicas

Multi-region keys provide active-active key material across AWS regions. The primary key is created in one region and replica keys are created in others.

Primary region key:

hcl resource "aws_kms_key" "primary" { description = "Multi-region primary key for ${var.project_name}" deletion_window_in_days = 7 enable_key_rotation = true multi_region = true tags = { Environment = var.environment } }

Secondary region replica:

hcl resource "aws_kms_key" "secondary" { provider = aws.secondary_region description = "Multi-region replica key for ${var.project_name}" deletion_window_in_days = 7 multi_region = true primary_key_arn =

The primary KMS key initially created was created as a multi-region KMS key. You can create a primary KMS key or a replica of a multi-region primary KMS key for use with the Mozilla SOPS tool.

Modules that wrap this functionality often support optional features:

  • Create a primary KMS key in either single/multi-region
  • Create a replica KMS key in a different region of the primary multi-region KMS key
  • Create a corresponding SOPS file containing the primary KMS or replica KMS arn
  • Create a KMS Grant including encryption constraints

Amazon Key Management Service makes it easy for you to create and manage cryptographic keys and control their use across a wide range of AWS services and in your applications. AWS KMS is a secure and resilient service that uses hardware security modules that have been validated under FIPS 140-2, or are in the process of being validated, to protect your keys. AWS KMS is integrated with AWS CloudTrail to provide you with logs of all key usage to help meet your regulatory and compliance needs.

Terraform State Encryption with KMS

By enabling KMS encryption for Terraform state files, teams can ensure that even if state files are compromised, the encryption keys remain protected through AWS KMS key rotation policies.

To enable KMS encryption in Terraform Cloud or Enterprise, you can use the following configuration:

hcl terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "my-terraform-state-key" region = "us-west-2" encrypt = true kms_key_id = "arn:aws:kms:us-west-2:123456789012:key/abcd1234-a123-4567-8abc-def123456789" } }

This configuration ensures that the Terraform state is encrypted using the specified KMS key, aligning with AWS best practices for securing configuration management data.

Integrating AWS Key Management Service with Terraform enables secure encryption of data at rest across AWS services such as Amazon S3, Amazon EBS, and others, while maintaining centralized control over cryptographic keys. This section provides practical examples of creating KMS keys with Terraform, configuring key policies, enabling key rotation, and auditing key usage.

Auditing and Compliance

AWS Config and CloudTrail play essential roles in continuous auditing and compliance monitoring. These configurations not only protect against unauthorized access but also align with modern DevOps and infrastructure-as-code principles, ensuring that security is baked into the infrastructure from the start.

Key usage is logged through CloudTrail, and key policies can be reviewed via Config rules to detect overly permissive principals or missing rotation settings.

Updating Existing Key Policies

While Terraform doesn't directly support updating an existing KMS key policy through its resources, there are a few approaches you can consider to achieve this.

Data source driven update pattern:

```hcl
data "awskmskey" "existingkey" {
key
id = "your-key-id-or-arn"
}

data "awskmskeypolicy" "existingpolicy" {
keyid = data.awskmskey.existingkey.id
}

locals {
updatedpolicy = jsonencode({
Version = "2012-10-17"
Statement = concat(
jsondecode(data.aws
kmskeypolicy.existing_policy.policy).Statement,
[
{
Sid = "NewStatement"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789012:user/NewUser"
}
Action = ["kms:Encrypt", "kms:Decrypt"]
Resource = "*"
}
]
)
})
}

resource "awskmskeypolicy" "updatedpolicy" {
keyid = data.awskmskey.existingkey.id
policy = local.updated_policy
}
```

If you need more control or if the above method doesn't work for your use case, you can use the awskmskey resource with the policy argument, but you'll need to import the existing key first:

hcl resource "aws_kms_key" "existing_key" { description = "Existing KMS key" policy = jsonencode({ Version = "2012-10-17" Statement = [ # Your existing policy statements ] }) }

Importing an existing key into Terraform state is required before managing its policy as code, otherwise drift will occur on the first apply.

Available Terraform Resources

The AWS provider exposes a set of KMS resources for fine-grained control.

Resource Purpose
awskmsalias Manages an Kms Alias resource
awskmsciphertext Manages an Kms Ciphertext resource
awskmscustomkeystore Manages an Kms Custom Key Store resource
awskmsexternal_key Manages an Kms External Key resource
awskmsgrant Manages an Kms Grant resource
awskmskey Manages an Kms Key resource
awskmskey_policy Manages an Kms Key Policy resource
awskmsreplicaexternalkey Manages an Kms Replica External Key resource
awskmsreplica_key Manages an Kms Replica Key resource

There are 9 Terraform resources and 7 data sources available for KMS operations.

Key attributes commonly used together:

Attribute Typical Value
deletionwindowin_days 7
enablekeyrotation true
multi_region true for primary or replica
policy jsonencode with Version 2012-10-17

Operational Practices

The guide shows how to set up KMS using Terraform.

A comprehensive guide to setting up AWS Key Management Service using Terraform Infrastructure as Code.

Managing AWS KMS with Terraform

Prerequisites include AWS CLI configured, Terraform installed, basic understanding of encryption concepts, and resources that need encryption.

Look at complete Terraform examples where you can get a better context of usage for various scenarios. The Terragrunt example can be viewed directly from GitHub.

  • Replica KMS Keys
  • The primary KMS key you initially created was created as a multi-region KMS key
  • You can create a primary KMS key or a replica of a multi-region primary KMS key for use with the Mozilla SOPS tool

For production workloads, combine key rotation, least-privilege policies, alias naming conventions, and CloudTrail logging. Keep policies in version control and test changes in a non-production account before applying to keys that protect live data.

Conclusion

AWS KMS managed through Terraform provides deterministic key creation, policy enforcement, and auditability. The core pattern is defining awskmskey with rotation enabled and a carefully scoped policy, attaching an alias for stable referencing, and using multi-region primary and replica keys where low-latency cross-region encryption is required. State encryption via the S3 backend with a specific kmskeyid protects Terraform state, while CloudTrail and AWS Config provide continuous compliance evidence. Updating existing policies requires data source reads and explicit import steps to avoid destructive recreation. Together these practices embed key governance into infrastructure as code without sacrificing operational flexibility.

Sources

  1. The Cloud Panda
  2. GitHub adamwshero terraform-aws-kms
  3. dasroot.net
  4. Repost AWS
  5. AWS Fundamentals

Related Posts