AWS Management & Governance Blog

Deploy Conformance Packs across an Organization with Automatic Remediation

AWS Config conformance packs help you manage configuration compliance of your AWS resources at scale – from policy definition to auditing and aggregated reporting using a common framework and packaging model.

Many enterprises have multiple AWS accounts to manage their AWS infrastructure and demand an easy way to manage compliance policy definitions across their organization. AWS Config Conformance packs are integrated with AWS Organizations and enable you to package a collection of AWS Config rules and remediation actions and deploy them together as a single entity across an entire organization. This is particularly useful if you need to quickly establish a common baseline for resource configuration policies and best practices across multiple accounts in your organization in a scalable and efficient way. These conformance packs and their underlying config rules and remediations actions are not modifiable by your organization’s member accounts. Only master accounts can create, update, and delete organization conformance packs.

In this post, I go over steps needed to set up and use conformance packs in an organization from the command-line interface (AWS CLI). Organization conformance packs are currently only available through AWS CLI and API.

Prerequisites

In order to use conformance packs in an organization, ensure you are meeting the following requirements:

  • You have access to AWS Organizations master account credentials.
  • AWS Config recording is turned on in the master account and member accounts in which you wish to deploy the organization conformance pack.
  • An Amazon S3 bucket is available in the master or member account for storing the organization conformance pack template with access granted to the organization.

Set up AWS Config recording in all AWS accounts

Use the Setting Up AWS Config with the Console guide to setup and enable recording in all AWS accounts in your organization. You can also use the AWS CLI to setup AWS Config

Set up permissions on your Amazon S3 delivery bucket

For AWS Config to be able to store conformance pack artifacts, you will need to provide an Amazon S3 bucket in the master account or any member account. This bucket name must start with the prefix “awsconfigconforms”. Each account in the organization must have access to this bucket. AWS Config recommends having limited permissions to the Amazon S3 bucket policy. To limit access, you can use following policy which uses PrincipalOrgID and PrincipalArn conditions in the Amazon S3 policy. This allows only accounts in an organization to have access to the bucket.

You can find your organization id from the AWS Organizations console under the Settings tab.

 

{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowGetPutObject",
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                     "s3:GetObject",
                     "s3:PutObject"
                ],
                "Resource": "arn:aws:s3:::awsconfigconforms<suffix in bucket name>/*",
                "Condition": {
                    "StringEquals": {
                        "aws:PrincipalOrgID": "customer_org_id"
                    },
                    "ArnLike": {
                        "aws:PrincipalArn": "arn:aws:iam::*:role/aws-service-role/config-conforms.amazonaws.com/AWSServiceRoleForConfigConforms"
                    }
                }
            },
            {
                "Sid": "AllowGetBucketAcl",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetBucketAcl",
                "Resource": "arn:aws:s3:::awsconfigconforms<suffix in bucket name>",
                "Condition": {
                    "StringEquals": {
                        "aws:PrincipalOrgID": "customer_org_id"
                    },
                    "ArnLike": {
                        "aws:PrincipalArn": "arn:aws:iam::*:role/aws-service-role/config-conforms.amazonaws.com/AWSServiceRoleForConfigConforms"
                    }
                }
            }
        ]
}

Deploying your first organization conformance pack

For your first conformance pack, use the Operational Best Practices for Amazon S3 pack, which includes the following AWS Config rules that are checked against all of your Amazon S3 buckets in the region. This pack contains the following rules.

  1. S3BucketPublicReadProhibited
  2. S3BucketPublicWriteProhibited
  3. S3BucketReplicationEnabled
  4. S3BucketSSLRequestsOnly
  5. S3BucketServerSideEncryptionEnabled
  6. S3BucketLoggingEnabled

Later in this example, you will learn how to improve your security posture by adding automatic remediation actions to this conformance pack to remediate non-compliant resources.

  1. To deploy your first pack using the CLI, save the Operational Best Practices for Amazon S3 pack locally and run the following command:

aws configservice put-organization-conformance-pack --organization-conformance-pack-name="OrgS3ConformancePack" --template-body="file://<PATH TO YOUR TEMPLATE>/<TEMPLATE FILENAME>" --delivery-s3-bucket=<YOUR BUCKET>

 

Make sure to replace the placeholders with their corresponding values. You can either specify a local source for the template, or point the service to an Amazon S3 bucket using the --template-s3-uri argument.

By default, the organization conformance pack is deployed to all accounts in an organization. However, you can optionally provide the --excluded-accounts parameter with the previous command to exclude some accounts.

The response you receive from the service is the organization conformance pack’s ARN.


{
    "OrganizationConformancePackArn": "arn:aws:config:us-west-2:012345678910:organization-conformance-pack/OrgS3ConformancePack-snzbcnxu"
}

 

2. Running the following command describes the organization conformance packs in your account. You can optionally provide the --organization-conformance-pack-name to see a specific pack.

aws configservice describe-organization-conformance-packs --organization-conformance-pack-name=OrgS3ConformancePack

The service returns the following response:

{
    "OrganizationConformancePacks": [
        {
            "OrganizationConformancePackName": "OrgS3ConformancePack",
            "OrganizationConformancePackArn": "arn:aws:config:us-west-2:012345678910:organization-conformance-pack/OrgS3ConformancePack-snzbcnxu",
            "DeliveryS3Bucket": "awsconfigconforms-bucket",
            "ConformancePackInputParameters": [],
            "ExcludedAccounts": [],
            "LastUpdateTime": 1578257793.596
        }
    ]
}

3. Deploying the organization conformance pack is an asynchronous process. You can view the status of the deployment by calling status APIs. There are two APIs available to check status of deployment.

  • describe-organization-conformance-pack-statuses.
  • get-organization-conformance-pack-detail-status.

a. Run the following command to see the overall status of the deployment. See the documentation for a list of all statuses and what they mean.


aws configservice describe-organization-conformance-pack-statuses --organization-conformance-pack-name=OrgS3ConformancePack

The service returns following response:

{
    "OrganizationConformancePackStatuses": [
        {
            "OrganizationConformancePackName": "OrgS3ConformancePack",
            "Status": "CREATE_IN_PROGRESS",
            "LastUpdateTime": 1578258040.397
        }
    ]
}

 

b. Run the following command to see detailed statuses for the deployment. This command gives the deployment status for each member account.

aws configservice get-organization-conformance-pack-detailed-status --organization-conformance-pack-name=OrgS3ConformancePack

 

The service returns the following response:

{
    "OrganizationConformancePackDetailedStatuses": [
        {
            "AccountId": "012345678910",
            "ConformancePackName": "OrgConformsPack-OrgS3ConformancePack-snzbcnxu",
            "Status": "CREATE_SUCCESSFUL",
            "LastUpdateTime": 1578257923
        },
        {
            "AccountId": "012345678911",
            "ConformancePackName": "OrgConformsPack-OrgS3ConformancePack-snzbcnxu",
            "Status": "CREATE_IN_PROGRESS",
            "LastUpdateTime": 1578257924
        }
    ]
}

5. Run the following command to delete an organization conformance pack. Organization conformance pack must be in either create/update completed/failed status before it can be deleted.


aws configservice delete-organization-conformance-pack —organization-conformance-pack-name=OrgS3ConformancePack

Adding Remediation to organization conformance pack

AWS Config supports both manual and automatic remediation actions with AWS Config rules. In this example, I use automatic remediation actions, which gives you the ability to address non-compliant resources without manual intervention, thereby reducing time to remediate. These remediation actions are backed up by AWS Systems Manager automation documents.

I use the following template, which enhances your first pack and adds automatic remediation actions to rules:


Resources:
  S3BucketPublicReadProhibited:
    Type: AWS::Config::ConfigRule
    Properties:
      ConfigRuleName: S3BucketPublicReadProhibited
      Description: >-
        Checks that your Amazon S3 buckets do not allow public read access.
        The rule checks the Block Public Access settings, the bucket policy, and the
        bucket access control list (ACL).
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_PUBLIC_READ_PROHIBITED
      MaximumExecutionFrequency: Six_Hours
  S3PublicReadRemediation:
    DependsOn: S3BucketPublicReadProhibited
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      ConfigRuleName: S3BucketPublicReadProhibited
      ResourceType: "AWS::S3::Bucket"
      TargetId: "AWS-DisableS3BucketPublicReadWrite"
      TargetType: "SSM_DOCUMENT"
      TargetVersion: "1"
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::<ACCOUNT_ID>:role/S3OperationsAutomationsExecutionRole
        S3BucketName:
          ResourceValue:
            Value: "RESOURCE_ID"
      ExecutionControls:
        SsmControls:
          ConcurrentExecutionRatePercentage: 10
          ErrorPercentage: 10
      Automatic: True
      MaximumAutomaticAttempts: 10
      RetryAttemptSeconds: 600

  S3BucketPublicWriteProhibited:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketPublicWriteProhibited
      Description: "Checks that your Amazon S3 buckets do not allow public write access. The rule checks the Block Public Access settings, the bucket policy, and the bucket access control list (ACL)."
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_PUBLIC_WRITE_PROHIBITED
      MaximumExecutionFrequency: Six_Hours
  S3PublicWriteRemediation:
    DependsOn: S3BucketPublicWriteProhibited
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      ConfigRuleName: S3BucketPublicWriteProhibited
      ResourceType: "AWS::S3::Bucket"
      TargetId: "AWS-DisableS3BucketPublicReadWrite"
      TargetType: "SSM_DOCUMENT"
      TargetVersion: "1"
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::<ACCOUNT_ID>:role/S3OperationsAutomationsExecutionRole
        S3BucketName:
          ResourceValue:
            Value: "RESOURCE_ID"
      ExecutionControls:
        SsmControls:
          ConcurrentExecutionRatePercentage: 10
          ErrorPercentage: 10
      Automatic: True
      MaximumAutomaticAttempts: 10
      RetryAttemptSeconds: 600

  S3BucketReplicationEnabled:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketReplicationEnabled
      Description: "Checks whether the Amazon S3 buckets have cross-region replication enabled."
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_REPLICATION_ENABLED
  S3BucketSSLRequestsOnly:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketSSLRequestsOnly
      Description: "Checks whether S3 buckets have policies that require requests to use Secure Socket Layer (SSL)."
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_SSL_REQUESTS_ONLY

  S3BucketServerSideEncryptionEnabled:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketServerSideEncryptionEnabled
      Description: "Checks that your Amazon S3 bucket either has S3 default encryption enabled or that the S3 bucket policy explicitly denies put-object requests without server side encryption."
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED
  S3BucketServerSideEncryptionEnabledRemediation:
    DependsOn: S3BucketServerSideEncryptionEnabled
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      ConfigRuleName: S3BucketServerSideEncryptionEnabled
      ResourceType: "AWS::S3::Bucket"
      TargetId: "AWS-EnableS3BucketEncryption"
      TargetType: "SSM_DOCUMENT"
      TargetVersion: "1"
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::<ACCOUNT_ID>:role/S3OperationsAutomationsExecutionRole
        BucketName:
          ResourceValue:
            Value: "RESOURCE_ID"
        SSEAlgorithm:
          StaticValue:
            Values:
              - "AES256"
      ExecutionControls:
        SsmControls:
          ConcurrentExecutionRatePercentage: 10
          ErrorPercentage: 10
      Automatic: True
      MaximumAutomaticAttempts: 10
      RetryAttemptSeconds: 600

  S3BucketLoggingEnabled:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketLoggingEnabled
      Description: "Checks whether logging is enabled for your S3 buckets."
      Scope:
        ComplianceResourceTypes:
        - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_LOGGING_ENABLED
  S3BucketLoggingEnabledRemediation:
    DependsOn: S3BucketLoggingEnabled
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      ConfigRuleName: S3BucketLoggingEnabled
      ResourceType: "AWS::S3::Bucket"
      TargetId: "AWS-ConfigureS3BucketLogging"
      TargetType: "SSM_DOCUMENT"
      TargetVersion: "1"
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::<ACCOUNT_ID>:role/S3OperationsAutomationsExecutionRole
        BucketName:
          ResourceValue:
            Value: "RESOURCE_ID"
        TargetBucket:
          StaticValue:
            Values:
              - Fn::ImportValue: S3LoggingBucketName
        GrantedPermission:
          StaticValue:
            Values:
              - "FULL_CONTROL"
        GranteeType:
          StaticValue:
            Values:
              - "Group"
        GranteeUri:
          StaticValue:
            Values:
              - "http://acs.amazonaws.com/groups/s3/LogDelivery"
      ExecutionControls:
        SsmControls:
          ConcurrentExecutionRatePercentage: 10
          ErrorPercentage: 10
      Automatic: True
      MaximumAutomaticAttempts: 10
      RetryAttemptSeconds: 600

Save the above template locally and replace the <ACCOUNT_ID> placeholder with the master account ID of your organization. Before you deploy this template, you will need to create prerequisite resources.

Prerequisites for organizational best practices for Amazon S3 with automatic remediation template

Use these prerequisites for Amazon S3 organizational best practices with an automatic remediation template.

  1. Automatic remediation actions require an automation assume role. This role needs to be created in all member accounts with the same name.
  2. The S3BucketLoggingEnabled rule checks whether logging is enabled for your Amazon S3 buckets. The associated remediation action for this rule enables logging on your Amazon S3 buckets and sets a log delivery bucket to which Amazon S3 delivers service access logs. This log delivery bucket needs to be created in all member accounts.

Use the follwing AWS Cloudformation template to create the automation assume role and Amazon S3 log delivery bucket. You can use AWS Cloudformation StackSets to deploy this role and bucket in all accounts in your organization.


Resources: 
  S3OperationsAutomationsExecutionRole: 
    Type: "AWS::IAM::Role"
    Properties: 
      RoleName: S3OperationsAutomationsExecutionRole
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - 
            Effect: "Allow"
            Principal: 
              Service: 
                - "ssm.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      Path: "/"
  
  S3OperationsAutomationExecutionRolePolicies: 
    Type: "AWS::IAM::Policy"
    Properties: 
      PolicyName: "S3OperationsAutomationsExecutionRolePolicy"
      PolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - 
            Effect: "Allow"
            Action: 
              - "s3:PutBucketPublicAccessBlock"
              - "s3:PutEncryptionConfiguration"
              - "s3:PutBucketLogging"
            Resource: "*"
      Roles: 
        - 
          Ref: "S3OperationsAutomationsExecutionRole"
  
  S3LoggingBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub 's3serversideloggingbucket-${AWS::AccountId}'
      AccessControl : "LogDeliveryWrite"

Outputs:
  S3LoggingBucketName:
    Export:
      Name: S3LoggingBucketName
    Value: !Sub 's3serversideloggingbucket-${AWS::AccountId}'   

Once prerequisites are deployed to all member accounts, run the following command to deploy the conformance pack with remediation to your organization.

aws configservice put-organization-conformance-pack --organization-conformance-pack-name="OrgS3ConformancePack" --template-body="file://<PATH TO YOUR TEMPLATE>/<TEMPLATE FILENAME>" --delivery-s3-bucket=<YOUR BUCKET>

Conclusion

This blog post demonstrated how to deploy AWS Config conformance packs with rules and remediation actions in your entire organization. To learn more about AWS Config conformance packs, visit our AWS documentation.

About the Author

Faraz Kazmi is a Software Development Engineer in AWS Config. In his spare time, Faraz likes to explore and photograph the PNW beauty with his camera.