Skip to content

StratusGrid/terraform-aws-config-rules

Repository files navigation

Contact Us | Stratusphere FinOps | StratusGrid Home | Blog

terraform-aws-config-rules

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

Example Single Region Configuration:

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 = {}
   }    
 }  
}

Alt aws-manage-rules


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
       }
     }
   }
 }
}

Example Multi Region Configuration:

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"
 }
}

Resources

Name Type
aws_config_config_rule.aws_managed_rules resource
aws_config_config_rule.custom_managed_rules resource

Inputs

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({
description = string
identifier = string
input_parameters = any
}))
{} 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)
{
"Developer": "StratusGrid",
"Provisioner": "Terraform"
}
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

Outputs

No outputs.


Migrating to V2

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

  1. Destroy existing config Rules
  2. Upgrade of the module to the latest version 2.x.x
  3. 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 .

About

AWS Config rules module to put in standard policies

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 11

Languages