From ec58344074d35d77407d5d40d08dfea7bba85030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20V=C3=B6st?= Date: Mon, 9 Sep 2024 17:33:43 +0200 Subject: [PATCH 1/2] feat(account_cloudtrail): Add KMS key support --- modules/account_cloudtrail/README.md | 13 ++- modules/account_cloudtrail/kms.tf | 115 ++++++++++++++++++++++++ modules/account_cloudtrail/main.tf | 18 ++-- modules/account_cloudtrail/variables.tf | 20 ++++- modules/account_cloudtrail/versions.tf | 4 +- 5 files changed, 156 insertions(+), 14 deletions(-) create mode 100644 modules/account_cloudtrail/kms.tf diff --git a/modules/account_cloudtrail/README.md b/modules/account_cloudtrail/README.md index 7621863..17ad154 100644 --- a/modules/account_cloudtrail/README.md +++ b/modules/account_cloudtrail/README.md @@ -7,19 +7,20 @@ For examples please look in the `tests` directory. | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0.0 | -| [aws](#requirement\_aws) | >= 4.7.0 | +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [aws](#requirement\_aws) | >= 5.4.9 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 4.7.0 | +| [aws](#provider\_aws) | >= 5.4.9 | ## Modules | Name | Source | Version | |------|--------|---------| +| [kms](#module\_kms) | terraform-aws-modules/kms/aws | 3.1.0 | | [s3-bucket](#module\_s3-bucket) | terraform-aws-modules/s3-bucket/aws | 3.6.0 | ## Resources @@ -29,14 +30,18 @@ For examples please look in the `tests` directory. | [aws_cloudtrail.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail) | resource | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [cloudtrail\_name](#input\_cloudtrail\_name) | The name of the cloudtrail. This is optional and defaults to cloudtrail-. | `string` | `null` | no | -| [kms\_key\_arn](#input\_kms\_key\_arn) | The ARN of the KMS key to use for encryption of cloudtrail. If no ARN is provided cloudtrail won't be encrypted. | `string` | `null` | no | +| [create\_kms\_key](#input\_create\_kms\_key) | Controls if a customer managed KMS key should be created | `bool` | `true` | no | +| [kms\_key\_arn](#input\_kms\_key\_arn) | The ARN of the KMS key to use for encryption of cloudtrail. If no ARN is provided and create\_kms\_key is not used cloudtrail won't be encrypted. | `string` | `null` | no | | [s3\_bucket\_name](#input\_s3\_bucket\_name) | The name of the S3 bucket to store cloudtrail logs in. This is optional and defaults to a prefix with cloudtrail--. | `string` | `null` | no | +| [s3\_lifecycle\_expiration](#input\_s3\_lifecycle\_expiration) | Days after which files get marked non-current from the expire lifecycle rule. | `number` | `365` | no | +| [s3\_lifecycle\_noncurrent\_expiration](#input\_s3\_lifecycle\_noncurrent\_expiration) | Days after which non-current marked files get deleted from the expire lifecycle rule. | `number` | `180` | no | ## Outputs diff --git a/modules/account_cloudtrail/kms.tf b/modules/account_cloudtrail/kms.tf new file mode 100644 index 0000000..a62c36e --- /dev/null +++ b/modules/account_cloudtrail/kms.tf @@ -0,0 +1,115 @@ +module "kms" { + source = "terraform-aws-modules/kms/aws" + version = "3.1.0" + + create = var.create_kms_key + aliases = ["cloudtrail-${local.region}"] + description = "CloudTrail encryption" + enable_default_policy = true + + key_statements = [ + { + sid = "Allow CloudTrail to encrypt logs" + actions = [ + "kms:GenerateDataKey*" + ] + resources = ["*"] + principals = [ + { + type = "Service" + identifiers = ["cloudtrail.amazonaws.com"] + } + ] + conditions = [ + { + test = "StringEquals" + variable = "aws:SourceArn" + values = ["arn:aws:cloudtrail:${local.region}:${local.account_id}:trail/${local.cloudtrail_name}"] + }, + { + test = "StringLike" + variable = "kms:EncryptionContext:aws:cloudtrail:arn" + values = ["arn:aws:cloudtrail:*:${local.account_id}:trail/*"] + } + ] + }, + { + sid = "Allow CloudTrail to describe key" + actions = [ + "kms:DescribeKey" + ] + resources = ["*"] + principals = [ + { + type = "Service" + identifiers = ["cloudtrail.amazonaws.com"] + } + ] + }, + { + sid = "Allow principals in the account to decrypt log files" + actions = [ + "kms:Decrypt", + "kms:ReEncryptFrom" + ] + resources = ["*"] + principals = [ + { + type = "AWS" + identifiers = ["*"] + } + ] + conditions = [ + { + test = "StringEquals" + variable = "kms:CallerAccount" + values = [local.account_id] + }, + { + test = "StringLike" + variable = "kms:EncryptionContext:aws:cloudtrail:arn" + values = ["arn:aws:cloudtrail:*:${local.account_id}:trail/*"] + } + ] + }, + { + sid = "Allow alias creation during setup" + actions = [ + "kms:CreateAlias" + ] + resources = ["arn:aws:kms:region:${local.account_id}:key/*"] + principals = [ + { + type = "AWS" + identifiers = ["*"] + } + ] + conditions = [ + { + test = "StringEquals" + variable = "kms:ViaService" + values = ["ec2.us-east-1.amazonaws.com"] + }, + { + test = "StringEquals" + variable = "kms:CallerAccount" + values = [local.account_id] + } + ] + }, + { + sid = "Allow CloudTrail to encrypt event data store" + actions = [ + "kms:GenerateDataKey*", + "kms:Decrypt" + ] + resources = ["*"] + principals = [ + { + type = "Service" + identifiers = ["cloudtrail.amazonaws.com"] + } + ] + } + ] +} diff --git a/modules/account_cloudtrail/main.tf b/modules/account_cloudtrail/main.tf index 93973c6..3181425 100644 --- a/modules/account_cloudtrail/main.tf +++ b/modules/account_cloudtrail/main.tf @@ -1,8 +1,12 @@ data "aws_caller_identity" "current" {} +data "aws_region" "current" {} locals { - cloudtrail_name = var.cloudtrail_name == null ? "cloudtrail-${data.aws_caller_identity.current.account_id}" : var.cloudtrail_name - s3_encryption_configuration = var.kms_key_arn == null ? { + account_id = data.aws_caller_identity.current.account_id + cloudtrail_name = var.cloudtrail_name == null ? "cloudtrail-${local.account_id}" : var.cloudtrail_name + kms_key_arn = var.create_kms_key ? module.kms.key_arn : var.kms_key_arn + region = data.aws_region.current.name + s3_encryption_configuration = local.kms_key_arn == null ? { rule = { apply_server_side_encryption_by_default = { sse_algorithm = "AES256" @@ -11,7 +15,7 @@ locals { } : { rule = { apply_server_side_encryption_by_default = { - kms_master_key_id = var.kms_key_arn + kms_master_key_id = local.kms_key_arn sse_algorithm = "aws:kms" } } @@ -23,7 +27,7 @@ module "s3-bucket" { version = "3.6.0" bucket = var.s3_bucket_name - bucket_prefix = var.s3_bucket_name == null ? "cloudtrail-${data.aws_caller_identity.current.account_id}-" : null + bucket_prefix = var.s3_bucket_name == null ? "cloudtrail-${local.account_id}-" : null acl = "private" attach_policy = true policy = data.aws_iam_policy_document.bucket_policy.json @@ -44,10 +48,10 @@ module "s3-bucket" { prefix = "/" } expiration = { - days = 365 + days = var.s3_lifecycle_expiration } noncurrent_version_expiration = { - days = 180 + days = var.s3_lifecycle_noncurrent_expiration } } ] @@ -101,5 +105,5 @@ resource "aws_cloudtrail" "this" { include_global_service_events = true is_multi_region_trail = true s3_bucket_name = module.s3-bucket.s3_bucket_id - kms_key_id = var.kms_key_arn + kms_key_id = local.kms_key_arn } diff --git a/modules/account_cloudtrail/variables.tf b/modules/account_cloudtrail/variables.tf index b5be8ce..ab27501 100644 --- a/modules/account_cloudtrail/variables.tf +++ b/modules/account_cloudtrail/variables.tf @@ -1,5 +1,11 @@ +variable "create_kms_key" { + description = "Controls if a customer managed KMS key should be created" + type = bool + default = true +} + variable "kms_key_arn" { - description = "The ARN of the KMS key to use for encryption of cloudtrail. If no ARN is provided cloudtrail won't be encrypted." + description = "The ARN of the KMS key to use for encryption of cloudtrail. If no ARN is provided and create_kms_key is not used cloudtrail won't be encrypted." type = string default = null } @@ -10,6 +16,18 @@ variable "s3_bucket_name" { default = null } +variable "s3_lifecycle_expiration" { + description = "Days after which files get marked non-current from the expire lifecycle rule." + type = number + default = 365 +} + +variable "s3_lifecycle_noncurrent_expiration" { + description = "Days after which non-current marked files get deleted from the expire lifecycle rule." + type = number + default = 180 +} + variable "cloudtrail_name" { description = "The name of the cloudtrail. This is optional and defaults to cloudtrail-." type = string diff --git a/modules/account_cloudtrail/versions.tf b/modules/account_cloudtrail/versions.tf index aee4a1c..5914549 100644 --- a/modules/account_cloudtrail/versions.tf +++ b/modules/account_cloudtrail/versions.tf @@ -1,8 +1,8 @@ terraform { - required_version = ">= 1.0.0" + required_version = ">= 1.3.0" required_providers { aws = { - version = ">= 4.7.0" + version = ">= 5.4.9" } } } From cd3518e0b0ac3246ed6f0ef4a47886d5b920d309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20V=C3=B6st?= Date: Mon, 9 Sep 2024 17:37:22 +0200 Subject: [PATCH 2/2] chore(account_cloudtrail): Bump terraform-aws-modules/s3-bucket to 4.1.2 --- modules/account_cloudtrail/README.md | 2 +- modules/account_cloudtrail/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/account_cloudtrail/README.md b/modules/account_cloudtrail/README.md index 17ad154..60d3d51 100644 --- a/modules/account_cloudtrail/README.md +++ b/modules/account_cloudtrail/README.md @@ -21,7 +21,7 @@ For examples please look in the `tests` directory. | Name | Source | Version | |------|--------|---------| | [kms](#module\_kms) | terraform-aws-modules/kms/aws | 3.1.0 | -| [s3-bucket](#module\_s3-bucket) | terraform-aws-modules/s3-bucket/aws | 3.6.0 | +| [s3-bucket](#module\_s3-bucket) | terraform-aws-modules/s3-bucket/aws | 4.1.2 | ## Resources diff --git a/modules/account_cloudtrail/main.tf b/modules/account_cloudtrail/main.tf index 3181425..d9bf509 100644 --- a/modules/account_cloudtrail/main.tf +++ b/modules/account_cloudtrail/main.tf @@ -24,7 +24,7 @@ locals { module "s3-bucket" { source = "terraform-aws-modules/s3-bucket/aws" - version = "3.6.0" + version = "4.1.2" bucket = var.s3_bucket_name bucket_prefix = var.s3_bucket_name == null ? "cloudtrail-${local.account_id}-" : null