AWS Cloud Operations & Migrations Blog

AWS Organizations, AWS Config, and Terraform

In this post, I show how you can use AWS Organizations, AWS Config, and HashiCorp’s Terraform to deploy guardrails at scale. AWS Config provides configuration, compliance, and auditing features that are required for governing your resources and providing security posture assessment at scale. With its recent support for AWS Organizations, AWS Config makes it possible for you to manage your organization centrally, with rules deployed either with AWS CloudFormation or Terraform.

Terraform is an IaC solution that operates in a way similar to AWS CloudFormation, the AWS native IaC solution. If you plan to use Terraform to manage your AWS environment, this post shows how to deploy controls. AWS CloudFormation also providers resources and properties for deploying organization AWS Config rules.

Architecture

When the solution described in this post is deployed, Terraform creates the following infrastructure:

Terraform Config Rule architecture

Figure 1: Architecture shows interaction between Terraform, AWS Config rule, and aggregator.

 

In this solution, AWS Config and the configuration recorder and delivery channel must be run in the delegated administrator and member accounts. The administrator account aggregates its findings through AWS Organizations. In the secondary/member accounts, Config is collecting data on resources in the environment, and making a determination of compliant or non-compliant based on the AWS Config rules. For more information, see Evaluating Resources with AWS Config Rules in the AWS Config Developer Guide.

AWS Organizations allows us to take an approach of centralizing our rules so that they’re deployed out automatically to other accounts in the Organization. After the data is collected from the accounts, you can aggregate the findings into one account – ideally the administrator account where the aggregator is created. The process of creating the aggregator is done from the account aggregator because otherwise users would have to specify the accounts that are aggregated and find some method for updating the aggregation.

 

Variables

The attached variables.tf file contains the following variables for the S3 bucket that’s used for the AWS Config history. The variables are for the bucket policy, to allow AWS Config to post its findings into the bucket and determine is server-side encryption is enabled in the bucket.

  • encryption_enabled: Takes in a Boolean value and determines if S3 bucket will have server-side encryption enabled.
  • password_parameters: Mapped string that feeds a JSON object into input parameters for the AWS Organizations AWS Config Rule.
  • config_role_name: Name of the IAM role AWS Config uses used for the service and organization aggregator.
  • aggregator_name: Name of the AWS Config aggregator that resides in the parent account.

Configuration Recorder 

To use AWS Config organization Rules, you must create a configuration recorder and delivery channel. The configuration recorder is used to detect configuration changes in the resources that you’re monitoring. It captures these changes as configuration items. You can customize AWS Config to record changes for all supported types of resources or for only those types that are relevant for you. With AWS Config, you can specify if you want these resources supported in all AWS regions.

Most AWS services are region-agnostic, but some resources, like those for (IAM) and CloudFront, are global. It’s important to consider this when tracking compliance in your environment. AWS Config charges are based on every configuration item being recorded. If there is duplicate reporting on these resources, you run the risk of paying extra for those duplicate items.

To avoid duplicate alerts and unnecessary additional costs, you should define AWS Config rules based on which resources are being tracked to support only one Region (There is a working example later in this post.). We strongly recommend setting to allSupported true. AWS Config will add support for a new type of global resource and start recording resources of that type automatically.

Terraform allows you to make specific API calls for the recording group through an optional parameter.  For more information, see Resource: aws_config_configuration_recorder on the Terraform website.

After you create the configuration recorder, the Terraform stack (in the file config.tf file) starts creating the delivery channel, which determines to which S3 bucket the configuration information will be delivered. Before you can create a delivery channel, you must first create a configuration recorder. You can download the source code from the following Github repo.

AWS Config rules

AWS Config rules now include support for AWS Organizations. You can use this functionality to scale security controls in your environment with zero overhead. AWS Config has introduced multi-account, multi-Region data aggregation (discussed later in this post) and allowed users to have centralized auditing for governance. Organization AWS Config rules allow you to limit the rules launched on a per-account basis and deploy from a single delegated administrator account that includes all accounts in an organization.

After the delivery channel and configuration recorder are created, the Terraform configuration creates the organization-managed rules, as shown in the following code:

 

# AWS Config Rule that manages IAM Password Policy
resource "aws_config_organization_managed_rule" "iam_policy_organization_config_rule"
 count = data.aws_region.current.name == "us-east-1" ? 1 : 0
 depends_on = [
  aws_config_configuration_recorder.config_recorder
 ]
 input_parameters  = lookup(var.password_parameters, "iam-password-policy", "")
 name = "iam-password-policy"
 rule_identifier = "IAM_PASSWORD_POLICY"

# AWS Config Rule that manages IAM Root Access Keys to see if they exist
resource "aws_config_organization_managed_rule" "iam_root_access_key_organization_config_rule" 
 count = data.aws_region.current.name == "us-east-1" ? 1 : 0
 depends_on = [
  aws_config_configuration_recorder.config_recorder
 ]
 name = "iam-root-access-key-check"
 rule_identifier   = "IAM_ROOT_ACCESS_KEY_CHECK"

There are a few things to mention about this configuration.

The count parameter helps simplifying configurations. It allows you to scale resources by simply incrementing a number. In this case, to avoid redundant monitoring, the count parameter is used to make sure that the IAM config rules are only created in us-east-1.

The managed organization rules are created with the IAM account password policy and IAM root user access key check. Because IAM resources are global and these resources are being deployed across multiple AWS Regions (us-east-1 and us-east-2), you want to avoid creating these rules in both Regions because they’re only needed in one Region. When you launch the organization rules, you can verify from a single rule the root access key in place on an account and the configuration of every AWS account’s password policy.

The rule_identifier parameter is used to identify the managed rule.

There are also some managed AWS Config rules that take in specific input parameters. In this case, the input_parameter uses the lookup feature, which retrieves a value of a single element from a map, given its key. If no value exists, a default value is provided (in this case, an empty string).

For more information about managed rules in many different categories, see List of AWS Config Managed Rules in the AWS Config Developer Guide.

Running the Terraform script

After you’ve downloaded the source code, make sure that you’re in the folder. Before you run terraform plan or terraform apply, initialize the working directory that contains the Terraform configuration files by running terraform init. You can run this command multiple times without interfering with pre-existing resources or modifications to existing resources.

Now run terraform apply in your terminal. The output should show that all resources are complete.

AWS Config aggregator

One of the notable benefits of AWS Config is its ability to aggregate findings in many ways, through multi-Region or single Region capabilities. AWS Config allows users to customize their aggregation strategy for centralizing their findings to establish governance. You can configure the aws_config_configuration_aggregator resource. The aggregator can be configured for multiple accounts, or it can be done for the entire organization, as shown in the following source code:

resource "aws_config_configuration_aggregator" "organization" {
  name = var.aggregator_name
  organization_aggregation_source {
    all_regions = true     role_arn    = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role/${var.config_role_name}"
  }
}

The AWS Config aggregator takes the IAM Role configured for AWS Config. It requires the following API calls to retrieve information from AWS Organizations about the data that it’s collecting from the accounts (that reside within your organization).

 

{
  "Action": [
    "config:GetOrganizationConfigRuleDetailedStatus",
    "config:Put*",
    "organizations:ListAccounts",
    "organizations:DescribeOrganization",
    "organizations:ListAWSServiceAccessForOrganization",
    "organization:EnableAWSServiceAccess"
  ],
  "Effect": "Allow",
  "Resource": "*"
}

After the Terraform stack has been launched, open the AWS Config console and go to the aggregated view of the rules.

Aggregated view of Config Rules

Figure 2: Aggregated view of rules in the AWS Config console

Cleanup

Before destroying the Terraform configuration, you must first empty the S3 bucket where the AWS Config findings are stored. For information see How do I empty an S3 Bucket? In the Amazon Simple Storage Service Console User Guide.

Then, if you haven’t done already, initialize the directory.

Lastly, run terraform destroy to tear down the Terraform configuration.

Conclusion

In this post, I showed you how to use Terraform to deploy AWS Config Rules and its organization functionality. The solution discussed in this post makes it possible for users to scale out their auditing foot-print within AWS. Through the AWS provider for Terraform, you can manage and scale rules through infrastructure as code. For more information, see AWS Config documentation, AWS Organizations documentation, and Terraform documentation.

 

About the Author

Bo Lechangeur is a Cloud Infrastructure Architect for AWS Professional Services. Bo enjoys helping customers build automated solutions and solving complex problems to help them through their journey in AWS.