Sign in
Menu
Start free trial

AWS KMS Terraform module

Terraform module which creates AWS KMS resources.

SWUbanner

Usage

See examples directory for working examples to reference:

Autoscaling Service Linked Role

Reference usage for EC2 AutoScaling service linked role to launch encrypted EBS volumes:

module "kms" {
  source = "terraform-aws-modules/kms/aws"

  description = "EC2 AutoScaling key usage"
  key_usage   = "ENCRYPT_DECRYPT"

  # Policy
  key_administrators                 = ["arn:aws:iam::012345678901:role/admin"]
  key_service_roles_for_autoscaling  = ["arn:aws:iam::012345678901:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"]

  # Aliases
  aliases = ["mycompany/ebs"]

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

External Key

Reference usage for external CMK (externally provided encryption material):

module "kms" {
  source = "terraform-aws-modules/kms/aws"

  description         = "External key example"
  key_material_base64 = "Wblj06fduthWggmsT0cLVoIMOkeLbc2kVfMud77i/JY="
  valid_to            = "2085-04-12T23:20:50.52Z"

  # Policy
  key_owners         = ["arn:aws:iam::012345678901:role/owner"]
  key_administrators = ["arn:aws:iam::012345678901:role/admin"]
  key_users          = ["arn:aws:iam::012345678901:role/user"]
  key_service_users  = ["arn:aws:iam::012345678901:role/ec2-role"]

  # Aliases
  aliases                 = ["mycompany/external"]
  aliases_use_name_prefix = true

  # Grants
  grants = {
    lambda = {
      grantee_principal = "arn:aws:iam::012345678901:role/lambda-function"
      operations        = ["Encrypt", "Decrypt", "GenerateDataKey"]
      constraints = {
        encryption_context_equals = {
          Department = "Finance"
        }
      }
    }
  }

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Reference

Reference usage showing available configurations.

module "kms" {
  source = "terraform-aws-modules/kms/aws"

  description             = "Complete key example showing various configurations available"
  deletion_window_in_days = 7
  enable_key_rotation     = true
  is_enabled              = true
  key_usage               = "ENCRYPT_DECRYPT"
  multi_region            = false

  # Policy
  enable_default_policy                  = true
  key_owners                             = ["arn:aws:iam::012345678901:role/owner"]
  key_administrators                     = ["arn:aws:iam::012345678901:role/admin"]
  key_users                              = ["arn:aws:iam::012345678901:role/user"]
  key_service_users                      = ["arn:aws:iam::012345678901:role/ec2-role"]
  key_symmetric_encryption_users         = ["arn:aws:iam::012345678901:role/symmetric-user"]
  key_hmac_users                         = ["arn:aws:iam::012345678901:role/hmac-user"]
  key_asymmetric_public_encryption_users = ["arn:aws:iam::012345678901:role/asymmetric-public-user"]
  key_asymmetric_sign_verify_users       = ["arn:aws:iam::012345678901:role/sign-verify-user"]

  # Aliases
  aliases = ["one", "foo/bar"] # accepts static strings only
  computed_aliases = {
    ex = {
      # Sometimes you want to pass in an upstream attribute as the name and
      # that conflicts with using `for_each over a `toset()` since the value is not
      # known until after applying. Instead, we can use `computed_aliases` to work
      # around this limitation
      # Reference: https://github.com/hashicorp/terraform/issues/30937
      name = aws_iam_role.lambda.name
    }
  }
  aliases_use_name_prefix = true

  # Grants
  grants = {
    lambda = {
      grantee_principal = "arn:aws:iam::012345678901:role/lambda-function"
      operations        = ["Encrypt", "Decrypt", "GenerateDataKey"]
      constraints = {
        encryption_context_equals = {
          Department = "Finance"
        }
      }
    }
  }

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Known limitations (Terraform/OpenTofu, not this module)

A few requests come up again and again and cannot be implemented by this module, or by any module: Terraform requires lifecycle arguments to be literal values inside the resource block. hashicorp/terraform#18367 has been open since 2018, #22544 since 2019, and opentofu/opentofu#1329 is the same request for OpenTofu.

  • terraform destroy scheduled deletion of a KMS key - Native option: raise deletion_window_in_days to 30, which this module already exposes, so a scheduled deletion can be cancelled.

Compliance.tf serves this module with these rules applied at download time, on top of whatever your organization already has enabled there. Inputs and outputs do not change; the source line does. Drop the version argument and pin the release you use by adding &version= and that release number to the URL. To get started, register a free compliance.tf account and configure an access token:

source = "https://registry.compliance.tf/terraform-aws-modules/kms/aws?add_rules=lifecycle_prevent_destroy_encryption"

The full workaround for each item above, and the exact diff each rule makes, are in the compliance.tf docs for this module. To preview a diff without an account, open this module in the Rules Playground.

Disclosure: written by this module's maintainer, who also builds compliance.tf.

Examples

Examples codified under the examples are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module. If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you!

License

Apache-2.0 Licensed. See LICENSE.