Contact Us | Stratusphere FinOps | StratusGrid Home | Blog
GitHub: StratusGrid/terraform-aws-config-rules
Terraform Registry: StratusGrid/config-rules
AWS Config rules module to put in standard policies
Note: Config Rule requires an existing Configuration Recorder to be present. There is available a StratusGrid terraform module to provision it StratusGrid/config-recorder
The simplest example deploy the default AWS managed rules we added in the module
- ROOT_ACCOUNT_MFA_ENABLED
- IAM_ROOT_ACCESS_KEY_CHECK
- IAM_USER_MFA_ENABLED
If you want to disable those default rules set enable_default_aws_managed_rules = false
module "aws_config_rules_us_east_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
}
The second example adds besides the default AWS managed rules added in the example 1 the AWS managed rule required_tags_enabled along with the required parameters
module "aws_config_rules_us_east_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
required_tags_enabled = true
required_tags = { # Yes, the actual required format is tag#Key and tag#Value
tag1Key = "Provisioner"
tag1Value = "Terraform"
tag2Key = "Customer"
tag3Key = "Application"
}
}
The third example use the aws_managed_rules map with two defined rules. The existing AWS Managed rules can be found here, and you can map them as shown below.
module "aws_config_rules_us_east_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
aws_managed_rules = {
access-keys-rotated = {
description = "Checks if active IAM access keys are rotated (changed) within the number of days specified in maxAccessKeyAge. The rule is NON_COMPLIANT if access keys are not rotated within the specified time period."
identifier = "ACCESS_KEYS_ROTATED"
input_parameters = {
maxAccessKeyAge = "10"
}
}
cloudtrail-security-trail-enabled = {
description = "Checks that there is at least one AWS CloudTrail trail defined with security best practices. This rule is COMPLIANT if there is at least one trail that meets: https://docs.aws.amazon.com/config/latest/developerguide/cloudtrail-security-trail-enabled.html"
identifier = "CLOUDTRAIL_SECURITY_TRAIL_ENABLED"
input_parameters = {}
}
}
}
The fourth example shows the creation of a custom rule using Guard domain-specific language (DSL)
module "aws_config_rules_us_east_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
custom_managed_rules = {
out-of-scope-ec2-instance-families = {
description = "Ensure EC2 instance configurations do not belong to out-of-scope families."
scope = {
compliance_resource_types = ["AWS::EC2::Instance"]
}
source = {
source_detail = {
message_type = "ConfigurationItemChangeNotification"
}
custom_policy_details = {
policy_runtime = "guard-2.x.x"
policy_text = <<POLICY
rule check_out_of_scope_instance_families when resourceType == "AWS::EC2::Instance" {
configuration.instanceType != /x1e\.*/
configuration.instanceType != /x2i\.*/
}
POLICY
}
}
}
}
}
module "aws_config_rules_us_east_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
include_global_resource_rules = true #only include global resource on one region to prevent duplicate rules
required_tags_enabled = true
required_tags = { # Yes, the actual required format is tag#Key and tag#Value
tag1Key = "Provisioner"
tag1Value = "Terraform"
tag2Key = "Customer"
tag3Key = "Application"
}
providers = {
aws = "aws.us-east-1"
}
}
module "aws_config_rules_us_east_2" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
required_tags_enabled = true
required_tags = { # Yes, the actual required format is tag#Key and tag#Value
tag1Key = "Provisioner"
tag1Value = "Terraform"
tag2Key = "Customer"
tag3Key = "Application"
}
providers = {
aws = "aws.us-east-2"
}
}
module "aws_config_rules_us_west_1" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
required_tags_enabled = true
required_tags = { # Yes, the actual required format is tag#Key and tag#Value
tag1Key = "Provisioner"
tag1Value = "Terraform"
tag2Key = "Customer"
tag3Key = "Application"
}
providers = {
aws = "aws.us-west-1"
}
}
module "aws_config_rules_us_west_2" {
source = "StratusGrid/config-rules/aws"
# StratusGrid recommends pinning every module to a specific version
version = "x.x.x"
required_tags_enabled = true
required_tags = { # Yes, the actual required format is tag#Key and tag#Value
tag1Key = "Provisioner"
tag1Value = "Terraform"
tag2Key = "Customer"
tag3Key = "Application"
}
providers = {
aws = "aws.us-west-2"
}
}
Name | Type |
---|---|
aws_config_config_rule.aws_managed_rules | resource |
aws_config_config_rule.custom_managed_rules | resource |
Name | Description | Type | Default | Required |
---|---|---|---|---|
aws_managed_rules | A list of AWS Managed Rules that should be enabled on the account. See the following for a list of possible rules to enable: https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-aws-config.html |
map(object({ |
{} |
no |
custom_managed_rules | A list of AWS Managed Custom Rules that should be enabled on the account. Reference https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config_develop-rules.html |
map(any) |
{} |
no |
enable_default_aws_managed_rules | True/False to add default Config Rules. Default is true | bool |
true |
no |
input_tags | Map of tags to apply to resources | map(any) |
{ |
no |
required_tags | Map of tag keys, and optionally values, that are required. | map(any) |
{} |
no |
required_tags_enabled | True/False to add RequiredTags to Config. Default is false | bool |
false |
no |
No outputs.
In the V2 version, the resource enumeration for AWS Config Rules has been updated. This change impacts how Terraform manages the lifecycle of your Config Rules deployed with any previous versions.
In the previous versions the resources were naming with fixed names. e.g ("root_account_mfa_enabled", "iam_root_access_key_check", "required_tags"), now with this new version as we're using a for_each for the generation of resources the naming convention changes to from a fixed name to an element of a list (variable aws_managed_rules) e.g. (aws_managed_rules["root-account-mfa-enabled"], aws_managed_rules["iam-root-access-key-check"],aws_managed_rules["required-tags"])
The actions required for the migration would been
- Destroy existing config Rules
- Upgrade of the module to the latest version 2.x.x
- Recreate the config rules
Why this is necessary: The change in resource enumeration means that Terraform will no longer recognize the existing resources as being managed by the current state. As a result, Terraform would otherwise attempt to create new resources rather than update the existing ones, leading to duplicate rules.
Note: Manual changes to the README will be overwritten when the documentation is updated. To update the documentation, run terraform-docs -c .config/.terraform-docs.yml .