AWS Organizations Config Rules
This module allows you to configure AWS Config Managed Rules for your AWS accounts.
AWS Organizations Architecture
Features
-
Configure a best-practices set of Managed Config Rules for your AWS accounts
-
Configure either organization-level rules which apply to the root and all child accounts or account-level rules which apply just to the current account
-
Enforce governance by ensuring that the underlying AWS Config rules are not modifiable by the child accounts
-
Configure additional rules on top of the default set of rules
-
Exclude specific accounts
Learn
Note
This repo is a part of the Gruntwork Infrastructure as Code Library, a collection of reusable, battle-tested, production ready infrastructure code. If you’ve never used the Infrastructure as Code Library before, make sure to read How to use the Gruntwork Infrastructure as Code Library!
Core concepts
Repo organization
-
modules: the main implementation code for this repo, broken down into multiple standalone, orthogonal submodules.
-
examples: This folder contains working examples of how to use the submodules.
-
test: Automated tests for the modules and examples.
Deploy
Non-production deployment (quick start for learning)
If you just want to try this repo out for experimenting and learning, check out the following resources:
- examples/aws-config-rules: The
examples/aws-organizations-config-rules
folder contains sample code optimized for learning, experimenting, and testing (but not production usage).
Production deployment
If you want to deploy this repo in production, check out the following resources:
-
Coming soon. We have not yet added this module to the Acme example Reference Architecture.
Manage
Day-to-day operations
Sample Usage
- Terraform
- Terragrunt
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S AWS-CONFIG-RULES MODULE
# ------------------------------------------------------------------------------------------------------
module "aws_config_rules" {
source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/aws-config-rules?ref=v0.74.5"
# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------
# Map of additional managed rules to add. The key is the name of the rule
# (e.g. ´acm-certificate-expiration-check´) and the value is an object
# specifying the rule details
additional_rules = {}
# Set to true to create these rules at the account level or false to create
# them at the organization level. When you create rules at the organization
# level, you must run this module in the root account, and the rules will
# apply to EVERY account in the organization. This allows you to manage the
# rules centrally, which is convenient, but also has a dependency / ordering
# issue, as org level config rules require every child account to have an AWS
# Config Recorder already set up, which is very inconvenient (when adding a
# new account, you first have to leave the rules disabled for it, then create
# the account, apply a baseline to it that creates a Config Recorder, and then
# go back to the root and enable the rules). When creating rules at the
# account level, you have to create and manage the rules in each account
# separately, which is inconvenient (but only slightly, since it's all managed
# as code), but there are no dependency or ordering issues.
create_account_rules = false
# Set to false to have this module skip creating resources. This weird
# parameter exists solely because Terraform does not support conditional
# modules. Therefore, this is a hack to allow you to conditionally decide if
# the resources should be created or not.
create_resources = true
# Create a dependency between the resources in this module to the interpolated
# values in this list (and thus the source resources). In other words, the
# resources in this module will now depend on the resources backing the values
# in this list such that those resources need to be created before the
# resources in this module, and the resources in this module need to be
# destroyed before the resources in the list.
dependencies = []
# Checks whether the EBS volumes that are in an attached state are encrypted.
enable_encrypted_volumes = true
# Set to true to enable all default config rules that apply to global
# (non-regional) resources, like IAM roles. This will also control rules
# included with var.additional_rules depending on the attribute,
# applies_to_global_resources.
enable_global_resource_rules = true
# Checks whether the account password policy for IAM users meets the specified
# requirements.
enable_iam_password_policy = true
# Checks whether your IAM users have passwords or active access keys that have
# not been used within the specified number of days.
enable_iam_user_unused_credentials_check = true
# Checks whether the security group with 0.0.0.0/0 of any Amazon Virtual
# Private Cloud (Amazon VPC) allows only specific inbound TCP or UDP traffic.
enable_insecure_sg_rules = true
# Checks whether storage encryption is enabled for your RDS DB instances.
enable_rds_storage_encrypted = true
# Checks whether users of your AWS account require a multi-factor
# authentication (MFA) device to sign in with root credentials.
enable_root_account_mfa = true
# Checks that your Amazon S3 buckets do not allow public read access.
enable_s3_bucket_public_read_prohibited = true
# Checks that your Amazon S3 buckets do not allow public write access.
enable_s3_bucket_public_write_prohibited = true
# ID or ARN of the KMS key that is used to encrypt the volume.
encrypted_volumes_kms_id = null
# List of AWS account identifiers to exclude from the rules.
excluded_accounts = []
# Number of days before password expiration.
iam_password_policy_max_password_age = 30
# Password minimum length.
iam_password_policy_minimum_password_length = 16
# Number of passwords before allowing reuse.
iam_password_policy_password_reuse_prevention = 5
# Require at least one lowercase character in password.
iam_password_policy_require_lowercase_characters = true
# Require at least one number in password.
iam_password_policy_require_numbers = true
# Require at least one symbol in password.
iam_password_policy_require_symbols = true
# Require at least one uppercase character in password.
iam_password_policy_require_uppercase_characters = true
# Maximum number of days a credential can be not used.
iam_user_max_credential_usage_age = 90
# Comma-separated list of TCP ports authorized to be open to 0.0.0.0/0. Ranges
# are defined by a dash; for example, '443,1020-1025'.
insecure_sg_rules_authorized_tcp_ports = null
# Comma-separated list of UDP ports authorized to be open to 0.0.0.0/0. Ranges
# are defined by a dash; for example, '500,1020-1025'.
insecure_sg_rules_authorized_udp_ports = null
# The maximum frequency with which AWS Config runs evaluations for the
# ´PERIODIC´ rules. See
# https://www.terraform.io/docs/providers/aws/r/config_organization_managed_rule.html#maximum_execution_frequency
maximum_execution_frequency = "TwentyFour_Hours"
# KMS key ID or ARN used to encrypt the storage.
rds_storage_encrypted_kms_id = null
}
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S AWS-CONFIG-RULES MODULE
# ------------------------------------------------------------------------------------------------------
terraform {
source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/aws-config-rules?ref=v0.74.5"
}
inputs = {
# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------
# Map of additional managed rules to add. The key is the name of the rule
# (e.g. ´acm-certificate-expiration-check´) and the value is an object
# specifying the rule details
additional_rules = {}
# Set to true to create these rules at the account level or false to create
# them at the organization level. When you create rules at the organization
# level, you must run this module in the root account, and the rules will
# apply to EVERY account in the organization. This allows you to manage the
# rules centrally, which is convenient, but also has a dependency / ordering
# issue, as org level config rules require every child account to have an AWS
# Config Recorder already set up, which is very inconvenient (when adding a
# new account, you first have to leave the rules disabled for it, then create
# the account, apply a baseline to it that creates a Config Recorder, and then
# go back to the root and enable the rules). When creating rules at the
# account level, you have to create and manage the rules in each account
# separately, which is inconvenient (but only slightly, since it's all managed
# as code), but there are no dependency or ordering issues.
create_account_rules = false
# Set to false to have this module skip creating resources. This weird
# parameter exists solely because Terraform does not support conditional
# modules. Therefore, this is a hack to allow you to conditionally decide if
# the resources should be created or not.
create_resources = true
# Create a dependency between the resources in this module to the interpolated
# values in this list (and thus the source resources). In other words, the
# resources in this module will now depend on the resources backing the values
# in this list such that those resources need to be created before the
# resources in this module, and the resources in this module need to be
# destroyed before the resources in the list.
dependencies = []
# Checks whether the EBS volumes that are in an attached state are encrypted.
enable_encrypted_volumes = true
# Set to true to enable all default config rules that apply to global
# (non-regional) resources, like IAM roles. This will also control rules
# included with var.additional_rules depending on the attribute,
# applies_to_global_resources.
enable_global_resource_rules = true
# Checks whether the account password policy for IAM users meets the specified
# requirements.
enable_iam_password_policy = true
# Checks whether your IAM users have passwords or active access keys that have
# not been used within the specified number of days.
enable_iam_user_unused_credentials_check = true
# Checks whether the security group with 0.0.0.0/0 of any Amazon Virtual
# Private Cloud (Amazon VPC) allows only specific inbound TCP or UDP traffic.
enable_insecure_sg_rules = true
# Checks whether storage encryption is enabled for your RDS DB instances.
enable_rds_storage_encrypted = true
# Checks whether users of your AWS account require a multi-factor
# authentication (MFA) device to sign in with root credentials.
enable_root_account_mfa = true
# Checks that your Amazon S3 buckets do not allow public read access.
enable_s3_bucket_public_read_prohibited = true
# Checks that your Amazon S3 buckets do not allow public write access.
enable_s3_bucket_public_write_prohibited = true
# ID or ARN of the KMS key that is used to encrypt the volume.
encrypted_volumes_kms_id = null
# List of AWS account identifiers to exclude from the rules.
excluded_accounts = []
# Number of days before password expiration.
iam_password_policy_max_password_age = 30
# Password minimum length.
iam_password_policy_minimum_password_length = 16
# Number of passwords before allowing reuse.
iam_password_policy_password_reuse_prevention = 5
# Require at least one lowercase character in password.
iam_password_policy_require_lowercase_characters = true
# Require at least one number in password.
iam_password_policy_require_numbers = true
# Require at least one symbol in password.
iam_password_policy_require_symbols = true
# Require at least one uppercase character in password.
iam_password_policy_require_uppercase_characters = true
# Maximum number of days a credential can be not used.
iam_user_max_credential_usage_age = 90
# Comma-separated list of TCP ports authorized to be open to 0.0.0.0/0. Ranges
# are defined by a dash; for example, '443,1020-1025'.
insecure_sg_rules_authorized_tcp_ports = null
# Comma-separated list of UDP ports authorized to be open to 0.0.0.0/0. Ranges
# are defined by a dash; for example, '500,1020-1025'.
insecure_sg_rules_authorized_udp_ports = null
# The maximum frequency with which AWS Config runs evaluations for the
# ´PERIODIC´ rules. See
# https://www.terraform.io/docs/providers/aws/r/config_organization_managed_rule.html#maximum_execution_frequency
maximum_execution_frequency = "TwentyFour_Hours"
# KMS key ID or ARN used to encrypt the storage.
rds_storage_encrypted_kms_id = null
}
Reference
- Inputs
- Outputs
Optional
additional_rules
map(object(…))Map of additional managed rules to add. The key is the name of the rule (e.g. ´acm-certificate-expiration-check´) and the value is an object specifying the rule details
map(object({
# Description of the rule
description = string
# Identifier of an available AWS Config Managed Rule to call.
identifier = string
# Trigger type of the rule, must be one of ´CONFIG_CHANGE´ or ´PERIODIC´.
trigger_type = string
# A map of input parameters for the rule. If you don't have parameters, pass in an empty map ´{}´.
input_parameters = map(string)
# Whether or not this applies to global (non-regional) resources like IAM roles. When true, these rules are disabled
# if var.enable_global_resource_rules is false.
applies_to_global_resources = bool
}))
{}
Example
additional_rules = {
acm-certificate-expiration-check = {
description = "Checks whether ACM Certificates in your account are marked for expiration within the specified number of days.",
identifier = "ACM_CERTIFICATE_EXPIRATION_CHECK",
trigger_type = "PERIODIC",
input_parameters = { "daysToExpiration": "14"},
applies_to_global_resources = false
}
}
Set to true to create these rules at the account level or false to create them at the organization level. When you create rules at the organization level, you must run this module in the root account, and the rules will apply to EVERY account in the organization. This allows you to manage the rules centrally, which is convenient, but also has a dependency / ordering issue, as org level config rules require every child account to have an AWS Config Recorder already set up, which is very inconvenient (when adding a new account, you first have to leave the rules disabled for it, then create the account, apply a baseline to it that creates a Config Recorder, and then go back to the root and enable the rules). When creating rules at the account level, you have to create and manage the rules in each account separately, which is inconvenient (but only slightly, since it's all managed as code), but there are no dependency or ordering issues.
false
create_resources
boolSet to false to have this module skip creating resources. This weird parameter exists solely because Terraform does not support conditional modules. Therefore, this is a hack to allow you to conditionally decide if the resources should be created or not.
true
dependencies
list(string)Create a dependency between the resources in this module to the interpolated values in this list (and thus the source resources). In other words, the resources in this module will now depend on the resources backing the values in this list such that those resources need to be created before the resources in this module, and the resources in this module need to be destroyed before the resources in the list.
[]
Checks whether the EBS volumes that are in an attached state are encrypted.
true
Set to true to enable all default config rules that apply to global (non-regional) resources, like IAM roles. This will also control rules included with additional_rules
depending on the attribute, applies_to_global_resources.
true
Checks whether the account password policy for IAM users meets the specified requirements.
true
Checks whether your IAM users have passwords or active access keys that have not been used within the specified number of days.
true
Checks whether the security group with 0.0.0.0/0 of any Amazon Virtual Private Cloud (Amazon VPC) allows only specific inbound TCP or UDP traffic.
true
Checks whether storage encryption is enabled for your RDS DB instances.
true
Checks whether users of your AWS account require a multi-factor authentication (MFA) device to sign in with root credentials.
true
Checks that your Amazon S3 buckets do not allow public read access.
true
Checks that your Amazon S3 buckets do not allow public write access.
true
encrypted_volumes_kms_id
stringID or ARN of the KMS key that is used to encrypt the volume.
null
excluded_accounts
list(string)List of AWS account identifiers to exclude from the rules.
[]
Number of days before password expiration.
30
Password minimum length.
16
Number of passwords before allowing reuse.
5
Require at least one lowercase character in password.
true
Require at least one number in password.
true
Require at least one symbol in password.
true
Require at least one uppercase character in password.
true
Maximum number of days a credential can be not used.
90
Comma-separated list of TCP ports authorized to be open to 0.0.0.0/0. Ranges are defined by a dash; for example, '443,1020-1025'.
null
Comma-separated list of UDP ports authorized to be open to 0.0.0.0/0. Ranges are defined by a dash; for example, '500,1020-1025'.
null
The maximum frequency with which AWS Config runs evaluations for the ´PERIODIC´ rules. See https://www.terraform.io/docs/providers/aws/r/config_organization_managed_rule.html#maximum_execution_frequency
"TwentyFour_Hours"
KMS key ID or ARN used to encrypt the storage.
null
Map of config rule ARNs. Key is rule ID, value is rule ARN