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 = < [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_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 +}