Skip to content

Repository files navigation

Terraform AWS KMS Module

GitHub release (latest by date)

Reusable Terraform module for one AWS KMS key per module call. It follows the sibling EKS, ElastiCache, and S3 module conventions: a selected singleton primary resource named main, flat documented inputs, stable maps for repeatable resources, resources split by concern, composition outputs, native tests, runnable examples, and generated documentation.

Key types

key_type Terraform resource Purpose
standard aws_kms_key.main AWS-generated key material; this is the default
external aws_kms_external_key.main Imported key material for a primary key
replica aws_kms_replica_key.main AWS-generated-material replica of a multi-Region primary key
replica_external aws_kms_replica_external_key.main Imported-material replica of a multi-Region external primary key

Use a separate module call for each independent key. For replicas, set primary_key_arn and use region to select the destination Region without requiring a provider alias on AWS provider 6.x.

Usage

module "kms" {
  source  = "native-cube/kms/aws"
  version = "~> 2.1"

  description             = "Orders data encryption key"
  deletion_window_in_days = 30
  enable_key_rotation     = true
  key_spec                = "SYMMETRIC_DEFAULT"
  rotation_period_in_days = 365

  aliases = {
    application = {
      name = "orders/data"
    }
  }

  grants = {
    orders = {
      grantee_principal = aws_iam_role.orders.arn
      operations        = ["Decrypt", "GenerateDataKey"]
      constraints = [{
        encryption_context_equals = {
          Service = "orders"
        }
      }]
    }
  }

  tags = {
    Environment = "production"
    Service     = "orders"
  }
}

alias_name and alias_name_prefix remain available for compatibility and retain the existing aws_kms_alias.main[0] address. Prefer the aliases map for new configurations so multiple aliases have stable keys.

Policies, grants, and key material

  • Set policy to a valid KMS key policy JSON document. When it is null, AWS KMS applies its default key policy. Do not manage the same policy with aws_kms_key_policy as well.
  • bypass_policy_lockout_safety_check = true can make a key unmanageable. Leave it disabled unless the supplied policy has been independently verified.
  • External key material is sensitive, but the AWS provider stores key_material_base64 in Terraform state. Use an encrypted remote backend with tightly restricted access and inject the value through a secure workflow.
  • Grants are keyed by stable map keys and support every AWS provider grant argument, including encryption-context constraints, grant creation tokens, retirement settings, and all KMS operations accepted by the provider.
  • Automatic rotation settings apply to standard keys. Replica keys inherit their key spec, key usage, and rotation state from the primary key.
  • Treat key_type and create as lifecycle controls: changing the key type or disabling creation destroys the currently selected key after its deletion window. Use policy-as-code or a caller wrapper with prevent_destroy when accidental key deletion must be blocked.

Provider argument coverage

Every configurable argument and nested block in HashiCorp AWS provider 6.62.0 is wired for:

  • aws_kms_key
  • aws_kms_external_key
  • aws_kms_replica_key
  • aws_kms_replica_external_key
  • aws_kms_alias
  • aws_kms_grant

make schema-check compares the initialized provider schema with all six resource definitions and fails if a configurable argument or nested-block field is missing.

The module accepts an existing custom_key_store_id and optional xks_key_id, but intentionally does not provision aws_kms_custom_key_store; CloudHSM and external key-store connectivity and credentials have a separate lifecycle. It also does not create aws_kms_ciphertext resources because encrypting application plaintext in Terraform can expose sensitive data through configuration or state.

Compatibility

Module version 2.1.0 requires Terraform 1.9 or newer and HashiCorp AWS provider 6.62 or newer. Root configurations should set their own compatible upper bound and commit a dependency lock file. Existing standard keys are migrated from aws_kms_key.main to aws_kms_key.main[0] by the included moved block. The default remains a standard symmetric key, and the legacy single-alias inputs and outputs remain supported.

Examples

Development

Run make check to verify formatting, generated documentation, initialization, validation, native Terraform tests, provider argument coverage, and every example. Run make docs after changing inputs, outputs, resources, or version constraints.

Module Documentation

Requirements

Name Version
terraform >= 1.9.0
aws >= 6.62.0

Providers

Name Version
aws >= 6.62.0

Resources

Name Type
aws_kms_alias.additional resource
aws_kms_alias.main resource
aws_kms_external_key.main resource
aws_kms_grant.main resource
aws_kms_key.main resource
aws_kms_replica_external_key.main resource
aws_kms_replica_key.main resource

Inputs

Name Description Type Default Required
alias_name Legacy exact alias name to create without the alias/ prefix. Prefer aliases for new configurations. string null no
alias_name_prefix Legacy alias name prefix to create without the alias/ prefix. Prefer aliases for new configurations. string null no
aliases Additional KMS aliases keyed by a stable Terraform key. Set exactly one of name or name_prefix and omit the alias/ prefix.
map(object({
name = optional(string)
name_prefix = optional(string)
}))
{} no
bypass_policy_lockout_safety_check Whether to bypass the policy lockout safety check. Enabling this can make the KMS key unmanageable. bool false no
create Whether to create the selected KMS key, aliases, and grants. bool true no
create_timeout Optional custom creation timeout for a standard KMS key, for example 5m. string null no
custom_key_store_id ID of an existing CloudHSM or external custom key store for a standard key. string null no
customer_master_key_spec Deprecated compatibility input for key_spec. Prefer key_spec for new configurations. string null no
deletion_window_in_days Waiting period in days before AWS KMS permanently deletes the key. number 10 no
description Description of the KMS key. string "Parameter Store KMS key" no
enable_key_rotation Whether automatic rotation is enabled for a standard KMS key. bool true no
grants KMS grants to create for the selected key, keyed by a stable Terraform key.
map(object({
grantee_principal = string
operations = set(string)
name = optional(string)
grant_creation_tokens = optional(set(string), [])
retire_on_delete = optional(bool)
retiring_principal = optional(string)
constraints = optional(list(object({
encryption_context_equals = optional(map(string))
encryption_context_subset = optional(map(string))
})), [])
}))
{} no
is_enabled Whether the KMS key is enabled. bool true no
key_material_base64 Base64-encoded key material to import into an external or replica external KMS key. The provider stores this value in Terraform state. string null no
key_spec KMS key spec. Defaults to SYMMETRIC_DEFAULT. Replica key specs are inherited from the primary key. string null no
key_type KMS key resource type to create: standard, external, replica, or replica_external. string "standard" no
key_usage Intended cryptographic use of a standard or external KMS key. Replica keys inherit this value from the primary key. string "ENCRYPT_DECRYPT" no
multi_region Whether a standard or external primary key is a multi-Region key. Replica keys are always multi-Region. bool false no
policy Optional KMS key policy JSON document. Null lets AWS KMS apply its default key policy. string null no
primary_key_arn ARN of the multi-Region primary key used by replica and replica_external key types. string null no
region AWS Region where the KMS resources are managed. Defaults to the provider Region. string null no
rotation_period_in_days Custom automatic rotation period for a standard KMS key, from 90 through 2560 days. number null no
tags Tags to apply to the selected KMS key. map(string) {} no
valid_to Optional RFC3339 expiration time for imported key material on an external or replica external key. string null no
xks_key_id ID of the external key material used by a standard key in an external custom key store. string null no

Outputs

Name Description
alias_arn ARN of the legacy alias, or null when alias_name and alias_name_prefix are omitted.
alias_name Name of the legacy alias, or null when alias_name and alias_name_prefix are omitted.
alias_target_key_arn Target key ARN of the legacy alias, or null when the legacy alias is not created.
aliases Additional aliases created by the module, keyed by the aliases input map key.
external_key_expiration_model Expiration model of imported key material, or null for non-external keys.
external_key_state State of the external KMS key, or null for non-external keys.
grants KMS grants created by the module, keyed by the grants input map key.
key_arn ARN of the selected KMS key, or null when creation is disabled.
key_id ID of the selected KMS key, or null when creation is disabled.
key_policy Policy reported for the selected KMS key, or null when creation is disabled.
key_region Region where the selected KMS key is managed, or null when creation is disabled.
key_spec Key spec of the selected KMS key, including the inherited spec for a replica.
key_type Selected KMS key resource type, or null when creation is disabled.
key_usage Cryptographic usage of the selected KMS key.
tags_all Tags assigned to the selected KMS key, including provider default tags.

License

See LICENSE for details.

Releases

Sponsor this project

Packages

Used by

Contributors

Languages