initial commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<!-- This readme file is generated with terraform-docs -->
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | n/a |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [aws_kms_alias.allpurpose](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.notify](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_alias.storage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
|
||||
| [aws_kms_key.allpurpose](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.eks_ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.notify](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_kms_key.storage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
|
||||
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
|
||||
| [aws_iam_policy_document.UseOfKeyByAll](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.base](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.eksebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.notify](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.rds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_policy_document.storage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
|
||||
| [aws_iam_role.asg-service-linked-role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_role) | data source |
|
||||
| [aws_region.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| bypass\_policy\_lockout\_safety\_check | A flag to indicate whether to bypass the key policy lockout safety check. Setting this value to true increases the risk that the KMS key becomes unmanageable | `bool` | `false` | no |
|
||||
| create-allpurpose-key | Create a CMK for general use | `bool` | n/a | yes |
|
||||
| create-backup-key | Create a CMK for use with AWS backup | `bool` | n/a | yes |
|
||||
| create-database-key | Create a CMK for use with databases such as RDS, DynamoDB, Redis | `bool` | n/a | yes |
|
||||
| create-eksebs-key | Create a CMK for use with ENS volumes on EKS nodes | `bool` | n/a | yes |
|
||||
| create-log-key | Create a CMK for use with logging such as CloudwatchLogs and Cloudtrail | `bool` | n/a | yes |
|
||||
| create-notify-key | Create a CMK for use with notification and events | `bool` | n/a | yes |
|
||||
| create-secret-key | Create a CMK for use with secretsmanager | `bool` | n/a | yes |
|
||||
| create-storage-key | Create a CMK for use with storage such as EBS, S3, EFS | `bool` | n/a | yes |
|
||||
| customer\_master\_key\_spec | 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 |
|
||||
| deletion\_window\_in\_days | The waiting period, specified in number of days. After the waiting period ends, AWS KMS deletes the KMS key. If you specify a value, it must be between `7` and `30`, inclusive. If you do not specify a value, it defaults to `30` | `number` | `30` | no |
|
||||
| description | The description of the key as viewed in AWS console | `string` | `null` | no |
|
||||
| enable\_default\_policy | Specifies whether to enable the default key policy. Defaults to `true` | `bool` | `true` | no |
|
||||
| enable\_key\_rotation | Specifies whether key rotation is enabled. Defaults to `true` | `bool` | `true` | no |
|
||||
| grants | A map of grant definitions to create | `any` | `{}` | no |
|
||||
| is\_enabled | Specifies whether the key is enabled. Defaults to `true` | `bool` | `true` | no |
|
||||
| key\_administrator\_arn | IAM user/group/role with highest permissions. If none is specified, access will be granted to this account | `string` | `null` | no |
|
||||
| key\_usage | Specifies the intended use of the key. Valid values: `ENCRYPT_DECRYPT` or `SIGN_VERIFY`. Defaults to `ENCRYPT_DECRYPT` | `string` | `"ENCRYPT_DECRYPT"` | no |
|
||||
| multi\_region | Indicates whether the KMS key is a multi-Region (`true`) or regional (`false`) key. Defaults to `false` | `bool` | `false` | no |
|
||||
| name-prefix | Assign a name prefix for key alias | `string` | `null` | no |
|
||||
| policy | 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 |
|
||||
| rotation\_period\_in\_days | rotation period in days | `number` | `365` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| cmks | Customer managed KMS key arns |
|
||||
|
||||
---
|
||||
## Authorship
|
||||
This module was developed by xpk.
|
||||
@@ -0,0 +1,21 @@
|
||||
data "aws_caller_identity" "this" {}
|
||||
|
||||
module "example-keys" {
|
||||
source = "../"
|
||||
|
||||
name-prefix = "xpk"
|
||||
deletion_window_in_days = 7
|
||||
create-allpurpose-key = true
|
||||
create-backup-key = true
|
||||
create-database-key = true
|
||||
create-log-key = true
|
||||
create-notify-key = true
|
||||
create-secret-key = true
|
||||
create-storage-key = true
|
||||
create-eksebs-key = true
|
||||
key_administrator_arn = data.aws_caller_identity.this.arn
|
||||
}
|
||||
|
||||
output "cmks" {
|
||||
value = module.example-keys.cmks.*
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
provider "aws" {
|
||||
region = "ap-east-1"
|
||||
|
||||
default_tags {
|
||||
tags = {
|
||||
Environment = "lab"
|
||||
Project = "iac"
|
||||
Application = "terraform"
|
||||
Owner = "ken2026"
|
||||
TerraformDir = "${reverse(split("/", path.cwd))[1]}/${reverse(split("/", path.cwd))[0]}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output "last-updated" {
|
||||
value = timestamp()
|
||||
}
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.13.0"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.100.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
Module to create the following CMKs:
|
||||
- allpurpose
|
||||
- storage
|
||||
- database
|
||||
- secrets
|
||||
- backup
|
||||
- log
|
||||
- notify
|
||||
*/
|
||||
|
||||
data "aws_region" "this" {}
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
# Keys
|
||||
resource "aws_kms_key" "allpurpose" {
|
||||
count = var.create-allpurpose-key ? 1 : 0
|
||||
description = "All purpose customer-managed KMS key"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.UseOfKeyByAll.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "storage" {
|
||||
count = var.create-storage-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for encrypting cloud storage such as EBS and S3"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.storage.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
# Key use for EBS volumes on EKS nodes
|
||||
resource "aws_kms_key" "eks_ebs" {
|
||||
count = var.create-eksebs-key ? 1 : 0
|
||||
description = "CMK for use with ENS volumes on EKS nodes"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.eksebs[0].json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "database" {
|
||||
count = var.create-database-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for encrypting cloud databases such as RDS and Elasticache"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.rds.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "secret" {
|
||||
count = var.create-secret-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for encrypting secrets"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.UseOfKeyByAll.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "backup" {
|
||||
count = var.create-backup-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for encrypting backup data"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.UseOfKeyByAll.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "log" {
|
||||
count = var.create-log-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for cloudwatch logs and cloudtrail"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.log.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
resource "aws_kms_key" "notify" {
|
||||
count = var.create-notify-key ? 1 : 0
|
||||
description = "Customer-managed KMS key for encrypting notifications"
|
||||
enable_key_rotation = var.enable_key_rotation
|
||||
rotation_period_in_days = var.rotation_period_in_days
|
||||
is_enabled = var.is_enabled
|
||||
policy = data.aws_iam_policy_document.notify.json
|
||||
deletion_window_in_days = var.deletion_window_in_days
|
||||
customer_master_key_spec = "SYMMETRIC_DEFAULT"
|
||||
key_usage = "ENCRYPT_DECRYPT"
|
||||
multi_region = var.multi_region
|
||||
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check
|
||||
}
|
||||
|
||||
|
||||
locals {
|
||||
prefix = var.name-prefix == null ? "" : "${var.name-prefix}-"
|
||||
}
|
||||
|
||||
# Key aliases
|
||||
resource "aws_kms_alias" "allpurpose" {
|
||||
count = var.create-allpurpose-key ? 1 : 0
|
||||
name = "alias/${local.prefix}allpurpose"
|
||||
target_key_id = aws_kms_key.allpurpose[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "storage" {
|
||||
count = var.create-storage-key ? 1 : 0
|
||||
name = "alias/${local.prefix}storage"
|
||||
target_key_id = aws_kms_key.storage[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "database" {
|
||||
count = var.create-database-key ? 1 : 0
|
||||
name = "alias/${local.prefix}database"
|
||||
target_key_id = aws_kms_key.database[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "backup" {
|
||||
count = var.create-backup-key ? 1 : 0
|
||||
name = "alias/${local.prefix}backup"
|
||||
target_key_id = aws_kms_key.backup[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "secret" {
|
||||
count = var.create-secret-key ? 1 : 0
|
||||
name = "alias/${local.prefix}secret"
|
||||
target_key_id = aws_kms_key.secret[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "log" {
|
||||
count = var.create-log-key ? 1 : 0
|
||||
name = "alias/${local.prefix}log"
|
||||
target_key_id = aws_kms_key.log[0].id
|
||||
}
|
||||
|
||||
resource "aws_kms_alias" "notify" {
|
||||
count = var.create-notify-key ? 1 : 0
|
||||
name = "alias/${local.prefix}notify"
|
||||
target_key_id = aws_kms_key.notify[0].id
|
||||
}
|
||||
|
||||
# Policies
|
||||
data "aws_iam_policy_document" "storage" {
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "Allow use by AWS services"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [
|
||||
"delivery.logs.amazonaws.com" # vpc flow log
|
||||
]
|
||||
type = "Service"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
statement {
|
||||
sid = "Allow use of key by s3 and ec2"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [data.aws_caller_identity.current.account_id]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
values = [
|
||||
"ec2.${data.aws_region.this.name}.amazonaws.com",
|
||||
"s3.${data.aws_region.this.name}.amazonaws.com"
|
||||
]
|
||||
variable = "kms:ViaService"
|
||||
}
|
||||
}
|
||||
# this needs to be explicitly allowed for users and roles to be able to encrypt and decrypt data
|
||||
statement {
|
||||
sid = "Allow use of key by users and roles in same account"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [data.aws_caller_identity.current.account_id]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "rds" {
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "Allow use by AWS services"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
values = [
|
||||
"rds.${data.aws_region.this.id}.amazonaws.com",
|
||||
"elasticache.${data.aws_region.this.id}.amazonaws.com",
|
||||
"dax.${data.aws_region.this.id}.amazonaws.com"
|
||||
]
|
||||
variable = "kms:ViaService"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_iam_role" "asg-service-linked-role" {
|
||||
count = var.create-eksebs-key ? 1 : 0
|
||||
name = "AWSServiceRoleForAutoScaling"
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "eksebs" {
|
||||
count = var.create-eksebs-key ? 1 : 0
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "Allow use by EKS"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [
|
||||
data.aws_iam_role.asg-service-linked-role[0].arn
|
||||
]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
|
||||
statement {
|
||||
sid = "Allow grants by EKS"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [
|
||||
data.aws_iam_role.asg-service-linked-role[0].arn
|
||||
]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:RevokeGrant",
|
||||
"kms:ListGrants",
|
||||
"kms:CreateGrant"
|
||||
]
|
||||
resources = ["*"]
|
||||
condition {
|
||||
test = "Bool"
|
||||
values = ["true"]
|
||||
variable = "kms:GrantIsForAWSResource"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "notify" {
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "Allow use by AWS services"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [
|
||||
"logs.${data.aws_region.this.id}.amazonaws.com", # cloudwatch log groups
|
||||
"backup.amazonaws.com", # Notifications
|
||||
"events.amazonaws.com" # Notifications
|
||||
]
|
||||
type = "Service"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "log" {
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "Allow use by AWS services"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = [
|
||||
"logs.${data.aws_region.this.id}.amazonaws.com", # cloudwatch log groups
|
||||
"apigateway.${data.aws_region.this.id}.amazonaws.com", # api gateway
|
||||
"delivery.logs.amazonaws.com", # vpc flow log
|
||||
"cloudtrail.amazonaws.com" # cloudtrail
|
||||
]
|
||||
type = "Service"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:Describe*"
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
}
|
||||
|
||||
# allow all entities in this account to perform encryption and decryption
|
||||
data "aws_iam_policy_document" "UseOfKeyByAll" {
|
||||
source_policy_documents = [data.aws_iam_policy_document.base.json]
|
||||
statement {
|
||||
sid = "AllowUseOfKey"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:Encrypt",
|
||||
"kms:Decrypt",
|
||||
"kms:ReEncrypt*",
|
||||
"kms:GenerateDataKey*",
|
||||
"kms:DescribeKey"
|
||||
]
|
||||
resources = ["*"]
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
values = [data.aws_caller_identity.current.account_id]
|
||||
variable = "aws:PrincipalAccount"
|
||||
}
|
||||
}
|
||||
statement {
|
||||
sid = "AllowAttachmentOfPersistentResources"
|
||||
effect = "Allow"
|
||||
principals {
|
||||
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
|
||||
type = "AWS"
|
||||
}
|
||||
actions = [
|
||||
"kms:CreateGrant",
|
||||
"kms:ListGrants",
|
||||
"kms:RevokeGrant"
|
||||
]
|
||||
resources = ["*"]
|
||||
condition {
|
||||
test = "Bool"
|
||||
values = ["true"]
|
||||
variable = "kms:GrantIsForAWSResource"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# base policies allowing full access to key admin and read access to all
|
||||
data "aws_iam_policy_document" "base" {
|
||||
source_policy_documents = [jsonencode(
|
||||
{
|
||||
"Id" : "CmkBasePolicy",
|
||||
"Version" : "2012-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "ReadPermissonForAll",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : {
|
||||
"AWS" : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
|
||||
},
|
||||
"Action" : [
|
||||
"kms:DescribeKey",
|
||||
"kms:GetKeyPolicy",
|
||||
"kms:ListAliases",
|
||||
"kms:ListKeyPolicies",
|
||||
"kms:ListKeys",
|
||||
"kms:ListResourceTags"
|
||||
],
|
||||
"Resource" : "*"
|
||||
},
|
||||
{
|
||||
"Sid" : "KeyAdministratorsAccess",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : {
|
||||
"AWS" : var.key_administrator_arn != null ? var.key_administrator_arn : "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
|
||||
},
|
||||
"Action" : [
|
||||
"kms:Create*",
|
||||
"kms:Describe*",
|
||||
"kms:Enable*",
|
||||
"kms:List*",
|
||||
"kms:Put*",
|
||||
"kms:Update*",
|
||||
"kms:Revoke*",
|
||||
"kms:Disable*",
|
||||
"kms:Get*",
|
||||
"kms:Delete*",
|
||||
"kms:TagResource",
|
||||
"kms:UntagResource",
|
||||
"kms:ScheduleKeyDeletion",
|
||||
"kms:CancelKeyDeletion",
|
||||
"kms:RotateKeyOnDemand"
|
||||
],
|
||||
"Resource" : "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
)]
|
||||
}
|
||||
|
||||
# data "aws_iam_policy_document" "this" {
|
||||
# source_policy_documents = var.source_policy_documents
|
||||
# override_policy_documents = var.override_policy_documents
|
||||
#
|
||||
# # Default policy - account wide access to all key operations
|
||||
# dynamic "statement" {
|
||||
# for_each = var.enable_default_policy ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "Default"
|
||||
# actions = ["kms:*"]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root"]
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Key owner - all key operations
|
||||
# dynamic "statement" {
|
||||
# for_each = var.enable_default_policy ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "KeyOwner"
|
||||
# actions = ["kms:*"]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = var.key_owners
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Key administrators - https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-default-allow-administrators
|
||||
# dynamic "statement" {
|
||||
# for_each = length(var.key_administrators) > 0 ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "KeyAdministration"
|
||||
# actions = [
|
||||
# "kms:Create*",
|
||||
# "kms:Describe*",
|
||||
# "kms:Enable*",
|
||||
# "kms:List*",
|
||||
# "kms:Put*",
|
||||
# "kms:Update*",
|
||||
# "kms:Revoke*",
|
||||
# "kms:Disable*",
|
||||
# "kms:Get*",
|
||||
# "kms:Delete*",
|
||||
# "kms:TagResource",
|
||||
# "kms:UntagResource",
|
||||
# "kms:ScheduleKeyDeletion",
|
||||
# "kms:CancelKeyDeletion",
|
||||
# ]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = var.key_administrators
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Key users - https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-default-allow-users
|
||||
# dynamic "statement" {
|
||||
# for_each = length(var.key_users) > 0 ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "KeyUsage"
|
||||
# actions = [
|
||||
# "kms:Encrypt",
|
||||
# "kms:Decrypt",
|
||||
# "kms:ReEncrypt*",
|
||||
# "kms:GenerateDataKey*",
|
||||
# "kms:DescribeKey",
|
||||
# ]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = var.key_users
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Key service users - https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-service-integration
|
||||
# dynamic "statement" {
|
||||
# for_each = length(var.key_service_users) > 0 ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "KeyServiceUsage"
|
||||
# actions = [
|
||||
# "kms:CreateGrant",
|
||||
# "kms:ListGrants",
|
||||
# "kms:RevokeGrant",
|
||||
# ]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = var.key_service_users
|
||||
# }
|
||||
#
|
||||
# condition {
|
||||
# test = "Bool"
|
||||
# variable = "kms:GrantIsForAWSResource"
|
||||
# values = [true]
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # Key cryptographic operations - https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-users-crypto
|
||||
# dynamic "statement" {
|
||||
# for_each = length(var.key_symmetric_encryption_users) > 0 ? [1] : []
|
||||
#
|
||||
# content {
|
||||
# sid = "KeySymmetricEncryption"
|
||||
# actions = [
|
||||
# "kms:Decrypt",
|
||||
# "kms:DescribeKey",
|
||||
# "kms:Encrypt",
|
||||
# "kms:GenerateDataKey*",
|
||||
# "kms:ReEncrypt*",
|
||||
# ]
|
||||
# resources = ["*"]
|
||||
#
|
||||
# principals {
|
||||
# type = "AWS"
|
||||
# identifiers = var.key_symmetric_encryption_users
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
# ################################################################################
|
||||
# # Grant
|
||||
# ################################################################################
|
||||
#
|
||||
# resource "aws_kms_grant" "this" {
|
||||
# for_each = { for k, v in var.grants : k => v if var.create }
|
||||
#
|
||||
# name = try(each.value.name, each.key)
|
||||
# key_id = aws_kms_key.this[0].key_id
|
||||
# grantee_principal = each.value.grantee_principal
|
||||
# operations = each.value.operations
|
||||
#
|
||||
# dynamic "constraints" {
|
||||
# for_each = length(lookup(each.value, "constraints", {})) == 0 ? [] : [each.value.constraints]
|
||||
#
|
||||
# content {
|
||||
# encryption_context_equals = try(constraints.value.encryption_context_equals, null)
|
||||
# encryption_context_subset = try(constraints.value.encryption_context_subset, null)
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# retiring_principal = try(each.value.retiring_principal, null)
|
||||
# grant_creation_tokens = try(each.value.grant_creation_tokens, null)
|
||||
# retire_on_delete = try(each.value.retire_on_delete, null)
|
||||
# }
|
||||
@@ -0,0 +1,33 @@
|
||||
output "cmks" {
|
||||
description = "Customer managed KMS key arns"
|
||||
value = {
|
||||
backup = {
|
||||
alias = aws_kms_alias.backup.*.name
|
||||
arn = aws_kms_key.backup.*.arn
|
||||
},
|
||||
database = {
|
||||
alias = aws_kms_alias.database.*.name
|
||||
arn = aws_kms_key.database.*.arn
|
||||
},
|
||||
allpurpose = {
|
||||
alias = aws_kms_alias.allpurpose.*.name
|
||||
arn = aws_kms_key.allpurpose.*.arn
|
||||
},
|
||||
secret = {
|
||||
alias = aws_kms_alias.secret.*.name
|
||||
arn = aws_kms_key.secret.*.arn
|
||||
},
|
||||
log = {
|
||||
alias = aws_kms_alias.log.*.name
|
||||
arn = aws_kms_key.log.*.arn
|
||||
},
|
||||
notify = {
|
||||
alias = aws_kms_alias.notify.*.name
|
||||
arn = aws_kms_key.notify.*.arn
|
||||
},
|
||||
storage = {
|
||||
alias = aws_kms_alias.storage.*.name
|
||||
arn = aws_kms_key.storage.*.arn
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
variable "create-allpurpose-key" {
|
||||
description = "Create a CMK for general use"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-storage-key" {
|
||||
description = "Create a CMK for use with storage such as EBS, S3, EFS"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-eksebs-key" {
|
||||
description = "Create a CMK for use with ENS volumes on EKS nodes"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-database-key" {
|
||||
description = "Create a CMK for use with databases such as RDS, DynamoDB, Redis"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-backup-key" {
|
||||
description = "Create a CMK for use with AWS backup"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-secret-key" {
|
||||
description = "Create a CMK for use with secretsmanager"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-log-key" {
|
||||
description = "Create a CMK for use with logging such as CloudwatchLogs and Cloudtrail"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "create-notify-key" {
|
||||
description = "Create a CMK for use with notification and events"
|
||||
type = bool
|
||||
}
|
||||
|
||||
variable "name-prefix" {
|
||||
description = "Assign a name prefix for key alias"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "bypass_policy_lockout_safety_check" {
|
||||
description = "A flag to indicate whether to bypass the key policy lockout safety check. Setting this value to true increases the risk that the KMS key becomes unmanageable"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "customer_master_key_spec" {
|
||||
description = "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"
|
||||
}
|
||||
|
||||
variable "deletion_window_in_days" {
|
||||
description = "The waiting period, specified in number of days. After the waiting period ends, AWS KMS deletes the KMS key. If you specify a value, it must be between `7` and `30`, inclusive. If you do not specify a value, it defaults to `30`"
|
||||
type = number
|
||||
default = 30
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "The description of the key as viewed in AWS console"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "enable_key_rotation" {
|
||||
description = "Specifies whether key rotation is enabled. Defaults to `true`"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "is_enabled" {
|
||||
description = "Specifies whether the key is enabled. Defaults to `true`"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "key_usage" {
|
||||
description = "Specifies the intended use of the key. Valid values: `ENCRYPT_DECRYPT` or `SIGN_VERIFY`. Defaults to `ENCRYPT_DECRYPT`"
|
||||
type = string
|
||||
default = "ENCRYPT_DECRYPT"
|
||||
}
|
||||
|
||||
variable "multi_region" {
|
||||
description = "Indicates whether the KMS key is a multi-Region (`true`) or regional (`false`) key. Defaults to `false`"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "policy" {
|
||||
description = "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
|
||||
}
|
||||
|
||||
variable "enable_default_policy" {
|
||||
description = "Specifies whether to enable the default key policy. Defaults to `true`"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "key_administrator_arn" {
|
||||
description = "IAM user/group/role with highest permissions. If none is specified, access will be granted to this account"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Grant
|
||||
################################################################################
|
||||
|
||||
variable "grants" {
|
||||
description = "A map of grant definitions to create"
|
||||
type = any
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "rotation_period_in_days" {
|
||||
description = "rotation period in days"
|
||||
type = number
|
||||
default = 365
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user