diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2056df3..f146357 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,8 +8,11 @@ repos: args: ['table'] exclude: common/*.tf exclude: version.tf + exclude: examples - id: terraform_tflint args: [ "--args=--config=__GIT_WORKING_DIR__/.tflint.hcl"] + exclude: cloudtrail_orig + exclude: examples - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index c021633..a72b45a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -126,3 +126,9 @@ * v1.13.3 -- 20211122 - config - fix by commenting policy_id from sqs policies + +* v1.14.0 -- 20211115 + - cloudtrail-key + - create module to setup a KMS key per region for cloudtrail + - cloudtrail + - create module to setup needed resources for cloudtrail, cloudwatch logs, sns, sqs, and splunk diff --git a/README.md b/README.md index dccaf0b..f852f84 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,23 @@ This sets the SES domain of the form `{account_id}.aws.mail.census.gov`. At this so be sure run it in the west region for govcloud. ### object-logging -### cloudtrail -### config + +This is in its own module [aws-setup-s3-object-logging](https://github.e.it.census.gov/terraform-modules/aws-setup-s3-object-logging). + +### [cloudtrail-key](cloudtrail-key) + +This creates a KMS key (region specific) for use by CloudTrail and all its resources (Cloudwatch Log, SNS, SQS, S3). + +### [cloudtrail](cloudtrail) + +This creates a CloudTrail (region specific) and supporing resources Cloudwatch Log, SNS, SQS, S3. It requires a KMS +key created specifically for this, from [cloudtrail-key](cloudtrail-key) above. It also creates Splunk input +configuration files. + +### [config](config) + +This creates the Config setup, a few Config Rules, SNS and SQS and Splunk input configurations files. + ### gpg-key ## Submodules :: Common diff --git a/cloudtrail-key/README.md b/cloudtrail-key/README.md new file mode 100644 index 0000000..61a86d0 --- /dev/null +++ b/cloudtrail-key/README.md @@ -0,0 +1,99 @@ +# aws-inf-setup :: cloudtrail-keys + +This set up the KMS key used by Cloudtrail for the ts S3 bucket, CloudTrail, and SQS (if possible). + +* Cloudtrail +* S3 bucket +* SQS + +## Usage, Simple Example +Here is a simple example, the one most commonly expected to be used. + +```hcl +module "cloudtrail_key_simple" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key" + + tags = { + Environment = "csvd:infrastructure" + } +} +``` + +## Usage, Longer Example +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_key_full" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key" + + name = "mycloudtrail" + kms_admin_roles = ["arn:aws:iam::079788916859:role/r-inf-cloud-admin"] + kms_policy_document = data.aws_iam_policy_document.myct_policy.json + + tags = { + Environment = "csvd:infrastructure" + } + + component_tags = { + "kms" = { + "SpecialTag1" = "something" + "SpecialTag2" = "somethingElse" + } + } +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.12 | +| [aws](#requirement\_aws) | >= 3.66.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.66.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [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_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.empty](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.key_admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.key_orig](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.key_policy_combined](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 | +|------|-------------|------|---------|:--------:| +| [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 | +| [component\_tags](#input\_component\_tags) | Additional tags for Components (s3, kms, ddb) | `map(map(string))` |
{
"ddb": {},
"kms": {},
"s3": {}
} | no |
+| [kms\_admin\_roles](#input\_kms\_admin\_roles) | AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default. | `list(string)` | `[]` | no |
+| [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `null` | no |
+| [name](#input\_name) | Name to apply to Cloudtrail KMS Key (default: k-inf-cloudtrail) | `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 |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [kms\_aliase\_nam](#output\_kms\_aliase\_nam) | Cloudtrail Key Alias name |
+| [kms\_key\_arn](#output\_kms\_key\_arn) | Cloudtrail Key ARN |
+| [kms\_key\_id](#output\_kms\_key\_id) | Cloudtrail Key ID |
diff --git a/cloudtrail-key/base_tags.tf b/cloudtrail-key/base_tags.tf
new file mode 120000
index 0000000..91c15aa
--- /dev/null
+++ b/cloudtrail-key/base_tags.tf
@@ -0,0 +1 @@
+../common/base_tags.tf
\ No newline at end of file
diff --git a/cloudtrail-key/data.tf b/cloudtrail-key/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/cloudtrail-key/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/cloudtrail-key/defaults.tf b/cloudtrail-key/defaults.tf
new file mode 120000
index 0000000..a5556ac
--- /dev/null
+++ b/cloudtrail-key/defaults.tf
@@ -0,0 +1 @@
+../common/defaults.tf
\ No newline at end of file
diff --git a/cloudtrail-key/main.tf b/cloudtrail-key/main.tf
new file mode 100644
index 0000000..a8e3fc1
--- /dev/null
+++ b/cloudtrail-key/main.tf
@@ -0,0 +1,318 @@
+/*
+* # aws-inf-setup :: cloudtrail-keys
+*
+* This set up the KMS key used by Cloudtrail for the ts S3 bucket, CloudTrail, and SQS (if possible).
+*
+* * Cloudtrail
+* * S3 bucket
+* * SQS
+*
+* ## Usage, Simple Example
+* Here is a simple example, the one most commonly expected to be used.
+*
+* ```hcl
+* module "cloudtrail_key_simple" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+*
+* tags = {
+* Environment = "csvd:infrastructure"
+* }
+* }
+* ```
+*
+* ## Usage, Longer Example
+* 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_key_full" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+*
+* name = "mycloudtrail"
+* kms_admin_roles = ["arn:aws:iam::079788916859:role/r-inf-cloud-admin"]
+* kms_policy_document = data.aws_iam_policy_document.myct_policy.json
+*
+* tags = {
+* Environment = "csvd:infrastructure"
+* }
+*
+* component_tags = {
+* "kms" = {
+* "SpecialTag1" = "something"
+* "SpecialTag2" = "somethingElse"
+* }
+* }
+* }
+* ```
+*/
+
+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
+
+}
+
+resource "aws_kms_key" "key" {
+ description = "KMS CMK for cloudtrail"
+ enable_key_rotation = true
+ policy = data.aws_iam_policy_document.key_policy_combined.json
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ map("boc:aws:region", local.region),
+ map("Name", local.name),
+ )
+}
+
+resource "aws_kms_alias" "key" {
+ name = "alias/${local.kms_key_name}"
+ target_key_id = aws_kms_key.key.key_id
+}
+
+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_orig" {
+ policy_id = "Cloudtrail KMS Access"
+ statement {
+ sid = "EnableIAMUserPermissions"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+ identifiers = [local.kms_admin_root]
+ }
+ }
+ statement {
+ sid = "AllowCloudTrailEncryptLogs"
+ effect = "Allow"
+ actions = ["kms:GenerateDataKey*"]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com", "logs.amazonaws.com", "logs.${local.region}.amazonaws.com"]
+ }
+ condition {
+ test = "StringLike"
+ variable = "kms:EncryptionContext:aws:cloudtrail:arn"
+ # values = [format("arn:%v:cloudtrail:%v:%v:trail/*",local.partition,local.region,local.account_id]
+ values = [format("arn:%v:cloudtrail:*:%v:trail/*", local.partition, local.account_id)]
+ }
+ }
+ 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 = [format("arn:%v:cloudtrail:%v:%v:trail/*",local.partition,local.region,local.account_id]
+ values = [format("arn:%v:cloudtrail:*:%v:trail/*", local.partition, local.account_id)]
+ }
+ }
+ 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 = [format("arn:%v:cloudtrail:%v:%v:trail/*",local.partition,local.region,local.account_id]
+ values = [format("arn:%v:cloudtrail:*:%v:trail/*", local.partition, local.account_id)]
+ }
+ }
+ 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 = [format("ec2.%v.amazonaws.com", local.region)]
+ }
+ }
+}
+
+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"]
+ }
+ }
+ statement {
+ sid = "CloudTrailKMSEncryptAccess"
+ effect = "Allow"
+ actions = [
+ "kms:Decrypt*",
+ "kms:Encrypt*",
+ "kms:ReEncrypt*",
+ "kms:GenerateDataKey",
+ ]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.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"]
+ }
+ }
+}
+
+# producers and consumers
+# https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html#compatibility-with-aws-services
diff --git a/cloudtrail-key/outputs.tf b/cloudtrail-key/outputs.tf
new file mode 100644
index 0000000..bb73d2e
--- /dev/null
+++ b/cloudtrail-key/outputs.tf
@@ -0,0 +1,14 @@
+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
+}
+
+output "kms_aliase_nam" {
+ description = "Cloudtrail Key Alias name"
+ value = aws_kms_alias.key.arn
+}
diff --git a/cloudtrail-key/prefixes.tf b/cloudtrail-key/prefixes.tf
new file mode 120000
index 0000000..7e265d5
--- /dev/null
+++ b/cloudtrail-key/prefixes.tf
@@ -0,0 +1 @@
+../common/prefixes.tf
\ No newline at end of file
diff --git a/cloudtrail-key/variables.common.tf b/cloudtrail-key/variables.common.tf
new file mode 120000
index 0000000..7439ed8
--- /dev/null
+++ b/cloudtrail-key/variables.common.tf
@@ -0,0 +1 @@
+../common/variables.common.tf
\ No newline at end of file
diff --git a/cloudtrail-key/variables.tf b/cloudtrail-key/variables.tf
new file mode 100644
index 0000000..9f58d60
--- /dev/null
+++ b/cloudtrail-key/variables.tf
@@ -0,0 +1,23 @@
+variable "name" {
+ description = "Name to apply to Cloudtrail KMS Key (default: k-inf-cloudtrail)"
+ type = string
+ default = null
+}
+
+variable "kms_policy_document" {
+ description = "AWS KMS Key Policy Document JSON, merged with admin policy document"
+ type = string
+ default = null
+}
+
+variable "kms_admin_roles" {
+ description = "AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default."
+ type = list(string)
+ default = []
+}
+
+variable "component_tags" {
+ description = "Additional tags for Components (s3, kms, ddb)"
+ type = map(map(string))
+ default = { "s3" = {}, "kms" = {}, "ddb" = {} }
+}
diff --git a/cloudtrail-key/version.tf b/cloudtrail-key/version.tf
new file mode 120000
index 0000000..b83c5b7
--- /dev/null
+++ b/cloudtrail-key/version.tf
@@ -0,0 +1 @@
+../common/version.tf
\ No newline at end of file
diff --git a/cloudtrail-key/versions.tf b/cloudtrail-key/versions.tf
new file mode 100644
index 0000000..3d116e6
--- /dev/null
+++ b/cloudtrail-key/versions.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 3.66.0"
+ }
+ # ldap = {
+ # source = "trevex/ldap"
+ # version = ">= 0.5.4"
+ # }
+ }
+ required_version = ">= 0.12"
+ # required_version = ">= 0.13"
+}
diff --git a/cloudtrail/README.md b/cloudtrail/README.md
new file mode 100644
index 0000000..a3af4b0
--- /dev/null
+++ b/cloudtrail/README.md
@@ -0,0 +1,195 @@
+# 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
+* SNS Topic
+* SQS Queue (and Deadletter queue)
+* Cloudwatch Log
+* setup/*.conf files for Splunk
+ * inputs.{name}.{account}.{region}.conf
+
+Once setup, the gnerated Splunk configuration files can be provided to the Splunk team for ingesting
+as CloudTrail.
+
+## Usage: Simple
+
+This siomple configuration is how it will typically be deployed.
+
+```hcl
+module "cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ tags = local.common_tags
+}
+
+module "cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ account_alias = var.account_alias
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.cloudtrail_key.kms_key_arn
+
+ enable_sns = true
+ enable_sqs = true
+
+ tags = local.common_tags
+}
+```
+
+## Usage: Extended
+
+This shows the creation of a key with additional variables, along with a policy for key access (currently
+just a placholder), and the cloudtrail with more variables offered.
+
+```hcl
+module "cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ name = "mycloudtrail"
+ kms_admin_roles = ["arn:aws:iam::079788916859:role/r-inf-cloud-admin"]
+ kms_policy_document = data.aws_iam_policy_document.myct_policy.json
+
+ tags = {
+ Environment = "csvd:infrastructure"
+ }
+
+ component_tags = {
+ "kms" = {
+ "SpecialTag1" = "something"
+ "SpecialTag2" = "somethingElse"
+ }
+ }
+}
+
+data "aws_iam_policy_document" "myct_policy" {}
+
+module "cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ name = "mycloudtrail"
+ account_alias = var.account_alias
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.cloudtrail_key.kms_key_arn
+
+ enable_organization = false
+ enable_sns = true
+ enable_sqs = true
+
+ tags = merge(
+ local.common_tags,
+ tomap({ Environment = "csvd:infrastructure" }),
+ )
+}
+```hcl
+
+## Usage: Organization Cloudtrail
+
+This can be used for creation of an organization cloud trail. It is only applicable to the master
+account of the organization, so you won't see this one used very often.
+
+```hcl
+data "aws_organizations_organization" "org" {}
+
+module "org_cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ name = "org-cloudtrail"
+ tags = local.common_tags
+}
+
+module "org_cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ account_alias = var.account_alias
+ enable_organization = true
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.org_cloudtrail_key.kms_key_arn
+ organization_id = data.aws_organizations_organization.org.id
+
+ enable_sns = true
+ enable_sqs = true
+
+ tags = local.common_tags
+}
+```
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.12 |
+| [aws](#requirement\_aws) | >= 3.66.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | >= 3.66.0 |
+| [null](#provider\_null) | n/a |
+| [random](#provider\_random) | n/a |
+| [template](#provider\_template) | n/a |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_cloudtrail.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail) | resource |
+| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
+| [aws_iam_policy.cloudtrail_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_iam_role.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
+| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | 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.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
+| [aws_sns_topic.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
+| [aws_sns_topic_policy.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource |
+| [aws_sns_topic_subscription.cloudtrail_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
+| [aws_sqs_queue.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource |
+| [aws_sqs_queue.cloudtrail_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource |
+| [aws_sqs_queue_policy.cloudtrail_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource |
+| [aws_sqs_queue_policy.cloudtrail_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource |
+| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [null_resource.splunk_cloudtrail](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [random_uuid.splunk_cloudtrail](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/uuid) | 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.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.cloudtrail_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.cloudtrail_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.cloudtrail_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | 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.cloudtrail_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.cloudtrail_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_kms_key.incoming_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_key) | data source |
+| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
+| [template_file.splunk_cloudtrail](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file) | 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\_organization](#input\_enable\_organization) | Enable CloudTrail as an organization trail. This will only work in the organization master account | `bool` | `false` | 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\_arn](#input\_kms\_key\_arn) | AWS CloudTrail KMS ARN to be used for encrypting the ClouldTrail, S3 Bucket, and SQS | `string` | n/a | yes |
+| [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 |
+| [organization\_id](#input\_organization\_id) | AWS Organization ID | `string` | `""` | 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 |
+
+## Outputs
+
+No outputs.
diff --git a/cloudtrail/TODO b/cloudtrail/TODO
new file mode 100644
index 0000000..adc6571
--- /dev/null
+++ b/cloudtrail/TODO
@@ -0,0 +1,10 @@
+- cloudtrail
+- cloudtrail key
+- cloudwatch log stream
+- s3 bucket
+- s3 bucket policy
+- iam role
+- sqs
+- sns
+
+
diff --git a/cloudtrail/base_tags.tf b/cloudtrail/base_tags.tf
new file mode 120000
index 0000000..91c15aa
--- /dev/null
+++ b/cloudtrail/base_tags.tf
@@ -0,0 +1 @@
+../common/base_tags.tf
\ No newline at end of file
diff --git a/cloudtrail/cloudtrail.tf b/cloudtrail/cloudtrail.tf
new file mode 100644
index 0000000..0052076
--- /dev/null
+++ b/cloudtrail/cloudtrail.tf
@@ -0,0 +1,84 @@
+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 = true
+ is_multi_region_trail = false
+ enable_log_file_validation = true
+ enable_logging = true
+ kms_key_id = var.kms_key_arn
+ sns_topic_name = var.enable_sns ? aws_sns_topic.cloudtrail[0].arn : null
+ cloud_watch_logs_group_arn = format("%v:*", aws_cloudwatch_log_group.this.arn)
+ cloud_watch_logs_role_arn = aws_iam_role.cloudtrail.arn
+ is_organization_trail = var.enable_organization
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ map("Name", local.name),
+ )
+ depends_on = [aws_s3_bucket_policy.policy]
+}
+
+resource "aws_iam_role" "cloudtrail" {
+ name = local.role_name
+ assume_role_policy = data.aws_iam_policy_document.cloudtrail_assume.json
+ description = "AWS CloudTrail Role for ${local.name}"
+ force_detach_policies = false
+ max_session_duration = 3600
+ # add deny billing
+ managed_policy_arns = [aws_iam_policy.cloudtrail_policy.arn]
+ path = "/"
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ map("Name", local.role_name),
+ )
+}
+
+data "aws_iam_policy_document" "cloudtrail_assume" {
+ statement {
+ sid = "AWSCloudTrailServiceAssumeRole"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ }
+}
+
+resource "aws_iam_policy" "cloudtrail_policy" {
+ name = local.policy_name
+ policy = data.aws_iam_policy_document.cloudtrail_cloudwatch.json
+}
+
+
+data "aws_iam_policy_document" "cloudtrail_cloudwatch" {
+ statement {
+ sid = "AWSCloudTrailCreateLogStream"
+ effect = "Allow"
+ actions = ["logs:CreateLogStream"]
+ resources = local.resources
+ }
+ statement {
+ sid = "AWSCloudTrailPutLogEvents"
+ effect = "Allow"
+ actions = ["logs:PutLogEvents"]
+ resources = local.resources
+ }
+}
+
+# resource "aws_cloudwatch_log_group" "cloudtrail" {
+# name = local.name
+#
+# kms_key_id = var.kms_key_arn
+# retention_in_days = 7
+#
+# tags = merge(
+# local.base_tags,
+# var.tags,
+# map("Name", format("%v-log", local.name)),
+# )
+# }
diff --git a/cloudtrail/cloudtrail.tf.off b/cloudtrail/cloudtrail.tf.off
new file mode 100644
index 0000000..2614c6e
--- /dev/null
+++ b/cloudtrail/cloudtrail.tf.off
@@ -0,0 +1,20 @@
+
+#---
+# 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]
+}
diff --git a/cloudtrail/cloudwatch.tf b/cloudtrail/cloudwatch.tf
new file mode 100644
index 0000000..355eed2
--- /dev/null
+++ b/cloudtrail/cloudwatch.tf
@@ -0,0 +1,37 @@
+locals {
+ cloudwatch_prefix = replace(aws_cloudwatch_log_group.this.arn, "/:\\*$/", "")
+ cloudwatch_suffix = format("%v_CloudTrail_%v", local.account_id, local.region)
+ org_cloudwatch_suffix = format("%v_*", var.organization_id)
+ cloudwatch_resources = join(":", list(local.cloudwatch_prefix, "log-stream", local.cloudwatch_suffix))
+ org_cloudwatch_resources = var.enable_organization ? join(":", list(local.cloudwatch_prefix, "log-stream", local.org_cloudwatch_suffix)) : null
+ resources = compact([local.cloudwatch_resources, local.org_cloudwatch_resources])
+}
+
+resource "aws_cloudwatch_log_group" "this" {
+ name = local.name
+ kms_key_id = var.kms_key_arn
+ retention_in_days = lookup(local._defaults["cloudwatch"], "retention_in_days", 7)
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ map("Name", local.name),
+ )
+}
+
+## data "aws_iam_policy_document" "cloudwatch_policy" {
+## statement {
+## sid = "AWSCloudTrailCreateLogStream"
+## effect = "Allow"
+## actions = ["logs:CreateLogStream"]
+## resources = local.resources
+## }
+##
+## statement {
+## sid = "AWSCloudTrailPutLogEvents"
+## effect = "Allow"
+## actions = ["logs:PutLogEvents"]
+## resources = local.resources
+## }
+## }
+##
diff --git a/cloudtrail/data.policies.tf b/cloudtrail/data.policies.tf
new file mode 100644
index 0000000..7a99e9c
--- /dev/null
+++ b/cloudtrail/data.policies.tf
@@ -0,0 +1,31 @@
+data "aws_iam_policy_document" "cloudtrail_s3" {
+ statement {
+ sid = "AWSCloudTrailWrite"
+ effect = "Allow"
+ resources = ["${aws_s3_bucket.this.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.this.arn]
+ actions = ["s3:GetBucketAcl"]
+
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+ }
+}
diff --git a/cloudtrail/data.tf b/cloudtrail/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/cloudtrail/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/cloudtrail/defaults.tf b/cloudtrail/defaults.tf
new file mode 120000
index 0000000..a5556ac
--- /dev/null
+++ b/cloudtrail/defaults.tf
@@ -0,0 +1 @@
+../common/defaults.tf
\ No newline at end of file
diff --git a/cloudtrail/edl.cloudtrail.sns.txt b/cloudtrail/edl.cloudtrail.sns.txt
new file mode 100644
index 0000000..381f530
--- /dev/null
+++ b/cloudtrail/edl.cloudtrail.sns.txt
@@ -0,0 +1,179 @@
+#---
+# sns: cloudtrail, one global one (us-gov-east-1)
+#---
+resource "aws_sns_topic" "cloudtrail" {
+ name = "inf-cloudtrail"
+ display_name = "DO3MA3GC"
+}
+
+resource "aws_sns_topic_policy" "cloudtrail" {
+ arn = aws_sns_topic.cloudtrail.arn
+ policy = data.aws_iam_policy_document.cloudtrail_topic.json
+}
+
+data "aws_iam_policy_document" "cloudtrail_topic" {
+ policy_id = "inf-cloudtrail_topic"
+
+ statement {
+ sid = "CloudtrailSNSPermissions"
+ effect = "Allow"
+
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+
+ actions = [
+ "sns:Subscribe",
+ "sns:SetTopicAttributes",
+ "sns:RemovePermission",
+ "sns:Receive",
+ "sns:Publish",
+ "sns:ListSubscriptionsByTopic",
+ "sns:GetTopicAttributes",
+ "sns:DeleteTopic",
+ "sns:AddPermission",
+ ]
+
+ condition {
+ test = "StringEquals"
+ variable = "AWS:SourceOwner"
+ values = [var.account_id]
+ }
+
+ resources = [aws_sns_topic.cloudtrail.arn]
+ }
+
+ statement {
+ sid = "CloudTrailSNSPolicy"
+ effect = "Allow"
+
+ principals {
+ type = "Service"
+ identifiers = ["cloudtrail.amazonaws.com"]
+ }
+
+ actions = ["sns:Publish"]
+ resources = [aws_sns_topic.cloudtrail.arn]
+ }
+}
+
+
+#---
+# sqs (from splunk)
+#---
+# one per region we are using
+#---
+# cloudtrail
+#---
+resource "aws_sqs_queue" "cloudtrail_deadletter" {
+ # delay=0 retention=4d max=256k visibility=1h
+ count = length(var.regions)
+ name = "inf-cloudtrail-${var.regions[count.index]}-deadletter"
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = 345600
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 3600
+
+ # disable kms, doesn't seem to work with splunk
+ # kms_master_key_id = "alias/${var.kms_inf_key}"
+ # kms_data_key_reuse_period_seconds = 300
+
+ tags = merge(
+ local.common_tags,
+ map("Name", "inf-cloudtrail-${var.regions[count.index]}-deadletter"),
+ )
+}
+
+resource "aws_sqs_queue_policy" "cloudtrail_deadletter" {
+ count = length(var.regions)
+ queue_url = aws_sqs_queue.cloudtrail_deadletter[count.index].id
+ policy = data.aws_iam_policy_document.cloudtrail_deadletter[count.index].json
+}
+
+data "aws_iam_policy_document" "cloudtrail_deadletter" {
+ count = length(var.regions)
+ policy_id = "SQSDefaultPolicy"
+
+ statement {
+ sid = "AllowSNSSendMessage"
+ effect = "Allow"
+ actions = ["SQS:SendMessage"]
+ resources = [aws_sqs_queue.cloudtrail_deadletter[count.index].arn]
+
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+
+ condition {
+ test = "ArnEquals"
+ variable = "aws:SourceArn"
+ values = [aws_sns_topic.cloudtrail.arn]
+ }
+ }
+}
+
+resource "aws_sqs_queue" "cloudtrail" {
+ # delay=0 retention=7d max=256k visibity=2h
+ count = length(var.regions)
+ name = "inf-cloudtrail-${var.regions[count.index]}"
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = 604800
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 7200
+
+ redrive_policy = <{
"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_orig/version.tf b/cloudtrail_orig/version.tf
new file mode 120000
index 0000000..b83c5b7
--- /dev/null
+++ b/cloudtrail_orig/version.tf
@@ -0,0 +1 @@
+../common/version.tf
\ No newline at end of file
diff --git a/common/base_tags.tf b/common/base_tags.tf
new file mode 100644
index 0000000..602b87a
--- /dev/null
+++ b/common/base_tags.tf
@@ -0,0 +1,6 @@
+locals {
+ base_tags = {
+ "boc:tf_module_version" = local._module_version
+ "boc:created_by" = "terraform"
+ }
+}
diff --git a/common/defaults.tf b/common/defaults.tf
index 91dc82b..6a1f087 100644
--- a/common/defaults.tf
+++ b/common/defaults.tf
@@ -17,9 +17,24 @@ locals {
"ses" = {
"event_types" = ["bounce", "delivery", "complaint"]
}
+ "org_cloudtrail" = {
+ "name" = "inf-org-cloudtrail"
+ }
+ "cloudtrail" = {
+ "name" = "inf-cloudtrail"
+ }
"config" = {
"name" = "inf-config"
}
+ "cloudwatch" = {
+ "retention_in_days" = 14
+ }
+ "sqs" = {
+ "message_retention_seconds" = 14 * 86400
+ }
+ "sqs_deadletter" = {
+ "message_retention_seconds" = 7 * 86400
+ }
"splunk_description" = {
"api_list" = [
"ec2_volumes", "ec2_instances", "ec2_reserved_instances", "ec2_key_pairs", "ec2_security_groups", "ec2_images", "ec2_addresses",
diff --git a/common/version.tf b/common/version.tf
index 389f7ae..cf6531c 100644
--- a/common/version.tf
+++ b/common/version.tf
@@ -1,3 +1,3 @@
locals {
- _module_version = "1.13.3"
+ _module_version = "1.14.0"
}
diff --git a/examples/cloudtrail-key/cloudtrail_key_full.tf b/examples/cloudtrail-key/cloudtrail_key_full.tf
new file mode 100644
index 0000000..a1fdd69
--- /dev/null
+++ b/examples/cloudtrail-key/cloudtrail_key_full.tf
@@ -0,0 +1,18 @@
+module "cloudtrail_key_full" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ name = "mycloudtrail"
+ kms_admin_roles = ["arn:aws:iam::079788916859:role/r-inf-cloud-admin"]
+ kms_policy_document = data.aws_iam_policy_document.myct_policy.json
+
+ tags = {
+ Environment = "csvd:infrastructure"
+ }
+
+ component_tags = {
+ "kms" = {
+ "SpecialTag1" = "something"
+ "SpecialTag2" = "somethingElse"
+ }
+ }
+}
diff --git a/examples/cloudtrail-key/cloudtrail_key_simple.tf b/examples/cloudtrail-key/cloudtrail_key_simple.tf
new file mode 100644
index 0000000..c5124d2
--- /dev/null
+++ b/examples/cloudtrail-key/cloudtrail_key_simple.tf
@@ -0,0 +1,7 @@
+module "cloudtrail_key_simple" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ tags = {
+ Environment = "csvd:infrastructure"
+ }
+}
diff --git a/examples/cloudtrail/cloudtrail_full.tf b/examples/cloudtrail/cloudtrail_full.tf
new file mode 100644
index 0000000..d70f5c0
--- /dev/null
+++ b/examples/cloudtrail/cloudtrail_full.tf
@@ -0,0 +1,38 @@
+module "cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ name = "mycloudtrail"
+ kms_admin_roles = ["arn:aws:iam::079788916859:role/r-inf-cloud-admin"]
+ kms_policy_document = data.aws_iam_policy_document.myct_policy.json
+
+ tags = {
+ Environment = "csvd:infrastructure"
+ }
+
+ component_tags = {
+ "kms" = {
+ "SpecialTag1" = "something"
+ "SpecialTag2" = "somethingElse"
+ }
+ }
+}
+
+data "aws_iam_policy_document" "myct_policy" {}
+
+module "cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ name = "mycloudtrail"
+ account_alias = var.account_alias
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.cloudtrail_key.kms_key_arn
+
+ enable_organization = false
+ enable_sns = true
+ enable_sqs = true
+
+ tags = merge(
+ local.common_tags,
+ tomap({ Environment = "csvd:infrastructure" }),
+ )
+}
diff --git a/examples/cloudtrail/cloudtrail_simple.tf b/examples/cloudtrail/cloudtrail_simple.tf
new file mode 100644
index 0000000..329599a
--- /dev/null
+++ b/examples/cloudtrail/cloudtrail_simple.tf
@@ -0,0 +1,18 @@
+module "cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ tags = local.common_tags
+}
+
+module "cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ account_alias = var.account_alias
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.cloudtrail_key.kms_key_arn
+
+ enable_sns = true
+ enable_sqs = true
+
+ tags = local.common_tags
+}
diff --git a/examples/cloudtrail/org_cloudtrail_simple.tf b/examples/cloudtrail/org_cloudtrail_simple.tf
new file mode 100644
index 0000000..409f0ef
--- /dev/null
+++ b/examples/cloudtrail/org_cloudtrail_simple.tf
@@ -0,0 +1,23 @@
+data "aws_organizations_organization" "org" {}
+
+module "org_cloudtrail_key" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail-key"
+
+ name = "org-cloudtrail"
+ tags = local.common_tags
+}
+
+module "org_cloudtrail" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//cloudtrail"
+
+ account_alias = var.account_alias
+ enable_organization = true
+ access_log_bucket = module.logs.bucket_id
+ kms_key_arn = module.org_cloudtrail_key.kms_key_arn
+ organization_id = data.aws_organizations_organization.org.id
+
+ enable_sns = true
+ enable_sqs = true
+
+ tags = local.common_tags
+}