diff --git a/s3-logs/README.md b/s3-logs/README.md index a348763..55a5554 100644 --- a/s3-logs/README.md +++ b/s3-logs/README.md @@ -174,6 +174,7 @@ No modules. | [bucket\_name](#input\_bucket\_name) | Logs S3 bucket name | `string` | `""` | no | | [bucket\_name\_prefix](#input\_bucket\_name\_prefix) | Logs S3 bucket prefix, prepended to the AWS account ID to make the bucket name. | `string` | `"inf-logs"` | no | | [component\_tags](#input\_component\_tags) | Additional tags for Components (s3, kms, ddb) | `map(map(string))` |
{
"ddb": {},
"kms": {},
"s3": {}
}
| no | +| [kms\_key\_arn](#input\_kms\_key\_arn) | AWS KMS ARN to be used for encrypting the S3 bucket. If not provided, the default aws/s3 key will be used | `string` | `null` | no | | [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component (efs, s3, ebs, kms, role, policy, security-group). This should be used primarily for common infrastructure things | `map(string)` | `{}` | no | | [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no | | [versioning\_configuration](#input\_versioning\_configuration) | S3 Versioning Configuration (Enabled, Disabled, Suspended). To disable, use Suspended if existing bucket and Disabled if new | `string` | `"Disabled"` | no | diff --git a/s3-logs/kms.tf.off b/s3-logs/kms.tf.off index 89c7831..6b63e59 100644 --- a/s3-logs/kms.tf.off +++ b/s3-logs/kms.tf.off @@ -17,3 +17,140 @@ resource "aws_kms_alias" "key" { name = "alias/${local.kms_key_name}" target_key_id = aws_kms_key.key.key_id } + +locals { + # basic details about the env + account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id + region = data.aws_region.current.name + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" + partition = data.aws_arn.current.partition + + name = var.name == null ? format("%v-%v", lookup(local._defaults["cloudtrail"], "name"), local.region) : var.name + kms_key_name = format("%v%v", local._prefixes["kms"], local.name) + kms_admin_root = format("arn:%v:iam::%v:root", local.partition, local.account_id) + # kms_admin_roles = compact(concat([local.kms_admin_root], var.kms_admin_roles)) + kms_admin_roles = var.kms_admin_roles + kms_policy_document = var.kms_policy_document != null ? var.kms_policy_document : data.aws_iam_policy_document.empty.json +} + +data "aws_iam_policy_document" "key_policy_combined" { + source_policy_documents = [ + data.aws_iam_policy_document.key.json, + data.aws_iam_policy_document.key_admin.json, + local.kms_policy_document + ] +} + +data "aws_iam_policy_document" "key_admin" { + dynamic "statement" { + for_each = length(local.kms_admin_roles) > 0 ? [1] : [] + content { + sid = "BuiltinKMSAdminRoles" + effect = "Allow" + actions = ["kms:*"] + resources = ["*"] + principals { + type = "AWS" + identifiers = local.kms_admin_roles + } + } + } +} + +data "aws_iam_policy_document" "empty" {} + + +#--- +# key policy for clodutrail +# https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-kms-key-policy-for-cloudtrail.html +# can't use aws_cloudtrail.this.arn as it makes for a circular reference +# +# from aws-setup-s3-object-logging +#--- +data "aws_iam_policy_document" "key" { + policy_id = "object-logging-cloud-trail" + # manage key by root and other principals + statement { + sid = "IAMPermissionsAccessKMSManagement" + effect = "Allow" + actions = ["kms:*"] + resources = ["*"] + principals { + type = "AWS" + identifiers = [local.kms_admin_root] + } + } + # let cloudtrial, logs, sns, and sqs find key + statement { + sid = "KMSDescribeKeyFromServices" + effect = "Allow" + actions = ["kms:DescribeKey"] + resources = ["*"] + principals { + type = "Service" + identifiers = ["cloudtrail.amazonaws.com", "sns.amazonaws.com", "sqs.amazonaws.com", "s3.amazonaws.com"] + } + } + statement { + sid = "CloudTrailKMSEncryptAccess" + effect = "Allow" + actions = [ + "kms:Decrypt*", + "kms:Encrypt*", + "kms:ReEncrypt*", + "kms:GenerateDataKey", + ] + resources = ["*"] + principals { + type = "Service" + identifiers = ["cloudtrail.amazonaws.com", "s3.amazonaws.com"] + } + # condition { + # test = "StringLike" + # variable = "kms:EncryptionContext:aws:cloudtrail:arn" + # values = [format("arn:%v:cloudtrail:*:%v:trail/*", local.partition, local.account_id)] + # } + } + # https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/encrypt-log-data-kms.html + statement { + sid = "Cloudwatch" + effect = "Allow" + actions = [ + "kms:Decrypt*", + "kms:Encrypt*", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:Describe*" + ] + resources = ["*"] + principals { + type = "Service" + identifiers = ["logs.amazonaws.com", "logs.${local.region}.amazonaws.com"] + } + condition { + test = "StringLike" + variable = "kms:EncryptionContext:aws:logs:arn" + values = [format("arn:%v:logs:%v:%v:log-group:*", local.partition, local.region, local.account_id)] + } + } + # https://aws.amazon.com/blogs/compute/encrypting-messages-published-to-amazon-sns-with-aws-kms/ + # https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html#sns-what-permissions-for-sse + # https://docs.aws.amazon.com/sns/latest/dg/sns-enable-encryption-for-topic-sqs-queue-subscriptions.html + statement { + sid = "ServiceMSAccess" + effect = "Allow" + actions = [ + "kms:Decrypt*", + "kms:GenerateDataKey*", + "kms:Describe*" + ] + resources = ["*"] + principals { + type = "Service" + identifiers = ["sns.amazonaws.com", "sqs.amazonaws.com", "s3.amazonaws.com"] + } + } +} + +# producers and consumers +# https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html#compatibility-with-aws-services diff --git a/s3-logs/main.tf b/s3-logs/main.tf index a721a40..5f83680 100644 --- a/s3-logs/main.tf +++ b/s3-logs/main.tf @@ -132,8 +132,8 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "logs" { bucket = aws_s3_bucket.logs.id rule { apply_server_side_encryption_by_default { - # sse_algorithm = "aws:kms" - sse_algorithm = "AES256" + sse_algorithm = "aws:kms" + kms_master_key_id = var.kms_key_arn } bucket_key_enabled = true } diff --git a/s3-logs/variables.tf b/s3-logs/variables.tf index fc0eac1..5f23d1e 100644 --- a/s3-logs/variables.tf +++ b/s3-logs/variables.tf @@ -21,3 +21,9 @@ variable "versioning_configuration" { type = string default = "Disabled" } + +variable "kms_key_arn" { + description = "AWS KMS ARN to be used for encrypting the S3 bucket. If not provided, the default aws/s3 key will be used" + type = string + default = null +}