diff --git a/org-logging/README.md b/org-logging/README.md new file mode 100644 index 0000000..1d09f36 --- /dev/null +++ b/org-logging/README.md @@ -0,0 +1,212 @@ +# aws-inf-setup :: logging + +This set up the needed components for logging in a region: S3, KMS key, SNS, SQS, logging, +cloudwatch log groups, and associated permissions. It also generates a splunk configuration to be used +for pulling logging 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 Logging. + +## Usage: Simple + +This siomple configuration is how it will typically be deployed. + +```hcl +module "logging_key" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key" + + tags = local.common_tags +} + +module "logging" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging" + + account_alias = var.account_alias + access_log_bucket = module.logs.bucket_id + kms_key_arn = module.logging_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 logging with more variables offered. + +```hcl +module "logging_key" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key" + + name = "mylogging" + 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 "logging" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging" + + name = "mylogging" + account_alias = var.account_alias + access_log_bucket = module.logs.bucket_id + kms_key_arn = module.logging_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_logging_key" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key" + + name = "org-logging" + tags = local.common_tags +} + +module "org_logging" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging" + + account_alias = var.account_alias + enable_organization = true + access_log_bucket = module.logs.bucket_id + kms_key_arn = module.org_logging_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 | +| [local](#provider\_local) | n/a | +| [null](#provider\_null) | n/a | +| [template](#provider\_template) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.logging_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.logging](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_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | +| [aws_s3_bucket_logging.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource | +| [aws_s3_bucket_ownership_controls.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | 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_s3_bucket_server_side_encryption_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_sns_topic.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | +| [aws_sns_topic_policy.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource | +| [aws_sns_topic_subscription.additional_logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | +| [aws_sns_topic_subscription.logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | +| [aws_sqs_queue.additional_logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue.additional_logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue.logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | +| [aws_sqs_queue_policy.additional_logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | +| [aws_sqs_queue_policy.additional_logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | +| [aws_sqs_queue_policy.logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | +| [aws_sqs_queue_policy.logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | +| [local_file.splunk_logging](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | +| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [null_resource.splunk_logging](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.additional_logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.additional_logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | 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.logging_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logging_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logging_deadletter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logging_s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logging_sqs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.logging_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 | +| [aws_regions.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/regions) | data source | +| [template_file.splunk_logging](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 | +| [additional\_sqs\_names](#input\_additional\_sqs\_names) | List of additional SQS queues to create and subscribe to the SNS topic (if enabled) | `list(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 Logging 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 Logging 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
+
+| Name | Description |
+|------|-------------|
+| [additional\_sqs\_info](#output\_additional\_sqs\_info) | Additional SQS ARNs and IDs (main, deadletter) |
+| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | Created S3 Bucket ARN |
+| [s3\_bucket\_id](#output\_s3\_bucket\_id) | Created S3 Bucket ID |
+| [sns\_arn](#output\_sns\_arn) | SNS ARN |
+| [sqs\_info](#output\_sqs\_info) | Main SQS ARNs and IDs (main, deadletter) |
diff --git a/org-logging/additional-sqs.tf b/org-logging/additional-sqs.tf
new file mode 100644
index 0000000..af47251
--- /dev/null
+++ b/org-logging/additional-sqs.tf
@@ -0,0 +1,103 @@
+locals {
+ additional_sqs_names = var.enable_sqs ? toset(var.additional_sqs_names) : toset([])
+}
+
+resource "aws_sqs_queue" "additional_logging_deadletter" {
+ for_each = local.additional_sqs_names
+ name = format("%v-deadletter", each.key)
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = lookup(local._defaults["sqs_deadletter"], "message_retention_seconds", 1 * 86400)
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 3600
+
+ kms_master_key_id = data.aws_kms_key.incoming_key.id
+ kms_data_key_reuse_period_seconds = 300
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = format("%v-deadletter", each.key) }),
+ )
+}
+
+resource "aws_sqs_queue_policy" "additional_logging_deadletter" {
+ for_each = local.additional_sqs_names
+ queue_url = var.enable_sqs ? aws_sqs_queue.additional_logging_deadletter[each.key].id : null
+ policy = data.aws_iam_policy_document.additional_logging_deadletter[each.key].json
+}
+
+data "aws_iam_policy_document" "additional_logging_deadletter" {
+ for_each = local.additional_sqs_names
+ statement {
+ sid = "AllowSNSSendMessage"
+ effect = "Allow"
+ actions = ["sqs:SendMessage"]
+ resources = [var.enable_sqs ? aws_sqs_queue.additional_logging_deadletter[each.key].arn : ""]
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ condition {
+ test = "ArnEquals"
+ variable = "aws:SourceArn"
+ values = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+ }
+}
+
+resource "aws_sqs_queue" "additional_logging" {
+ for_each = local.additional_sqs_names
+ name = each.key
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = lookup(local._defaults["sqs_deadletter"], "message_retention_seconds", 7 * 86400)
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 7200
+
+ redrive_policy = jsonencode({
+ deadLetterTargetArn = var.enable_sqs ? aws_sqs_queue.additional_logging_deadletter[each.key].arn : null
+ maxReceiveCount = 100
+ })
+
+ kms_master_key_id = data.aws_kms_key.incoming_key.id
+ kms_data_key_reuse_period_seconds = 300
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = each.key }),
+ )
+}
+
+resource "aws_sqs_queue_policy" "additional_logging_sqs" {
+ for_each = local.additional_sqs_names
+ queue_url = var.enable_sqs ? aws_sqs_queue.additional_logging[each.key].id : null
+ policy = data.aws_iam_policy_document.additional_logging_sqs[each.key].json
+}
+
+data "aws_iam_policy_document" "additional_logging_sqs" {
+ for_each = local.additional_sqs_names
+ statement {
+ sid = "AllowSNSSendMessage"
+ effect = "Allow"
+ actions = ["sqs:SendMessage"]
+ resources = [var.enable_sqs ? aws_sqs_queue.additional_logging[each.key].arn : ""]
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ condition {
+ test = "ArnEquals"
+ variable = "aws:SourceArn"
+ values = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+ }
+}
+
+resource "aws_sns_topic_subscription" "additional_logging_sqs" {
+ for_each = var.enable_sns ? local.additional_sqs_names : toset([])
+ protocol = "sqs"
+ topic_arn = var.enable_sns ? aws_sns_topic.logging[0].arn : null
+ endpoint = var.enable_sqs ? aws_sqs_queue.additional_logging[each.key].arn : null
+}
diff --git a/org-logging/base_tags.tf b/org-logging/base_tags.tf
new file mode 100644
index 0000000..602b87a
--- /dev/null
+++ b/org-logging/base_tags.tf
@@ -0,0 +1,6 @@
+locals {
+ base_tags = {
+ "boc:tf_module_version" = local._module_version
+ "boc:created_by" = "terraform"
+ }
+}
diff --git a/org-logging/cloudtrail.tf b/org-logging/cloudtrail.tf
new file mode 100644
index 0000000..6899337
--- /dev/null
+++ b/org-logging/cloudtrail.tf
@@ -0,0 +1,49 @@
+resource "aws_iam_role" "logging" {
+ name = local.role_name
+ assume_role_policy = data.aws_iam_policy_document.logging_assume.json
+ description = "AWS Logging Role for ${local.name}"
+ force_detach_policies = false
+ max_session_duration = 3600
+ # add deny billing
+ managed_policy_arns = [aws_iam_policy.logging_policy.arn]
+ path = "/"
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = local.role_name }),
+ )
+}
+
+data "aws_iam_policy_document" "logging_assume" {
+ statement {
+ sid = "AWSLoggingServiceAssumeRole"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+ }
+}
+
+resource "aws_iam_policy" "logging_policy" {
+ name = local.policy_name
+ policy = data.aws_iam_policy_document.logging_cloudwatch.json
+}
+
+
+data "aws_iam_policy_document" "logging_cloudwatch" {
+ statement {
+ sid = "AWSLoggingCreateLogStream"
+ effect = "Allow"
+ actions = ["logs:CreateLogStream"]
+ resources = local.resources
+ }
+ statement {
+ sid = "AWSLoggingPutLogEvents"
+ effect = "Allow"
+ actions = ["logs:PutLogEvents"]
+ resources = local.resources
+ }
+}
diff --git a/org-logging/cloudwatch.tf.off b/org-logging/cloudwatch.tf.off
new file mode 100644
index 0000000..355bc17
--- /dev/null
+++ b/org-logging/cloudwatch.tf.off
@@ -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(":", [local.cloudwatch_prefix, "log-stream", local.cloudwatch_suffix])
+ org_cloudwatch_resources = var.enable_organization ? join(":", [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,
+ tomap({ 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/org-logging/data.policies.tf b/org-logging/data.policies.tf
new file mode 100644
index 0000000..f35b38c
--- /dev/null
+++ b/org-logging/data.policies.tf
@@ -0,0 +1,31 @@
+data "aws_iam_policy_document" "logging_s3" {
+ statement {
+ sid = "AWSLoggingWrite"
+ effect = "Allow"
+ resources = ["${aws_s3_bucket.this.arn}/*"]
+ actions = ["s3:PutObject"]
+
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+
+ condition {
+ test = "StringLike"
+ variable = "s3:x-amz-acl"
+ values = ["bucket-owner-full-control"]
+ }
+ }
+
+ statement {
+ sid = "AWSLoggingAclCheck"
+ effect = "Allow"
+ resources = [aws_s3_bucket.this.arn]
+ actions = ["s3:GetBucketAcl"]
+
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+ }
+}
diff --git a/org-logging/data.tf b/org-logging/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/org-logging/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/org-logging/defaults.tf b/org-logging/defaults.tf
new file mode 100644
index 0000000..7d127a1
--- /dev/null
+++ b/org-logging/defaults.tf
@@ -0,0 +1,66 @@
+# for the accesss logs for load balancers
+# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-logging-bucket-permissions
+
+locals {
+ _defaults = {
+ "account_settings" = {
+ allow_users_to_change_password = true
+ hard_expiry = false
+ max_password_age = 89
+ minimum_password_length = 14
+ password_reuse_prevention = 24
+ require_lowercase_characters = true
+ require_numbers = true
+ require_symbols = true
+ require_uppercase_characters = true
+ }
+ "load-balancer" = {
+ "gov" = ["190560391635", "048591011584"]
+ "us-gov-east-1" = "190560391635"
+ "us-gov-west-1" = "048591011584"
+
+ "ew" = ["127311923021", "033677994240", "027434742980", "797873946194"]
+ "us-east-1" = "127311923021"
+ "us-east-2" = "033677994240"
+ "us-west-1" = "027434742980"
+ "us-west-2" = "797873946194"
+ }
+ "ses" = {
+ "event_types" = ["bounce", "delivery", "complaint"]
+ }
+ "org_logging" = {
+ "name" = "inf-org-logging"
+ }
+ "logging" = {
+ "name" = "inf-logging"
+ }
+ "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",
+ "ebs_snapshots", "classic_load_balancers", "application_load_balancers",
+ "vpcs", "vpc_network_acls", "vpc_subnets",
+ "rds_instances",
+ "lambda_functions",
+ "s3_buckets",
+ "iam_users"
+ ]
+ "api_interval" = 3600
+ }
+ "force_detach_policies" = false
+ "max_session_duration" = 3600
+ }
+}
+
+
diff --git a/org-logging/generate_splunk.cloudtrail.tf b/org-logging/generate_splunk.cloudtrail.tf
new file mode 100644
index 0000000..d626d62
--- /dev/null
+++ b/org-logging/generate_splunk.cloudtrail.tf
@@ -0,0 +1,45 @@
+#---
+# generate splunk inputs file
+#---
+data "template_file" "splunk_logging" {
+ template = file("${path.module}/templates/inputs.logging.conf.tpl")
+ vars = {
+ account_id = local.account_id
+ account_alias = local.account_alias
+ # entry_uuid = random_uuid.splunk_logging.result
+ region = local.region
+ logging_name = local.splunk_name
+ queue_url = var.enable_sqs ? aws_sqs_queue.logging[0].id : null
+ }
+}
+
+# resource "random_uuid" "splunk_logging" {
+# keepers = {
+# queue_url = var.enable_sqs ? aws_sqs_queue.logging[0].id : null
+# }
+# }
+
+resource "null_resource" "splunk_logging" {
+ count = var.enable_sqs ? 1 : 0
+ triggers = {
+ filename = format("inputs.%v.%v-%v.%v.conf", local.splunk_name, local.account_id, local.account_alias, local.region)
+ directory = format("%v/setup", path.root)
+ }
+
+ provisioner "local-exec" {
+ command = "test -d ${self.triggers.directory} || mkdir ${self.triggers.directory}"
+ }
+
+ # provisioner "local-exec" {
+ # working_dir = "setup"
+ # command = "echo '${data.template_file.splunk_logging.rendered}' > inputs.${local.splunk_name}.${local.account_id}.${local.region}.conf"
+ # }
+}
+
+resource "local_file" "splunk_logging" {
+ count = var.enable_sqs ? 1 : 0
+
+ content = data.template_file.splunk_logging.rendered
+ file_permission = "0644"
+ filename = var.enable_sqs ? format("%v/%v", null_resource.splunk_logging[0].triggers.directory, null_resource.splunk_logging[0].triggers.filename) : null
+}
diff --git a/org-logging/main.tf b/org-logging/main.tf
new file mode 100644
index 0000000..be2c776
--- /dev/null
+++ b/org-logging/main.tf
@@ -0,0 +1,160 @@
+/*
+* # aws-inf-setup :: logging
+*
+* This set up the needed components for logging in a region: S3, KMS key, SNS, SQS, logging,
+* cloudwatch log groups, and associated permissions. It also generates a splunk configuration to be used
+* for pulling logging 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 Logging.
+*
+* ## Usage: Simple
+*
+* This siomple configuration is how it will typically be deployed.
+*
+* ```hcl
+* module "logging_key" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key"
+*
+* tags = local.common_tags
+* }
+*
+* module "logging" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging"
+*
+* account_alias = var.account_alias
+* access_log_bucket = module.logs.bucket_id
+* kms_key_arn = module.logging_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 logging with more variables offered.
+*
+* ```hcl
+* module "logging_key" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key"
+*
+* name = "mylogging"
+* 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 "logging" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging"
+*
+* name = "mylogging"
+* account_alias = var.account_alias
+* access_log_bucket = module.logs.bucket_id
+* kms_key_arn = module.logging_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_logging_key" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging-key"
+*
+* name = "org-logging"
+* tags = local.common_tags
+* }
+*
+* module "org_logging" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//logging"
+*
+* account_alias = var.account_alias
+* enable_organization = true
+* access_log_bucket = module.logs.bucket_id
+* kms_key_arn = module.org_logging_key.kms_key_arn
+* organization_id = data.aws_organizations_organization.org.id
+*
+* enable_sns = true
+* enable_sqs = true
+*
+* tags = local.common_tags
+* }
+* ```
+*/
+
+# key_name = (var.name != "" && var.name != null) ? var.name : local.name
+# sns_name = local.name
+# sqs_name = local.name
+# role_name = local.name
+# policy_name = local.name
+
+
+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
+ account_alias = var.account_alias == "" ? "MISSING" : var.account_alias
+
+ _name = var.name == null ? format("%v-%v", lookup(local._defaults["logging"], "name"), local.region) : var.name
+ name = var.enable_organization ? lookup(local._defaults["org_logging"], "name") : local._name
+ kms_key_name = format("k-%v", local.name)
+ kms_admin_root = format("arn:%v:iam::%v:root", local.partition, local.account_id)
+ # kms_admin_roles = compact(concat([var.kms_admin_root], var.kms_admin_roles))
+ # kms_policy_document = var.kms_policy_document != null ? var.kms_policy_document : data.aws_iam_policy_document.empty.json
+
+ _bucket_name = var.name == null ? format("%v-%v-%v", lookup(local._defaults["logging"], "name"), local.account_id, local.region) : var.name
+ bucket_name = var.enable_organization ? format("%v-%v-%v", lookup(local._defaults["org_logging"], "name"), local.account_id, local.region) : local._bucket_name
+
+ role_name = format("%v%v", local._prefixes["role"], local.name)
+ policy_name = format("%v%v", local._prefixes["policy"], local.name)
+
+ splunk_name = var.enable_organization ? "org-logging" : "logging"
+}
+
+data "aws_kms_key" "incoming_key" {
+ key_id = var.kms_key_arn
+}
+
+# data "aws_organizations_organization" "org" {}
+
+
+
diff --git a/org-logging/outputs.tf b/org-logging/outputs.tf
new file mode 100644
index 0000000..3e1b408
--- /dev/null
+++ b/org-logging/outputs.tf
@@ -0,0 +1,43 @@
+output "s3_bucket_arn" {
+ description = "Created S3 Bucket ARN"
+ value = aws_s3_bucket.this.arn
+}
+
+output "s3_bucket_id" {
+ description = "Created S3 Bucket ID"
+ value = aws_s3_bucket.this.id
+}
+
+output "sqs_info" {
+ description = "Main SQS ARNs and IDs (main, deadletter)"
+ value = {
+ "main" = {
+ arn = var.enable_sqs ? aws_sqs_queue.logging[0].arn : null
+ id = var.enable_sqs ? aws_sqs_queue.logging[0].id : null
+ }
+ "deadletter" = {
+ arn = var.enable_sqs ? aws_sqs_queue.logging_deadletter[0].arn : null
+ id = var.enable_sqs ? aws_sqs_queue.logging_deadletter[0].id : null
+ }
+ }
+}
+
+output "additional_sqs_info" {
+ description = "Additional SQS ARNs and IDs (main, deadletter)"
+ value = { for k in local.additional_sqs_names : k => {
+ "name" = k
+ "main" = {
+ arn = lookup(aws_sqs_queue.additional_logging, k, { arn : null }).arn
+ id = lookup(aws_sqs_queue.additional_logging, k, { id : null }).id
+ }
+ "deadletter" = {
+ arn = lookup(aws_sqs_queue.additional_logging_deadletter, k, { arn : null }).arn
+ id = lookup(aws_sqs_queue.additional_logging_deadletter, k, { id : null }).id
+ }
+ } }
+}
+
+output "sns_arn" {
+ description = "SNS ARN"
+ value = var.enable_sns ? aws_sns_topic.logging[0].arn : null
+}
diff --git a/org-logging/prefixes.tf b/org-logging/prefixes.tf
new file mode 100644
index 0000000..361746b
--- /dev/null
+++ b/org-logging/prefixes.tf
@@ -0,0 +1,33 @@
+locals {
+ _prefixes = {
+ "efs" = "v-efs-"
+ "s3" = "v-s3-"
+ "ebs" = "v-ebs-"
+ "kms" = "k-kms-"
+ "role" = "r-"
+ "policy" = "p-"
+ "group" = "g-"
+ "security-group" = "" # "sg-"
+ # VPC
+ "vpc" = ""
+ "dhcp-options" = ""
+ "vpc-peer" = "vpcp-"
+ "route-table" = "route-"
+ "subnet" = ""
+ "vpc-endpoint" = "vpce-"
+ "elastic-ip" = "eip-"
+ "nat-gateway" = "nat-"
+ "internet-gateway" = "igw-"
+ "network-acl" = "nacl-"
+ "customer-gateway" = "cgw-"
+ "vpn-gateway" = "vpcg-"
+ "vpn-connection" = "vpn_"
+ "log-group" = "lg-"
+ "log-stream" = "lgs-"
+ "transit-gateway" = "tgw-"
+ "transit-gateway-peer" = "tgwp-"
+ "transit-gateway-route-table" = "tgwr-"
+ "transit-gateway-attachment" = "tgwa-"
+ "transit-gateway-vpn" = "tgwv-"
+ }
+}
diff --git a/org-logging/s3.tf b/org-logging/s3.tf
new file mode 100644
index 0000000..efb42dc
--- /dev/null
+++ b/org-logging/s3.tf
@@ -0,0 +1,105 @@
+resource "aws_s3_bucket" "this" {
+ bucket = local.bucket_name
+ # acl = "private"
+ force_destroy = false
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ { "Name" = local.name },
+ )
+}
+
+resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
+ bucket = aws_s3_bucket.this.id
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = var.kms_key_arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+}
+
+resource "aws_s3_bucket_logging" "this" {
+ bucket = aws_s3_bucket.this.id
+ target_bucket = var.access_log_bucket
+ target_prefix = format("%s/%s/", var.access_log_bucket_prefix, local.bucket_name)
+}
+
+resource "aws_s3_bucket_acl" "this" {
+ count = 0
+ bucket = aws_s3_bucket.this.id
+ acl = "private"
+}
+
+resource "aws_s3_bucket_ownership_controls" "this" {
+ bucket = aws_s3_bucket.this.id
+
+ rule {
+ object_ownership = "BucketOwnerEnforced"
+ }
+}
+
+#---
+# bucket policy (apply also encryption key usage here?)
+# deny unencrypted uploads policy statement removed for default encryption
+#---
+data "aws_iam_policy_document" "bucket_policy" {
+ statement {
+ sid = "AWSLoggingAclCheck"
+ effect = "Allow"
+ actions = ["s3:GetBucketAcl"]
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+ resources = [aws_s3_bucket.this.arn]
+ }
+ statement {
+ sid = "AWSLoggingWrite"
+ effect = "Allow"
+ actions = ["s3:PutObject"]
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+ resources = [format("%v/%v/*", aws_s3_bucket.this.arn, var.logging_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.bucket_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 logging to point to it
+#---
+resource "null_resource" "policy_delay" {
+ triggers = {
+ bucket = aws_s3_bucket.this.id
+ }
+ provisioner "local-exec" {
+ when = create
+ command = "sleep 180"
+ }
+}
+
diff --git a/org-logging/s3.tf2 b/org-logging/s3.tf2
new file mode 100644
index 0000000..b537e45
--- /dev/null
+++ b/org-logging/s3.tf2
@@ -0,0 +1,57 @@
+#---
+# s3
+#---
+resource "aws_s3_bucket" "logging" {
+ bucket = local.bucket_name
+ acl = "private"
+
+ server_side_encryption_logginguration {
+ rule {
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = aws_kms_key.logging_key.arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+ }
+
+ versioning {
+ enabled = false
+ }
+
+ logging {
+ target_bucket = aws_s3_bucket.logs.id
+ target_prefix = "s3/{local.logging_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" "logging" {
+ bucket = aws_s3_bucket.logging.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_policy" "logging" {
+ bucket = aws_s3_bucket.logging.id
+ policy = data.aws_iam_policy_document.logging_s3.json
+}
diff --git a/org-logging/sns.tf b/org-logging/sns.tf
new file mode 100644
index 0000000..e7dc064
--- /dev/null
+++ b/org-logging/sns.tf
@@ -0,0 +1,56 @@
+resource "aws_sns_topic" "logging" {
+ count = var.enable_sns ? 1 : 0
+ name = local.name
+ kms_master_key_id = data.aws_kms_key.incoming_key.id
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = local.name }),
+ )
+}
+
+resource "aws_sns_topic_policy" "logging" {
+ count = var.enable_sns ? 1 : 0
+ arn = var.enable_sns ? aws_sns_topic.logging[0].arn : null
+ policy = data.aws_iam_policy_document.logging_topic.json
+}
+
+data "aws_iam_policy_document" "logging_topic" {
+ policy_id = format("%v_topic", local.name)
+ 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 = [local.account_id]
+ }
+ resources = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+ statement {
+ sid = "LoggingSNSPolicy"
+ effect = "Allow"
+ principals {
+ type = "Service"
+ identifiers = ["logging.amazonaws.com"]
+ }
+ actions = ["sns:Publish"]
+ resources = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+}
diff --git a/org-logging/sqs.tf b/org-logging/sqs.tf
new file mode 100644
index 0000000..32dc07c
--- /dev/null
+++ b/org-logging/sqs.tf
@@ -0,0 +1,103 @@
+resource "aws_sqs_queue" "logging_deadletter" {
+ count = var.enable_sqs ? 1 : 0
+ # delay=0 retention=4d max=256k visibility=1h
+ name = format("%v-deadletter", local.name)
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = lookup(local._defaults["sqs_deadletter"], "message_retention_seconds", 1 * 86400)
+ # message_retention_seconds = 345600
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 3600
+
+ kms_master_key_id = data.aws_kms_key.incoming_key.id
+ kms_data_key_reuse_period_seconds = 300
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = format("%v-deadletter", local.name) }),
+ )
+}
+
+resource "aws_sqs_queue_policy" "logging_deadletter" {
+ count = var.enable_sqs ? 1 : 0
+ queue_url = var.enable_sqs ? aws_sqs_queue.logging_deadletter[0].id : null
+ policy = data.aws_iam_policy_document.logging_deadletter.json
+}
+
+data "aws_iam_policy_document" "logging_deadletter" {
+ # policy_id = "SQSDefaultPolicy"
+ statement {
+ sid = "AllowSNSSendMessage"
+ effect = "Allow"
+ actions = ["sqs:SendMessage"]
+ resources = [var.enable_sqs ? aws_sqs_queue.logging_deadletter[0].arn : ""]
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ condition {
+ test = "ArnEquals"
+ variable = "aws:SourceArn"
+ values = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+ }
+}
+
+resource "aws_sqs_queue" "logging" {
+ count = var.enable_sqs ? 1 : 0
+ # delay=0 retention=7d max=256k visibity=2h
+ name = local.name
+ delay_seconds = 0
+ max_message_size = 262144
+ message_retention_seconds = lookup(local._defaults["sqs_deadletter"], "message_retention_seconds", 7 * 86400)
+ # message_retention_seconds = 604800
+ receive_wait_time_seconds = 15
+ visibility_timeout_seconds = 7200
+
+ redrive_policy = jsonencode({
+ deadLetterTargetArn = var.enable_sqs ? aws_sqs_queue.logging_deadletter[0].arn : null
+ maxReceiveCount = 100
+ })
+
+ kms_master_key_id = data.aws_kms_key.incoming_key.id
+ kms_data_key_reuse_period_seconds = 300
+
+ tags = merge(
+ local.base_tags,
+ var.tags,
+ tomap({ Name = local.name }),
+ )
+}
+
+resource "aws_sqs_queue_policy" "logging_sqs" {
+ count = var.enable_sqs ? 1 : 0
+ queue_url = var.enable_sqs ? aws_sqs_queue.logging[0].id : null
+ policy = data.aws_iam_policy_document.logging_sqs.json
+}
+
+data "aws_iam_policy_document" "logging_sqs" {
+ # policy_id = "SQSDefaultPolicy"
+ statement {
+ sid = "AllowSNSSendMessage"
+ effect = "Allow"
+ actions = ["sqs:SendMessage"]
+ resources = [var.enable_sqs ? aws_sqs_queue.logging[0].arn : ""]
+ principals {
+ type = "AWS"
+ identifiers = ["*"]
+ }
+ condition {
+ test = "ArnEquals"
+ variable = "aws:SourceArn"
+ values = [var.enable_sns ? aws_sns_topic.logging[0].arn : ""]
+ }
+ }
+}
+
+resource "aws_sns_topic_subscription" "logging_sqs" {
+ count = var.enable_sqs && var.enable_sns ? 1 : 0
+ protocol = "sqs"
+ topic_arn = var.enable_sns ? aws_sns_topic.logging[0].arn : null
+ endpoint = var.enable_sqs ? aws_sqs_queue.logging[0].arn : null
+}
diff --git a/org-logging/variables.common.tf b/org-logging/variables.common.tf
new file mode 120000
index 0000000..7439ed8
--- /dev/null
+++ b/org-logging/variables.common.tf
@@ -0,0 +1 @@
+../common/variables.common.tf
\ No newline at end of file
diff --git a/org-logging/variables.tf b/org-logging/variables.tf
new file mode 100644
index 0000000..92fc932
--- /dev/null
+++ b/org-logging/variables.tf
@@ -0,0 +1,91 @@
+## 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 "kms_key_arn" {
+ description = "AWS Logging KMS ARN to be used for encrypting the ClouldTrail, S3 Bucket, and SQS"
+ type = string
+}
+
+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" = {} }
+}
+
+variable "enable_organization" {
+ description = "Enable Logging as an organization trail. This will only work in the organization master account"
+ type = bool
+ default = false
+}
+
+variable "organization_id" {
+ description = "AWS Organization ID"
+ type = string
+ default = ""
+}
+
+variable "additional_sqs_names" {
+ description = "List of additional SQS queues to create and subscribe to the SNS topic (if enabled)"
+ type = list(string)
+ default = []
+}
diff --git a/org-logging/version.tf b/org-logging/version.tf
new file mode 120000
index 0000000..b83c5b7
--- /dev/null
+++ b/org-logging/version.tf
@@ -0,0 +1 @@
+../common/version.tf
\ No newline at end of file
diff --git a/org-logging/versions.tf b/org-logging/versions.tf
new file mode 100644
index 0000000..3d116e6
--- /dev/null
+++ b/org-logging/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"
+}