diff --git a/cloudtrail_orig/README.md b/cloudtrail_orig/README.md new file mode 100644 index 0000000..d6eef0c --- /dev/null +++ b/cloudtrail_orig/README.md @@ -0,0 +1,100 @@ +# aws-inf-setup :: cloudtrail + +This set up the needed components for cloudtrail in a region: S3, KMS key, SNS, SQS, cloudtrail, +cloudwatch log groups, and associated permissions. It also generates a splunk configuration to be used +for pulling cloudtrail events. + +* S3 bucket +* S3 bucket policy + +# Usage +Here is a simple example, the one most commonly expected to be used. + +```hcl +module "cloudtrail" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail" + + # account_alias = "do2-govcloud" + name = "mycloudtrail" + access_log_bucket = "myaccesslogbucket" + kms_key_management_identifiers = [ "arn:aws:iam::079788916859:role/r-inf-cloud-admin" ] +} +``` + +This one can be used if you need to customize stuff, though really, the defaults are all built +for a reason, and deployment code (i.e., Ansible) will expect these defaults to be used in +variable file generation. + +```hcl +module "cloudtrail_full" { + + # logs is generally not needed and not recommended + component_tags = { + "s3" = { + "SpecialTag1" = "something" + "SpecialTag2" = "somethingElse" + } + } +} +``` + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [null](#provider\_null) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudtrail.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail) | resource | +| [aws_kms_alias.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_s3_bucket.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_policy.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [aws_s3_bucket_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [aws_s3_bucket_public_access_block.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.cloudtrail_s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.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 | +|------|-------------|------|---------|:--------:| +| [access\_log\_bucket](#input\_access\_log\_bucket) | Server Access Logging Bucket ID | `string` | n/a | yes | +| [access\_log\_bucket\_prefix](#input\_access\_log\_bucket\_prefix) | Server Access Log bucket prefix, to which the Object Logging bucket name will be appended to make the target\_prefix | `string` | `"s3"` | no | +| [account\_alias](#input\_account\_alias) | AWS Account Alias | `string` | `""` | no | +| [account\_id](#input\_account\_id) | AWS Account ID (default will pull from current user) | `string` | `""` | no | +| [cloudtrail\_bucket\_prefix](#input\_cloudtrail\_bucket\_prefix) | Access log bucket prefix, to which the bucket name will be appended to make the target\_prefix | `string` | `"cloudtrail"` | no | +| [component\_tags](#input\_component\_tags) | Additional tags for Components (s3, kms, ddb) | `map(map(string))` |
{
"ddb": {},
"kms": {},
"s3": {}
} | no |
+| [enable\_sns](#input\_enable\_sns) | Flag to enable or disable the creation of SNS for Cloudtrail (TBD) | `bool` | `false` | no |
+| [enable\_sqs](#input\_enable\_sqs) | Flag to enable or disable the creation of SQS attached to SNS for Cloudtrail, used for Splunk ingestion (TBD) | `bool` | `false` | no |
+| [kms\_key\_management\_identifiers](#input\_kms\_key\_management\_identifiers) | AWS IAM ARNs (roles, groups, users) for full access to the created KMS Key for this bucket | `list(string)` | `[]` | no |
+| [name](#input\_name) | Name to apply to Cloudtrail, S3, SNS and SQS | `string` | `null` | no |
+| [object\_log\_bucket\_prefix](#input\_object\_log\_bucket\_prefix) | Access log bucket prefix, to which the bucket name will be appended to make the target\_prefix | `string` | `"s3_object_logs"` | 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) | Tags to apply to all resources | `map(string)` | `{}` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [kms\_key\_arn](#output\_kms\_key\_arn) | Cloudtrail Key ARN |
+| [kms\_key\_id](#output\_kms\_key\_id) | Cloudtrail Key ID |
diff --git a/cloudtrail_orig/data.policies.tf b/cloudtrail_orig/data.policies.tf
new file mode 100644
index 0000000..e092555
--- /dev/null
+++ b/cloudtrail_orig/data.policies.tf
@@ -0,0 +1,31 @@
+data "aws_iam_policy_document" "cloudtrail_s3" {
+ statement {
+ sid = "AWSCloudTrailWrite"
+ effect = "Allow"
+ resources = ["${aws_s3_bucket.cloudtrail.arn}/*"]
+ actions = ["s3:PutObject"]
+
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+
+ condition {
+ test = "StringLike"
+ variable = "s3:x-amz-acl"
+ values = ["bucket-owner-full-control"]
+ }
+ }
+
+ statement {
+ sid = "AWSCloudTrailAclCheck"
+ effect = "Allow"
+ resources = [aws_s3_bucket.cloudtrail.arn]
+ actions = ["s3:GetBucketAcl"]
+
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ }
+}
diff --git a/cloudtrail_orig/data.tf b/cloudtrail_orig/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/cloudtrail_orig/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/cloudtrail_orig/defaults.tf b/cloudtrail_orig/defaults.tf
new file mode 120000
index 0000000..a5556ac
--- /dev/null
+++ b/cloudtrail_orig/defaults.tf
@@ -0,0 +1 @@
+../common/defaults.tf
\ No newline at end of file
diff --git a/cloudtrail_orig/kms.tf b/cloudtrail_orig/kms.tf
new file mode 100644
index 0000000..63f49fa
--- /dev/null
+++ b/cloudtrail_orig/kms.tf
@@ -0,0 +1,166 @@
+#---
+# kms key
+#---
+resource "aws_kms_key" "key" {
+ description = "Encrypt CloudTrail objects and streams"
+ enable_key_rotation = true
+ policy = data.aws_iam_policy_document.key.json
+
+ tags = merge(
+ local.common_tags,
+ map("boc:aws:region", local.region),
+ map("Name", var.kms_key),
+ )
+ lifecycle {
+ ignore_changes = [tags["boc:tf_module_version"]]
+ }
+}
+
+resource "aws_kms_alias" "key" {
+ name = "alias/${var.kms_key}"
+ target_key_id = aws_kms_key.key.key_id
+}
+
+output "kms_key_id" {
+ description = "Cloudtrail Key ID"
+ value = aws_kms_key.key.id
+}
+output "kms_key_arn" {
+ description = "Cloudtrail Key ARN"
+ value = aws_kms_key.key.arn
+}
+
+data "aws_iam_policy_document" "key" {
+ policy_id = "inf-cloudtrail KMS access"
+ statement {
+ sid = "EnableIAMUserPermissions"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+
+ identifiers = [
+ # data.aws_caller_identity.current.arn,
+ "arn:${data.aws_arn.current.partition}:iam::${var.account_id}:root",
+ # "arn:${data.aws_arn.current.partition}:sts::${var.account_id}:assumed-role/r-inf-cloud-admin/${var.tag_creator}",
+ ]
+ }
+ }
+
+ statement {
+ sid = "AllowCloudTrailEncryptLogs"
+ effect = "Allow"
+ actions = ["kms:GenerateDataKey*"]
+ resources = ["*"]
+
+ principals {
+ type = "Service"
+ # identifiers = ["cloudtrail.amazonaws.com"]
+ identifiers = ["cloudtrail.amazonaws.com", "logs.amazonaws.com", "logs.${local.region}.amazonaws.com"]
+ }
+
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:${data.aws_arn.current.partition}:cloudtrail:*:${var.account_id}:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "AllowCloudTrailKeyActivities"
+ effect = "Allow"
+ actions = [
+ "kms:Describe*",
+ "log:AssociateKmsKey",
+ "log:DisassociateKmsKey"
+ ]
+ resources = ["*"]
+
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com", "logs.amazonaws.com", "logs.${local.region}.amazonaws.com"]
+ }
+ }
+
+ statement {
+ sid = "AllowPrincipalsDecryptLogFiles"
+ effect = "Allow"
+
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ actions = [
+ "kms:Encrypt",
+ "kms:Decrypt",
+ "kms:ReEncryptFrom"
+ ]
+ resources = ["*"]
+
+ condition {
+ test = "StringEquals"
+ variable = "kms:CallerAccount"
+ values = [var.account_id]
+ }
+
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:${data.aws_arn.current.partition}:cloudtrail:*:${var.account_id}:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "EnableCrossAccountDecryptLogFiles"
+ effect = "Allow"
+
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+
+ actions = [
+ "kms:Encrypt",
+ "kms:Decrypt",
+ "kms:ReEncryptFrom"
+ ]
+ resources = ["*"]
+
+ condition {
+ test = "StringEquals"
+ variable = "kms:CallerAccount"
+ values = [var.account_id]
+ }
+
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = ["arn:${data.aws_arn.current.partition}:cloudtrail:*:${var.account_id}:trail/*"]
+ }
+ }
+
+ statement {
+ sid = "AllowAliasCreationDuringSetup"
+ effect = "Allow"
+ actions = ["kms:CreateAlias"]
+ resources = ["*"]
+
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+
+ condition {
+ test = "StringEquals"
+ variable = "kms:CallerAccount"
+ values = [var.account_id]
+ }
+
+ condition {
+ test = "StringEquals"
+ variable = "kms:ViaService"
+ values = ["ec2.${local.region}.amazonaws.com}"]
+ }
+ }
+}
diff --git a/cloudtrail_orig/m b/cloudtrail_orig/m
new file mode 100644
index 0000000..2797179
--- /dev/null
+++ b/cloudtrail_orig/m
@@ -0,0 +1,6 @@
+/*
+*
+* cloudtrail
+* sqs, dead letter
+* sns
+*
diff --git a/cloudtrail_orig/main.tf b/cloudtrail_orig/main.tf
new file mode 100644
index 0000000..e90fa70
--- /dev/null
+++ b/cloudtrail_orig/main.tf
@@ -0,0 +1,272 @@
+/*
+* # aws-inf-setup :: cloudtrail
+*
+* This set up the needed components for cloudtrail in a region: S3, KMS key, SNS, SQS, cloudtrail,
+* cloudwatch log groups, and associated permissions. It also generates a splunk configuration to be used
+* for pulling cloudtrail events.
+*
+* * S3 bucket
+* * S3 bucket policy
+*
+* # Usage
+* Here is a simple example, the one most commonly expected to be used.
+*
+* ```hcl
+* module "cloudtrail" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+*
+* # account_alias = "do2-govcloud"
+* name = "mycloudtrail"
+* access_log_bucket = "myaccesslogbucket"
+* kms_key_management_identifiers = [ "arn:aws:iam::079788916859:role/r-inf-cloud-admin" ]
+* }
+* ```
+*
+* This one can be used if you need to customize stuff, though really, the defaults are all built
+* for a reason, and deployment code (i.e., Ansible) will expect these defaults to be used in
+* variable file generation.
+*
+* ```hcl
+* module "cloudtrail_full" {
+*
+* # logs is generally not needed and not recommended
+* component_tags = {
+* "s3" = {
+* "SpecialTag1" = "something"
+* "SpecialTag2" = "somethingElse"
+* }
+* }
+* }
+* ```
+*/
+
+locals {
+ 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
+
+
+ # remap do2 to do1 for govcloud (undo this later when accounts are renamed in splunk)
+ # account_alias = replace(var.account_alias, "do2", "do1")
+
+ name = (var.name != "" && var.name != null) ? var.name : format("%v-%v-%v", lookup(local._defaults["cloudtrail"], "name"), local.account_id, local.region)
+
+ bucket_id = aws_s3_bucket.cloudtrail.id
+ bucket_arn = aws_s3_bucket.cloudtrail.arn
+
+ # kms_key_arn_exists = var.kms_key_arn != "" && var.kms_key_arn != null
+ # kms_key_arn = aws_kms_key.key.arn
+ kms_key_name = format("%s%s", local._prefixes["kms"], local.name)
+
+ base_tags = {
+ "boc:tf_module_version" = local._module_version
+ "boc:created_by" = "terraform"
+ }
+}
+
+#@@@
+
+#---
+# cloudtrail, with encryption
+#---
+resource "aws_cloudtrail" "this" {
+ name = local.name
+ s3_bucket_name = aws_s3_bucket.this.id
+ s3_key_prefix = var.cloudtrail_bucket_prefix
+ include_global_service_events = false
+ is_multi_region_trail = false
+ kms_key_id = aws_kms_key.key.arn
+ enable_log_file_validation = true
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ { "Name" = local.name },
+ )
+ depends_on = [aws_s3_bucket_policy.policy]
+}
+
+#---
+# s3 object logging bucket, with encryption
+#---
+resource "aws_s3_bucket" "this" {
+ bucket = local.name
+ acl = "private"
+ force_destroy = false
+
+ logging {
+ target_bucket = var.access_log_bucket
+ target_prefix = format("%s/%s/", var.access_log_bucket_prefix, local.name)
+ }
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ { "Name" = local.name },
+ )
+
+ server_side_encryption_configuration {
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = aws_kms_key.key.arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+ }
+}
+
+#---
+# bucket policy (apply also encryption key usage here?)
+# deny unencrypted uploads policy statement removed for default encryption
+#---
+data "aws_iam_policy_document" "policy" {
+ statement {
+ sid = "AWSCloudTrailAclCheck"
+ effect = "Allow"
+ actions = ["s3:GetBucketAcl"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ resources = [aws_s3_bucket.this.arn]
+ }
+ statement {
+ sid = "AWSCloudTrailWrite"
+ effect = "Allow"
+ actions = ["s3:PutObject"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ resources = ["${aws_s3_bucket.this.arn}/${var.cloudtrail_bucket_prefix}/*"]
+ condition {
+ test = "StringEquals"
+ variable = "s3:x-amz-acl"
+ values = ["bucket-owner-full-control"]
+ }
+ }
+}
+
+#---
+# apply policy to bucket and public access block policy to bucket
+#---
+resource "aws_s3_bucket_policy" "policy" {
+ bucket = aws_s3_bucket.this.bucket
+ policy = data.aws_iam_policy_document.policy.json
+ depends_on = [null_resource.policy_delay]
+}
+
+resource "aws_s3_bucket_public_access_block" "this" {
+ bucket = aws_s3_bucket.this.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+#---
+# 180s delay needed for bucket to create and policy to apply, before
+# creating a cloudtrail to point to it
+#---
+resource "null_resource" "policy_delay" {
+ triggers = {
+ bucket = aws_s3_bucket.this.id
+ # policy = aws_s3_bucket_policy.policy.id
+ }
+ provisioner "local-exec" {
+ when = create
+ command = "sleep 180"
+ }
+}
+
+#---
+# create a key and alias if not specified
+#---
+resource "aws_kms_key" "key" {
+ description = "KMS CMK for Cloudtrail and S3 bucket ${local.name}"
+ enable_key_rotation = true
+ policy = data.aws_iam_policy_document.key.json
+
+ tags = merge(
+ local.base_tags,
+ { "Name" = local.kms_key_name },
+ var.tags
+ )
+}
+
+resource "aws_kms_alias" "key" {
+ name = "alias/${local.kms_key_name}"
+ target_key_id = aws_kms_key.key.key_id
+}
+
+
+#---
+# 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
+#---
+data "aws_iam_policy_document" "key" {
+ policy_id = "object-logging-cloud-trail"
+ statement {
+ sid = "IAMPermissionsAccessKMSManagement"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+ identifiers = compact(concat(list(format("arn:%s:iam::%s:root", local.partition, local.account_id)), var.kms_key_management_identifiers))
+ # data.aws_caller_identity.current.arn,
+ # aws_iam_role.inf-cloud-admin.arn,
+ # "arn:${data.aws_arn.current.partition}:iam::${var.account_id}:root",
+ }
+ }
+ statement {
+ sid = "CloudTrailKMSAccess"
+ effect = "Allow"
+ actions = ["kms:DescribeKey"]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ }
+ statement {
+ sid = "CloudTrailKMSEncryptAccess"
+ effect = "Allow"
+ actions = ["kms:GenerateDataKey"]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = [format("arn:%s:cloudtrail:*:%s:trail/%s", local.partition, local.account_id, local.name)]
+ }
+ }
+}
+
+
+## {
+## "Sid": "Enable CloudTrail log decrypt permissions",
+## "Effect": "Allow",
+## "Principal": {
+## "AWS": "arn:aws:iam::111111111111:user/Bob"
+## },
+## "Action": "kms:Decrypt",
+## "Resource": "*",
+## "Condition": {
+## "Null": {
+## "kms:EncryptionContext:aws:cloudtrail:arn": "false"
+## }
+## }
+## }
+##
+##
+##
+##
+
+#@@@
+
diff --git a/cloudtrail_orig/ol.tf b/cloudtrail_orig/ol.tf
new file mode 100644
index 0000000..7470898
--- /dev/null
+++ b/cloudtrail_orig/ol.tf
@@ -0,0 +1,252 @@
+/*
+* ```hcl
+* module "cloudtrail" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+*
+* name = "mycloudtrail"
+* access_log_bucket = "myaccesslogbucket"
+* kms_key_management_identifiers = [ "arn:aws:iam::079788916859:role/r-inf-cloud-admin" ]
+* }
+* ```
+*
+*/
+
+#---
+# get account and partition values from caller
+#---
+data "aws_caller_identity" "current" {}
+data "aws_arn" "current" {
+ arn = data.aws_caller_identity.current.arn
+}
+data "aws_region" "current" {}
+
+#---
+# setup name, if missing
+# setup key, if missing
+# set base tags
+#---
+locals {
+ account_id = data.aws_caller_identity.current.account_id
+ aws_region = data.aws_region.current.name
+ partition = data.aws_arn.current.partition
+ name = (var.name != "" && var.name != null) ? var.name : format("inf-objectlogging-%v-%v", local.account_id, local.aws_region)
+
+ # kms_key_arn_exists = var.kms_key_arn != "" && var.kms_key_arn != null
+ kms_key_arn = aws_kms_key.key.arn
+ kms_key_name = format("%s%s", local._prefixes["kms"], local.name)
+
+ base_tags = {
+ "boc:tf_module_version" = var._module_version
+ "boc:created_by" = "terraform"
+ }
+}
+
+#---
+# cloudtrail, with encryption
+#---
+resource "aws_cloudtrail" "this" {
+ name = local.name
+ s3_bucket_name = aws_s3_bucket.this.id
+ s3_key_prefix = var.object_log_bucket_prefix
+ include_global_service_events = false
+ is_multi_region_trail = false
+ kms_key_id = local.kms_key_arn
+ enable_log_file_validation = true
+
+ event_selector {
+ read_write_type = "All"
+ include_management_events = false
+
+ data_resource {
+ type = "AWS::S3::Object"
+ values = ["arn:${local.partition}:s3:::"]
+ }
+ }
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ { "Name" = local.name },
+ )
+ depends_on = [aws_s3_bucket_policy.policy]
+}
+
+#---
+# s3 object logging bucket, with encryption
+#---
+resource "aws_s3_bucket" "this" {
+ bucket = local.name
+ acl = "private"
+ force_destroy = false
+
+ logging {
+ target_bucket = var.access_log_bucket
+ target_prefix = format("%s/%s/", var.access_log_bucket_prefix, local.name)
+ }
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ { "Name" = local.name },
+ )
+
+ server_side_encryption_configuration {
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = local.kms_key_arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+ }
+}
+
+#---
+# bucket policy (apply also encryption key usage here?)
+# deny unencrypted uploads policy statement removed for default encryption
+#---
+data "aws_iam_policy_document" "policy" {
+ statement {
+ sid = "AWSCloudTrailAclCheck"
+ effect = "Allow"
+ actions = ["s3:GetBucketAcl"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ resources = [aws_s3_bucket.this.arn]
+ }
+ statement {
+ sid = "AWSCloudTrailWrite"
+ effect = "Allow"
+ actions = ["s3:PutObject"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ resources = ["${aws_s3_bucket.this.arn}/${var.object_log_bucket_prefix}/*"]
+ condition {
+ test = "StringEquals"
+ variable = "s3:x-amz-acl"
+ values = ["bucket-owner-full-control"]
+ }
+ }
+}
+
+#---
+# apply policy to bucket and public access block policy to bucket
+#---
+resource "aws_s3_bucket_policy" "policy" {
+ bucket = aws_s3_bucket.this.bucket
+ policy = data.aws_iam_policy_document.policy.json
+ depends_on = [null_resource.policy_delay]
+}
+
+resource "aws_s3_bucket_public_access_block" "this" {
+ bucket = aws_s3_bucket.this.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+#---
+# 180s delay needed for bucket to create and policy to apply, before
+# creating a cloudtrail to point to it
+#---
+resource "null_resource" "policy_delay" {
+ triggers = {
+ bucket = aws_s3_bucket.this.id
+ # policy = aws_s3_bucket_policy.policy.id
+ }
+ provisioner "local-exec" {
+ when = create
+ command = "sleep 180"
+ }
+}
+
+#---
+# create a key and alias if not specified
+#---
+resource "aws_kms_key" "key" {
+ description = "KMS CMK for Cloudtrail and S3 bucket ${local.name}"
+ enable_key_rotation = true
+ policy = data.aws_iam_policy_document.key.json
+
+ tags = merge(
+ local.base_tags,
+ { "Name" = local.kms_key_name },
+ var.tags
+ )
+}
+
+resource "aws_kms_alias" "key" {
+ name = "alias/${local.kms_key_name}"
+ target_key_id = aws_kms_key.key.key_id
+}
+
+
+#---
+# 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
+#---
+data "aws_iam_policy_document" "key" {
+ policy_id = "object-logging-cloud-trail"
+ statement {
+ sid = "IAMPermissionsAccessKMSManagement"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+ identifiers = compact(concat(list(format("arn:%s:iam::%s:root", local.partition, local.account_id)), var.kms_key_management_identifiers))
+ # data.aws_caller_identity.current.arn,
+ # aws_iam_role.inf-cloud-admin.arn,
+ # "arn:${data.aws_arn.current.partition}:iam::${var.account_id}:root",
+ }
+ }
+ statement {
+ sid = "CloudTrailKMSAccess"
+ effect = "Allow"
+ actions = ["kms:DescribeKey"]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ }
+ statement {
+ sid = "CloudTrailKMSEncryptAccess"
+ effect = "Allow"
+ actions = ["kms:GenerateDataKey"]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ values = [format("arn:%s:cloudtrail:*:%s:trail/%s", local.partition, local.account_id, local.name)]
+ }
+ }
+}
+
+
+## {
+## "Sid": "Enable CloudTrail log decrypt permissions",
+## "Effect": "Allow",
+## "Principal": {
+## "AWS": "arn:aws:iam::111111111111:user/Bob"
+## },
+## "Action": "kms:Decrypt",
+## "Resource": "*",
+## "Condition": {
+## "Null": {
+## "kms:EncryptionContext:aws:cloudtrail:arn": "false"
+## }
+## }
+## }
+##
+##
+##
+##
diff --git a/cloudtrail_orig/olv.tf b/cloudtrail_orig/olv.tf
new file mode 100644
index 0000000..26fdd59
--- /dev/null
+++ b/cloudtrail_orig/olv.tf
@@ -0,0 +1,68 @@
+# enable_sns
+# enable_sqs
+# name (default = inf-objectlogging-{account}-{region})
+# cloudtrail_name (name)
+# log_bucket (existing bucket; if empty, will create one)
+# sns_name (name)
+# sqs_name (name)
+
+variable "name" {
+ description = "Name to apply to Cloudtrail, S3, SNS and SQS"
+ type = string
+ default = null
+}
+
+variable "object_log_bucket_prefix" {
+ description = "Access log bucket prefix, to which the bucket name will be appended to make the target_prefix"
+ type = string
+ default = "s3_object_logs"
+}
+
+# required
+variable "access_log_bucket" {
+ description = "Server Access Logging Bucket ID"
+ type = string
+ # default = null
+}
+
+variable "access_log_bucket_prefix" {
+ description = "Server Access Log bucket prefix, to which the Object Logging bucket name will be appended to make the target_prefix"
+ type = string
+ default = "s3"
+}
+
+# variable "bucket_folders" {
+# description = "List of folders (keys) to create after creation of Object Logging bucket"
+# type = list(string)
+# default = []
+# }
+
+# variable "kms_key_arn" {
+# description = "AWS KMS Key ARN for cloudtrail and bucket"
+# type = string
+# default = null
+# }
+
+variable "kms_key_management_identifiers" {
+ description = "AWS IAM ARNs (roles, groups, users) for full access to the created KMS Key for this bucket"
+ type = list(string)
+ default = []
+}
+
+variable "tags" {
+ description = "Tags to apply to all resources"
+ type = map(string)
+ default = {}
+}
+
+variable "enable_sns" {
+ description = "Flag to enable or disable the creation of SNS for Cloudtrail (TBD)"
+ type = bool
+ default = false
+}
+
+variable "enable_sqs" {
+ description = "Flag to enable or disable the creation of SQS attached to SNS for Cloudtrail, used for Splunk ingestion (TBD)"
+ type = bool
+ default = false
+}
diff --git a/cloudtrail_orig/prefixes.tf b/cloudtrail_orig/prefixes.tf
new file mode 120000
index 0000000..7e265d5
--- /dev/null
+++ b/cloudtrail_orig/prefixes.tf
@@ -0,0 +1 @@
+../common/prefixes.tf
\ No newline at end of file
diff --git a/cloudtrail_orig/s3.tf b/cloudtrail_orig/s3.tf
new file mode 100644
index 0000000..287b161
--- /dev/null
+++ b/cloudtrail_orig/s3.tf
@@ -0,0 +1,57 @@
+#---
+# s3
+#---
+resource "aws_s3_bucket" "cloudtrail" {
+ bucket = local.bucket_name
+ acl = "private"
+
+ server_side_encryption_cloudtrailuration {
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = aws_kms_key.cloudtrail_key.arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+ }
+
+ versioning {
+ enabled = false
+ }
+
+ logging {
+ target_bucket = aws_s3_bucket.logs.id
+ target_prefix = "s3/{local.cloudtrail_bucket}/"
+ }
+
+ lifecycle {
+ prevent_destroy = true
+ ignore_changes = [tags["boc:tf_module_version"]]
+ }
+
+ # probably want some migration of old data to some other location
+ # like glacier
+
+ tags = merge(
+ var.tags,
+ local.base_tags,
+ lookup(var.component_tags, "s3", {}),
+ map("Name", local.bucket_name),
+ )
+
+ provisioner "local-exec" {
+ command = "sleep 30"
+ }
+}
+
+resource "aws_s3_bucket_public_access_block" "cloudtrail" {
+ bucket = aws_s3_bucket.cloudtrail.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_policy" "cloudtrail" {
+ bucket = aws_s3_bucket.cloudtrail.id
+ policy = data.aws_iam_policy_document.cloudtrail_s3.json
+}
diff --git a/cloudtrail_orig/variables.common.tf b/cloudtrail_orig/variables.common.tf
new file mode 120000
index 0000000..7439ed8
--- /dev/null
+++ b/cloudtrail_orig/variables.common.tf
@@ -0,0 +1 @@
+../common/variables.common.tf
\ No newline at end of file
diff --git a/cloudtrail_orig/variables.tf b/cloudtrail_orig/variables.tf
new file mode 100644
index 0000000..bce9464
--- /dev/null
+++ b/cloudtrail_orig/variables.tf
@@ -0,0 +1,75 @@
+## variable "bucket_name" {
+## description = "Cloudtrail S3 bucket name"
+## type = string
+## default = ""
+## }
+##
+## variable "bucket_name_prefix" {
+## description = "Cloudtrail S3 bucket prefix, prepended to the AWS account ID and region to make the bucket name."
+## type = string
+## default = ""
+## }
+
+# enable_sns
+# enable_sqs
+# name (default = inf-cloudtrail-{account}-{region})
+# cloudtrail_name (name)
+# log_bucket (existing bucket; if empty, will create one)
+# sns_name (name)
+# sqs_name (name)
+
+variable "name" {
+ description = "Name to apply to Cloudtrail, S3, SNS and SQS"
+ type = string
+ default = null
+}
+
+variable "cloudtrail_bucket_prefix" {
+ description = "Access log bucket prefix, to which the bucket name will be appended to make the target_prefix"
+ type = string
+ default = "cloudtrail"
+}
+
+# required
+variable "access_log_bucket" {
+ description = "Server Access Logging Bucket ID"
+ type = string
+ # default = null
+}
+
+variable "access_log_bucket_prefix" {
+ description = "Server Access Log bucket prefix, to which the Object Logging bucket name will be appended to make the target_prefix"
+ type = string
+ default = "s3"
+}
+
+variable "kms_key_management_identifiers" {
+ description = "AWS IAM ARNs (roles, groups, users) for full access to the created KMS Key for this bucket"
+ type = list(string)
+ default = []
+}
+
+variable "tags" {
+ description = "Tags to apply to all resources"
+ type = map(string)
+ default = {}
+}
+
+variable "enable_sns" {
+ description = "Flag to enable or disable the creation of SNS for Cloudtrail (TBD)"
+ type = bool
+ default = false
+}
+
+variable "enable_sqs" {
+ description = "Flag to enable or disable the creation of SQS attached to SNS for Cloudtrail, used for Splunk ingestion (TBD)"
+ type = bool
+ default = false
+}
+
+variable "component_tags" {
+ description = "Additional tags for Components (s3, kms, ddb)"
+ type = map(map(string))
+ default = { "s3" = {}, "kms" = {}, "ddb" = {} }
+}
+
diff --git a/cloudtrail/version.tf b/cloudtrail_orig/version.tf
similarity index 100%
rename from cloudtrail/version.tf
rename to cloudtrail_orig/version.tf
diff --git a/common/defaults.tf b/common/defaults.tf
index 91dc82b..7e84a52 100644
--- a/common/defaults.tf
+++ b/common/defaults.tf
@@ -17,6 +17,12 @@ locals {
"ses" = {
"event_types" = ["bounce", "delivery", "complaint"]
}
+ "organization-cloudtrail" = {
+ "name" = "inf-org-cloudtrail"
+ }
+ "cloudtrail" = {
+ "name" = "inf-cloudtrail"
+ }
"config" = {
"name" = "inf-config"
}