NTC Security Tooling
Descriptionβ
NTC Security Tooling simplifies the deployment and configuration of essential AWS security services to ensure a secure and compliant cloud environment. This building block automates the provisioning of centralized security services, such as AWS Security Hub, GuardDuty, IAM Access Analyzer, and Inspector, enabling comprehensive threat detection, data protection, and vulnerability management. NTC Security Tooling enforces standardized security configurations across accounts and integrates seamlessly with multi-account setups.
By centralizing security operations and applying consistent guardrails, this building block ensures your AWS environment is protected and aligned with industry best practices.
Usageβ
Latest Release | 1.4.1 |
---|
- Security Tooling
- Regional Configuration
# WARNING: securityhub will get enabled by default when creating the admin delegation in organizations
# this will cause an error when configuring security tooling
# to avoid this issue securityhub can be imported
import {
to = module.ntc_security_tooling.aws_securityhub_account.ntc_securityhub_central
id = data.aws_caller_identity.current.account_id
}
# --------------------------------------------------------------------------------------------------
# Β¦ NTC SECURITY TOOLING
# --------------------------------------------------------------------------------------------------
module "ntc_security_tooling" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-security-tooling?ref=X.X.X"
# set to true to enable securityhub standards that securityhub has designated as automatically enabled
#Β use 'securityhub_central_configuration_polices' to configure security standards across entire aws organizations
enable_securityhub_default_standards = false
# securityhub aggregration is required for central configuration
enable_securityhub_central_configuration = true
enable_securityhub_aggregation = true
#Β can be either "ALL_REGIONS" or a list of regions which should be aggregated
securityhub_aggregation_regions = ["ALL_REGIONS"]
# (optional) aggregate config data from all accounts in all regions across organizations
# admin delegation for "config.amazonaws.com" required
# https://docs.aws.amazon.com/config/latest/developerguide/aggregate-data.html
enable_config_aggregation = false
# enrich securityhub findings with account context
securityhub_enrichment_settings = {
enable_enrichment = true
# enrich only findings of specific severity from ["INFORMATIONAL", "LOW", "MEDIUM", "HIGH", "CRITICAL"]
severity_labels = ["INFORMATIONAL", "LOW", "MEDIUM", "HIGH", "CRITICAL"]
# to get alternate contact an assumable iam role is required in the org management account
alternate_contact_assume_role = "ntc-org-account-reader"
}
# get notified via sns topic about security hub findings
securityhub_notification_settings = {
enable_notifications = true
# identify for which AWS Organization notifications are sent
org_identifier = "c2"
# prettified finding notifications for specific severities
severity_labels_findings_pretty = ["CRITICAL"]
subscriptions_findings_pretty = [
{
protocol = "email"
endpoints = ["demo-security@nuvibit.com"]
}
]
# raw json notifications for specific severities
severity_labels_findings_raw = ["CRITICAL"]
subscriptions_raw_findings = []
# define how frequent reminders for findings should be sent
reminder_x_days_unresolved_by_severity = {
critical = 1
high = 3
medium = 7
low = 14
informational = 14
}
}
# generate security hub reports and get notified via sns topic
securityhub_report_settings = [
{
# choose from predefined security hub reports
report = "securityhub-summary"
# reports can be scheduled to be generated every x days
schedule_in_days = 7
subscriptions = [
{
protocol = "email"
endpoints = ["demo-security@nuvibit.com"]
}
]
}
]
securityhub_processing_settings = {
enable_processing = true
#Β uses the security hub automation rules and asff syntax
# https://docs.aws.amazon.com/securityhub/latest/userguide/automation-rules.html#automation-rules-criteria-actions
# https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings-format-syntax.html
automation_rules = jsondecode(file("${path.module}/example_automation_rules.json"))
}
# define securityhub central configuration policies
# https://docs.aws.amazon.com/securityhub/latest/userguide/central-configuration-intro.html
securityhub_central_configuration_polices = [
{
name = "ntc-securityhub-central-policy"
description = "securityhub central policy"
# enable or disable securityhub in target accounts
enable_securityhub = true
# policy targets can either be organizational units (OU) or aws accounts (ID)
policy_targets = [
local.ntc_parameters["mgmt-organizations"]["ou_ids"]["/root/workloads"],
]
enabled_standards = [
"aws-foundational-security-best-practices/v/1.0.0",
"cis-aws-foundations-benchmark/v/3.0.0",
# "cis-aws-foundations-benchmark/v/1.4.0",
# "cis-aws-foundations-benchmark/v/1.2.0",
# "nist-800-53/v/5.0.0",
# "pci-dss/v/3.2.1",
]
# either provide a list of control ids which should be enabled (all other existing and future controls will be disabled)
enabled_control_ids = []
# or a list of control ids which should be disabled (all other existing and future controls will be enabled)
# https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-controls-reference.html
disabled_control_ids = [
"IAM.9", # "MFA should be enabled for the root user"
"IAM.18", # "Ensure a support role has been created to manage incidents with AWS Support"
"Config.1", # "AWS Config should be enabled"
"EC2.10", # "Security groups should not allow ingress from 0.0.0.0/0 or ::/0 to port 22"
"IAM.6", # "Hardware MFA should be enabled for the root user"
"S3.1" # "S3 general purpose buckets should have block public access settings enabled"
]
# some controls allow to customize parameters
# https://docs.aws.amazon.com/securityhub/latest/userguide/custom-control-parameters.html
# https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-controls-reference.html
customized_security_controls = [
{
control_id = "IAM.7"
parameters = [
{
name = "MaxPasswordAge"
value = 60
type = "Integer"
},
{
name = "RequireNumbers"
value = false
type = "Boolean"
}
]
}
]
}
]
providers = {
# WARNING some features of security tooling cannot be provisioned in an opt-in region
# e.g security hub aggregation does not supported an opt-in region as main region
# https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-regions.html
aws = aws.euc1
}
}
# WARNING: guardduty will get enabled by default when creating the admin delegation in organizations
#Β this will cause an error when configuring regional security config for guardduty
# to avoid this issue guardduty detector can be imported
data "aws_guardduty_detector" "euc1" {
provider = aws.euc1
}
import {
to = module.ntc_regional_security_config_euc1.aws_guardduty_detector.ntc_guardduty[0]
id = data.aws_guardduty_detector.euc1.id
}
# --------------------------------------------------------------------------------------------------
# Β¦ NTC SECURITY TOOLING - REGIONAL CONFIGURATION - FRANKFURT
# --------------------------------------------------------------------------------------------------
module "ntc_regional_security_config_euc1" {
# source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-security-tooling//modules/regional-security-config?ref=X.X.X"
# https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_regions.html
guardduty_config = {
enabled = true
finding_publishing_frequency = "SIX_HOURS"
# WARNING: requires admin delegation of 'guardduty.amazonaws.com'
organization_config = {
#Β enable guardduty in organization for 'ALL' members, 'NEW' members or 'NONE'
auto_enable = "ALL"
# individual features can be enabled in organization for 'ALL' members, 'NEW' members or 'NONE'
# enabled features will also be configured for current account
features = [
{
auto_enable = "ALL"
name = "S3_DATA_EVENTS"
},
{
auto_enable = "ALL"
name = "EBS_MALWARE_PROTECTION"
},
{
auto_enable = "ALL"
name = "RDS_LOGIN_EVENTS"
},
{
auto_enable = "ALL"
name = "LAMBDA_NETWORK_LOGS"
},
{
auto_enable = "NONE"
name = "EKS_AUDIT_LOGS"
},
{
auto_enable = "ALL"
name = "RUNTIME_MONITORING"
# 'RUNTIME_MONITORING' has additional configurations
additional_configuration = [
{
auto_enable = "NONE"
name = "EKS_ADDON_MANAGEMENT"
},
{
auto_enable = "ALL"
name = "ECS_FARGATE_AGENT_MANAGEMENT"
},
{
auto_enable = "ALL"
name = "EC2_AGENT_MANAGEMENT"
}
]
}
]
# (optional) invite existing organization members to guardduty
invite_members_by_account_id = []
}
# (optional) export all guardduty findings to s3 log archive
export_findings = true
log_archive_bucket_arn = local.ntc_parameters["log-archive"]["log_bucket_arns"]["guardduty"]
log_archive_kms_key_arn = local.ntc_parameters["log-archive"]["log_bucket_kms_key_arns"]["guardduty"]
}
# https://docs.aws.amazon.com/inspector/latest/user/inspector_regions.html
inspector_config = {
enabled = true
# WARNING: requires admin delegation of 'inspector2.amazonaws.com'
organization_config = {
auto_enable = true
# individual features can be enabled in organization for 'NEW' members or 'NONE'
# WARNING: features cannot be enabled for 'ALL' members (inspector limitation)
# enabled features will also be configured for current account
features = [
{
auto_enable = "NEW"
name = "EC2"
},
{
auto_enable = "NEW"
name = "ECR"
},
{
auto_enable = "NEW"
name = "LAMBDA"
},
{
auto_enable = "NEW"
name = "LAMBDA_CODE"
}
]
# (optional) invite existing organization members to inspector
invite_members_by_account_id = []
}
}
providers = {
aws = aws.euc1
}
}
Requirementsβ
The following requirements are needed by this module:
-
terraform (>= 1.5.0)
-
aws (>= 5.69)
-
local (>= 2.0)
-
time (>= 0.11)
Providersβ
The following providers are used by this module:
-
aws (>= 5.69)
-
local (>= 2.0)
-
time (>= 0.11)
Modulesβ
The following Modules are called:
lambda_security_reportβ
Source: ./modules/lambda
Version:
lambda_step_functionβ
Source: ./modules/lambda
Version:
Resourcesβ
The following resources are used by this module:
- aws_cloudwatch_event_rule.ntc_reports_schedule (resource)
- aws_cloudwatch_event_rule.ntc_securityhub_findings (resource)
- aws_cloudwatch_event_target.ntc_reports_trigger (resource)
- aws_cloudwatch_event_target.ntc_securityhub_findings (resource)
- aws_config_configuration_aggregator.ntc_aws_config_aggregator (resource)
- aws_dynamodb_table.ntc_securityhub_findings_enrichment (resource)
- aws_iam_policy.ntc_reports_lambda_permissions (resource)
- aws_iam_role.ntc_aws_config_aggregator (resource)
- aws_iam_role.ntc_lambda_execution_role (resource)
- aws_iam_role.ntc_state_machine_event_rule_role (resource)
- aws_iam_role_policy.ntc_state_machine_event_rule_policy (resource)
- aws_iam_role_policy_attachment.ntc_aws_config_aggregator (resource)
- aws_iam_role_policy_attachment.ntc_reports_lambda (resource)
- aws_kms_alias.ntc_security_tooling_encryption (resource)
- aws_kms_key.ntc_security_tooling_encryption (resource)
- aws_securityhub_account.ntc_securityhub_central (resource)
- aws_securityhub_configuration_policy.ntc_securityhub_central (resource)
- aws_securityhub_configuration_policy_association.ntc_securityhub_central (resource)
- aws_securityhub_finding_aggregator.ntc_securityhub_central (resource)
- aws_securityhub_insight.ntc_findings_by_severity_last_x_days (resource)
- aws_securityhub_insight.ntc_findings_by_status_last_x_days (resource)
- aws_securityhub_insight.ntc_unresolved_findings_by_severity (resource)
- aws_securityhub_organization_configuration.ntc_securityhub_central (resource)
- aws_sfn_state_machine.ntc_securityhub_findings_state_machine (resource)
- aws_sns_topic.ntc_securityhub_findings_notification_pretty (resource)
- aws_sns_topic.ntc_securityhub_findings_notification_raw (resource)
- aws_sns_topic.ntc_securityhub_reports (resource)
- aws_sns_topic_policy.ntc_securityhub_findings_notification_pretty (resource)
- aws_sns_topic_policy.ntc_securityhub_findings_notification_raw (resource)
- aws_sns_topic_subscription.ntc_securityhub_findings_pretty (resource)
- aws_sns_topic_subscription.ntc_securityhub_findings_raw (resource)
- aws_sns_topic_subscription.ntc_securityhub_reports (resource)
- local_file.ntc_automation_rules (resource)
- time_sleep.ntc_securityhub_central (resource)
- aws_caller_identity.current (data source)
- aws_iam_policy_document.ntc_aws_config_aggregator (data source)
- aws_iam_policy_document.ntc_lambda_assume_role (data source)
- aws_iam_policy_document.ntc_reports_lambda_permissions (data source)
- aws_iam_policy_document.ntc_securityhub_findings_notification_pretty (data source)
- aws_iam_policy_document.ntc_securityhub_findings_notification_raw (data source)
- aws_iam_policy_document.ntc_state_machine_event_rule_assume_role (data source)
- aws_iam_policy_document.ntc_state_machine_event_rule_policy (data source)
- aws_organizations_organization.current (data source)
- aws_partition.current (data source)
- aws_region.current (data source)
Required Inputsβ
No required inputs.
Optional Inputsβ
The following input variables are optional (have default values):
arm_based_computeβ
Description: Set to false to use x86_64 instead of arm for pipelines and lambdas.
Type: bool
Default: true
config_aggregator_iam_role_nameβ
Description: Name of the IAM role used by AWS Config to aggregate regions.
Type: string
Default: "ntc-config-aggregator-role"
config_aggregator_nameβ
Description: Name of the AWS Config Aggregator used to aggregate Config data from every account in the AWS Organization.
Type: string
Default: "ntc-config-aggregator"
enable_config_aggregationβ
Description: Set to true to enable aggregation of AWS Config across all regions.
Type: bool
Default: false
enable_securityhub_aggregationβ
Description: Set to true to aggregate all securityhub findings to current region (home region).
Type: bool
Default: true
enable_securityhub_central_configurationβ
Description: Set to true to enable Security Hub central configuration. Requires 'enable_securityhub_aggregation' to be set to true.
Type: bool
Default: true
enable_securityhub_consolidated_control_findingsβ
Description: Set to true to consolidate all securityhub findings with duplicate controls from enabled standards.
Type: bool
Default: true
enable_securityhub_default_standardsβ
Description: Set to true to enable securityhub standards that securityhub has designated as automatically enabled.
Type: bool
Default: true
lambda_execution_policy_nameβ
Description: Name of security lambda execution policy.
Type: string
Default: "ntc-security-lambda-policy"
lambda_execution_role_nameβ
Description: Name of security lambda execution role.
Type: string
Default: "ntc-security-lambda-role"
lambda_runtimeβ
Description: The runtime with which all the lambda function runs
Type: string
Default: "python3.9"
security_tooling_kms_alias_nameβ
Description: Alias of KMS key used for security tooling.
Type: string
Default: "ntc-security-tooling"
securityhub_aggregation_regionsβ
Description: List of regions which should be aggregated in securityhub. Requires 'enable_securityhub_aggregation' to be set to true.
Type: list(string)
Default:
[
"ALL_REGIONS"
]
securityhub_central_configuration_policesβ
Description: Securityhub central configuration policies. Requires 'enable_securityhub_aggregation' to be set to true.
Type:
list(object({
name = string
description = string
policy_targets = list(string)
service_enabled = optional(bool, true)
enabled_standards = optional(list(string), [])
disabled_control_ids = optional(list(string), [])
enabled_control_ids = optional(list(string), [])
customized_security_controls = optional(list(object({
control_id = string
parameters = optional(list(object({
name = string
value = string
type = string
})), [])
})), [])
}))
Default: []
securityhub_enrichment_settingsβ
Description: Configuration of enrichment for AWS Security Hub findings.
Type:
object({
enable_enrichment = optional(bool, true)
severity_labels = optional(list(string), ["INFORMATIONAL", "LOW", "MEDIUM", "HIGH", "CRITICAL"])
alternate_contact_assume_role = optional(string, "")
lambda_name = optional(string, "ntc-securityhub-enrichment-lambda")
dynamodb_cache_table_name = optional(string, "ntc-securityhub-enrichment-cache")
dynamodb_cache_max_hours = optional(number, 24)
dynamodb_cache_billing_mode = optional(string, "PAY_PER_REQUEST")
dynamodb_cache_provisioned_capacity = optional(object({
read = optional(string, 20)
write = optional(string, 20)
}), {})
})
Default: {}
securityhub_findings_state_machine_event_rule_role_nameβ
Description: The iam role name to trigger the state machine for securityhub findings.
Type: string
Default: "ntc-securityhub-findings-state-machine-trigger"
securityhub_findings_state_machine_nameβ
Description: The state machine name for securityhub findings step functions.
Type: string
Default: "ntc-securityhub-findings-state-machine"
securityhub_notification_settingsβ
Description: Configuration of notifications for AWS Security Hub findings.
Type:
object({
enable_notifications = optional(bool, true)
org_identifier = optional(string, "")
event_rule_name = optional(string, "ntc-securityhub-findings-rule")
prettify_lambda_name = optional(string, "ntc-securityhub-findings-prettify-lambda")
severity_labels_findings_raw = optional(list(string), ["HIGH", "CRITICAL"])
sns_topic_name_findings_raw = optional(string, "ntc-securityhub-findings-raw")
subscriptions_findings_raw = optional(list(object({
protocol = string
endpoints = list(string)
subscription_role_arn = optional(string, null)
})), [])
severity_labels_findings_pretty = optional(list(string), ["HIGH", "CRITICAL"])
sns_topic_name_findings_pretty = optional(string, "ntc-securityhub-findings-pretty")
subscriptions_findings_pretty = optional(list(object({
protocol = string
endpoints = list(string)
subscription_role_arn = optional(string, null)
})), [])
reminder_x_days_unresolved_by_severity = optional(object({
critical = optional(number, 1)
high = optional(number, 3)
medium = optional(number, 7)
low = optional(number, 14)
informational = optional(number, 14)
}), {})
})
Default: {}
securityhub_processing_settingsβ
Description: Configuration of processing for AWS Security Hub findings.
Type:
object({
enable_processing = optional(bool, false)
lambda_name = optional(string, "ntc-securityhub-processing-lambda")
automation_rules = optional(list(object({
IsTerminal = bool
RuleName = string
RuleOrder = number
RuleStatus = string
Description = optional(string, "")
Criteria = map(list(object({
Key = optional(string)
Value = string
Comparison = string
})))
Actions = list(object({
Type = string
FindingFieldsUpdate = object({
Note = optional(object({
Text = optional(string)
UpdatedBy = optional(string)
}))
Severity = optional(object({
Normalized = optional(number)
Product = optional(number)
Label = optional(string)
}))
VerificationState = optional(string)
Confidence = optional(number)
Criticality = optional(number)
Types = optional(list(string))
UserDefinedFields = optional(map(string))
Workflow = optional(object({
Status = string
}))
RelatedFindings = optional(list(object({
ProductArn = optional(string)
Id = optional(string)
})))
})
}))
})), [])
})
Default:
{
"automation_rules": []
}
securityhub_report_settingsβ
Description: Configuration of reoccuring Security Hub reports
Type:
list(object({
report = string
schedule_in_days = optional(number, 7)
lambda_prefix_name = optional(string, "ntc-security-report-lambda-")
schedule_prefix_name = optional(string, "ntc-security-report-schedule-")
sns_prefix_name = optional(string, "ntc-security-report-sns-")
subscriptions = optional(list(object({
protocol = string
endpoints = list(string)
subscription_role_arn = optional(string, null)
})), [])
}))
Default: []
tracing_mode_lambdasβ
Description: Whether to sample and trace a subset of incoming requests with AWS X-Ray for all Lambdas.
Can be either PassThrough or Active and if omitted tracing is disabled.
If PassThrough, Lambdas will only trace the request from an upstream service if it contains a tracing header with "sampled=1".
If Active, Lambdas will respect any tracing header it receives from an upstream service.
If no tracing header is received, Lambdas will call X-Ray for a tracing decision.
Type: string
Default: null
tracing_mode_step_functionsβ
Description: Whether to sample and trace a subset of incoming requests with AWS X-Ray for all Step Functions.
Can be either PassThrough or Active and if omitted tracing is disabled.
If PassThrough, Lambdas will only trace the request from an upstream service if it contains a tracing header with "sampled=1".
If Active, Lambdas will respect any tracing header it receives from an upstream service.
If no tracing header is received, Lambdas will call X-Ray for a tracing decision.
Type: string
Default: null
Outputsβ
The following outputs are exported:
sns_topic_arn_findings_prettyβ
Description: Amazon Resource Name (ARN) of the Security Hub finding SNS topic
sns_topic_arn_findings_rawβ
Description: Amazon Resource Name (ARN) of the Security Hub finding SNS topic
sns_topic_id_findings_prettyβ
Description: Identifier of the Security Hub finding SNS topic
sns_topic_id_findings_rawβ
Description: Identifier of the Security Hub finding SNS topic
stepfunction_arnβ
Description: Amazon Resource Name (ARN) of the Security Hub finding SNS topic