From 60db1091d4eecac40a77f012a49fec6511032a53 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Fri, 13 Dec 2024 10:39:51 +0100 Subject: [PATCH 01/19] feature: support central Security Hub configuration --- security_hub.tf | 23 ++++++++++++++++++++--- variables.tf | 34 ++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/security_hub.tf b/security_hub.tf index 5bbeb76..6392198 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -1,4 +1,10 @@ // AWS Security Hub - Management account configuration and enrollment +locals { + security_configuration_type = ( + var.aws_security_hub.organization_configuration_type == "CENTRAL" ? "NONE" : + (var.aws_security_hub.auto_enable_default_standards ? "DEFAULT" : "NONE") + ) +} resource "aws_securityhub_organization_admin_account" "default" { admin_account_id = data.aws_caller_identity.audit.account_id @@ -41,10 +47,14 @@ resource "aws_securityhub_account" "default" { resource "aws_securityhub_organization_configuration" "default" { provider = aws.audit - auto_enable = var.aws_security_hub.auto_enable_new_accounts - auto_enable_standards = var.aws_security_hub.auto_enable_default_standards ? "DEFAULT" : "NONE" + auto_enable = var.aws_security_hub.organization_configuration_type == "CENTRAL" ? false : var.aws_security_hub.auto_enable_new_accounts + auto_enable_standards = local.security_configuration_type + + organization_configuration { + configuration_type = var.aws_security_hub.organization_configuration_type + } - depends_on = [aws_securityhub_organization_admin_account.default] + depends_on = [aws_securityhub_organization_admin_account.default, aws_securityhub_finding_aggregator.default] } resource "aws_securityhub_product_subscription" "default" { @@ -133,3 +143,10 @@ resource "aws_securityhub_standards_subscription" "logging" { standards_arn = each.value depends_on = [aws_securityhub_account.default] } + +resource "aws_securityhub_finding_aggregator" "default" { + linking_mode = var.aws_security_hub.linking_mode + specified_regions = var.aws_security_hub.specified_regions + + depends_on = [aws_securityhub_account.default] +} diff --git a/variables.tf b/variables.tf index 9bd2c79..595d504 100644 --- a/variables.tf +++ b/variables.tf @@ -151,22 +151,28 @@ variable "aws_required_tags" { variable "aws_security_hub" { type = object({ - auto_enable_controls = optional(bool, true) - auto_enable_default_standards = optional(bool, false) - auto_enable_new_accounts = optional(bool, true) - control_finding_generator = optional(string, "SECURITY_CONTROL") - create_cis_metric_filters = optional(bool, true) - product_arns = optional(list(string), []) - standards_arns = optional(list(string), null) + aggregator_linking_mode = optional(string, "ALL_REGIONS") + aggregator_specified_regions = optional(list(string), []) + auto_enable_controls = optional(bool, true) + auto_enable_default_standards = optional(bool, false) + auto_enable_new_accounts = optional(bool, true) + control_finding_generator = optional(string, "SECURITY_CONTROL") + create_cis_metric_filters = optional(bool, true) + organization_configuration_type = optional(string, "LOCAL") + product_arns = optional(list(string), []) + standards_arns = optional(list(string), null) }) default = { - auto_enable_controls = true - auto_enable_default_standards = false - auto_enable_new_accounts = true - control_finding_generator = "SECURITY_CONTROL" - create_cis_metric_filters = true - product_arns = [] - standards_arns = null + aggregator_linking_mode = "ALL_REGIONS" + aggregator_specified_regions = null + auto_enable_controls = true + auto_enable_default_standards = false + auto_enable_new_accounts = true + control_finding_generator = "SECURITY_CONTROL" + create_cis_metric_filters = true + organization_configuration_type = "LOCAL" + product_arns = [] + standards_arns = null } description = "AWS Security Hub settings" From 7020061a67ac4b7f4070c86b48cffc260bfd52e0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Dec 2024 10:09:52 +0000 Subject: [PATCH 02/19] docs(readme): update module usage --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 938501f..99105cf 100644 --- a/README.md +++ b/README.md @@ -504,6 +504,7 @@ module "landing_zone" { | [aws_s3_account_public_access_block.master](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_account_public_access_block) | resource | | [aws_securityhub_account.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_account) | resource | | [aws_securityhub_account.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_account) | resource | +| [aws_securityhub_finding_aggregator.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_finding_aggregator) | resource | | [aws_securityhub_member.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_member) | resource | | [aws_securityhub_member.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_member) | resource | | [aws_securityhub_organization_admin_account.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_organization_admin_account) | resource | @@ -549,7 +550,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
|
{
"auto_enable_controls": true,
"auto_enable_default_standards": false,
"auto_enable_new_accounts": true,
"control_finding_generator": "SECURITY_CONTROL",
"create_cis_metric_filters": true,
"product_arns": [],
"standards_arns": null
}
| no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), [])
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
|
{
"aggregator_linking_mode": "ALL_REGIONS",
"aggregator_specified_regions": null,
"auto_enable_controls": true,
"auto_enable_default_standards": false,
"auto_enable_new_accounts": true,
"control_finding_generator": "SECURITY_CONTROL",
"create_cis_metric_filters": true,
"organization_configuration_type": "LOCAL",
"product_arns": [],
"standards_arns": null
}
| no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From 9ca7e78f5d23160c549e672b94761505df76cbf9 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Fri, 13 Dec 2024 11:14:58 +0100 Subject: [PATCH 03/19] rely on defaults of optionals --- variables.tf | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/variables.tf b/variables.tf index 595d504..06d075f 100644 --- a/variables.tf +++ b/variables.tf @@ -162,18 +162,7 @@ variable "aws_security_hub" { product_arns = optional(list(string), []) standards_arns = optional(list(string), null) }) - default = { - aggregator_linking_mode = "ALL_REGIONS" - aggregator_specified_regions = null - auto_enable_controls = true - auto_enable_default_standards = false - auto_enable_new_accounts = true - control_finding_generator = "SECURITY_CONTROL" - create_cis_metric_filters = true - organization_configuration_type = "LOCAL" - product_arns = [] - standards_arns = null - } + default = {} description = "AWS Security Hub settings" validation { From b71a6a59a83287d97923b6b41763e6bd8d7a3676 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Dec 2024 14:01:48 +0000 Subject: [PATCH 04/19] docs(readme): update module usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99105cf..0b60809 100644 --- a/README.md +++ b/README.md @@ -550,7 +550,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), [])
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
|
{
"aggregator_linking_mode": "ALL_REGIONS",
"aggregator_specified_regions": null,
"auto_enable_controls": true,
"auto_enable_default_standards": false,
"auto_enable_new_accounts": true,
"control_finding_generator": "SECURITY_CONTROL",
"create_cis_metric_filters": true,
"organization_configuration_type": "LOCAL",
"product_arns": [],
"standards_arns": null
}
| no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), [])
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From d39d1f08217fba7b285d5f2a9d0588f7d6f0178c Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Fri, 13 Dec 2024 16:42:26 +0100 Subject: [PATCH 05/19] do not use key if no value --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 06d075f..49e38cf 100644 --- a/variables.tf +++ b/variables.tf @@ -152,7 +152,7 @@ variable "aws_required_tags" { variable "aws_security_hub" { type = object({ aggregator_linking_mode = optional(string, "ALL_REGIONS") - aggregator_specified_regions = optional(list(string), []) + aggregator_specified_regions = optional(list(string), null) auto_enable_controls = optional(bool, true) auto_enable_default_standards = optional(bool, false) auto_enable_new_accounts = optional(bool, true) From 83290a5b75c39d6bf7e0b83fa0f24cdf9793e7bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Dec 2024 15:42:54 +0000 Subject: [PATCH 06/19] docs(readme): update module usage --- README.md | 2 +- variables.tf | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b60809..225170f 100644 --- a/README.md +++ b/README.md @@ -550,7 +550,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), [])
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | diff --git a/variables.tf b/variables.tf index 49e38cf..53e626e 100644 --- a/variables.tf +++ b/variables.tf @@ -162,7 +162,6 @@ variable "aws_security_hub" { product_arns = optional(list(string), []) standards_arns = optional(list(string), null) }) - default = {} description = "AWS Security Hub settings" validation { From c6ccfc779681e0716be5737304714bd3ea7f5e98 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Dec 2024 08:27:42 +0000 Subject: [PATCH 07/19] docs(readme): update module usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 225170f..c56c8fd 100644 --- a/README.md +++ b/README.md @@ -539,6 +539,7 @@ module "landing_zone" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| n/a | yes | | [control\_tower\_account\_ids](#input\_control\_tower\_account\_ids) | Control Tower core account IDs |
object({
audit = string
logging = string
})
| n/a | yes | | [tags](#input\_tags) | Map of tags | `map(string)` | n/a | yes | | [additional\_auditing\_trail](#input\_additional\_auditing\_trail) | CloudTrail configuration for additional auditing trail |
object({
name = string
bucket = string
kms_key_id = string

event_selector = optional(object({
data_resource = optional(object({
type = string
values = list(string)
}))
exclude_management_event_sources = optional(set(string), null)
include_management_events = optional(bool, true)
read_write_type = optional(string, "All")
}))
})
| `null` | no | @@ -550,7 +551,6 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From 09235946704252bb64220fcba9a9d065802960ae Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 10:14:18 +0100 Subject: [PATCH 08/19] feat: Add validation rules to security_hub configuration --- security_hub.tf | 4 ++-- variables.tf | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/security_hub.tf b/security_hub.tf index 010703f..ac1f512 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -47,8 +47,8 @@ resource "aws_securityhub_account" "default" { resource "aws_securityhub_organization_configuration" "default" { provider = aws.audit - auto_enable = var.aws_security_hub.organization_configuration_type == "CENTRAL" ? false : var.aws_security_hub.auto_enable_new_accounts - auto_enable_standards = local.security_configuration_type + auto_enable = var.aws_security_hub.auto_enable_new_accounts + auto_enable_standards = var.aws_security_hub.auto_enable_default_standards organization_configuration { configuration_type = var.aws_security_hub.organization_configuration_type diff --git a/variables.tf b/variables.tf index 53e626e..e86cc12 100644 --- a/variables.tf +++ b/variables.tf @@ -162,12 +162,23 @@ variable "aws_security_hub" { product_arns = optional(list(string), []) standards_arns = optional(list(string), null) }) + default = {} description = "AWS Security Hub settings" validation { condition = contains(["SECURITY_CONTROL", "STANDARD_CONTROL"], var.aws_security_hub.control_finding_generator) error_message = "The \"control_finding_generator\" variable must be set to either \"SECURITY_CONTROL\" or \"STANDARD_CONTROL\"." } + + validation { + condition = contains(["LOCAL", "CENTRAL"], var.security_hub.organization_configuration_type) + error_message = "Invalid var.security_hub.organization_configuration_type: Must be one of \"LOCAL\" or \"CENTRAL\"." + } + + validation { + condition = var.security_hub.organization_configuration_type == "LOCAL" || (var.security_hub.auto_enable_new_accounts == false && var.security_hub.auto_enable_default_standards == "NONE") + error_message = "If var.security_hub.organization_configuration_type is \"CENTRAL\", var.security_hub.auto_enable_new_accounts` must be \"False\" and var.security_hub.auto_enable_default_standards must be \"NONE\"." + } } variable "aws_security_hub_sns_subscription" { From 750cdc13065e5b63d6364a364b30ed7eed082557 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 17 Dec 2024 09:20:10 +0000 Subject: [PATCH 09/19] docs(readme): update module usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c56c8fd..225170f 100644 --- a/README.md +++ b/README.md @@ -539,7 +539,6 @@ module "landing_zone" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| n/a | yes | | [control\_tower\_account\_ids](#input\_control\_tower\_account\_ids) | Control Tower core account IDs |
object({
audit = string
logging = string
})
| n/a | yes | | [tags](#input\_tags) | Map of tags | `map(string)` | n/a | yes | | [additional\_auditing\_trail](#input\_additional\_auditing\_trail) | CloudTrail configuration for additional auditing trail |
object({
name = string
bucket = string
kms_key_id = string

event_selector = optional(object({
data_resource = optional(object({
type = string
values = list(string)
}))
exclude_management_event_sources = optional(set(string), null)
include_management_events = optional(bool, true)
read_write_type = optional(string, "All")
}))
})
| `null` | no | @@ -551,6 +550,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From ac42a576490b751d0b6aa40cda2d6b8af8d17bdc Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 10:27:26 +0100 Subject: [PATCH 10/19] Set provider for aws_securityhub_finding_aggregator --- security_hub.tf | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/security_hub.tf b/security_hub.tf index ac1f512..f935bd3 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -1,10 +1,4 @@ // AWS Security Hub - Management account configuration and enrollment -locals { - security_configuration_type = ( - var.aws_security_hub.organization_configuration_type == "CENTRAL" ? "NONE" : - (var.aws_security_hub.auto_enable_default_standards ? "DEFAULT" : "NONE") - ) -} resource "aws_securityhub_organization_admin_account" "default" { admin_account_id = data.aws_caller_identity.audit.account_id @@ -145,6 +139,8 @@ resource "aws_securityhub_standards_subscription" "logging" { } resource "aws_securityhub_finding_aggregator" "default" { + provider = aws.audit + linking_mode = var.aws_security_hub.aggregator_linking_mode specified_regions = var.aws_security_hub.aggregator_specified_regions From 3f1d890cea49ab04b53efb839bb5481a09a1890c Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 12:26:15 +0100 Subject: [PATCH 11/19] Move Security Hub Configuration to Central --- UPGRADING.md | 9 ++++++++ security_hub.tf | 59 ++++++++++++++++++++----------------------------- variables.tf | 27 ++++++---------------- 3 files changed, 40 insertions(+), 55 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 79fa1f8..74325bd 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,6 +2,15 @@ This document captures required refactoring on your part when upgrading to a module version that contains breaking changes. +## Upgrading to v4.1.0 + +### Behaviour + +This version changes the detault [Security Hub configuration to Central](https://docs.aws.amazon.com/securityhub/latest/userguide/central-configuration-intro.html). You can change this behaviour by setting `var.aws_security_hub.organization_configuration_type` to `LOCAL`. + +This version enables Security Hub Findings Aggregation for all regions. You can change this behauviour by setting `var.aws_security_hub.aggregator_linking_mode` to `ALL_REGIONS_EXCEPT_SPECIFIED` or `SPECIFIED_REGIONS` and providing the list of regions via `var.aws_security_hub.aggregator_specified_regions` + + ## Upgrading to v4.0.0 > [!WARNING] diff --git a/security_hub.tf b/security_hub.tf index 023927d..5b92370 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -23,14 +23,6 @@ resource "aws_securityhub_member" "management" { } } -resource "aws_securityhub_standards_subscription" "management" { - for_each = toset(local.security_hub_standards_arns) - - standards_arn = each.value - - depends_on = [aws_securityhub_account.default] -} - // AWS Security Hub - Audit account configuration and enrollment resource "aws_securityhub_account" "default" { provider = aws.audit @@ -41,33 +33,16 @@ resource "aws_securityhub_account" "default" { resource "aws_securityhub_organization_configuration" "default" { provider = aws.audit - auto_enable = var.aws_security_hub.auto_enable_new_accounts - auto_enable_standards = var.aws_security_hub.auto_enable_default_standards ? "DEFAULT" : "NONE" + auto_enable = false + auto_enable_standards = "NONE" organization_configuration { - configuration_type = var.aws_security_hub.organization_configuration_type + configuration_type = "CENTRAL" } depends_on = [aws_securityhub_organization_admin_account.default, aws_securityhub_finding_aggregator.default] } -resource "aws_securityhub_product_subscription" "default" { - for_each = toset(var.aws_security_hub.product_arns) - provider = aws.audit - - product_arn = each.value - - depends_on = [aws_securityhub_account.default] -} - -resource "aws_securityhub_standards_subscription" "default" { - for_each = toset(local.security_hub_standards_arns) - provider = aws.audit - - standards_arn = each.value - - depends_on = [aws_securityhub_account.default] -} resource "aws_cloudwatch_event_rule" "security_hub_findings" { provider = aws.audit @@ -130,13 +105,6 @@ resource "aws_securityhub_member" "logging" { depends_on = [aws_securityhub_organization_configuration.default] } -resource "aws_securityhub_standards_subscription" "logging" { - for_each = toset(local.security_hub_standards_arns) - provider = aws.logging - - standards_arn = each.value - depends_on = [aws_securityhub_account.default] -} resource "aws_securityhub_finding_aggregator" "default" { provider = aws.audit @@ -146,3 +114,24 @@ resource "aws_securityhub_finding_aggregator" "default" { depends_on = [aws_securityhub_account.default] } + +resource "aws_securityhub_configuration_policy" "default" { + name = "mcaf-lz" + description = "MCAF Landing Zone default configuration policy" + + configuration_policy { + service_enabled = true + enabled_standard_arns = local.security_hub_standards_arns + + security_controls_configuration { + disabled_control_identifiers = [] + } + } + + depends_on = [aws_securityhub_organization_configuration.default] +} + +resource "aws_securityhub_configuration_policy_association" "root" { + target_id = data.aws_organizations_organization.default.id + policy_id = aws_securityhub_configuration_policy.default.id +} diff --git a/variables.tf b/variables.tf index 3ce407c..eb41d90 100644 --- a/variables.tf +++ b/variables.tf @@ -151,16 +151,13 @@ variable "aws_required_tags" { variable "aws_security_hub" { type = object({ - aggregator_linking_mode = optional(string, "ALL_REGIONS") - aggregator_specified_regions = optional(list(string), null) - auto_enable_controls = optional(bool, true) - auto_enable_default_standards = optional(bool, false) - auto_enable_new_accounts = optional(bool, true) - control_finding_generator = optional(string, "SECURITY_CONTROL") - create_cis_metric_filters = optional(bool, true) - organization_configuration_type = optional(string, "LOCAL") - product_arns = optional(list(string), []) - standards_arns = optional(list(string), null) + aggregator_linking_mode = optional(string, "ALL_REGIONS") + aggregator_specified_regions = optional(list(string), null) + auto_enable_controls = optional(bool, true) + control_finding_generator = optional(string, "SECURITY_CONTROL") + create_cis_metric_filters = optional(bool, true) + product_arns = optional(list(string), []) + standards_arns = optional(list(string), null) }) default = {} description = "AWS Security Hub settings" @@ -169,16 +166,6 @@ variable "aws_security_hub" { condition = contains(["SECURITY_CONTROL", "STANDARD_CONTROL"], var.aws_security_hub.control_finding_generator) error_message = "The \"control_finding_generator\" variable must be set to either \"SECURITY_CONTROL\" or \"STANDARD_CONTROL\"." } - - validation { - condition = contains(["LOCAL", "CENTRAL"], var.aws_security_hub.organization_configuration_type) - error_message = "Invalid var.aws_security_hub.organization_configuration_type: Must be one of \"LOCAL\" or \"CENTRAL\"." - } - - validation { - condition = var.aws_security_hub.organization_configuration_type == "LOCAL" || (var.aws_security_hub.auto_enable_new_accounts == false && var.aws_security_hub.auto_enable_default_standards == false) - error_message = "If var.aws_security_hub.organization_configuration_type is \"CENTRAL\", var.aws_security_hub.auto_enable_new_accounts` must be \"False\" and var.aws_security_hub.auto_enable_default_standards must be \"False\"." - } } variable "aws_security_hub_sns_subscription" { From d623e1027ead6c8b62b1e24c8b17e574008e50f7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 17 Dec 2024 11:31:26 +0000 Subject: [PATCH 12/19] docs(readme): update module usage --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 225170f..46683d6 100644 --- a/README.md +++ b/README.md @@ -504,15 +504,13 @@ module "landing_zone" { | [aws_s3_account_public_access_block.master](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_account_public_access_block) | resource | | [aws_securityhub_account.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_account) | resource | | [aws_securityhub_account.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_account) | resource | +| [aws_securityhub_configuration_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_configuration_policy) | resource | +| [aws_securityhub_configuration_policy_association.root](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_configuration_policy_association) | resource | | [aws_securityhub_finding_aggregator.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_finding_aggregator) | resource | | [aws_securityhub_member.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_member) | resource | | [aws_securityhub_member.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_member) | resource | | [aws_securityhub_organization_admin_account.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_organization_admin_account) | resource | | [aws_securityhub_organization_configuration.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_organization_configuration) | resource | -| [aws_securityhub_product_subscription.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_product_subscription) | resource | -| [aws_securityhub_standards_subscription.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_standards_subscription) | resource | -| [aws_securityhub_standards_subscription.logging](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_standards_subscription) | resource | -| [aws_securityhub_standards_subscription.management](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_standards_subscription) | resource | | [aws_sns_topic.iam_activity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic.security_hub_findings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic_policy.iam_activity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource | @@ -550,7 +548,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
auto_enable_default_standards = optional(bool, false)
auto_enable_new_accounts = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
organization_configuration_type = optional(string, "LOCAL")
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From 5afe35788cebd427505535f8d61ef0c7faece673 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 13:21:25 +0100 Subject: [PATCH 13/19] Use correct org root id --- UPGRADING.md | 3 ++- security_hub.tf | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 74325bd..c762184 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -6,7 +6,8 @@ This document captures required refactoring on your part when upgrading to a mod ### Behaviour -This version changes the detault [Security Hub configuration to Central](https://docs.aws.amazon.com/securityhub/latest/userguide/central-configuration-intro.html). You can change this behaviour by setting `var.aws_security_hub.organization_configuration_type` to `LOCAL`. +> [!IMPORTANT] +> **This version changes the [Security Hub configuration to Central](https://docs.aws.amazon.com/securityhub/latest/userguide/central-configuration-intro.html).** This version enables Security Hub Findings Aggregation for all regions. You can change this behauviour by setting `var.aws_security_hub.aggregator_linking_mode` to `ALL_REGIONS_EXCEPT_SPECIFIED` or `SPECIFIED_REGIONS` and providing the list of regions via `var.aws_security_hub.aggregator_specified_regions` diff --git a/security_hub.tf b/security_hub.tf index 5b92370..8e88190 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -132,6 +132,6 @@ resource "aws_securityhub_configuration_policy" "default" { } resource "aws_securityhub_configuration_policy_association" "root" { - target_id = data.aws_organizations_organization.default.id + target_id = data.aws_organizations_organization.default.roots[0].id policy_id = aws_securityhub_configuration_policy.default.id } From f4b3571a725d8a81de50959f4808a04e6894758e Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 14:25:44 +0100 Subject: [PATCH 14/19] Use central allowed_region for all region bound configurations --- UPGRADING.md | 6 +++++- config.tf | 4 ++-- organizations_policy.tf | 6 +++--- security_hub.tf | 2 +- variables.tf | 25 ++++++++++++++++--------- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index c762184..23ac501 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,7 +2,7 @@ This document captures required refactoring on your part when upgrading to a module version that contains breaking changes. -## Upgrading to v4.1.0 +## Upgrading to v5.0.0 ### Behaviour @@ -11,6 +11,10 @@ This document captures required refactoring on your part when upgrading to a mod This version enables Security Hub Findings Aggregation for all regions. You can change this behauviour by setting `var.aws_security_hub.aggregator_linking_mode` to `ALL_REGIONS_EXCEPT_SPECIFIED` or `SPECIFIED_REGIONS` and providing the list of regions via `var.aws_security_hub.aggregator_specified_regions` +The following variables have been replaced: +* `aws_service_control_policies.allowed_regions` -> `allowed_regions` +* `aws_config.aggregator_regions` -> `allowed_regions` + ## Upgrading to v4.0.0 diff --git a/config.tf b/config.tf index 17f8171..74079f2 100644 --- a/config.tf +++ b/config.tf @@ -1,7 +1,7 @@ locals { aws_config_aggregators = flatten([ for account in toset(try(var.aws_config.aggregator_account_ids, [])) : [ - for region in toset(try(var.aws_config.aggregator_regions, [])) : { + for region in toset(try(var.allowed_regions, [])) : { account_id = account region = region } @@ -32,7 +32,7 @@ resource "aws_config_aggregate_authorization" "master" { } resource "aws_config_aggregate_authorization" "master_to_audit" { - for_each = toset(coalescelist(var.aws_config.aggregator_regions, [data.aws_region.current.name])) + for_each = toset(coalescelist(var.allowed_regions, [data.aws_region.current.name])) account_id = var.control_tower_account_ids.audit region = each.value diff --git a/organizations_policy.tf b/organizations_policy.tf index 3f2d3d3..f515965 100644 --- a/organizations_policy.tf +++ b/organizations_policy.tf @@ -1,9 +1,9 @@ locals { enabled_root_policies = { allowed_regions = { - enable = var.aws_service_control_policies.allowed_regions != null ? true : false - policy = var.aws_service_control_policies.allowed_regions != null ? templatefile("${path.module}/files/organizations/allowed_regions.json.tpl", { - allowed = var.aws_service_control_policies.allowed_regions != null ? var.aws_service_control_policies.allowed_regions : [] + enable = var.allowed_regions != null ? true : false + policy = var.allowed_regions != null ? templatefile("${path.module}/files/organizations/allowed_regions.json.tpl", { + allowed = var.allowed_regions != null ? var.allowed_regions : [] exceptions = local.aws_service_control_policies_principal_exceptions }) : null } diff --git a/security_hub.tf b/security_hub.tf index 35358fb..bcd85e8 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -110,7 +110,7 @@ resource "aws_securityhub_finding_aggregator" "default" { provider = aws.audit linking_mode = var.aws_security_hub.aggregator_linking_mode - specified_regions = var.aws_security_hub.aggregator_specified_regions + specified_regions = var.aws_security_hub.aggregator_linking_mode == "SPECIFIED_REGIONS" ? var.allowed_regions : null depends_on = [aws_securityhub_account.default] } diff --git a/variables.tf b/variables.tf index eb41d90..56f60f3 100644 --- a/variables.tf +++ b/variables.tf @@ -18,6 +18,11 @@ variable "additional_auditing_trail" { description = "CloudTrail configuration for additional auditing trail" } +variable "allowed_regions" { + type = list(string) + description = "List of AWS regions where operations are allowed and for which central services like Security Hub and AWS Config are configured." +} + variable "aws_account_password_policy" { type = object({ allow_users_to_change = bool @@ -57,7 +62,6 @@ variable "aws_auditmanager" { variable "aws_config" { type = object({ aggregator_account_ids = optional(list(string), []) - aggregator_regions = optional(list(string), []) delivery_channel_s3_bucket_name = optional(string, null) delivery_channel_s3_key_prefix = optional(string, null) delivery_frequency = optional(string, "TwentyFour_Hours") @@ -65,7 +69,6 @@ variable "aws_config" { }) default = { aggregator_account_ids = [] - aggregator_regions = [] delivery_channel_s3_bucket_name = null delivery_channel_s3_key_prefix = null delivery_frequency = "TwentyFour_Hours" @@ -151,13 +154,12 @@ variable "aws_required_tags" { variable "aws_security_hub" { type = object({ - aggregator_linking_mode = optional(string, "ALL_REGIONS") - aggregator_specified_regions = optional(list(string), null) - auto_enable_controls = optional(bool, true) - control_finding_generator = optional(string, "SECURITY_CONTROL") - create_cis_metric_filters = optional(bool, true) - product_arns = optional(list(string), []) - standards_arns = optional(list(string), null) + aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS") + auto_enable_controls = optional(bool, true) + control_finding_generator = optional(string, "SECURITY_CONTROL") + create_cis_metric_filters = optional(bool, true) + product_arns = optional(list(string), []) + standards_arns = optional(list(string), null) }) default = {} description = "AWS Security Hub settings" @@ -166,6 +168,11 @@ variable "aws_security_hub" { condition = contains(["SECURITY_CONTROL", "STANDARD_CONTROL"], var.aws_security_hub.control_finding_generator) error_message = "The \"control_finding_generator\" variable must be set to either \"SECURITY_CONTROL\" or \"STANDARD_CONTROL\"." } + + validation { + condition = var.aws_security_hub.aggregator_linking_mode != "ALL_REGIONS" + error_message = "Security Hub Linking mode cannot be set to \"ALL_REGIONS\" since AWS Config needs to be configured in all regions individually." + } } variable "aws_security_hub_sns_subscription" { From 5ece85bea47b2c80f7c59f44203a73b0197dfe9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 17 Dec 2024 13:26:09 +0000 Subject: [PATCH 15/19] docs(readme): update module usage --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46683d6..26d2e83 100644 --- a/README.md +++ b/README.md @@ -537,18 +537,19 @@ module "landing_zone" { | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [allowed\_regions](#input\_allowed\_regions) | List of AWS regions where operations are allowed and for which central services like Security Hub and AWS Config are configured. | `list(string)` | n/a | yes | | [control\_tower\_account\_ids](#input\_control\_tower\_account\_ids) | Control Tower core account IDs |
object({
audit = string
logging = string
})
| n/a | yes | | [tags](#input\_tags) | Map of tags | `map(string)` | n/a | yes | | [additional\_auditing\_trail](#input\_additional\_auditing\_trail) | CloudTrail configuration for additional auditing trail |
object({
name = string
bucket = string
kms_key_id = string

event_selector = optional(object({
data_resource = optional(object({
type = string
values = list(string)
}))
exclude_management_event_sources = optional(set(string), null)
include_management_events = optional(bool, true)
read_write_type = optional(string, "All")
}))
})
| `null` | no | | [aws\_account\_password\_policy](#input\_aws\_account\_password\_policy) | AWS account password policy parameters for the audit, logging and master account |
object({
allow_users_to_change = bool
max_age = number
minimum_length = number
require_lowercase_characters = bool
require_numbers = bool
require_symbols = bool
require_uppercase_characters = bool
reuse_prevention_history = number
})
|
{
"allow_users_to_change": true,
"max_age": 90,
"minimum_length": 14,
"require_lowercase_characters": true,
"require_numbers": true,
"require_symbols": true,
"require_uppercase_characters": true,
"reuse_prevention_history": 24
}
| no | | [aws\_auditmanager](#input\_aws\_auditmanager) | AWS Audit Manager config settings |
object({
enabled = bool
reports_bucket_prefix = string
})
|
{
"enabled": true,
"reports_bucket_prefix": "audit-manager-reports"
}
| no | -| [aws\_config](#input\_aws\_config) | AWS Config settings |
object({
aggregator_account_ids = optional(list(string), [])
aggregator_regions = optional(list(string), [])
delivery_channel_s3_bucket_name = optional(string, null)
delivery_channel_s3_key_prefix = optional(string, null)
delivery_frequency = optional(string, "TwentyFour_Hours")
rule_identifiers = optional(list(string), [])
})
|
{
"aggregator_account_ids": [],
"aggregator_regions": [],
"delivery_channel_s3_bucket_name": null,
"delivery_channel_s3_key_prefix": null,
"delivery_frequency": "TwentyFour_Hours",
"rule_identifiers": []
}
| no | +| [aws\_config](#input\_aws\_config) | AWS Config settings |
object({
aggregator_account_ids = optional(list(string), [])
delivery_channel_s3_bucket_name = optional(string, null)
delivery_channel_s3_key_prefix = optional(string, null)
delivery_frequency = optional(string, "TwentyFour_Hours")
rule_identifiers = optional(list(string), [])
})
|
{
"aggregator_account_ids": [],
"delivery_channel_s3_bucket_name": null,
"delivery_channel_s3_key_prefix": null,
"delivery_frequency": "TwentyFour_Hours",
"rule_identifiers": []
}
| no | | [aws\_config\_sns\_subscription](#input\_aws\_config\_sns\_subscription) | Subscription options for the aws-controltower-AggregateSecurityNotifications (AWS Config) SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_ebs\_encryption\_by\_default](#input\_aws\_ebs\_encryption\_by\_default) | Set to true to enable AWS Elastic Block Store encryption by default | `bool` | `true` | no | | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "ALL_REGIONS")
aggregator_specified_regions = optional(list(string), null)
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS")
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no | From 3e36ef609eb400381791d06132ed25bccc628807 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 15:02:10 +0100 Subject: [PATCH 16/19] Ensure home region is not used for findings aggregator --- security_hub.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/security_hub.tf b/security_hub.tf index bcd85e8..a6bcac8 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -1,3 +1,7 @@ +locals { + all_regions_except_home_region = setsubtract(var.allowed_regions, (data.aws_region.current.name)) +} + // AWS Security Hub - Management account configuration and enrollment resource "aws_securityhub_organization_admin_account" "default" { admin_account_id = data.aws_caller_identity.audit.account_id @@ -107,10 +111,11 @@ resource "aws_securityhub_member" "logging" { resource "aws_securityhub_finding_aggregator" "default" { + count = length(local.all_regions_except_home_region) == 0 ? 0 : 1 provider = aws.audit linking_mode = var.aws_security_hub.aggregator_linking_mode - specified_regions = var.aws_security_hub.aggregator_linking_mode == "SPECIFIED_REGIONS" ? var.allowed_regions : null + specified_regions = var.aws_security_hub.aggregator_linking_mode == "SPECIFIED_REGIONS" ? local.all_regions_except_home_region : null depends_on = [aws_securityhub_account.default] } From 341311f5d09a8e8ad42b69507175d7b55227dba3 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Tue, 17 Dec 2024 16:07:50 +0100 Subject: [PATCH 17/19] Ensure allowed_regions contains at least one region. --- config.tf | 4 ++-- locals.tf | 4 ++++ organizations_policy.tf | 4 ++-- security_hub.tf | 8 ++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config.tf b/config.tf index 74079f2..203705e 100644 --- a/config.tf +++ b/config.tf @@ -1,7 +1,7 @@ locals { aws_config_aggregators = flatten([ for account in toset(try(var.aws_config.aggregator_account_ids, [])) : [ - for region in toset(try(var.allowed_regions, [])) : { + for region in toset(try(local.allowed_regions_with_us_east, [])) : { account_id = account region = region } @@ -32,7 +32,7 @@ resource "aws_config_aggregate_authorization" "master" { } resource "aws_config_aggregate_authorization" "master_to_audit" { - for_each = toset(coalescelist(var.allowed_regions, [data.aws_region.current.name])) + for_each = local.allowed_regions_with_us_east account_id = var.control_tower_account_ids.audit region = each.value diff --git a/locals.tf b/locals.tf index 0727e22..d6d9659 100644 --- a/locals.tf +++ b/locals.tf @@ -34,4 +34,8 @@ locals { security_hub_has_cis_aws_foundations_enabled = length(regexall( "cis-aws-foundations-benchmark/v", join(",", local.security_hub_standards_arns) )) > 0 ? true : false + + allowed_regions = toset(distinct(concat(var.allowed_regions, [data.aws_region.current.name]))) + allowed_regions_with_us_east = toset(distinct(concat(var.allowed_regions, [data.aws_region.current.name], ["us-east-1"]))) + allowed_regions_except_home_region = setsubtract(local.allowed_regions_with_us_east, [data.aws_region.current.name]) } diff --git a/organizations_policy.tf b/organizations_policy.tf index f515965..8803971 100644 --- a/organizations_policy.tf +++ b/organizations_policy.tf @@ -2,8 +2,8 @@ locals { enabled_root_policies = { allowed_regions = { enable = var.allowed_regions != null ? true : false - policy = var.allowed_regions != null ? templatefile("${path.module}/files/organizations/allowed_regions.json.tpl", { - allowed = var.allowed_regions != null ? var.allowed_regions : [] + policy = local.allowed_regions != null ? templatefile("${path.module}/files/organizations/allowed_regions.json.tpl", { + allowed = var.allowed_regions != null ? local.allowed_regions : [] exceptions = local.aws_service_control_policies_principal_exceptions }) : null } diff --git a/security_hub.tf b/security_hub.tf index a6bcac8..04eec56 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -1,7 +1,3 @@ -locals { - all_regions_except_home_region = setsubtract(var.allowed_regions, (data.aws_region.current.name)) -} - // AWS Security Hub - Management account configuration and enrollment resource "aws_securityhub_organization_admin_account" "default" { admin_account_id = data.aws_caller_identity.audit.account_id @@ -111,11 +107,11 @@ resource "aws_securityhub_member" "logging" { resource "aws_securityhub_finding_aggregator" "default" { - count = length(local.all_regions_except_home_region) == 0 ? 0 : 1 + count = length(local.allowed_regions_except_home_region) == 0 ? 0 : 1 provider = aws.audit linking_mode = var.aws_security_hub.aggregator_linking_mode - specified_regions = var.aws_security_hub.aggregator_linking_mode == "SPECIFIED_REGIONS" ? local.all_regions_except_home_region : null + specified_regions = var.aws_security_hub.aggregator_linking_mode == "SPECIFIED_REGIONS" ? local.allowed_regions_except_home_region : null depends_on = [aws_securityhub_account.default] } From f63139ed79570caff0bd6e52331ed426f090bcb1 Mon Sep 17 00:00:00 2001 From: Johan Steenhoven Date: Wed, 18 Dec 2024 09:05:05 +0100 Subject: [PATCH 18/19] Allow disabling of securityhub controls by ID --- UPGRADING.md | 7 ++++++- security_hub.tf | 2 +- variables.tf | 13 +++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 23ac501..8b0eb76 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -9,12 +9,17 @@ This document captures required refactoring on your part when upgrading to a mod > [!IMPORTANT] > **This version changes the [Security Hub configuration to Central](https://docs.aws.amazon.com/securityhub/latest/userguide/central-configuration-intro.html).** -This version enables Security Hub Findings Aggregation for all regions. You can change this behauviour by setting `var.aws_security_hub.aggregator_linking_mode` to `ALL_REGIONS_EXCEPT_SPECIFIED` or `SPECIFIED_REGIONS` and providing the list of regions via `var.aws_security_hub.aggregator_specified_regions` +This version enables Security Hub Findings Aggregation for all regions specfied in `allowed_regions`. You can change this behauviour by setting `var.aws_security_hub.aggregator_linking_mode` to `ALL_REGIONS_EXCEPT_SPECIFIED` and providing the list of regions via `var.aws_security_hub.aggregator_specified_regions`. + + +### Variables The following variables have been replaced: * `aws_service_control_policies.allowed_regions` -> `allowed_regions` * `aws_config.aggregator_regions` -> `allowed_regions` +The following variable is added: +* `aws_security_hub.disabled_control_identifiers`. List of Security Hub control IDs that are disabled in the organisation. ## Upgrading to v4.0.0 diff --git a/security_hub.tf b/security_hub.tf index 04eec56..083837a 100644 --- a/security_hub.tf +++ b/security_hub.tf @@ -127,7 +127,7 @@ resource "aws_securityhub_configuration_policy" "default" { enabled_standard_arns = local.security_hub_standards_arns security_controls_configuration { - disabled_control_identifiers = [] + disabled_control_identifiers = var.aws_security_hub.disabled_control_identifiers } } diff --git a/variables.tf b/variables.tf index 56f60f3..05266d0 100644 --- a/variables.tf +++ b/variables.tf @@ -154,12 +154,13 @@ variable "aws_required_tags" { variable "aws_security_hub" { type = object({ - aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS") - auto_enable_controls = optional(bool, true) - control_finding_generator = optional(string, "SECURITY_CONTROL") - create_cis_metric_filters = optional(bool, true) - product_arns = optional(list(string), []) - standards_arns = optional(list(string), null) + aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS") + auto_enable_controls = optional(bool, true) + control_finding_generator = optional(string, "SECURITY_CONTROL") + create_cis_metric_filters = optional(bool, true) + product_arns = optional(list(string), []) + standards_arns = optional(list(string), null) + disabled_control_identifiers = optional(list(string), []) }) default = {} description = "AWS Security Hub settings" From c3cc4b9e52a26e6368c593adec5d190b76ea1177 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Dec 2024 08:05:25 +0000 Subject: [PATCH 19/19] docs(readme): update module usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26d2e83..95a80e9 100644 --- a/README.md +++ b/README.md @@ -549,7 +549,7 @@ module "landing_zone" { | [aws\_guardduty](#input\_aws\_guardduty) | AWS GuardDuty settings |
object({
enabled = optional(bool, true)
finding_publishing_frequency = optional(string, "FIFTEEN_MINUTES")
ebs_malware_protection_status = optional(bool, true)
eks_audit_logs_status = optional(bool, true)
lambda_network_logs_status = optional(bool, true)
rds_login_events_status = optional(bool, true)
s3_data_events_status = optional(bool, true)
runtime_monitoring_status = optional(object({
enabled = optional(bool, true)
eks_addon_management_status = optional(bool, true)
ecs_fargate_agent_management_status = optional(bool, true)
ec2_agent_management_status = optional(bool, true)
}), {})
})
| `{}` | no | | [aws\_inspector](#input\_aws\_inspector) | AWS Inspector settings, at least one of the scan options must be enabled |
object({
enabled = optional(bool, false)
enable_scan_ec2 = optional(bool, true)
enable_scan_ecr = optional(bool, true)
enable_scan_lambda = optional(bool, true)
enable_scan_lambda_code = optional(bool, true)
resource_create_timeout = optional(string, "15m")
})
|
{
"enable_scan_ec2": true,
"enable_scan_ecr": true,
"enable_scan_lambda": true,
"enable_scan_lambda_code": true,
"enabled": false,
"resource_create_timeout": "15m"
}
| no | | [aws\_required\_tags](#input\_aws\_required\_tags) | AWS Required tags settings |
map(list(object({
name = string
values = optional(list(string))
enforced_for = optional(list(string))
})))
| `null` | no | -| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS")
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
})
| `{}` | no | +| [aws\_security\_hub](#input\_aws\_security\_hub) | AWS Security Hub settings |
object({
aggregator_linking_mode = optional(string, "SPECIFIED_REGIONS")
auto_enable_controls = optional(bool, true)
control_finding_generator = optional(string, "SECURITY_CONTROL")
create_cis_metric_filters = optional(bool, true)
product_arns = optional(list(string), [])
standards_arns = optional(list(string), null)
disabled_control_identifiers = optional(list(string), [])
})
| `{}` | no | | [aws\_security\_hub\_sns\_subscription](#input\_aws\_security\_hub\_sns\_subscription) | Subscription options for the LandingZone-SecurityHubFindings SNS topic |
map(object({
endpoint = string
protocol = string
}))
| `{}` | no | | [aws\_service\_control\_policies](#input\_aws\_service\_control\_policies) | AWS SCP's parameters to disable required/denied policies, set a list of allowed AWS regions, and set principals that are exempt from the restriction |
object({
allowed_regions = optional(list(string), [])
aws_deny_disabling_security_hub = optional(bool, true)
aws_deny_leaving_org = optional(bool, true)
aws_deny_root_user_ous = optional(list(string), [])
aws_require_imdsv2 = optional(bool, true)
principal_exceptions = optional(list(string), [])
})
| `{}` | no | | [aws\_sso\_permission\_sets](#input\_aws\_sso\_permission\_sets) | Map of AWS IAM Identity Center permission sets with AWS accounts and group names that should be granted access to each account |
map(object({
assignments = list(map(list(string)))
inline_policy = optional(string, null)
managed_policy_arns = optional(list(string), [])
session_duration = optional(string, "PT4H")
}))
| `{}` | no |