diff --git a/README.md b/README.md index 820a376..bf417c2 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Full contributing [guidelines are covered here](.github/contributing.md). | [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the lambda. Required if `create_iam_role` is set to `false` | `string` | `null` | no | | [included\_accounts](#input\_included\_accounts) | List of accounts that be scanned to manual actions. If empty will scan all accounts. | `list(string)` | `[]` | no | | [included\_users](#input\_included\_users) | List of emails that be scanned to manual actions. If empty will scan all emails. | `list(string)` | `[]` | no | +| [kms\_key\_id\_for\_sns\_topic](#input\_kms\_key\_id\_for\_sns\_topic) | KMS key ID for encrypting the sns\_topic (only applicable to org deployments). | `string` | `null` | no | | [lambda\_deployment\_s3\_bucket](#input\_lambda\_deployment\_s3\_bucket) | S3 bucket for lambda deployment package. | `string` | `null` | no | | [lambda\_deployment\_s3\_key](#input\_lambda\_deployment\_s3\_key) | S3 object key for lambda deployment package. Otherwise, defaults to `var.naming_prefix/local.deployment_filename`. | `string` | `null` | no | | [lambda\_deployment\_upload\_to\_s3\_enabled](#input\_lambda\_deployment\_upload\_to\_s3\_enabled) | If `true`, the lambda deployment package within this module repo will be copied to S3. If `false` then the S3 object must be uploaded separately. Ignored if `lambda_deployment_s3_bucket` is null. | `bool` | `true` | no | diff --git a/deployment_organization.tf b/deployment_organization.tf index 022d2a9..8e0084b 100644 --- a/deployment_organization.tf +++ b/deployment_organization.tf @@ -27,6 +27,7 @@ resource "aws_sns_topic" "bucket_notifications" { # Cannot use AWS managed KMS key with S3 bucket notifications # Ref: https://aws.amazon.com/premiumsupport/knowledge-center/sns-not-receiving-s3-event-notifications/ # kms_master_key_id = "alias/aws/sns" + kms_master_key_id = var.kms_key_id_for_sns_topic tags = var.tags } diff --git a/examples/basic/README.md b/examples/basic/README.md index 2175d07..0664aa8 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -46,6 +46,9 @@ module "clickops_notifications" { webhook = "https://fake.com" message_format = "slack" tags = local.tags + + # Optional + kms_key_id_for_sns_topic = aws_kms_key.clickops_sns_topic.arn } @@ -53,6 +56,50 @@ resource "aws_s3_bucket" "test_bucket" { bucket = local.naming_prefix tags = local.tags } + +# To encrypt the SNS topic +data "aws_caller_identity" "current" {} + +data "aws_iam_policy_document" "clickops_sns_topic" { + statement { + sid = "Enable IAM User Permissions" + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] + } + actions = ["kms:*"] + resources = ["*"] + } + statement { + principals { + type = "Service" + identifiers = ["s3.amazonaws.com"] + } + actions = [ + "kms:GenerateDataKey*", + "kms:Decrypt" + ] + resources = ["*"] + condition { + test = "ArnEquals" + variable = "aws:SourceArn" + values = [aws_s3_bucket.test_bucket.arn] + } + condition { + test = "StringEquals" + variable = "aws:SourceAccount" + values = [data.aws_caller_identity.current.account_id] + } + } +} + +resource "aws_kms_key" "clickops_sns_topic" { + description = "KMS key for SNS topic ${local.naming_prefix}" + deletion_window_in_days = 7 + policy = data.aws_iam_policy_document.clickops_sns_topic.json + + tags = local.tags +} ``` ---- @@ -99,8 +146,11 @@ No outputs. | Name | Type | |------|------| +| [aws_kms_key.clickops_sns_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | | [aws_s3_bucket.test_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | | [random_pet.run_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.clickops_sns_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | ---- diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 66bb967..0c330b1 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -42,6 +42,9 @@ module "clickops_notifications" { webhook = "https://fake.com" message_format = "slack" tags = local.tags + + # Optional + kms_key_id_for_sns_topic = aws_kms_key.clickops_sns_topic.arn } @@ -49,3 +52,47 @@ resource "aws_s3_bucket" "test_bucket" { bucket = local.naming_prefix tags = local.tags } + +# To encrypt the SNS topic +data "aws_caller_identity" "current" {} + +data "aws_iam_policy_document" "clickops_sns_topic" { + statement { + sid = "Enable IAM User Permissions" + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] + } + actions = ["kms:*"] + resources = ["*"] + } + statement { + principals { + type = "Service" + identifiers = ["s3.amazonaws.com"] + } + actions = [ + "kms:GenerateDataKey*", + "kms:Decrypt" + ] + resources = ["*"] + condition { + test = "ArnEquals" + variable = "aws:SourceArn" + values = [aws_s3_bucket.test_bucket.arn] + } + condition { + test = "StringEquals" + variable = "aws:SourceAccount" + values = [data.aws_caller_identity.current.account_id] + } + } +} + +resource "aws_kms_key" "clickops_sns_topic" { + description = "KMS key for SNS topic ${local.naming_prefix}" + deletion_window_in_days = 7 + policy = data.aws_iam_policy_document.clickops_sns_topic.json + + tags = local.tags +} diff --git a/variables.tf b/variables.tf index e465a54..640331b 100644 --- a/variables.tf +++ b/variables.tf @@ -201,6 +201,13 @@ variable "additional_iam_policy_statements" { default = {} } +# Encryption configuration +variable "kms_key_id_for_sns_topic" { + description = "KMS key ID for encrypting the sns_topic (only applicable to org deployments)." + type = string + default = null +} + # Other configuration variable "firehose_delivery_stream_name" { description = "Kinesis Firehose delivery stream name to output ClickOps events to."