Skip to main content
Control Tower 0.4.3Last updated in version 0.2.0

Account Baseline App with Control Tower Integration

View SourceRelease Notes

A CIS compliant security baseline for AWS Landing Zone for configuring the app and logs accounts (dev, stage, prod, and other similar child accounts), as part of a Control Tower integration. This module fills in features NOT supported by Control Tower, including setting up Amazon Guard Duty, Macie, IAM roles, IAM password policy, and more.

Sample Usage

main.tf

# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S CONTROL-TOWER-APP-ACCOUNT-BASELINE MODULE
# ------------------------------------------------------------------------------------------------------

module "control_tower_app_account_baseline" {

source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-app-account-baseline?ref=v0.4.3"

# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------

# The AWS Account ID the template should be operated on. This avoids
# misconfiguration errors caused by environment variables.
aws_account_id = <string>

# The AWS Region to use as the global config recorder.
aws_region = <string>

# Creates resources in the specified regions. The best practice is to enable
# EBS Encryption in all enabled regions in your AWS account. This variable
# must NOT be set to null or empty. Otherwise, we won't know which regions to
# use and authenticate to, and may use some not enabled in your AWS account
# (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS
# account, you can use the AWS CLI: aws ec2 describe-regions.
ebs_opt_in_regions = <list(string)>

# Creates resources in the specified regions. The best practice is to enable
# GuardDuty in all enabled regions in your AWS account. This variable must NOT
# be set to null or empty. Otherwise, we won't know which regions to use and
# authenticate to, and may use some not enabled in your AWS account (e.g.,
# GovCloud, China, etc). To get the list of regions enabled in your AWS
# account, you can use the AWS CLI: aws ec2 describe-regions.
guardduty_opt_in_regions = <list(string)>

# Creates resources in the specified regions. The best practice is to enable
# IAM Access Analyzer in all enabled regions in your AWS account. This
# variable must NOT be set to null or empty. Otherwise, we won't know which
# regions to use and authenticate to, and may use some not enabled in your AWS
# account (e.g., GovCloud, China, etc). To get the list of regions enabled in
# your AWS account, you can use the AWS CLI: aws ec2 describe-regions.
iam_access_analyzer_opt_in_regions = <list(string)>

# Creates resources in the specified regions. This variable must NOT be set to
# null or empty. Otherwise, we won't know which regions to use and
# authenticate to, and may use some not enabled in your AWS account (e.g.,
# GovCloud, China, etc). To get the list of regions enabled in your AWS
# account, you can use the AWS CLI: aws ec2 describe-regions.
kms_cmk_opt_in_regions = <list(string)>

# Creates resources in the specified regions. The best practice is to enable
# Amazon Macie in all enabled regions in your AWS account. This variable must
# NOT be set to null or empty. Otherwise, we won't know which regions to use
# and authenticate to, and may use some not enabled in your AWS account (e.g.,
# GovCloud, China, etc). To get the list of regions enabled in your AWS
# account, you can use the AWS CLI: aws ec2 describe-regions.
macie_opt_in_regions = <list(string)>

# The name used to prefix AWS Config and Cloudtrail resources, including the
# S3 bucket names and SNS topics used for each.
name_prefix = <string>

# Creates resources in the specified regions. The best practice is to enable
# AWS Security Hub in all enabled regions in your AWS account. This variable
# must NOT be set to null or empty. Otherwise, we won't know which regions to
# use and authenticate to, and may use some not enabled in your AWS account
# (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS
# account, you can use the AWS CLI: aws ec2 describe-regions.
security_hub_opt_in_regions = <list(string)>

# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------

# A list of IAM ARNs from other AWS accounts that will be allowed to assume
# the auto deploy IAM role that has the permissions in
# var.auto_deploy_permissions.
allow_auto_deploy_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed full (read
# and write) access to the billing info for this account.
allow_billing_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed full (read
# and write) access to the services in this account specified in
# var.dev_permitted_services.
allow_dev_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed full (read
# and write) access to this account.
allow_full_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed read access
# to the logs in CloudTrail, AWS Config, and CloudWatch in this account.
allow_logs_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed read-only
# access to this account.
allow_read_only_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed read access
# to IAM groups and publish SSH keys. This is used for ssh-grunt.
allow_ssh_grunt_access_from_other_account_arns = []

# A list of IAM ARNs from other AWS accounts that will be allowed access to
# AWS support for this account.
allow_support_access_from_other_account_arns = []

# A list of IAM permissions (e.g. ec2:*) that will be added to an IAM Group
# for doing automated deployments. NOTE: If
# var.should_create_iam_group_auto_deploy is true, the list must have at least
# one element (e.g. '*').
auto_deploy_permissions = []

# Namespace all Lambda resources created by this module with this name.
cleanup_expired_certs_lambda_namespace = "cleanup-expired-iam-certs"

# If set true, just before the Lambda function finishes running, it will
# report a custom metric to CloudWatch, as specified by
# var.report_cloudwatch_metric_namespace and
# var.report_cloudwatch_metric_name. You can set an alarm on this metric to
# detect if the Lambda job deleted any certificates. Note: you must also set
# var.report_cloudwatch_metric_namespace and var.report_cloudwatch_metric_name
# if this variable is set to true.
cleanup_expired_certs_report_cloudwatch_metric = true

# The name to use for the custom CloudWatch metric. Only used if
# var.report_cloudwatch_metric is set to true.
cleanup_expired_certs_report_cloudwatch_metric_name = "cleanup-expired-iam-certs-count"

# The namespace to use for the custom CloudWatch metric. Only used if
# var.report_cloudwatch_metric is set to true.
cleanup_expired_certs_report_cloudwatch_metric_namespace = "custom/cis"

# An expression that defines how often to run the Lambda function to clean up
# expired IAM certs. For example, cron(0 20 * * ? *) or rate(5 minutes).
cleanup_expired_certs_schedule_expression = "rate(1 hour)"

# Set to false to create an S3 bucket of name var.cloudtrail_s3_bucket_name in
# this account for storing CloudTrail logs (e.g., if this is the logs
# account). Set to true to assume the bucket specified in
# var.cloudtrail_s3_bucket_name already exists in another AWS account (e.g.,
# if this is the stage or prod account and var.cloudtrail_s3_bucket_name is
# the name of a bucket in the logs account).
cloudtrail_s3_bucket_already_exists = true

# Set to true to create an S3 bucket of name var.config_s3_bucket_name in this
# account for storing AWS Config data (e.g., if this is the logs account). Set
# to false to assume the bucket specified in var.config_s3_bucket_name already
# exists in another AWS account (e.g., if this is the stage or prod account
# and var.config_s3_bucket_name is the name of a bucket in the logs account).
config_should_create_s3_bucket = false

# The ID of the your management (root) AWS account where Control Tower is
# enabled. Only used if create_control_tower_execution_role is set to true.
control_tower_management_account_id = null

# Set to true to create the Control Tower Execution IAM role. This role gives
# Control Tower permissions to manage this account. If you create an account
# using Control Tower, it will create this role automatically, but if you are
# enrolling an existing account in Control Tower, you MUST set this variable
# to true to create this IAM role. If set to true, you MUST also set the
# control_tower_management_account_id input variable.
create_control_tower_execution_role = false

# Set to true to create an S3 bucket of name macie_bucket_name for storing
# sensitive data discovery results. Set to false to assume the bucket already
# exists. NOTE: Whether you choose to create the bucket yourself, or have it
# automatically created by Terraform, you will need to manually configure this
# bucket to store sensitive data discovery results in AWS Console.
create_macie_bucket = false

# A map of tags to apply to the IAM roles.
cross_account_iam_role_tags = {}

# A list of AWS services for which the developers from the accounts in
# var.allow_dev_access_from_other_account_arns will receive full permissions.
# See https://goo.gl/ZyoHlz to find the IAM Service name. For example, to
# grant developers access only to EC2 and Amazon Machine Learning, use the
# value ["ec2","machinelearning"]. Do NOT add iam to the list of services, or
# that will grant Developers de facto admin access.
dev_permitted_services = []

# The name of the KMS CMK to use by default for encrypting EBS volumes, if
# var.enable_encryption and var.use_existing_kms_keys are enabled. The name
# must match the name given the var.kms_customer_master_keys variable.
ebs_kms_key_name = ""

# If set to true, the KMS Customer Managed Keys (CMK) with the name in
# var.ebs_kms_key_name will be set as the default for EBS encryption. When
# false (default), the AWS-managed aws/ebs key will be used.
ebs_use_existing_kms_keys = false

# When true, create an Open ID Connect Provider that GitHub actions can use to
# assume IAM roles in the account. Refer to
# https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
# for more information.
enable_github_actions_access = false

# Set to false to disable Security Hub in the account.
enable_security_hub = true

# If set to true, when you run 'terraform destroy', delete all objects from
# all S3 buckets and any IAM users created by this module so that everything
# can be destroyed without error. Warning: these objects are not recoverable
# so only use this if you're absolutely sure you want to permanently delete
# everything! This is mostly useful when testing.
force_destroy = false

# If set to true, when you run 'terraform destroy', delete all objects from
# the bucket macie_bucket_name so that the bucket can be destroyed without
# error. Warning: these objects are not recoverable so only use this if you're
# absolutely sure you want to permanently delete everything!
force_destroy_macie_bucket = false

# When set, use the statically provided hardcoded list of thumbprints rather
# than looking it up dynamically. This is useful if you want to trade
# relibaility of the OpenID Connect Provider across certificate renewals with
# a static list that is obtained using a trustworthy mechanism to mitigate
# potential damage from a domain hijacking attack on GitHub domains.
github_actions_openid_connect_provider_thumbprint_list = null

# The name of the IAM Access Analyzer module
iam_access_analyzer_name = "baseline_app-iam_access_analyzer"

# Password expiration requires administrator reset.
iam_password_policy_hard_expiry = true

# The number of days that an user password is valid. Enter 0 for no
# expiration.
iam_password_policy_max_password_age = 0

# Password minimum length. To be compliant with CIS recommendation 1.8, the
# minimum password length is 14.
iam_password_policy_minimum_password_length = 14

# Whether to require lowercase characters for user passwords (true or false).
iam_password_policy_require_lowercase_characters = true

# Whether to require numbers for user passwords (true or false).
iam_password_policy_require_numbers = true

# Whether to require symbols for user passwords (true or false).
iam_password_policy_require_symbols = true

# Whether to require uppercase characters for user passwords (true or false).
iam_password_policy_require_uppercase_characters = true

# Include this value as a prefix in the name of every IAM role created by this
# module. This is useful to prepend, for example, '<account-name>-' to every
# IAM role name: e.g., allow-full-access-from-other-accounts becomes
# stage-allow-full-access-from-other-accounts.
iam_role_name_prefix = ""

# A map of tags to apply to all KMS Keys to be created. In this map variable,
# the key is the tag name and the value is the tag value.
kms_cmk_global_tags = {}

# You can use this variable to create account-level KMS Customer Master Keys
# (CMKs) for encrypting and decrypting data. This variable should be a map
# where the keys are the names of the CMK and the values are an object that
# defines the configuration for that CMK. See the comment below for the
# configuration options you can set for each key.
kms_customer_master_keys = {}

# The map of names of KMS grants to the region where the key resides in. There
# should be a one to one mapping between entries in this map and the entries
# of the kms_grants map. This is used to workaround a terraform limitation
# where the for_each value can not depend on resources.
kms_grant_regions = {}

# Create the specified KMS grants to allow entities to use the KMS key without
# modifying the KMS policy or IAM. This is necessary to allow AWS services
# (e.g. ASG) to use CMKs encrypt and decrypt resources. The input is a map of
# grant name to grant properties. The name must be unique per account.
kms_grants = {}

# Specifies the status for the account. To enable Amazon Macie and start all
# Macie activities for the account, set this value to ENABLED. Valid values
# are ENABLED or PAUSED.
macie_account_status = "ENABLED"

# AWS Account to join this account's Amazon Macie to. Must have already
# received an invite from this account.
macie_administrator_account_id = ""

# The name of the S3 bucket for storing sensitive data discovery results. Only
# used if create_macie_bucket is true. If omitted, Terraform will assign a
# random, unique name.
macie_bucket_name = null

# S3 buckets that Macie should analyze. This should be a map, where each key
# is a region, and each value is a list of buckets in that region that should
# be analyzed. Unfortunately, due to the limitations in the Terraform AWS
# provider, there is no way to automatically select all buckets in a region,
# therefore an explicit list of buckets to analyze must be maintained in this
# variable. For more information, see
# https://github.com/gruntwork-io/terraform-aws-cis-service-catalog/blob/master/modules/security/macie/core-concepts.md#buckets-to-analyze.
macie_buckets_to_analyze = {}

# A map from region to ID (ARN, alias ARN, AWS ID) of a customer managed KMS
# Key to use for encrypting Macie log data. Only used if
# var.macie_create_logs_kms_key is set to false.
macie_cloudwatch_log_group_kms_key_id = null

# The number of days to retain log events in the log group for Macie. Refer to
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days
# for all the valid values. When null, the log events are retained forever.
macie_cloudwatch_log_group_retention_in_days = null

# Tags to apply on the Macie CloudWatch Log Group, encoded as a map where the
# keys are tag keys and values are tag values.
macie_cloudwatch_log_group_tags = null

# Set to true to create a KMS key to encrypt sensitive data discovery results.
# NOTE: Whether you choose to create the key yourself, or have it
# automatically created by Terraform, you will need to manually configure this
# key to encrypt sensitive data discovery results in AWS Console.
macie_create_discovery_results_kms_key = false

# Set to true to create a KMS key to encrypt Macie log entries. If false, log
# entries will not be encrypted unless a key is provided with
# var.macie_cloudwatch_log_group_kms_key_id.
macie_create_logs_kms_key = false

# The number of days to keep around the KMS Customer managed Key for
# encrypting sensitive discovery results after it has been marked for
# deletion.
macie_discovery_results_kms_key_deletion_window_in_days = 30

# The name of the KMS key to encrypt sensitive data discovery results.
# Required if create_kms_key is set to true, otherwise ignored.
macie_discovery_results_kms_key_name = null

# A list of IAM user ARNs with access to the KMS key above. Required if
# create_kms_key is set to true, otherwise ignored.
macie_discovery_results_kms_key_users = null

# Map of AWS Accounts to add as members to this account's Amazon Macie
# configuration. The keys in this map should each be a unique value (e.g., the
# account name) and the values should be objects that contain the account ID
# and Email.
macie_external_member_accounts = {}

# Specifies how often to publish updates to policy findings for the account.
# Valid values are FIFTEEN_MINUTES, ONE_HOUR or SIX_HOURS.
macie_finding_publishing_frequency = "FIFTEEN_MINUTES"

# A custom name for the job. If omitted, Terraform will assign a random,
# unique name.
macie_job_name = null

# The number of days to keep the KMS Customer managed Key for Macie Los around
# after it has been marked for deletion.
macie_logs_kms_key_deletion_window_in_days = 30

# The name of the KMS key to encrypt Macie logs. Required if
# macie_create_logs_kms_key is set to true, otherwise ignored.
macie_logs_kms_key_name = null

# The primary region where the kms key for encrypting Macie logs should be
# created. When set, the KMS key will be created in this region and then
# replicated to all opted in regions. On the other hand, when null, a
# different KMS key will be created in all opted in regions.
macie_logs_kms_key_primary_region = null

# A list of IAM user ARNs with access to the KMS key above. Required if
# macie_create_logs_kms_key is set to true, otherwise ignored.
macie_logs_kms_key_users = null

# When true, precreate the CloudWatch Log Group to use for the Macie Data
# Discovery job. This is useful if you wish to customize the CloudWatch Log
# Group with various settings such as retention periods and KMS encryption.
# When false, AWS Macie will automatically create a basic log group to use.
macie_should_create_cloudwatch_log_group = true

# The maximum allowable session duration, in seconds, for the credentials you
# get when assuming the IAM roles created by this module. This variable
# applies to all IAM roles created by this module that are intended for people
# to use, such as allow-read-only-access-from-other-accounts. For IAM roles
# that are intended for machine users, such as
# allow-auto-deploy-from-other-accounts, see
# var.max_session_duration_machine_users.
max_session_duration_human_users = 43200

# The maximum allowable session duration, in seconds, for the credentials you
# get when assuming the IAM roles created by this module. This variable
# applies to all IAM roles created by this module that are intended for
# machine users, such as allow-auto-deploy-from-other-accounts. For IAM roles
# that are intended for human users, such as
# allow-read-only-access-from-other-accounts, see
# var.max_session_duration_human_users.
max_session_duration_machine_users = 3600

# The amount of reserved concurrent executions for this lambda function or -1
# if unreserved. Note that this defaults to 1 to ensure that we only have one
# instance of this process running at a time. Since the process depends on
# querying expired IAM certificates, it can lead to errors if more than one of
# these are running at a time.
reserved_concurrent_executions = 1

# The AWS region (e.g., us-east-1) where all the findings will be aggregated.
# If null, no region will be designated as an aggregate region and findings
# will only be visible to the region where it was reported. NOTE: this can
# only be implemented on the SecurityHub administrator account.
security_hub_aggregate_region = null

# AWS Account to join this account's Security Hub to. Must have already
# received an invite from the another account. If SecurityHub is being
# centralized in the current AWS account, use
# var.security_hub_external_member_accounts instead.
security_hub_associate_to_admin_account_id = ""

# When true, enable the CIS benchmark v1.4 ruleset for automatic checks in
# SecurityHub. Set this to false if you are using Steampipe instead.
security_hub_enable_cis_1_4_check = true

# When true, enable the CIS benchmark v1.2 ruleset for automatic checks in
# SecurityHub. If you also want to disable the CIS benchmark v1.4 check, then
# var.security_hub_enable_cis_1_4_check should also be set to false. Set this
# to false if you are using Steampipe instead.
security_hub_enable_cis_check = true

# Map of AWS Accounts to add as members to this account's SecurityHub
# configuration. The keys in this map should each be a unique value (e.g., the
# account name) and the values should be objects that contain the account ID
# and Email to contact about security issues in the account. This variable is
# used when Security Hub is being centralized in the current AWS account (e.g.
# a logs account). If it's centralized elsewhere,
# var.security_hub_associate_to_admin_account_id should be used instead.
security_hub_external_member_accounts = {}

# Adjust the logging level of the script to sync SecurityHub member accounts.
# Valid values: debug, info, warn, error
security_hub_loglevel = "info"

# List of product integration IDs to enable on SecurityHub. Refer to
# https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html#argument-reference
# for valid values.
security_hub_product_integrations = []

# Create service-linked roles for this set of services. You should pass in the
# URLs of the services, but without the protocol (e.g., http://) in front:
# e.g., use elasticbeanstalk.amazonaws.com for Elastic Beanstalk or
# es.amazonaws.com for Amazon Elasticsearch. Service-linked roles are
# predefined by the service, can typically only be assumed by that service,
# and include all the permissions that the service requires to call other AWS
# services on your behalf. You can typically only create one such role per AWS
# account, which is why this parameter exists in the account baseline. See
# https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
# for the list of services that support service-linked roles.
service_linked_roles = []

# When true, all IAM policies will be managed as dedicated policies rather
# than inline policies attached to the IAM roles. Dedicated managed policies
# are friendlier to automated policy checkers, which may scan a single
# resource for findings. As such, it is important to avoid inline policies
# when targeting compliance with various security standards.
use_managed_iam_policies = true

}


Reference

Required

aws_account_idstringrequired

The AWS Account ID the template should be operated on. This avoids misconfiguration errors caused by environment variables.

aws_regionstringrequired

The AWS Region to use as the global config recorder.

ebs_opt_in_regionslist(string)required

Creates resources in the specified regions. The best practice is to enable EBS Encryption in all enabled regions in your AWS account. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

guardduty_opt_in_regionslist(string)required

Creates resources in the specified regions. The best practice is to enable GuardDuty in all enabled regions in your AWS account. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

Creates resources in the specified regions. The best practice is to enable IAM Access Analyzer in all enabled regions in your AWS account. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

kms_cmk_opt_in_regionslist(string)required

Creates resources in the specified regions. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

macie_opt_in_regionslist(string)required

Creates resources in the specified regions. The best practice is to enable Amazon Macie in all enabled regions in your AWS account. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

name_prefixstringrequired

The name used to prefix AWS Config and Cloudtrail resources, including the S3 bucket names and SNS topics used for each.

security_hub_opt_in_regionslist(string)required

Creates resources in the specified regions. The best practice is to enable AWS Security Hub in all enabled regions in your AWS account. This variable must NOT be set to null or empty. Otherwise, we won't know which regions to use and authenticate to, and may use some not enabled in your AWS account (e.g., GovCloud, China, etc). To get the list of regions enabled in your AWS account, you can use the AWS CLI: aws ec2 describe-regions.

Optional

A list of IAM ARNs from other AWS accounts that will be allowed to assume the auto deploy IAM role that has the permissions in auto_deploy_permissions.

[]

A list of IAM ARNs from other AWS accounts that will be allowed full (read and write) access to the billing info for this account.

[]

A list of IAM ARNs from other AWS accounts that will be allowed full (read and write) access to the services in this account specified in dev_permitted_services.

[]

A list of IAM ARNs from other AWS accounts that will be allowed full (read and write) access to this account.

[]

A list of IAM ARNs from other AWS accounts that will be allowed read access to the logs in CloudTrail, AWS Config, and CloudWatch in this account.

[]

A list of IAM ARNs from other AWS accounts that will be allowed read-only access to this account.

[]

A list of IAM ARNs from other AWS accounts that will be allowed read access to IAM groups and publish SSH keys. This is used for ssh-grunt.

[]

A list of IAM ARNs from other AWS accounts that will be allowed access to AWS support for this account.

[]
auto_deploy_permissionslist(string)optional

A list of IAM permissions (e.g. ec2:) that will be added to an IAM Group for doing automated deployments. NOTE: If should_create_iam_group_auto_deploy is true, the list must have at least one element (e.g. '').

[]

Namespace all Lambda resources created by this module with this name.

"cleanup-expired-iam-certs"

If set true, just before the Lambda function finishes running, it will report a custom metric to CloudWatch, as specified by report_cloudwatch_metric_namespace and report_cloudwatch_metric_name. You can set an alarm on this metric to detect if the Lambda job deleted any certificates. Note: you must also set report_cloudwatch_metric_namespace and report_cloudwatch_metric_name if this variable is set to true.

true

The name to use for the custom CloudWatch metric. Only used if report_cloudwatch_metric is set to true.

"cleanup-expired-iam-certs-count"

The namespace to use for the custom CloudWatch metric. Only used if report_cloudwatch_metric is set to true.

"custom/cis"

An expression that defines how often to run the Lambda function to clean up expired IAM certs. For example, cron(0 20 * ? ) or rate(5 minutes).

"rate(1 hour)"

Set to false to create an S3 bucket of name cloudtrail_s3_bucket_name in this account for storing CloudTrail logs (e.g., if this is the logs account). Set to true to assume the bucket specified in cloudtrail_s3_bucket_name already exists in another AWS account (e.g., if this is the stage or prod account and cloudtrail_s3_bucket_name is the name of a bucket in the logs account).

true

Set to true to create an S3 bucket of name config_s3_bucket_name in this account for storing AWS Config data (e.g., if this is the logs account). Set to false to assume the bucket specified in config_s3_bucket_name already exists in another AWS account (e.g., if this is the stage or prod account and config_s3_bucket_name is the name of a bucket in the logs account).

false

The ID of the your management (root) AWS account where Control Tower is enabled. Only used if create_control_tower_execution_role is set to true.

null

Set to true to create the Control Tower Execution IAM role. This role gives Control Tower permissions to manage this account. If you create an account using Control Tower, it will create this role automatically, but if you are enrolling an existing account in Control Tower, you MUST set this variable to true to create this IAM role. If set to true, you MUST also set the control_tower_management_account_id input variable.

false

Set to true to create an S3 bucket of name macie_bucket_name for storing sensitive data discovery results. Set to false to assume the bucket already exists. NOTE: Whether you choose to create the bucket yourself, or have it automatically created by Terraform, you will need to manually configure this bucket to store sensitive data discovery results in AWS Console.

false
cross_account_iam_role_tagsmap(string)optional

A map of tags to apply to the IAM roles.

{}
dev_permitted_serviceslist(string)optional

A list of AWS services for which the developers from the accounts in allow_dev_access_from_other_account_arns will receive full permissions. See https://goo.gl/ZyoHlz to find the IAM Service name. For example, to grant developers access only to EC2 and Amazon Machine Learning, use the value ['ec2','machinelearning']. Do NOT add iam to the list of services, or that will grant Developers de facto admin access.

[]
ebs_kms_key_namestringoptional

The name of the KMS CMK to use by default for encrypting EBS volumes, if enable_encryption and use_existing_kms_keys are enabled. The name must match the name given the kms_customer_master_keys variable.

""

If set to true, the KMS Customer Managed Keys (CMK) with the name in ebs_kms_key_name will be set as the default for EBS encryption. When false (default), the AWS-managed aws/ebs key will be used.

false

When true, create an Open ID Connect Provider that GitHub actions can use to assume IAM roles in the account. Refer to https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services for more information.

false

Set to false to disable Security Hub in the account.

true
force_destroybooloptional

If set to true, when you run 'terraform destroy', delete all objects from all S3 buckets and any IAM users created by this module so that everything can be destroyed without error. Warning: these objects are not recoverable so only use this if you're absolutely sure you want to permanently delete everything! This is mostly useful when testing.

false

If set to true, when you run 'terraform destroy', delete all objects from the bucket macie_bucket_name so that the bucket can be destroyed without error. Warning: these objects are not recoverable so only use this if you're absolutely sure you want to permanently delete everything!

false

When set, use the statically provided hardcoded list of thumbprints rather than looking it up dynamically. This is useful if you want to trade relibaility of the OpenID Connect Provider across certificate renewals with a static list that is obtained using a trustworthy mechanism to mitigate potential damage from a domain hijacking attack on GitHub domains.

null

The name of the IAM Access Analyzer module

"baseline_app-iam_access_analyzer"

Password expiration requires administrator reset.

true

The number of days that an user password is valid. Enter 0 for no expiration.

0

Password minimum length. To be compliant with CIS recommendation 1.8, the minimum password length is 14.

14

Whether to require lowercase characters for user passwords (true or false).

true

Whether to require numbers for user passwords (true or false).

true

Whether to require symbols for user passwords (true or false).

true

Whether to require uppercase characters for user passwords (true or false).

true
iam_role_name_prefixstringoptional

Include this value as a prefix in the name of every IAM role created by this module. This is useful to prepend, for example, '<account-name>-' to every IAM role name: e.g., allow-full-access-from-other-accounts becomes stage-allow-full-access-from-other-accounts.

""
kms_cmk_global_tagsmap(string)optional

A map of tags to apply to all KMS Keys to be created. In this map variable, the key is the tag name and the value is the tag value.

{}

You can use this variable to create account-level KMS Customer Master Keys (CMKs) for encrypting and decrypting data. This variable should be a map where the keys are the names of the CMK and the values are an object that defines the configuration for that CMK. See the comment below for the configuration options you can set for each key.

Any types represent complex values of variable type. For details, please consult `variables.tf` in the source repo.
{}
Details

Each entry in the map supports the following attributes:

OPTIONAL (defaults to value of corresponding module input):
- cmk_administrator_iam_arns [list(string)] : A list of IAM ARNs for users who should be given
administrator access to this CMK (e.g.
arn:aws:iam::<aws-account-id>:user/<iam-user-arn>).
- cmk_user_iam_arns [list(string)] : A list of IAM ARNs for users who should be given
permissions to use this CMK (e.g.
arn:aws:iam::<aws-account-id>:user/<iam-user-arn>).
- cmk_read_only_user_iam_arns [list(object[CMKUser])] : A list of IAM ARNs for users who should be given
read-only (decrypt-only) permissions to use this CMK (e.g.
arn:aws:iam::<aws-account-id>:user/<iam-user-arn>).
- cmk_external_user_iam_arns [list(string)] : A list of IAM ARNs for users from external AWS accounts
who should be given permissions to use this CMK (e.g.
arn:aws:iam::<aws-account-id>:root).
- cmk_service_principals [list(object[ServicePrincipal])] : A list of Service Principals that should be given
permissions to use this CMK (e.g. s3.amazonaws.com). See
below for the structure of the object that should be passed
in.

- allow_manage_key_permissions_with_iam [bool] : If true, both the CMK's Key Policy and IAM Policies
(permissions) can be used to grant permissions on the CMK.
If false, only the CMK's Key Policy can be used to grant
permissions on the CMK. False is more secure (and
generally preferred), but true is more flexible and
convenient.
- region [string] : The region (e.g., us-west-2) where the key should be created. If null or
omitted, the key will be created in all enabled regions. Any keys
targeting an opted out region or invalid region string will show up in the
invalid_cmk_inputs output.
- deletion_window_in_days [number] : The number of days to keep this KMS Master Key around after it has been
marked for deletion.
- tags [map(string)] : A map of tags to apply to the KMS Key to be created. In this map
variable, the key is the tag name and the value is the tag value. Note
that this map is merged with var.global_tags, and can be used to override
tags specified in that variable.
- enable_key_rotation [bool] : Whether or not to enable automatic annual rotation of the KMS key.
- spec [string] : Specifies whether the key contains a symmetric key or an asymmetric key
pair and the encryption algorithms or signing algorithms that the key
supports. Valid values: SYMMETRIC_DEFAULT, RSA_2048, RSA_3072, RSA_4096,
ECC_NIST_P256, ECC_NIST_P384, ECC_NIST_P521, or ECC_SECG_P256K1.
Structure of ServicePrincipal object:
- name [string] : The name of the service principal (e.g.: s3.amazonaws.com).
- actions [list(string)] : The list of actions that the given service principal is allowed to
perform (e.g. ["kms:DescribeKey", "kms:GenerateDataKey"]).
- conditions [list(object[Condition])] : (Optional) List of conditions to apply to the permissions for the service
principal. Use this to apply conditions on the permissions for
accessing the KMS key (e.g., only allow access for certain encryption
contexts). The condition object accepts the same fields as the condition
block on the IAM policy document (See
https://www.terraform.io/docs/providers/aws/d/iam_policy_document.htmlcondition).


Example:
customer_master_keys = {
cmk-stage = {
region = "us-west-1"
cmk_administrator_iam_arns = ["arn:aws:iam::0000000000:user/admin"]
cmk_user_iam_arns = ["arn:aws:iam::0000000000:user/dev"]
cmk_read_only_user_iam_arns = [
{
name = ["arn:aws:iam::0000000000:user/qa"]
conditions = []
}
]
cmk_external_user_iam_arns = ["arn:aws:iam::1111111111:user/root"]
cmk_service_principals = [
{
name = "s3.amazonaws.com"
actions = ["kms:Encrypt"]
conditions = []
}
]
}
cmk-prod = {
region = "us-west-1"
cmk_administrator_iam_arns = ["arn:aws:iam::0000000000:user/admin"]
cmk_user_iam_arns = ["arn:aws:iam::0000000000:user/dev"]
allow_manage_key_permissions_with_iam = true
Override the default value for all keys configured with var.default_deletion_window_in_days
deletion_window_in_days = 7

Set extra tags on the CMK for prod
tags = {
Environment = "prod"
}
}
}

kms_grant_regionsmap(string)optional

The map of names of KMS grants to the region where the key resides in. There should be a one to one mapping between entries in this map and the entries of the kms_grants map. This is used to workaround a terraform limitation where the for_each value can not depend on resources.

{}
kms_grantsmap(object(…))optional

Create the specified KMS grants to allow entities to use the KMS key without modifying the KMS policy or IAM. This is necessary to allow AWS services (e.g. ASG) to use CMKs encrypt and decrypt resources. The input is a map of grant name to grant properties. The name must be unique per account.

map(object({
# ARN of the KMS CMK that the grant applies to. Note that the region is introspected based on the ARN.
kms_cmk_arn = string

# The principal that is given permission to perform the operations that the grant permits. This must be in ARN
# format. For example, the grantee principal for ASG is:
# arn:aws:iam::111122223333:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling
grantee_principal = string

# A list of operations that the grant permits. The permitted values are:
# Decrypt, Encrypt, GenerateDataKey, GenerateDataKeyWithoutPlaintext, ReEncryptFrom, ReEncryptTo, CreateGrant,
# RetireGrant, DescribeKey
granted_operations = list(string)
}))
{}
Details

The principal that is given permission to perform the operations that the grant permits. This must be in ARN
format. For example, the grantee principal for ASG is:
arn:aws:iam::111122223333:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling

Details

A list of operations that the grant permits. The permitted values are:
Decrypt, Encrypt, GenerateDataKey, GenerateDataKeyWithoutPlaintext, ReEncryptFrom, ReEncryptTo, CreateGrant,
RetireGrant, DescribeKey

macie_account_statusstringoptional

Specifies the status for the account. To enable Amazon Macie and start all Macie activities for the account, set this value to ENABLED. Valid values are ENABLED or PAUSED.

"ENABLED"

AWS Account to join this account's Amazon Macie to. Must have already received an invite from this account.

""
macie_bucket_namestringoptional

The name of the S3 bucket for storing sensitive data discovery results. Only used if create_macie_bucket is true. If omitted, Terraform will assign a random, unique name.

null
macie_buckets_to_analyzemap(list(…))optional

S3 buckets that Macie should analyze. This should be a map, where each key is a region, and each value is a list of buckets in that region that should be analyzed. Unfortunately, due to the limitations in the Terraform AWS provider, there is no way to automatically select all buckets in a region, therefore an explicit list of buckets to analyze must be maintained in this variable. For more information, see https://github.com/gruntwork-io/terraform-aws-cis-service-catalog/blob/master/modules/security/macie/core-concepts.md#buckets-to-analyze.

map(list(string))
{}

A map from region to ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for encrypting Macie log data. Only used if macie_create_logs_kms_key is set to false.

null

The number of days to retain log events in the log group for Macie. Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days for all the valid values. When null, the log events are retained forever.

null

Tags to apply on the Macie CloudWatch Log Group, encoded as a map where the keys are tag keys and values are tag values.

null

Set to true to create a KMS key to encrypt sensitive data discovery results. NOTE: Whether you choose to create the key yourself, or have it automatically created by Terraform, you will need to manually configure this key to encrypt sensitive data discovery results in AWS Console.

false

Set to true to create a KMS key to encrypt Macie log entries. If false, log entries will not be encrypted unless a key is provided with macie_cloudwatch_log_group_kms_key_id.

false

The number of days to keep around the KMS Customer managed Key for encrypting sensitive discovery results after it has been marked for deletion.

30

The name of the KMS key to encrypt sensitive data discovery results. Required if create_kms_key is set to true, otherwise ignored.

null

A list of IAM user ARNs with access to the KMS key above. Required if create_kms_key is set to true, otherwise ignored.

null
macie_external_member_accountsmap(object(…))optional

Map of AWS Accounts to add as members to this account's Amazon Macie configuration. The keys in this map should each be a unique value (e.g., the account name) and the values should be objects that contain the account ID and Email.

map(object({
account_id = string
email = string
}))
{}

Specifies how often to publish updates to policy findings for the account. Valid values are FIFTEEN_MINUTES, ONE_HOUR or SIX_HOURS.

"FIFTEEN_MINUTES"
macie_job_namestringoptional

A custom name for the job. If omitted, Terraform will assign a random, unique name.

null

The number of days to keep the KMS Customer managed Key for Macie Los around after it has been marked for deletion.

30

The name of the KMS key to encrypt Macie logs. Required if macie_create_logs_kms_key is set to true, otherwise ignored.

null

The primary region where the kms key for encrypting Macie logs should be created. When set, the KMS key will be created in this region and then replicated to all opted in regions. On the other hand, when null, a different KMS key will be created in all opted in regions.

null
macie_logs_kms_key_userslist(string)optional

A list of IAM user ARNs with access to the KMS key above. Required if macie_create_logs_kms_key is set to true, otherwise ignored.

null

When true, precreate the CloudWatch Log Group to use for the Macie Data Discovery job. This is useful if you wish to customize the CloudWatch Log Group with various settings such as retention periods and KMS encryption. When false, AWS Macie will automatically create a basic log group to use.

true

The maximum allowable session duration, in seconds, for the credentials you get when assuming the IAM roles created by this module. This variable applies to all IAM roles created by this module that are intended for people to use, such as allow-read-only-access-from-other-accounts. For IAM roles that are intended for machine users, such as allow-auto-deploy-from-other-accounts, see max_session_duration_machine_users.

43200

The maximum allowable session duration, in seconds, for the credentials you get when assuming the IAM roles created by this module. This variable applies to all IAM roles created by this module that are intended for machine users, such as allow-auto-deploy-from-other-accounts. For IAM roles that are intended for human users, such as allow-read-only-access-from-other-accounts, see max_session_duration_human_users.

3600

The amount of reserved concurrent executions for this lambda function or -1 if unreserved. Note that this defaults to 1 to ensure that we only have one instance of this process running at a time. Since the process depends on querying expired IAM certificates, it can lead to errors if more than one of these are running at a time.

1

The AWS region (e.g., us-east-1) where all the findings will be aggregated. If null, no region will be designated as an aggregate region and findings will only be visible to the region where it was reported. NOTE: this can only be implemented on the SecurityHub administrator account.

null

AWS Account to join this account's Security Hub to. Must have already received an invite from the another account. If SecurityHub is being centralized in the current AWS account, use security_hub_external_member_accounts instead.

""

When true, enable the CIS benchmark v1.4 ruleset for automatic checks in SecurityHub. Set this to false if you are using Steampipe instead.

true

When true, enable the CIS benchmark v1.2 ruleset for automatic checks in SecurityHub. If you also want to disable the CIS benchmark v1.4 check, then security_hub_enable_cis_1_4_check should also be set to false. Set this to false if you are using Steampipe instead.

true

Map of AWS Accounts to add as members to this account's SecurityHub configuration. The keys in this map should each be a unique value (e.g., the account name) and the values should be objects that contain the account ID and Email to contact about security issues in the account. This variable is used when Security Hub is being centralized in the current AWS account (e.g. a logs account). If it's centralized elsewhere, security_hub_associate_to_admin_account_id should be used instead.

map(object({
account_id = string
email = string
}))
{}
security_hub_loglevelstringoptional

Adjust the logging level of the script to sync SecurityHub member accounts. Valid values: debug, info, warn, error

"info"
security_hub_product_integrationslist(object(…))optional

List of product integration IDs to enable on SecurityHub. Refer to https://www.terraform.io/docs/providers/aws/r/securityhub_product_subscription.html#argument-reference for valid values.

list(object({
owning_account_id = string
product_id = string
}))
[]
service_linked_rolesset(string)optional

Create service-linked roles for this set of services. You should pass in the URLs of the services, but without the protocol (e.g., http://) in front: e.g., use elasticbeanstalk.amazonaws.com for Elastic Beanstalk or es.amazonaws.com for Amazon Elasticsearch. Service-linked roles are predefined by the service, can typically only be assumed by that service, and include all the permissions that the service requires to call other AWS services on your behalf. You can typically only create one such role per AWS account, which is why this parameter exists in the account baseline. See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html for the list of services that support service-linked roles.

[]

When true, all IAM policies will be managed as dedicated policies rather than inline policies attached to the IAM roles. Dedicated managed policies are friendlier to automated policy checkers, which may scan a single resource for findings. As such, it is important to avoid inline policies when targeting compliance with various security standards.

true