Skip to content

Commit

Permalink
Support individual kms key policy resource in kms-key (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
posquit0 authored May 8, 2024
1 parent 3f7e765 commit 0c36b24
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 72 deletions.
32 changes: 19 additions & 13 deletions modules/kms-key/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This module creates following resources.

- `aws_kms_key`
- `aws_kms_key_policy` (optional)
- `aws_kms_alias` (optional)
- `aws_kms_grant` (optional)

Expand All @@ -11,14 +12,14 @@ This module creates following resources.

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.22 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.23 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.19.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.48.0 |

## Modules

Expand All @@ -32,42 +33,47 @@ This module creates following resources.
|------|------|
| [aws_kms_alias.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_kms_key_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | (Required) Name of the KMS key. | `string` | n/a | yes |
| <a name="input_aliases"></a> [aliases](#input\_aliases) | (Optional) List of display name of the alias. The name must start with the word `alias/`. | `list(string)` | `[]` | no |
| <a name="input_bypass_policy_lockout_safety_check"></a> [bypass\_policy\_lockout\_safety\_check](#input\_bypass\_policy\_lockout\_safety\_check) | (Optional) Specifies whether to disable the policy lockout check performed when creating or updating the key's policy. Setting this value to true increases the risk that the CMK becomes unmanageable. For more information, refer to the scenario in the Default Key Policy section in the AWS Key Management Service Developer Guide. | `bool` | `false` | no |
| <a name="input_aliases"></a> [aliases](#input\_aliases) | (Optional) A set of display name of the alias. The name must start with the word `alias/`. | `set(string)` | `[]` | no |
| <a name="input_bypass_policy_lockout_safety_check"></a> [bypass\_policy\_lockout\_safety\_check](#input\_bypass\_policy\_lockout\_safety\_check) | (Optional) Whether to bypass the key policy lockout safety check performed when creating or updating the key's policy. Setting this value to true increases the risk that the CMK becomes unmanageable. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_custom_key_store"></a> [custom\_key\_store](#input\_custom\_key\_store) | (Optional) The ID of the KMS Custom Key Store where the key will be stored instead of KMS. This parameter is valid only for symmetric encryption KMS keys in a single region. | `string` | `null` | no |
| <a name="input_deletion_window_in_days"></a> [deletion\_window\_in\_days](#input\_deletion\_window\_in\_days) | (Optional) Duration in days after which the key is deleted after destruction of the resource. Valid value is between `7` and `30` days. Defaults to `30`. | `number` | `30` | no |
| <a name="input_description"></a> [description](#input\_description) | (Optional) The description of the KMS key. | `string` | `""` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | (Optional) Indicates whether the key is enabled. | `bool` | `true` | no |
| <a name="input_key_rotation_enabled"></a> [key\_rotation\_enabled](#input\_key\_rotation\_enabled) | (Optional) Indicates whether key rotation is enabled. | `bool` | `false` | no |
| <a name="input_description"></a> [description](#input\_description) | (Optional) The description of the KMS key. | `string` | `"Managed by Terraform."` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | (Optional) Indicates whether the key is enabled. Defaults to `true`. | `bool` | `true` | no |
| <a name="input_key_rotation_enabled"></a> [key\_rotation\_enabled](#input\_key\_rotation\_enabled) | (Optional) Indicates whether key rotation is enabled. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
| <a name="input_multi_region_enabled"></a> [multi\_region\_enabled](#input\_multi\_region\_enabled) | (Optional) Indicates whether the key is a multi-Region (true) or regional (false) key. | `bool` | `false` | no |
| <a name="input_multi_region_enabled"></a> [multi\_region\_enabled](#input\_multi\_region\_enabled) | (Optional) Indicates whether the key is a multi-Region (true) or regional (false) key. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_policy"></a> [policy](#input\_policy) | (Optional) A valid policy JSON document. Although this is a key policy, not an IAM policy, an `aws_iam_policy_document`, in the form that designates a principal, can be used. | `string` | `null` | no |
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
| <a name="input_resource_group_enabled"></a> [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
| <a name="input_spec"></a> [spec](#input\_spec) | (Optional) Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`. Defaults to `SYMMETRIC_DEFAULT`. | `string` | `"SYMMETRIC_DEFAULT"` | no |
| <a name="input_spec"></a> [spec](#input\_spec) | (Optional) Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `HMAC_256`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`. Defaults to `SYMMETRIC_DEFAULT`. | `string` | `"SYMMETRIC_DEFAULT"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |
| <a name="input_usage"></a> [usage](#input\_usage) | (Optional) Specifies the intended use of the key. Valid values are `ENCRYPT_DECRYPT` or `SIGN_VERIFY`. | `string` | `"ENCRYPT_DECRYPT"` | no |
| <a name="input_usage"></a> [usage](#input\_usage) | (Optional) Specifies the intended use of the key. Valid values are `ENCRYPT_DECRYPT`, `SIGN_VERIFY`, or `GENERATE_VERIFY_MAC`. Defaults to `ENCRYPT_DECRYPT`. | `string` | `"ENCRYPT_DECRYPT"` | no |
| <a name="input_xks_key"></a> [xks\_key](#input\_xks\_key) | (Optional) The ID of the external key that serves as key material for the KMS key in an external key store. | `string` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_aliases"></a> [aliases](#output\_aliases) | A collection of aliases of the key. |
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the KMS key. |
| <a name="output_bypass_policy_lockout_safety_check"></a> [bypass\_policy\_lockout\_safety\_check](#output\_bypass\_policy\_lockout\_safety\_check) | Whether to disable the policy lockout check performed when creating or updating the key's policy. |
| <a name="output_custom_key_store"></a> [custom\_key\_store](#output\_custom\_key\_store) | The ID of the KMS Custom Key Store where the key will be stored instead of KMS. |
| <a name="output_deletion_window_in_days"></a> [deletion\_window\_in\_days](#output\_deletion\_window\_in\_days) | Duration in days after which the key is deleted after destruction of the resource. |
| <a name="output_description"></a> [description](#output\_description) | The description of the KMS key. |
| <a name="output_enabled"></a> [enabled](#output\_enabled) | Whether the key is enabled. |
| <a name="output_id"></a> [id](#output\_id) | The ID of the KMS key. |
| <a name="output_key_rotation_enabled"></a> [key\_rotation\_enabled](#output\_key\_rotation\_enabled) | Whether the key rotation is enabled. |
| <a name="output_multi_region_enabled"></a> [multi\_region\_enabled](#output\_multi\_region\_enabled) | Whether the key is a multi-region key. |
| <a name="output_name"></a> [name](#output\_name) | The KMS Key name. |
| <a name="output_policy"></a> [policy](#output\_policy) | The Resource Policy for KMS Key. |
| <a name="output_spec"></a> [spec](#output\_spec) | The specification of KMS key which is the encryption algorithm or signing algorithm. |
| <a name="output_usage"></a> [usage](#output\_usage) | The usage of the KMS key. `ENCRYPT_DECRYPT` or `SIGN_VERIFY`. |
| <a name="output_usage"></a> [usage](#output\_usage) | The usage of the KMS key. |
| <a name="output_xks_key"></a> [xks\_key](#output\_xks\_key) | The ID of the external key that serves as key material for the KMS key in an external key store. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
42 changes: 31 additions & 11 deletions modules/kms-key/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@ locals {


###################################################
# KMS Resources
# Customer Managed Key in KMS
###################################################

# INFO: Use a separate resource
# - 'policy'
# - 'bypass_policy_lockout_safety_check'
resource "aws_kms_key" "this" {
description = var.description
description = var.description
is_enabled = var.enabled
deletion_window_in_days = var.deletion_window_in_days

key_usage = var.usage
customer_master_key_spec = var.spec

policy = var.policy
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check

deletion_window_in_days = var.deletion_window_in_days

is_enabled = var.enabled
enable_key_rotation = var.key_rotation_enabled
custom_key_store_id = var.custom_key_store
xks_key_id = var.xks_key
multi_region = var.multi_region_enabled
enable_key_rotation = var.key_rotation_enabled

tags = merge(
{
Expand All @@ -43,12 +44,31 @@ resource "aws_kms_key" "this" {
)
}


###################################################
# Aliases for Customer Managed Key
###################################################

# Provides an alias for a KMS customer master key.
# AWS Console enforces 1-to-1 mapping between aliases & keys,
# but API allows you to create as many aliases as the account limits.
resource "aws_kms_alias" "this" {
for_each = toset(var.aliases)
for_each = var.aliases

name = each.key
target_key_id = aws_kms_key.this.key_id
name = each.key
}


###################################################
# Key Policy for Customer Managed Key
###################################################

resource "aws_kms_key_policy" "this" {
count = var.policy != null ? 1 : 0

key_id = aws_kms_key.this.key_id

policy = var.policy
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
}
36 changes: 23 additions & 13 deletions modules/kms-key/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,23 @@ output "name" {
value = var.name
}

output "description" {
description = "The description of the KMS key."
value = aws_kms_key.this.description
}

output "enabled" {
description = "Whether the key is enabled."
value = aws_kms_key.this.is_enabled
}

output "deletion_window_in_days" {
description = "Duration in days after which the key is deleted after destruction of the resource."
value = aws_kms_key.this.deletion_window_in_days
}

output "usage" {
description = "The usage of the KMS key. `ENCRYPT_DECRYPT` or `SIGN_VERIFY`."
description = "The usage of the KMS key."
value = aws_kms_key.this.key_usage
}

Expand All @@ -25,22 +40,17 @@ output "spec" {

output "policy" {
description = "The Resource Policy for KMS Key."
value = aws_kms_key.this.policy
value = one(aws_kms_key_policy.this[*].policy)
}

output "bypass_policy_lockout_safety_check" {
description = "Whether to disable the policy lockout check performed when creating or updating the key's policy."
value = aws_kms_key.this.bypass_policy_lockout_safety_check
}

output "deletion_window_in_days" {
description = "Duration in days after which the key is deleted after destruction of the resource."
value = aws_kms_key.this.deletion_window_in_days
output "custom_key_store" {
description = "The ID of the KMS Custom Key Store where the key will be stored instead of KMS."
value = aws_kms_key.this.custom_key_store_id
}

output "enabled" {
description = "Whether the key is enabled."
value = aws_kms_key.this.is_enabled
output "xks_key" {
description = "The ID of the external key that serves as key material for the KMS key in an external key store."
value = aws_kms_key.this.xks_key_id
}

output "key_rotation_enabled" {
Expand Down
97 changes: 64 additions & 33 deletions modules/kms-key/variables.tf
Original file line number Diff line number Diff line change
@@ -1,90 +1,121 @@
variable "name" {
description = "(Required) Name of the KMS key."
type = string
nullable = false
}

variable "aliases" {
description = "(Optional) A set of display name of the alias. The name must start with the word ``alias/`."
type = set(string)
default = []
nullable = false
}

variable "description" {
description = "(Optional) The description of the KMS key."
type = string
default = ""
default = "Managed by Terraform."
nullable = false
}

variable "enabled" {
description = "(Optional) Indicates whether the key is enabled. Defaults to `true`."
type = bool
default = true
nullable = false
}

variable "deletion_window_in_days" {
description = "(Optional) Duration in days after which the key is deleted after destruction of the resource. Valid value is between `7` and `30` days. Defaults to `30`."
type = number
default = 30
nullable = false

validation {
condition = alltrue([
var.deletion_window_in_days >= 7,
var.deletion_window_in_days <= 30,
])
error_message = "Valid value is between `7` and `30` days."
}
}

variable "usage" {
description = "(Optional) Specifies the intended use of the key. Valid values are `ENCRYPT_DECRYPT` or `SIGN_VERIFY`."
description = "(Optional) Specifies the intended use of the key. Valid values are `ENCRYPT_DECRYPT`, `SIGN_VERIFY`, or `GENERATE_VERIFY_MAC`. Defaults to `ENCRYPT_DECRYPT`."
type = string
default = "ENCRYPT_DECRYPT"
nullable = false

validation {
condition = contains(["ENCRYPT_DECRYPT", "SIGN_VERIFY"], var.usage)
error_message = "Valid values are `ENCRYPT_DECRYPT` or `SIGN_VERIFY`."
condition = contains(["ENCRYPT_DECRYPT", "SIGN_VERIFY", "GENERATE_VERIFY_MAC"], var.usage)
error_message = "Valid values are `ENCRYPT_DECRYPT`, `SIGN_VERIFY`, or `GENERATE_VERIFY_MAC`."
}
}

variable "spec" {
description = "(Optional) Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`. Defaults to `SYMMETRIC_DEFAULT`."
description = "(Optional) Specifies whether the key contains a symmetric key or an asymmetric key pair and the encryption algorithms or signing algorithms that the key supports. Valid values: `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `HMAC_256`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`. Defaults to `SYMMETRIC_DEFAULT`."
type = string
default = "SYMMETRIC_DEFAULT"
nullable = false

validation {
condition = contains([
"SYMMETRIC_DEFAULT",
"RSA_2048",
"RSA_3072",
"RSA_4096",
"HMAC_256",
"ECC_NIST_P256",
"ECC_NIST_P384",
"ECC_NIST_P521",
"ECC_SECG_P256K1",
], var.spec)
error_message = "Valid values for `spec` are `SYMMETRIC_DEFAULT`, `RSA_2048`, `RSA_3072`, `RSA_4096`, `HMAC_256`, `ECC_NIST_P256`, `ECC_NIST_P384`, `ECC_NIST_P521`, or `ECC_SECG_P256K1`."
}
}

variable "policy" {
description = "(Optional) A valid policy JSON document. Although this is a key policy, not an IAM policy, an `aws_iam_policy_document`, in the form that designates a principal, can be used."
type = string
default = null
nullable = true
}

variable "bypass_policy_lockout_safety_check" {
description = "(Optional) Specifies whether to disable the policy lockout check performed when creating or updating the key's policy. Setting this value to true increases the risk that the CMK becomes unmanageable. For more information, refer to the scenario in the Default Key Policy section in the AWS Key Management Service Developer Guide."
description = "(Optional) Whether to bypass the key policy lockout safety check performed when creating or updating the key's policy. Setting this value to true increases the risk that the CMK becomes unmanageable. Defaults to `false`."
type = bool
default = false
nullable = false
}

variable "deletion_window_in_days" {
description = "(Optional) Duration in days after which the key is deleted after destruction of the resource. Valid value is between `7` and `30` days. Defaults to `30`."
type = number
default = 30
nullable = false

validation {
condition = alltrue([
var.deletion_window_in_days >= 7,
var.deletion_window_in_days <= 30,
])
error_message = "Valid value is between `7` and `30` days."
}
variable "custom_key_store" {
description = "(Optional) The ID of the KMS Custom Key Store where the key will be stored instead of KMS. This parameter is valid only for symmetric encryption KMS keys in a single region."
type = string
default = null
nullable = true
}

variable "enabled" {
description = "(Optional) Indicates whether the key is enabled."
type = bool
default = true
nullable = false
variable "xks_key" {
description = "(Optional) The ID of the external key that serves as key material for the KMS key in an external key store."
type = string
default = null
nullable = true
}

variable "key_rotation_enabled" {
description = "(Optional) Indicates whether key rotation is enabled."
description = "(Optional) Indicates whether key rotation is enabled. Defaults to `false`."
type = bool
default = false
nullable = false
}

variable "multi_region_enabled" {
description = "(Optional) Indicates whether the key is a multi-Region (true) or regional (false) key."
description = "(Optional) Indicates whether the key is a multi-Region (true) or regional (false) key. Defaults to `false`."
type = bool
default = false
nullable = false
}

variable "aliases" {
description = "(Optional) List of display name of the alias. The name must start with the word ``alias/`."
type = list(string)
default = []
nullable = false
}

variable "tags" {
description = "(Optional) A map of tags to add to all resources."
type = map(string)
Expand Down
4 changes: 2 additions & 2 deletions modules/kms-key/versions.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.5"
required_version = ">= 1.6"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.22"
version = ">= 5.23"
}
}
}

0 comments on commit 0c36b24

Please sign in to comment.