12 min read

AWS Config for Security Compliance: Automated Governance at Scale

AWS ConfigComplianceGovernanceAutomation

AWS Config transforms compliance from a manual, periodic activity into an automated, continuous process. This guide explores advanced Config patterns for implementing enterprise-grade security compliance that scales with your organization's growth.

Config Architecture for Compliance

Multi-Account Compliance Strategy

import boto3
import json

class ComplianceOrchestrator:
    def __init__(self):
        self.config_client = boto3.client('config')
        self.organizations_client = boto3.client('organizations')
        
    def setup_organization_config(self):
        """Setup Config across AWS Organization"""
        
        # Get all accounts in organization
        accounts = self.organizations_client.list_accounts()['Accounts']
        
        # Create aggregator for organization-wide compliance view
        aggregator_config = {
            'ConfigurationAggregatorName': 'SecurityComplianceAggregator',
            'OrganizationAggregationSource': {
                'RoleArn': 'arn:aws:iam::123456789012:role/aws-config-role',
                'AllAwsRegions': True
            },
            'Tags': [
                {'Key': 'Purpose', 'Value': 'SecurityCompliance'},
                {'Key': 'ManagedBy', 'Value': 'SecurityTeam'}
            ]
        }
        
        aggregator = self.config_client.put_configuration_aggregator(**aggregator_config)
        
        # Setup conformance packs for standardized compliance
        conformance_packs = [
            {
                'ConformancePackName': 'SecurityFoundations',
                'TemplateS3Uri': 's3://compliance-templates/security-foundations.yaml',
                'DeliveryS3Bucket': 'compliance-results-bucket'
            },
            {
                'ConformancePackName': 'DataProtection',
                'TemplateS3Uri': 's3://compliance-templates/data-protection.yaml',
                'DeliveryS3Bucket': 'compliance-results-bucket'
            }
        ]
        
        deployed_packs = []
        for pack_config in conformance_packs:
            try:
                pack = self.config_client.put_conformance_pack(**pack_config)
                deployed_packs.append(pack)
            except Exception as e:
                print(f"Failed to deploy conformance pack {pack_config['ConformancePackName']}: {e}")
        
        return aggregator, deployed_packs

Custom Config Rules for Security

def create_custom_security_rules():
    """Create custom Config rules for specific security requirements"""
    
    config_client = boto3.client('config')
    
    # Custom rule for detecting overprivileged IAM roles
    overprivileged_role_rule = {
        'ConfigRuleName': 'detect-overprivileged-iam-roles',
        'Description': 'Detects IAM roles with overly broad permissions',
        'Source': {
            'Owner': 'AWS_LAMBDA',
            'SourceIdentifier': 'arn:aws:lambda:us-east-1:123456789012:function:check-iam-role-permissions'
        },
        'InputParameters': json.dumps({
            'maxPolicySize': 6144,  # 6KB limit
            'prohibitedActions': [
                '*:*',
                'iam:*',
                's3:*',
                'ec2:*'
            ],
            'allowedRolePatterns': [
                'service-role/*',
                'aws-service-role/*'
            ]
        }),
        'ConfigurationItemTypes': ['AWS::IAM::Role'],
        'MaximumExecutionFrequency': 'TwentyFour_Hours'
    }
    
    # Custom rule for S3 bucket security configuration
    s3_security_rule = {
        'ConfigRuleName': 'comprehensive-s3-security-check',
        'Description': 'Comprehensive S3 bucket security validation',
        'Source': {
            'Owner': 'AWS_LAMBDA',
            'SourceIdentifier': 'arn:aws:lambda:us-east-1:123456789012:function:check-s3-security'
        },
        'InputParameters': json.dumps({
            'requireEncryption': True,
            'requireVersioning': True,
            'requireMFA': True,
            'prohibitPublicRead': True,
            'prohibitPublicWrite': True,
            'requireAccessLogging': True,
            'allowedKMSKeys': [
                'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
            ]
        }),
        'ConfigurationItemTypes': ['AWS::S3::Bucket']
    }
    
    # Custom rule for security group compliance
    security_group_rule = {
        'ConfigRuleName': 'security-group-compliance-check',
        'Description': 'Validates security group configurations against security standards',
        'Source': {
            'Owner': 'AWS_LAMBDA',
            'SourceIdentifier': 'arn:aws:lambda:us-east-1:123456789012:function:check-security-groups'
        },
        'InputParameters': json.dumps({
            'prohibitedPorts': [22, 3389, 1433, 3306, 5432],
            'allowedSourceRanges': ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'],
            'requireDescriptions': True,
            'maxRulesPerGroup': 50
        }),
        'ConfigurationItemTypes': ['AWS::EC2::SecurityGroup']
    }
    
    custom_rules = [overprivileged_role_rule, s3_security_rule, security_group_rule]
    created_rules = []
    
    for rule_config in custom_rules:
        try:
            rule = config_client.put_config_rule(ConfigRule=rule_config)
            created_rules.append(rule)
        except Exception as e:
            print(f"Failed to create rule {rule_config['ConfigRuleName']}: {e}")
    
    return created_rules

Lambda Functions for Custom Rules

def create_iam_role_compliance_function():
    """Lambda function to check IAM role compliance"""
    
    lambda_code = '''
import json
import boto3
from datetime import datetime

def lambda_handler(event, context):
    """Check IAM role for compliance violations"""
    
    # Parse Config event
    config_item = event['configurationItem']
    rule_parameters = json.loads(event['ruleParameters'])
    
    # Initialize compliance result
    compliance_result = {
        'complianceType': 'COMPLIANT',
        'annotation': 'IAM role meets security requirements'
    }
    
    if config_item['resourceType'] != 'AWS::IAM::Role':
        return compliance_result
    
    role_name = config_item['resourceName']
    role_config = config_item['configuration']
    
    violations = []
    
    # Check for overly broad permissions
    if 'rolePolicyList' in role_config:
        for policy in role_config['rolePolicyList']:
            policy_doc = json.loads(policy['policyDocument'])
            
            for statement in policy_doc.get('Statement', []):
                actions = statement.get('Action', [])
                if isinstance(actions, str):
                    actions = [actions]
                
                # Check for prohibited actions
                for action in actions:
                    if action in rule_parameters['prohibitedActions']:
                        violations.append(f"Prohibited action found: {action}")
    
    # Check attached managed policies
    if 'attachedManagedPolicies' in role_config:
        for policy in role_config['attachedManagedPolicies']:
            if 'AdministratorAccess' in policy['policyName']:
                violations.append("AdministratorAccess policy attached")
    
    # Check trust policy
    if 'assumeRolePolicyDocument' in role_config:
        trust_policy = json.loads(role_config['assumeRolePolicyDocument'])
        
        for statement in trust_policy.get('Statement', []):
            principal = statement.get('Principal', {})
            
            # Check for overly permissive trust relationships
            if principal == '*' or principal.get('AWS') == '*':
                violations.append("Overly permissive trust policy")
    
    # Set compliance result
    if violations:
        compliance_result['complianceType'] = 'NON_COMPLIANT'
        compliance_result['annotation'] = '; '.join(violations)
    
    # Submit evaluation to Config
    config_client = boto3.client('config')
    
    evaluation = {
        'ComplianceResourceType': config_item['resourceType'],
        'ComplianceResourceId': config_item['resourceId'],
        'ComplianceType': compliance_result['complianceType'],
        'Annotation': compliance_result['annotation'],
        'OrderingTimestamp': datetime.now()
    }
    
    config_client.put_evaluations(
        Evaluations=[evaluation],
        ResultToken=event['resultToken']
    )
    
    return compliance_result
'''
    
    return lambda_code

def create_s3_security_function():
    """Lambda function to check S3 bucket security"""
    
    lambda_code = '''
import json
import boto3
from datetime import datetime

def lambda_handler(event, context):
    """Check S3 bucket security configuration"""
    
    config_item = event['configurationItem']
    rule_parameters = json.loads(event['ruleParameters'])
    
    compliance_result = {
        'complianceType': 'COMPLIANT',
        'annotation': 'S3 bucket meets security requirements'
    }
    
    if config_item['resourceType'] != 'AWS::S3::Bucket':
        return compliance_result
    
    bucket_name = config_item['resourceName']
    bucket_config = config_item['configuration']
    
    violations = []
    s3_client = boto3.client('s3')
    
    try:
        # Check encryption
        if rule_parameters.get('requireEncryption', True):
            try:
                encryption = s3_client.get_bucket_encryption(Bucket=bucket_name)
            except s3_client.exceptions.ClientError as e:
                if e.response['Error']['Code'] == 'ServerSideEncryptionConfigurationNotFoundError':
                    violations.append("Bucket encryption not configured")
        
        # Check versioning
        if rule_parameters.get('requireVersioning', True):
            versioning = s3_client.get_bucket_versioning(Bucket=bucket_name)
            if versioning.get('Status') != 'Enabled':
                violations.append("Bucket versioning not enabled")
        
        # Check public access
        if rule_parameters.get('prohibitPublicRead', True) or rule_parameters.get('prohibitPublicWrite', True):
            try:
                public_access = s3_client.get_public_access_block(Bucket=bucket_name)
                config = public_access['PublicAccessBlockConfiguration']
                
                if not config.get('BlockPublicAcls', False):
                    violations.append("Public ACLs not blocked")
                if not config.get('IgnorePublicAcls', False):
                    violations.append("Public ACLs not ignored")
                if not config.get('BlockPublicPolicy', False):
                    violations.append("Public bucket policies not blocked")
                if not config.get('RestrictPublicBuckets', False):
                    violations.append("Public bucket access not restricted")
                    
            except s3_client.exceptions.ClientError:
                violations.append("Public access block not configured")
        
        # Check access logging
        if rule_parameters.get('requireAccessLogging', True):
            try:
                logging = s3_client.get_bucket_logging(Bucket=bucket_name)
                if 'LoggingEnabled' not in logging:
                    violations.append("Access logging not enabled")
            except s3_client.exceptions.ClientError:
                violations.append("Access logging not configured")
        
    except Exception as e:
        violations.append(f"Error checking bucket configuration: {str(e)}")
    
    # Set compliance result
    if violations:
        compliance_result['complianceType'] = 'NON_COMPLIANT'
        compliance_result['annotation'] = '; '.join(violations)
    
    # Submit evaluation
    config_client = boto3.client('config')
    
    evaluation = {
        'ComplianceResourceType': config_item['resourceType'],
        'ComplianceResourceId': config_item['resourceId'],
        'ComplianceType': compliance_result['complianceType'],
        'Annotation': compliance_result['annotation'],
        'OrderingTimestamp': datetime.now()
    }
    
    config_client.put_evaluations(
        Evaluations=[evaluation],
        ResultToken=event['resultToken']
    )
    
    return compliance_result
'''
    
    return lambda_code

Automated Remediation

Config Remediation Actions

def setup_automated_remediation():
    """Setup automated remediation for common compliance violations"""
    
    config_client = boto3.client('config')
    ssm_client = boto3.client('ssm')
    
    # Remediation configurations
    remediation_configs = [
        {
            'ConfigRuleName': 's3-bucket-public-read-prohibited',
            'TargetType': 'SSM_DOCUMENT',
            'TargetId': 'AWS-DisableS3BucketPublicReadWrite',
            'TargetVersion': '1',
            'Parameters': {
                'AutomationAssumeRole': {
                    'StaticValue': {
                        'Values': ['arn:aws:iam::123456789012:role/ConfigRemediationRole']
                    }
                },
                'BucketName': {
                    'ResourceValue': {
                        'Value': 'RESOURCE_ID'
                    }
                }
            },
            'Automatic': True,
            'MaximumAutomaticAttempts': 3
        },
        {
            'ConfigRuleName': 'security-group-ssh-restricted',
            'TargetType': 'SSM_DOCUMENT',
            'TargetId': 'AWS-RemoveUnrestrictedSourceInSecurityGroup',
            'TargetVersion': '1',
            'Parameters': {
                'AutomationAssumeRole': {
                    'StaticValue': {
                        'Values': ['arn:aws:iam::123456789012:role/ConfigRemediationRole']
                    }
                },
                'GroupId': {
                    'ResourceValue': {
                        'Value': 'RESOURCE_ID'
                    }
                },
                'IpProtocol': {
                    'StaticValue': {
                        'Values': ['tcp']
                    }
                },
                'FromPort': {
                    'StaticValue': {
                        'Values': ['22']
                    }
                }
            },
            'Automatic': True,
            'MaximumAutomaticAttempts': 2
        }
    ]
    
    # Create custom remediation document for IAM role cleanup
    iam_remediation_document = {
        'Name': 'RemoveOverprivilegedIAMPolicies',
        'DocumentType': 'Automation',
        'DocumentFormat': 'YAML',
        'Content': '''
schemaVersion: '0.3'
description: Remove overprivileged policies from IAM roles
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
  RoleName:
    type: String
    description: Name of the IAM role to remediate
  AutomationAssumeRole:
    type: String
    description: IAM role for automation
mainSteps:
  - name: DetachAdministratorAccess
    action: 'aws:executeAwsApi'
    inputs:
      Service: iam
      Api: DetachRolePolicy
      RoleName: '{{ RoleName }}'
      PolicyArn: 'arn:aws:iam::aws:policy/AdministratorAccess'
    onFailure: Continue
  - name: ListAttachedPolicies
    action: 'aws:executeAwsApi'
    inputs:
      Service: iam
      Api: ListAttachedRolePolicies
      RoleName: '{{ RoleName }}'
    outputs:
      - Name: AttachedPolicies
        Selector: $.AttachedPolicies
        Type: MapList
  - name: ReviewPolicies
    action: 'aws:executeScript'
    inputs:
      Runtime: python3.8
      Handler: review_policies
      Script: |
        def review_policies(events, context):
            # Logic to review and remove overprivileged policies
            return {"message": "Policies reviewed and cleaned up"}
'''
    }
    
    # Create the custom document
    try:
        ssm_client.create_document(**iam_remediation_document)
    except ssm_client.exceptions.DocumentAlreadyExistsException:
        pass  # Document already exists
    
    # Setup remediation configurations
    created_remediations = []
    for remediation_config in remediation_configs:
        try:
            remediation = config_client.put_remediation_configuration(
                RemediationConfigurations=[remediation_config]
            )
            created_remediations.append(remediation)
        except Exception as e:
            print(f"Failed to create remediation for {remediation_config['ConfigRuleName']}: {e}")
    
    return created_remediations

Custom Remediation Functions

def create_custom_remediation_lambda():
    """Create Lambda function for custom remediation actions"""
    
    remediation_code = '''
import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    """Handle custom remediation actions"""
    
    # Parse Config remediation event
    config_rule_name = event['configRuleName']
    resource_type = event['resourceType']
    resource_id = event['resourceId']
    
    logger.info(f"Remediating {resource_type} {resource_id} for rule {config_rule_name}")
    
    try:
        if config_rule_name == 'detect-overprivileged-iam-roles':
            remediate_iam_role(resource_id)
        elif config_rule_name == 'comprehensive-s3-security-check':
            remediate_s3_bucket(resource_id)
        elif config_rule_name == 'security-group-compliance-check':
            remediate_security_group(resource_id)
        else:
            logger.warning(f"No remediation available for rule: {config_rule_name}")
            
        return {
            'statusCode': 200,
            'body': json.dumps(f'Remediation completed for {resource_id}')
        }
        
    except Exception as e:
        logger.error(f"Remediation failed: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps(f'Remediation failed: {str(e)}')
        }

def remediate_iam_role(role_name):
    """Remediate overprivileged IAM role"""
    iam = boto3.client('iam')
    
    # Get attached policies
    attached_policies = iam.list_attached_role_policies(RoleName=role_name)
    
    # Remove overprivileged managed policies
    overprivileged_policies = [
        'arn:aws:iam::aws:policy/AdministratorAccess',
        'arn:aws:iam::aws:policy/PowerUserAccess'
    ]
    
    for policy in attached_policies['AttachedPolicies']:
        if policy['PolicyArn'] in overprivileged_policies:
            iam.detach_role_policy(
                RoleName=role_name,
                PolicyArn=policy['PolicyArn']
            )
            logger.info(f"Detached policy {policy['PolicyArn']} from role {role_name}")
    
    # Review inline policies
    inline_policies = iam.list_role_policies(RoleName=role_name)
    
    for policy_name in inline_policies['PolicyNames']:
        policy_doc = iam.get_role_policy(
            RoleName=role_name,
            PolicyName=policy_name
        )
        
        # Check for overly broad permissions
        policy_content = policy_doc['PolicyDocument']
        if has_overprivileged_statements(policy_content):
            # Create a more restrictive version
            restricted_policy = create_restricted_policy(policy_content)
            
            iam.put_role_policy(
                RoleName=role_name,
                PolicyName=policy_name,
                PolicyDocument=json.dumps(restricted_policy)
            )
            logger.info(f"Updated inline policy {policy_name} for role {role_name}")

def remediate_s3_bucket(bucket_name):
    """Remediate S3 bucket security issues"""
    s3 = boto3.client('s3')
    
    try:
        # Enable default encryption
        s3.put_bucket_encryption(
            Bucket=bucket_name,
            ServerSideEncryptionConfiguration={
                'Rules': [
                    {
                        'ApplyServerSideEncryptionByDefault': {
                            'SSEAlgorithm': 'AES256'
                        }
                    }
                ]
            }
        )
        logger.info(f"Enabled encryption for bucket {bucket_name}")
        
        # Enable versioning
        s3.put_bucket_versioning(
            Bucket=bucket_name,
            VersioningConfiguration={'Status': 'Enabled'}
        )
        logger.info(f"Enabled versioning for bucket {bucket_name}")
        
        # Block public access
        s3.put_public_access_block(
            Bucket=bucket_name,
            PublicAccessBlockConfiguration={
                'BlockPublicAcls': True,
                'IgnorePublicAcls': True,
                'BlockPublicPolicy': True,
                'RestrictPublicBuckets': True
            }
        )
        logger.info(f"Blocked public access for bucket {bucket_name}")
        
    except Exception as e:
        logger.error(f"Failed to remediate S3 bucket {bucket_name}: {str(e)}")
        raise

def remediate_security_group(group_id):
    """Remediate security group violations"""
    ec2 = boto3.client('ec2')
    
    # Get security group details
    sg_response = ec2.describe_security_groups(GroupIds=[group_id])
    security_group = sg_response['SecurityGroups'][0]
    
    # Remove overly permissive rules
    problematic_rules = []
    
    for rule in security_group['IpPermissions']:
        for ip_range in rule.get('IpRanges', []):
            if ip_range['CidrIp'] == '0.0.0.0/0':
                # Check if it's a problematic port
                from_port = rule.get('FromPort', 0)
                if from_port in [22, 3389, 1433, 3306, 5432]:  # SSH, RDP, SQL ports
                    problematic_rules.append(rule)
    
    # Revoke problematic rules
    if problematic_rules:
        ec2.revoke_security_group_ingress(
            GroupId=group_id,
            IpPermissions=problematic_rules
        )
        logger.info(f"Removed {len(problematic_rules)} problematic rules from {group_id}")

def has_overprivileged_statements(policy_doc):
    """Check if policy has overprivileged statements"""
    for statement in policy_doc.get('Statement', []):
        actions = statement.get('Action', [])
        if isinstance(actions, str):
            actions = [actions]
        
        for action in actions:
            if action in ['*', '*:*'] or action.endswith(':*'):
                return True
    
    return False

def create_restricted_policy(original_policy):
    """Create a more restrictive version of the policy"""
    # This is a simplified example - in practice, you'd need more sophisticated logic
    restricted_policy = original_policy.copy()
    
    for statement in restricted_policy.get('Statement', []):
        actions = statement.get('Action', [])
        if isinstance(actions, str):
            actions = [actions]
        
        # Replace overly broad actions with more specific ones
        new_actions = []
        for action in actions:
            if action == '*:*':
                # Replace with common read-only actions
                new_actions.extend([
                    's3:GetObject',
                    's3:ListBucket',
                    'ec2:DescribeInstances',
                    'iam:GetRole'
                ])
            elif not action.endswith(':*'):
                new_actions.append(action)
        
        statement['Action'] = new_actions
    
    return restricted_policy
'''
    
    return remediation_code

Compliance Reporting and Dashboards

Comprehensive Compliance Dashboard

def create_compliance_dashboard():
    """Create comprehensive compliance dashboard"""
    
    cloudwatch = boto3.client('cloudwatch')
    
    dashboard_widgets = [
        {
            "type": "metric",
            "properties": {
                "metrics": [
                    ["AWS/Config", "ComplianceByConfigRule", "ConfigRuleName", "s3-bucket-public-read-prohibited"],
                    [".", ".", ".", "iam-password-policy"],
                    [".", ".", ".", "root-access-key-check"],
                    [".", ".", ".", "encrypted-volumes"]
                ],
                "period": 300,
                "stat": "Average",
                "region": "us-east-1",
                "title": "Compliance Status by Rule"
            }
        },
        {
            "type": "log",
            "properties": {
                "query": "SOURCE '/aws/config/configuration-history'\n| fields @timestamp, resourceType, resourceId, configurationItemStatus\n| filter configurationItemStatus = \"ResourceDeleted\"\n| stats count() by resourceType\n| sort count desc",
                "region": "us-east-1",
                "title": "Resource Deletions",
                "view": "table"
            }
        },
        {
            "type": "metric",
            "properties": {
                "metrics": [
                    ["AWS/Config", "ComplianceByResourceType", "ResourceType", "AWS::S3::Bucket"],
                    [".", ".", ".", "AWS::EC2::SecurityGroup"],
                    [".", ".", ".", "AWS::IAM::Role"],
                    [".", ".", ".", "AWS::EC2::Instance"]
                ],
                "period": 300,
                "stat": "Average",
                "region": "us-east-1",
                "title": "Compliance by Resource Type"
            }
        }
    ]
    
    dashboard_body = {
        "widgets": dashboard_widgets
    }
    
    response = cloudwatch.put_dashboard(
        DashboardName='SecurityComplianceDashboard',
        DashboardBody=json.dumps(dashboard_body)
    )
    
    return response

def generate_compliance_report():
    """Generate detailed compliance report"""
    
    config_client = boto3.client('config')
    
    # Get compliance summary
    compliance_summary = config_client.get_compliance_summary_by_config_rule()
    
    # Get detailed compliance information
    compliance_details = {}
    
    # Get all config rules
    rules = config_client.describe_config_rules()['ConfigRules']
    
    for rule in rules:
        rule_name = rule['ConfigRuleName']
        
        # Get compliance details for this rule
        compliance_by_rule = config_client.get_compliance_details_by_config_rule(
            ConfigRuleName=rule_name
        )
        
        compliance_details[rule_name] = {
            'rule_description': rule.get('Description', ''),
            'compliant_resources': [],
            'non_compliant_resources': [],
            'not_applicable_resources': []
        }
        
        for result in compliance_by_rule['EvaluationResults']:
            resource_info = {
                'resource_type': result['EvaluationResultIdentifier']['EvaluationResultQualifier']['ResourceType'],
                'resource_id': result['EvaluationResultIdentifier']['EvaluationResultQualifier']['ResourceId'],
                'annotation': result.get('Annotation', ''),
                'result_recorded_time': result['ResultRecordedTime'].isoformat()
            }
            
            compliance_type = result['ComplianceType']
            if compliance_type == 'COMPLIANT':
                compliance_details[rule_name]['compliant_resources'].append(resource_info)
            elif compliance_type == 'NON_COMPLIANT':
                compliance_details[rule_name]['non_compliant_resources'].append(resource_info)
            else:
                compliance_details[rule_name]['not_applicable_resources'].append(resource_info)
    
    # Generate summary statistics
    total_rules = len(rules)
    total_compliant = sum(len(details['compliant_resources']) for details in compliance_details.values())
    total_non_compliant = sum(len(details['non_compliant_resources']) for details in compliance_details.values())
    
    compliance_percentage = (total_compliant / (total_compliant + total_non_compliant)) * 100 if (total_compliant + total_non_compliant) > 0 else 0
    
    report = {
        'report_generated': datetime.now().isoformat(),
        'summary': {
            'total_rules': total_rules,
            'total_compliant_resources': total_compliant,
            'total_non_compliant_resources': total_non_compliant,
            'compliance_percentage': round(compliance_percentage, 2)
        },
        'rule_details': compliance_details
    }
    
    return report

Advanced Config Patterns

Multi-Region Compliance Monitoring

def setup_multi_region_compliance():
    """Setup compliance monitoring across multiple regions"""
    
    regions = ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-southeast-1']
    
    regional_configs = {}
    
    for region in regions:
        config_client = boto3.client('config', region_name=region)
        
        # Setup Config in each region
        try:
            # Create configuration recorder
            config_client.put_configuration_recorder(
                ConfigurationRecorder={
                    'name': f'SecurityComplianceRecorder-{region}',
                    'roleARN': f'arn:aws:iam::123456789012:role/aws-config-role',
                    'recordingGroup': {
                        'allSupported': True,
                        'includeGlobalResourceTypes': region == 'us-east-1',  # Only in primary region
                        'resourceTypes': []
                    }
                }
            )
            
            # Create delivery channel
            config_client.put_delivery_channel(
                DeliveryChannel={
                    'name': f'SecurityComplianceChannel-{region}',
                    's3BucketName': 'compliance-config-bucket',
                    's3KeyPrefix': f'config/{region}/',
                    'configSnapshotDeliveryProperties': {
                        'deliveryFrequency': 'TwentyFour_Hours'
                    }
                }
            )
            
            # Start configuration recorder
            config_client.start_configuration_recorder(
                ConfigurationRecorderName=f'SecurityComplianceRecorder-{region}'
            )
            
            regional_configs[region] = 'configured'
            
        except Exception as e:
            print(f"Failed to setup Config in {region}: {e}")
            regional_configs[region] = f'failed: {str(e)}'
    
    return regional_configs

Conclusion

AWS Config transforms security compliance from a reactive, manual process into a proactive, automated system. Key takeaways include:

  • Implement organization-wide Config for comprehensive visibility
  • Create custom rules for specific security requirements
  • Enable automated remediation to reduce manual intervention
  • Build comprehensive dashboards for real-time compliance monitoring
  • Generate regular reports for stakeholder communication
  • Use conformance packs for standardized compliance frameworks

Effective Config implementation requires balancing automation with human oversight. While automated remediation can handle routine violations, complex security issues still require human analysis and decision-making.

The patterns shown here provide a foundation for building enterprise-grade compliance systems that scale with your organization's growth while maintaining strong security posture. Remember that compliance is not a destination but an ongoing journey that requires continuous monitoring, improvement, and adaptation to new threats and requirements.

Scaling Compliance Monitoring with AccessLens

While AWS Config provides the foundation for compliance monitoring, managing complex compliance requirements across multiple AWS accounts requires sophisticated analysis and reporting capabilities. This is where AccessLens enhances your compliance program.

AccessLens builds on AWS Config data to provide:

  • Cross-account compliance visibility that aggregates findings across your entire AWS organization
  • Advanced risk analysis that identifies compliance gaps and their business impact
  • Automated compliance reporting that meets audit and regulatory requirements
  • Policy drift detection that alerts you to configuration changes affecting compliance
  • Executive dashboards that communicate compliance status in business terms

Instead of manually correlating Config findings across accounts and services, AccessLens provides unified compliance intelligence that scales with your organization.

Transform your compliance monitoring with AccessLens and move from reactive compliance checking to proactive risk management.

Don't let compliance complexity become a security vulnerability. Get the automated analysis and reporting capabilities you need to maintain compliance at enterprise scale.