🎯 Mục tiêu Task 15: Setup AWS Config - TRACK CHANGES + COMPLIANCE RULES
Task 15 enable governance:
Flow: Resource Changes → Config Recording → Compliance Check → Alerts
AWS Config Console → Get started:
Recorder Settings:
Delivery Channel:
SNS Topic:
Service Role:
CLI Reference:
# Tạo bucket cho Config (optional)
aws s3 mb s3://vinashoes-aws-config-ap-southeast-1 --region ap-southeast-1
Config Console → Rules → Add rule:
Choose AWS Managed Rules:
For each rule:
Advanced Rule Configuration:
# Example: encrypted-volumes rule with parameters
Parameters:
kmsKeyArns: "arn:aws:kms:ap-southeast-1:ACCOUNT:key/KEY-ID"
# Example: restricted-ssh with custom IP ranges
Parameters:
allowedIps: "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
Essential Rules Summary:
Critical Security Rules:
1. S3 bucket public access prohibited (Block public S3 buckets)
2. S3 bucket public write prohibited (Prevent unauthorized writes)
3. SSH restricted to specific IPs (Network security)
4. IAM users no direct policies (Use groups/roles)
5. Root account no access keys (Security best practice)
6. VPC default security group closed (Network isolation)
7. Encrypted volumes (Data at rest encryption)
8. EC2 instances no public IP (Network security)
9. CloudTrail enabled (Audit logging)
10. Multi-region CloudTrail (Comprehensive logging)
11. S3 SSE enabled (Storage encryption)
12. RDS storage encrypted (Database security)
13. Lambda public access prohibited (Function security)
14. API Gateway logging enabled (API monitoring)
15. CloudFormation notifications (Infrastructure monitoring)
Config Console → Rules → [Rule Name] → Actions → Manage remediation:
Automatic Remediation Setup:
Common Remediation Actions:
AWS-EnableS3BucketEncryption - Enable SSE on S3 bucketsAWS-EnableEncryptionOnRDSDBInstance - Enable RDS encryptionAWS-ConfigureS3BucketPublicAccessBlock - Block public accessAWS-EnableCloudTrail - Enable CloudTrail loggingCustom Remediation with SSM Automation:
AutomationDocument:
Name: AWS-ConfigRemediation-EnableS3Versioning
Parameters:
- BucketName: "$.ResourceId"
Actions:
- Name: EnableVersioning
Action: aws:executeAwsApi
Inputs:
Service: s3
Api: PutBucketVersioning
Bucket: "{{BucketName}}"
VersioningConfiguration:
Status: Enabled
Rule Interaction Matrix:
Rule Dependencies:
- cloudtrail-enabled → multi-region-cloudtrail-enabled
- s3-bucket-public-read-prohibited → s3-bucket-public-write-prohibited
Rule Conflicts:
- ec2-instance-no-public-ip ↔ vpc-default-security-group-closed
- encrypted-volumes ↔ rds-storage-encrypted (different services)
Resolution Strategies:
🐳 Custom Rule: ECR Internal Images ECS tasks chỉ được dùng images từ ECR nội bộ để đảm bảo security và compliance
Lambda Console → Create function:
Advanced Function Code:
import json
import boto3
import re
from botocore.exceptions import ClientError
def lambda_handler(event, context):
config = boto3.client('config')
ecr = boto3.client('ecr')
configuration_item = event['configurationItem']
compliance_type = 'COMPLIANT'
annotation = 'ECS task definition uses approved ECR images'
if configuration_item['resourceType'] == 'AWS::ECS::TaskDefinition':
task_definition = json.loads(configuration_item['configuration'])
account_id = event['accountId']
region = event['region']
# Get approved repositories
try:
approved_repos = ecr.describe_repositories(
repositoryName='vinashoes-*'
)['repositories']
approved_repo_names = [repo['repositoryName'] for repo in approved_repos]
except ClientError:
approved_repo_names = ['vinashoes-web', 'vinashoes-api', 'vinashoes-worker']
for container in task_definition.get('containerDefinitions', []):
image = container.get('image', '')
# Check if image is from approved ECR
expected_pattern = f"{account_id}\.dkr\.ecr\.{region}\.amazonaws\.com/({'|'.join(approved_repo_names)})"
if not re.match(expected_pattern, image):
compliance_type = 'NON_COMPLIANT'
annotation = f'Container {container["name"]} uses non-approved image: {image}'
break
# Additional checks: tag validation
if ':' not in image or image.endswith(':latest'):
compliance_type = 'NON_COMPLIANT'
annotation = f'Container {container["name"]} uses latest tag or no tag: {image}'
break
evaluation = {
'ComplianceResourceType': configuration_item['resourceType'],
'ComplianceResourceId': configuration_item['resourceId'],
'ComplianceType': compliance_type,
'Annotation': annotation,
'OrderingTimestamp': configuration_item['configurationItemCaptureTime']
}
config.put_evaluations(
Evaluations=[evaluation],
ResultToken=event['resultToken']
)
return {'statusCode': 200}
Lambda Function: config-security-group-compliance
def lambda_handler(event, context):
config = boto3.client('config')
ec2 = boto3.client('ec2')
configuration_item = event['configurationItem']
if configuration_item['resourceType'] == 'AWS::EC2::SecurityGroup':
sg_id = configuration_item['resourceId']
# Get security group details
sg_details = ec2.describe_security_groups(GroupIds=[sg_id])['SecurityGroups'][0]
compliance_type = 'COMPLIANT'
violations = []
# Check for overly permissive rules
for permission in sg_details.get('IpPermissions', []):
if permission.get('IpProtocol') == '-1': # All traffic
violations.append('All traffic allowed')
for ip_range in permission.get('IpRanges', []):
if ip_range.get('CidrIp') == '0.0.0.0/0':
violations.append(f'Port {permission.get("FromPort", "N/A")} open to world')
if violations:
compliance_type = 'NON_COMPLIANT'
annotation = f'Security violations: {", ".join(violations)}'
else:
annotation = 'Security group follows best practices'
# Submit evaluation
evaluation = {
'ComplianceResourceType': configuration_item['resourceType'],
'ComplianceResourceId': configuration_item['resourceId'],
'ComplianceType': compliance_type,
'Annotation': annotation,
'OrderingTimestamp': configuration_item['configurationItemCaptureTime']
}
config.put_evaluations(Evaluations=[evaluation], ResultToken=event['resultToken'])
return {'statusCode': 200}
Lambda Function: config-cost-optimization
def lambda_handler(event, context):
config = boto3.client('config')
configuration_item = event['configurationItem']
compliance_type = 'COMPLIANT'
annotation = 'Resource follows cost optimization practices'
if configuration_item['resourceType'] == 'AWS::EC2::Instance':
instance_config = json.loads(configuration_item['configuration'])
# Check instance type
instance_type = instance_config.get('instanceType', '')
if instance_type.startswith(('t2.', 't3.')) and instance_config.get('state', {}).get('name') == 'running':
# Check if instance has been running for more than 24 hours
launch_time = instance_config.get('launchTime')
if launch_time:
import datetime
launch_dt = datetime.datetime.fromisoformat(launch_time.replace('Z', '+00:00'))
now = datetime.datetime.now(datetime.timezone.utc)
runtime = now - launch_dt
if runtime.days > 1:
compliance_type = 'NON_COMPLIANT'
annotation = f'Burstable instance {instance_type} running for {runtime.days} days - consider reserved instance'
evaluation = {
'ComplianceResourceType': configuration_item['resourceType'],
'ComplianceResourceId': configuration_item['resourceId'],
'ComplianceType': compliance_type,
'Annotation': annotation,
'OrderingTimestamp': configuration_item['configurationItemCaptureTime']
}
config.put_evaluations(Evaluations=[evaluation], ResultToken=event['resultToken'])
return {'statusCode': 200}
Advanced Compliance Frameworks:
# conformance-pack.yaml
Resources:
- AWSConfigRule:
Properties:
ConfigRuleName: s3-bucket-encryption-enabled
Description: Checks that S3 buckets have encryption enabled
Source:
Owner: AWS
SourceIdentifier: S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED
Scope:
ComplianceResourceTypes:
- AWS::S3::Bucket
- AWSConfigRule:
Properties:
ConfigRuleName: ec2-instance-detailed-monitoring-enabled
Description: Checks that EC2 instances have detailed monitoring enabled
Source:
Owner: AWS
SourceIdentifier: EC2_INSTANCE_DETAILED_MONITORING_ENABLED
# Upload to S3
aws s3 cp conformance-pack.yaml s3://vinashoes-config-conformance-packs/
# Deploy pack
aws configservice put-conformance-pack \
--conformance-pack-name VinaShoesSecurityPack \
--template-s3-uri s3://vinashoes-config-conformance-packs/conformance-pack.yaml \
--delivery-s3-bucket vinashoes-aws-config-ap-southeast-1
Test Custom Rules:
# Test Lambda function locally
aws lambda invoke \
--function-name config-ecr-internal-images \
--payload '{"test": "data"}' \
output.json
# Validate Config rule
aws configservice describe-config-rules \
--config-rule-names ecr-internal-images-only
# Test rule evaluation
aws configservice start-config-rules-evaluation \
--config-rule-names ecr-internal-images-only
CLI Reference:
# Deploy Lambda function
aws lambda create-function \
--function-name config-ecr-internal-images \
--runtime python3.9 \
--role arn:aws:iam::ACCOUNT:role/lambda-config-role \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip
# Create Config rule
aws configservice put-config-rule \
--config-rule '{
"ConfigRuleName": "ecr-internal-images-only",
"Source": {
"Owner": "AWS_LAMBDA",
"SourceIdentifier": "arn:aws:lambda:ap-southeast-1:ACCOUNT:function:config-ecr-internal-images"
},
"Scope": {
"ComplianceResourceTypes": ["AWS::ECS::TaskDefinition"]
}
}'
CloudWatch Console → Events → Rules → Create rule:
Event Source:
Advanced Event Pattern:
{
"source": ["aws.config"],
"detail-type": ["Config Rules Compliance Change"],
"detail": {
"newEvaluationResult": {
"complianceType": ["NON_COMPLIANT"]
},
"configRuleName": [
"s3-bucket-public-read-prohibited",
"iam-user-no-policies-check",
"root-access-key-check"
]
}
}
CloudWatch Console → Dashboards → Create dashboard:
Dashboard Name: VinaShoesCompliance
Compliance Overview Widget:
{
"type": "metric",
"properties": {
"metrics": [
["AWS/Config", "ComplianceByConfigRule", "ConfigRuleName", "s3-bucket-public-read-prohibited", "ComplianceType", "NON_COMPLIANT"],
[".", ".", ".", "iam-user-no-policies-check", ".", "."],
[".", ".", ".", "root-access-key-check", ".", "."]
],
"view": "timeSeries",
"stacked": false,
"region": "ap-southeast-1",
"title": "Critical Security Violations"
}
}
Resource Inventory Widget:
Trend Analysis Widget:
Security Hub Console → Integrations → AWS Config:
aws securityhub enable-security-hub
# Enable Config findings in Security Hub
aws securityhub batch-enable-standards \
--standards-subscription-requests '[
{"StandardsArn": "arn:aws:securityhub:ap-southeast-1::standards/aws-foundations-benchmark/v/1.2.0"}
]'
AWS Organizations Setup:
aws configservice put-organization-config-rule \
--organization-config-rule-name s3-bucket-public-read-prohibited \
--trigger-types ConfigurationItemChangeNotification \
--description "Checks that S3 buckets do not allow public read access"
aws organizations register-delegated-administrator \
--account-id DELEGATED_ACCOUNT_ID \
--service-principal config.amazonaws.com
SNS Topic Configuration:
{
"TopicName": "vinashoes-config-alerts",
"Attributes": {
"DeliveryPolicy": "{\"healthyRetryPolicy\":{\"numRetries\":3}}",
"DisplayName": "Config Compliance Alerts"
},
"Subscriptions": [
{
"Protocol": "email",
"Endpoint": "[email protected]"
},
{
"Protocol": "https",
"Endpoint": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
}
]
}
Escalation Rules:
Lambda Console → Create function:
Basic Information:
Advanced Function Code:
import boto3
import json
from botocore.exceptions import ClientError
def lambda_handler(event, context):
s3 = boto3.client('s3')
config = boto3.client('config')
# Parse Config event
detail = event.get('detail', {})
resource_id = detail.get('resourceId')
config_rule_name = detail.get('configRuleName')
remediation_actions = {
's3-bucket-public-read-prohibited': remediate_s3_public_access,
's3-bucket-server-side-encryption-enabled': remediate_s3_encryption,
'vpc-default-security-group-closed': remediate_default_sg
}
if config_rule_name in remediation_actions:
try:
result = remediation_actions[config_rule_name](resource_id)
print(f"Remediation successful for {config_rule_name}: {resource_id}")
return {'statusCode': 200, 'body': json.dumps(result)}
except Exception as e:
print(f"Remediation failed for {config_rule_name}: {str(e)}")
# Send alert for failed remediation
send_remediation_alert(config_rule_name, resource_id, str(e))
return {'statusCode': 500, 'body': json.dumps({'error': str(e)})}
return {'statusCode': 400, 'body': json.dumps({'error': 'Unsupported rule'})}
def remediate_s3_public_access(bucket_name):
s3 = boto3.client('s3')
# Block all public access
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
# Remove existing public policies
try:
policy = s3.get_bucket_policy(Bucket=bucket_name)
# Analyze and remove public statements
policy_doc = json.loads(policy['Policy'])
filtered_statements = []
for statement in policy_doc.get('Statement', []):
if is_public_statement(statement):
continue # Skip public statements
filtered_statements.append(statement)
if filtered_statements:
policy_doc['Statement'] = filtered_statements
s3.put_bucket_policy(Bucket=bucket_name, Policy=json.dumps(policy_doc))
else:
s3.delete_bucket_policy(Bucket=bucket_name)
except ClientError:
pass # No policy to remove
return {'remediated': bucket_name, 'action': 'blocked_public_access'}
def remediate_s3_encryption(bucket_name):
s3 = boto3.client('s3')
s3.put_bucket_encryption(
Bucket=bucket_name,
ServerSideEncryptionConfiguration={
'Rules': [{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'AES256'
},
'BucketKeyEnabled': True
}]
}
)
return {'remediated': bucket_name, 'action': 'enabled_encryption'}
def remediate_default_sg(sg_id):
ec2 = boto3.client('ec2')
# Remove all inbound rules from default security group
ec2.revoke_security_group_ingress(
GroupId=sg_id,
IpPermissions=[{
'IpProtocol': '-1' # All protocols
}]
)
return {'remediated': sg_id, 'action': 'closed_default_sg'}
def is_public_statement(statement):
"""Check if IAM policy statement allows public access"""
principal = statement.get('Principal', '')
if principal == '*' or principal == {'AWS': '*'}:
return True
# Check conditions for public access
conditions = statement.get('Condition', {})
if not conditions:
return True
# More complex logic for conditional public access
return False
def send_remediation_alert(rule_name, resource_id, error):
sns = boto3.client('sns')
sns.publish(
TopicArn='arn:aws:sns:ap-southeast-1:ACCOUNT:vinashoes-config-alerts',
Subject=f'Config Remediation Failed: {rule_name}',
Message=f'Failed to remediate {resource_id}\nError: {error}'
)
Create Automation Document:
description: Remediate non-compliant EC2 instances
schemaVersion: '0.3'
parameters:
InstanceId:
type: String
description: The ID of the EC2 instance to remediate
AutomationAssumeRole:
type: String
description: The ARN of the role that allows Automation to perform the actions
mainSteps:
- name: StopInstance
action: aws:executeAwsApi
inputs:
Service: ec2
Api: StopInstances
InstanceIds:
- '{{InstanceId}}'
description: Stop the non-compliant instance
- name: CreateImage
action: aws:executeAwsApi
inputs:
Service: ec2
Api: CreateImage
InstanceId: '{{InstanceId}}'
Name: 'remediated-{{InstanceId}}-{{global:DATE_TIME}}'
description: Create an AMI before remediation
- name: TerminateInstance
action: aws:executeAwsApi
inputs:
Service: ec2
Api: TerminateInstances
InstanceIds:
- '{{InstanceId}}'
description: Terminate the non-compliant instance
AWS Step Functions for Approval:
{
"Comment": "Config Remediation Approval Workflow",
"StartAt": "CheckSeverity",
"States": {
"CheckSeverity": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.severity",
"StringEquals": "CRITICAL",
"Next": "AutoRemediate"
}
],
"Default": "ManualApproval"
},
"AutoRemediate": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "config-s3-auto-remediation"
},
"End": true
},
"ManualApproval": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "arn:aws:sns:ap-southeast-1:ACCOUNT:remediation-approval",
"Message": "Config violation requires approval for remediation"
},
"End": true
}
}
}
CloudWatch Alarms for Remediation:
# Alarm for failed remediations
aws cloudwatch put-metric-alarm \
--alarm-name ConfigRemediationFailures \
--alarm-description "Alert when Config remediation fails" \
--metric-name RemediationFailureCount \
--namespace AWS/Config \
--statistic Sum \
--period 300 \
--threshold 1 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1
Remediation Success Dashboard:
Create Config Aggregator:
# In management account
aws configservice put-configuration-aggregator \
--configuration-aggregator-name VinaShoesOrgAggregator \
--organization-source \
OrganizationSourceType=ORGANIZATION \
RoleArn=arn:aws:iam::MANAGEMENT_ACCOUNT:role/ConfigAggregatorRole
Aggregator Permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Config Console → Advanced queries:
SELECT
resourceId,
resourceType,
configuration.instanceType,
configuration.state.name
WHERE
resourceType = 'AWS::EC2::Instance'
AND configuration.state.name = 'running'
AND configuration.instanceType LIKE 't2.%'
ORDER BY
configuration.launchTime DESC
Install RDK:
pip install rdk
Create Custom Rule:
rdk create ec2-instance-tags-check --runtime python3.9 --resource-types AWS::EC2::Instance
# Edit rule code in rules/ec2-instance-tags-check/ec2-instance-tags-check.py
rdk deploy ec2-instance-tags-check
Control Tower Preventive Controls:
Custom Controls:
# Landing Zone customizations
OrganizationalUnits:
- Name: Security
Controls:
- ControlIdentifier: CONFIG_RULE
Parameters:
RuleName: s3-bucket-public-read-prohibited
RuleParameters:
- Key: severity
Value: CRITICAL
Issue: Config recorder not recording changes
# Check recorder status
aws configservice describe-configuration-recorders
# Check IAM permissions
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::ACCOUNT:role/ConfigRole \
--action-names config:PutConfigurationRecorder
Issue: Rules not evaluating
# Force rule evaluation
aws configservice start-config-rules-evaluation \
--config-rule-names RULE_NAME
# Check rule status
aws configservice describe-config-rule-evaluation-status \
--config-rule-names RULE_NAME
Issue: High Config costs
Config Recorder Optimization:
# Selective recording configuration
RecordingGroup:
AllSupported: false
IncludeGlobalResourceTypes: true
ResourceTypes:
- AWS::EC2::Instance
- AWS::S3::Bucket
- AWS::IAM::Role
ExcludeResourceTypes:
- AWS::Config::ResourceCompliance
Rule Performance Tuning:
Config Security Hardening:
Data Protection:
Advanced Monitoring Setup:
# Config delivery failed alarm
aws cloudwatch put-metric-alarm \
--alarm-name ConfigDeliveryFailed \
--alarm-description "Config delivery to S3 failed" \
--metric-name ConfigDeliveryFailed \
--namespace AWS/Config \
--statistic Maximum \
--period 3600 \
--threshold 1 \
--comparison-operator GreaterThanThreshold
Compliance Trend Analysis:
⚠️ Cảnh báo: Việc clean up sẽ xóa tất cả Config rules, recorder và data. Hãy đảm bảo không còn cần thiết trước khi thực hiện!
Xóa Config rules:
# Xóa managed rules
aws configservice delete-config-rule --config-rule-name s3-bucket-public-read-prohibited
aws configservice delete-config-rule --config-rule-name s3-bucket-public-write-prohibited
aws configservice delete-config-rule --config-rule-name restricted-ssh
aws configservice delete-config-rule --config-rule-name iam-user-no-policies-check
aws configservice delete-config-rule --config-rule-name root-access-key-check
aws configservice delete-config-rule --config-rule-name vpc-default-security-group-closed
# Xóa custom rule
aws configservice delete-config-rule --config-rule-name ecr-internal-images-only
Xóa Lambda functions:
# Xóa Lambda functions
aws lambda delete-function --function-name config-ecr-internal-images
aws lambda delete-function --function-name config-s3-auto-remediation
Disable Config recorder:
# Stop configuration recorder
aws configservice stop-configuration-recorder --configuration-recorder-name default
# Delete configuration recorder
aws configservice delete-configuration-recorder --configuration-recorder-name default
Xóa S3 bucket và SNS topic:
# Xóa tất cả objects trong Config bucket
aws s3 rm s3://vinashoes-aws-config-ap-southeast-1 --recursive
# Xóa bucket
aws s3 rb s3://vinashoes-aws-config-ap-southeast-1
# Xóa SNS topic
aws sns delete-topic --topic-arn arn:aws:sns:ap-southeast-1:ACCOUNT:vinashoes-config-notifications
📋 Lưu ý khi clean up:
💰 Advanced Cost Analysis for AWS Config
| Cost Component | Pricing | Factors | Monthly Estimate |
|---|---|---|---|
| Configuration Items | $0.003/item | Resource changes, evaluations | $50-200 |
| Configuration Recorder | Free | Base service | $0 |
| S3 Storage | $0.023/GB | History retention (1 year) | $10-50 |
| Lambda Invocations | $0.20/1M requests | Custom rules | $5-20 |
| CloudWatch Events | Free | Event delivery | $0 |
| SNS Notifications | $0.50/100K requests | Alerts | $1-5 |
| Data Transfer | $0.09/GB | Cross-region replication | $5-15 |
Retention Policy Optimization:
# Set retention period to 1 year instead of indefinite
aws configservice put-retention-configuration \
--retention-period-in-days 365
Selective Recording Configuration:
# Only record critical resources
RecordingGroup:
AllSupported: false
ResourceTypes:
- AWS::EC2::Instance
- AWS::S3::Bucket
- AWS::RDS::DBInstance
- AWS::Lambda::Function
ExcludeResourceTypes:
- AWS::EC2::NetworkInterface
- AWS::EC2::Volume
- AWS::CloudWatch::Alarm
Rule Evaluation Optimization:
Config Cost Dashboard:
# CloudWatch metrics for Config costs
aws cloudwatch get-metric-statistics \
--namespace AWS/Config \
--metric-name ConfigurationItemsRecorded \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-31T23:59:59Z \
--period 86400 \
--statistics Sum
Cost Anomaly Detection:
| Metric | Without Config | With Config | Advanced Benefits |
|---|---|---|---|
| Security Incidents | High risk | Low risk | Automated prevention |
| Compliance Violations | Unknown | Monitored | Real-time detection |
| Audit Preparation | Manual (weeks) | Automated (hours) | 90% time reduction |
| Configuration Drift | Uncontrolled | Tracked | Immediate alerts |
| Remediation Time | Days | Minutes | 99% faster response |
| Annual Cost | $0 | $500 | Cost of security vs breaches |
Startup (10-50 resources):
Small Business (50-200 resources):
Enterprise (200+ resources):
Enterprise (1000+ resources):
Quantitative Benefits:
Qualitative Benefits:
Break-even Analysis:
⚠️ Cảnh báo: Việc clean up sẽ xóa tất cả Config rules, recorder và data. Hãy đảm bảo không còn cần thiết trước khi thực hiện!
Create cleanup script:
#!/bin/bash
# AWS Config Complete Cleanup Script
# Run with caution - this will remove all Config resources
echo "Starting AWS Config cleanup..."
# 1. Delete all Config rules
echo "Deleting Config rules..."
RULES=$(aws configservice describe-config-rules --query 'ConfigRules[].ConfigRuleName' --output text)
for RULE in $RULES; do
echo "Deleting rule: $RULE"
aws configservice delete-config-rule --config-rule-name "$RULE"
done
# 2. Delete Conformance Packs
echo "Deleting Conformance Packs..."
PACKS=$(aws configservice describe-conformance-packs --query 'ConformancePackNames' --output text)
for PACK in $PACKS; do
echo "Deleting conformance pack: $PACK"
aws configservice delete-conformance-pack --conformance-pack-name "$PACK"
done
# 3. Delete Organization Config Rules (if applicable)
echo "Deleting Organization Config Rules..."
ORG_RULES=$(aws configservice describe-organization-config-rules --query 'OrganizationConfigRules[].OrganizationConfigRuleName' --output text 2>/dev/null || echo "")
for ORG_RULE in $ORG_RULES; do
echo "Deleting org rule: $ORG_RULE"
aws configservice delete-organization-config-rule --organization-config-rule-name "$ORG_RULE"
done
# 4. Stop and delete Configuration Recorder
echo "Stopping Configuration Recorder..."
aws configservice stop-configuration-recorder --configuration-recorder-name default
echo "Deleting Configuration Recorder..."
aws configservice delete-configuration-recorder --configuration-recorder-name default
# 5. Delete Config Aggregator (if exists)
echo "Deleting Config Aggregator..."
AGGREGATORS=$(aws configservice describe-configuration-aggregators --query 'ConfigurationAggregators[].ConfigurationAggregatorName' --output text 2>/dev/null || echo "")
for AGG in $AGGREGATORS; do
echo "Deleting aggregator: $AGG"
aws configservice delete-configuration-aggregator --configuration-aggregator-name "$AGG"
done
# 6. Delete Lambda functions
echo "Deleting Lambda functions..."
LAMBDAS="config-ecr-internal-images config-s3-auto-remediation config-security-group-compliance config-cost-optimization"
for LAMBDA in $LAMBDAS; do
if aws lambda get-function --function-name "$LAMBDA" &>/dev/null; then
echo "Deleting Lambda: $LAMBDA"
aws lambda delete-function --function-name "$LAMBDA"
fi
done
# 7. Delete CloudWatch Events rules
echo "Deleting CloudWatch Events rules..."
RULES="ConfigComplianceChange ConfigRemediationApproval"
for RULE in $RULES; do
if aws events describe-rule --name "$RULE" &>/dev/null; then
echo "Deleting Event Rule: $RULE"
aws events delete-rule --name "$RULE"
fi
done
# 8. Delete SNS Topics
echo "Deleting SNS Topics..."
TOPICS="vinashoes-config-notifications vinashoes-config-alerts remediation-approval"
for TOPIC in $TOPICS; do
TOPIC_ARN=$(aws sns list-topics --query "Topics[?contains(TopicArn, '$TOPIC')].TopicArn" --output text)
if [ -n "$TOPIC_ARN" ]; then
echo "Deleting SNS Topic: $TOPIC"
aws sns delete-topic --topic-arn "$TOPIC_ARN"
fi
done
# 9. Delete S3 bucket (CAUTION: Contains historical data)
BUCKET="vinashoes-aws-config-ap-southeast-1"
echo "WARNING: About to delete S3 bucket $BUCKET containing Config history!"
read -p "Are you sure you want to delete the Config history bucket? (yes/no): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Deleting S3 bucket: $BUCKET"
aws s3 rb s3://"$BUCKET" --force
else
echo "Skipping S3 bucket deletion"
fi
# 10. Delete IAM Roles
echo "Deleting IAM Roles..."
ROLES="VinaShoesConfigRole ConfigAggregatorRole config-lambda-role"
for ROLE in $ROLES; do
if aws iam get-role --role-name "$ROLE" &>/dev/null; then
echo "Deleting IAM Role: $ROLE"
# Detach all policies first
POLICIES=$(aws iam list-attached-role-policies --role-name "$ROLE" --query 'AttachedPolicies[].PolicyArn' --output text)
for POLICY in $POLICIES; do
aws iam detach-role-policy --role-name "$ROLE" --policy-arn "$POLICY"
done
# Delete role
aws iam delete-role --role-name "$ROLE"
fi
done
# 11. Clean up CloudWatch resources
echo "Cleaning up CloudWatch resources..."
DASHBOARDS="VinaShoesCompliance"
ALARMS="ConfigDeliveryFailed ConfigRemediationFailures ConfigComplianceViolation"
for DASH in $DASHBOARDS; do
if aws cloudwatch describe-dashboards --dashboard-name "$DASH" &>/dev/null; then
echo "Deleting Dashboard: $DASH"
aws cloudwatch delete-dashboards --dashboard-names "$DASH"
fi
done
for ALARM in $ALARMS; do
if aws cloudwatch describe-alarms --alarm-names "$ALARM" &>/dev/null; then
echo "Deleting Alarm: $ALARM"
aws cloudwatch delete-alarms --alarm-names "$ALARM"
fi
done
echo "AWS Config cleanup completed!"
echo "Note: Some resources may take time to fully delete."
Delete specific rules:
# Delete single rule
aws configservice delete-config-rule --config-rule-name s3-bucket-public-read-prohibited
# Delete multiple rules
aws configservice delete-config-rule --config-rule-name rule1
aws configservice delete-config-rule --config-rule-name rule2
Clean up Lambda functions:
# List all Config-related Lambdas
aws lambda list-functions --query 'Functions[?contains(FunctionName, `config-`)]'
# Delete specific function
aws lambda delete-function --function-name config-s3-auto-remediation
Clean up CloudWatch resources:
# Delete specific alarm
aws cloudwatch delete-alarms --alarm-names ConfigDeliveryFailed
# Delete dashboard
aws cloudwatch delete-dashboards --dashboard-names VinaShoesCompliance
Before Cleanup:
Data Recovery Options:
📋 Lưu ý quan trọng khi clean up: