AWS Config: Identifying Compliant & Non-Compliant Resources
AWS Config provides a continuous auditing and governance framework that tracks resource inventories, monitors configuration changes, and evaluates compliance against organizational baselines. By integrating AWS Config with custom AWS Lambda functions, devops engineers can automatically detect configuration drift and enforce compliance standards across complex cloud environments.
1. The Core Problem: Maintaining Resource Compliance at Scale
As AWS environments scale into hundreds or thousands of instances, maintaining security standards, operational baselines, and regulatory compliance becomes challenging without automated tooling.
Organizational Compliance Rules
Different domains—such as banking, healthcare, government, and finance—require distinct operational standards:
- Banking/Finance: All storage buckets (S3) must have public access blocked and lifecycle management configured.
- Operational Monitoring: Every Amazon EC2 instance deployed across any region must have detailed monitoring enabled to facilitate immediate root-cause analysis and automated metrics ingestion.
- Resource Tagging: Mandatory key-value tagging (e.g.,
Owner,Environment,CostCenter) across all provisioned resources.
The Manual Auditing Dilemma
Without automation, detecting whether a newly provisioned resource adheres to organizational baselines requires manual inspection. If a developer provisions an EC2 instance without detailed monitoring, that instance is Non-Compliant. Tracking these violations manually across thousands of resources in real time is unsustainable.
2. Understanding AWS Config: Core Mental Model & Architecture
AWS Config continuously monitors and records resource configurations, allowing you to automate the evaluation of recorded configurations against desired baselines.
Real-Life Analogy: The Automated Building Inspector
Imagine a high-security office building with an automated inspector system. Whenever a tenant remodels a room (modifies an AWS resource configuration), the system alerts an inspector (AWS Config). The inspector executes a standardized checklist or calls a specialist (an AWS Lambda function) to check if the room meets safety codes (Organizational Compliance). If the modification violates code, the inspector flags the room as Non-Compliant on the central building dashboard.
3. AWS Config Rules: Managed vs. Custom Rules
AWS Config evaluates resource states using Rules. These rules define the ideal configuration state of your resources.
Evaluation Triggers
Rules evaluate resources based on two distinct trigger types:
- Configuration Changes (Event-Driven): Triggered immediately when a targeted resource is created, updated, or deleted. This allows near-real-time compliance evaluations.
- Periodic (Schedule-Driven): Triggered at fixed time intervals (e.g., every 1 hour, 12 hours, or 24 hours), functioning like a scheduled Cron job.
4. Architectural Event Flow & Vertical Sequence
When using custom evaluation logic, AWS Config triggers a serverless execution flow using AWS Lambda and the Python boto3 SDK.
5. Deep-Dive: Building a Custom Compliance Engine with Python & Boto3
To evaluate complex rules, such as checking whether EC2 detailed monitoring is active, write a custom Python Lambda function using the boto3 library.
JSON Payload Structure Passed by AWS Config
When AWS Config triggers a Lambda function, it passes an event object containing an invokingEvent stringified JSON. This payload includes the resourceId and invocation context:
{
"invokingEvent": "{\"configurationItem\":{\"resourceType\":\"AWS::EC2::Instance\",\"resourceId\":\"i-0123456789abcdef0\",\"configurationItemCaptureTime\":\"2023-10-25T10:00:00.000Z\"}}",
"resultToken": "EXAMPLE_RESULT_TOKEN_STRING"
}
Production-Grade Custom Lambda Rule (Python 3.x)
import json
import boto3
def lambda_handler(event, context):
# Initialize AWS SDK Clients
ec2_client = boto3.client('ec2')
config_client = boto3.client('config')
# Extract invoking event and result token from the AWS Config trigger
invoking_event = json.loads(event['invokingEvent'])
result_token = event['resultToken']
# Extract the target EC2 Instance ID
configuration_item = invoking_event.get('configurationItem', {})
instance_id = configuration_item.get('resourceId')
# Default evaluation state
compliance_type = 'COMPLIANT'
try:
# Fetch operational state of the target instance
response = ec2_client.describe_instances(InstanceIds=[instance_id])
reservations = response.get('Reservations', [])
if reservations:
instances = reservations[0].get('Instances', [])
if instances:
monitoring_state = instances[0].get('Monitoring', {}).get('State')
# Compliance Check: Standard requires monitoring state to be 'enabled'
if monitoring_state != 'enabled':
compliance_type = 'NON_COMPLIANT'
except Exception as e:
print(f"Error describing instance {instance_id}: {str(e)}")
compliance_type = 'NON_COMPLIANT'
# Submit evaluation results back to AWS Config
evaluation_result = {
'ComplianceResourceType': configuration_item.get('resourceType', 'AWS::EC2::Instance'),
'ComplianceResourceId': instance_id,
'ComplianceType': compliance_type,
'OrderingTimestamp': configuration_item.get('configurationItemCaptureTime')
}
config_client.put_evaluations(
Evaluations=[evaluation_result],
ResultToken=result_token
)
return {
'statusCode': 200,
'body': json.dumps(f"Successfully evaluated instance {instance_id} as {compliance_type}")
}
6. Real-World Execution, Step-by-Step Configuration & Troubleshooting
Execution Walkthrough
-
Provision Test Instances:
- Instance A: Provisioned with Detailed Monitoring Enabled.
- Instance B: Provisioned with default monitoring (Detailed Monitoring Disabled).
-
Deploy AWS Config Custom Rule:
- Navigate to AWS Config Rules Add Rule.
- Select Create custom Lambda rule.
- Paste the ARN of your deployed Python Lambda function.
- Under Trigger type, select When configuration changes.
- Set Resource Type to
AWS::EC2::Instance.
-
Verify Compliance Evaluation:
- AWS Config detects both instances.
- Instance A evaluates as
COMPLIANT. - Instance B evaluates as
NON_COMPLIANT.
Production Debugging Scenario: Resolving Lambda Execution Timeouts
During initial execution, AWS Config evaluations may remain stuck in a pending evaluation state or fail to update resource statuses.
Troubleshooting Workflow
-
Detect Evaluation Stalls: Check the
Last Successful Executiontimestamp on the Config Rule page. If the timestamp does not refresh after updating an EC2 instance's monitoring state, check CloudWatch logs. -
Inspect CloudWatch Log Groups: Navigate to AWS CloudWatch Log Groups
/aws/lambda/<your-function-name>. Search for execution logs matching the invocation timestamp. -
Identify Timeout Failures: CloudWatch logs may display the following error:
TEXT2023-10-25T10:00:05.123Z [ERROR] Task timed out after 3.00 seconds
Note: AWS Lambda functions carry a default execution timeout of 3 seconds. Making API calls (e.g.,
ec2.describe_instancesandconfig.put_evaluations) over the network can exceed this 3-second threshold, causing the execution thread to terminate before returning compliance statuses to AWS Config.
Resolution Strategy
- Open the Lambda Function Configuration panel.
- Select General Configuration Edit.
- Increase the Timeout setting from
3 secondsto10 seconds. - Return to AWS Config Rules, select Actions, and click Re-evaluate.
7. Security Best Practices & IAM Policy Considerations
For a Lambda function to evaluate AWS Config compliance rules, its execution role must follow the Principle of Least Privilege.
Initial Development vs. Production IAM Policy Blueprint
During initial setup, developers often attach broad permissions (AmazonEC2FullAccess, AWSConfigRole). For production deployments, narrow down access to explicit API actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2ReadAccess",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances"
],
"Resource": "*"
},
{
"Sid": "ConfigPutEvaluationsAccess",
"Effect": "Allow",
"Action": [
"config:PutEvaluations"
],
"Resource": "*"
},
{
"Sid": "CloudWatchLogging",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
8. Comparative Matrix: Compliance & Evaluation Strategies
Summary and Key Takeaways
- AWS Config Purpose: Acts as a continuous compliance and inventory monitoring engine that tracks configuration state changes across your AWS infrastructure.
- Compliance Definition: Resources are marked as COMPLIANT or NON-COMPLIANT based on whether their recorded state adheres to rules defined by your organization.
- Rule Taxonomy: Supports both AWS Managed Rules (pre-built compliance patterns) and Custom Rules (backed by serverless AWS Lambda code).
- Evaluation Triggers: Rules run dynamically via Configuration Changes (event-driven execution) or Periodic Schedules (cron-like recurring checks).
- Serverless Evaluators: Custom Lambda functions parse event payloads containing resource parameters, perform API checks via Boto3, and send evaluations back using
config_client.put_evaluations(). - Execution Delays: Configuration change evaluations do not always update instantaneously; status propagation routinely takes 1–3 minutes.
- Troubleshooting Timeouts: Increase default Lambda function timeouts beyond
3.0 seconds(e.g., to10 seconds) to prevent termination during multiple outbound AWS API calls. - CloudWatch Integration: Use CloudWatch Log Groups (
/aws/lambda/<function_name>) as your primary operational tool for debugging custom rule invocation failures.