AWS for DevOps — Security Exercises
13.6 — Practice Exercises: Security Best Practices
Test your understanding of GuardDuty, Security Hub, IAM Access Analyzer, KMS, and security automation.
Exercise 1 — Enable the Security Stack
Set up a basic security monitoring stack: enable GuardDuty, Security Hub, IAM Access Analyzer, and CloudTrail in your account.
Show Answer
# 1. Enable GuardDuty
$ aws guardduty create-detector --enable
# 2. Enable Security Hub with default standards
$ aws securityhub enable-security-hub --enable-default-standards
# 3. Create IAM Access Analyzer
$ aws accessanalyzer create-analyzer \
--analyzer-name account-analyzer \
--type ACCOUNT
# 4. Create CloudTrail (if not already enabled)
$ aws cloudtrail create-trail \
--name security-trail \
--s3-bucket-name my-cloudtrail-bucket \
--is-multi-region-trail \
--enable-log-file-validation
$ aws cloudtrail start-logging --name security-trail
Key points:
- Enable these services in every region you use
- GuardDuty + Security Hub = threat detection + centralized view
- IAM Access Analyzer = find overly permissive access
- CloudTrail = complete audit trail
Exercise 2 — Create an Encryption Strategy
Design a KMS encryption strategy for a production application that uses S3, RDS, and Secrets Manager. Create a customer managed key and use it for all three services.
Show Answer
# 1. Create a CMK for production
$ aws kms create-key \
--description "Production encryption key" \
--tags TagKey=Environment,TagValue=production
# Note the KeyId
# 2. Create an alias
$ aws kms create-alias \
--alias-name alias/production-encryption \
--target-key-id KEY_ID
# 3. Enable automatic rotation
$ aws kms enable-key-rotation --key-id KEY_ID
# 4. Use for S3 bucket encryption
$ aws s3api put-bucket-encryption \
--bucket my-production-data \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "alias/production-encryption"
},
"BucketKeyEnabled": true
}]
}'
# 5. Use for RDS (at creation time)
$ aws rds create-db-instance \
--db-instance-identifier prod-db \
--kms-key-id alias/production-encryption \
--storage-encrypted \
# ... other params
# 6. Use for Secrets Manager
$ aws secretsmanager create-secret \
--name myapp/production/db-creds \
--kms-key-id alias/production-encryption \
--secret-string '{"username":"app","password":"..."}'
Key policy should grant access to:
- RDS service role for database encryption
- ECS task role for Secrets Manager decryption
- Application role for S3 read/write
Exercise 3 — Investigate a Security Finding
GuardDuty reports: UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B — a console login from an unusual location. What steps do you take?
Show Answer
Immediate response (first 15 minutes):
- Verify the finding — Check if a team member logged in from that location
$ aws guardduty get-findings --detector-id DID --finding-ids FID - If unauthorized — Disable the IAM user’s console access:
$ aws iam delete-login-profile --user-name compromised-user - Deactivate access keys:
$ aws iam update-access-key --user-name compromised-user \ --access-key-id AKIA... --status Inactive - Attach deny-all policy:
$ aws iam put-user-policy --user-name compromised-user \ --policy-name EmergencyDenyAll \ --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'
Investigation (next 1-2 hours):
- Check CloudTrail for what the attacker did:
$ aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=Username,AttributeValue=compromised-user \ --start-time "2026-03-29T00:00:00Z" - Review created resources — Look for EC2 instances (crypto mining), IAM users, access keys
- Check for data exfiltration — S3 GetObject events, large data transfers
Recovery:
- Reset the user’s password and MFA
- Rotate all secrets the user had access to
- Remove the deny-all policy and re-enable access after investigation
- Document the incident
Exercise 4 — Build Auto-Remediation for Public S3
Create an automated system that detects when an S3 bucket is made public and automatically blocks public access within minutes.
Show Answer
Components needed:
- AWS Config rule:
s3-bucket-public-read-prohibited - EventBridge rule to catch non-compliance
- Lambda function to remediate
EventBridge rule:
$ aws events put-rule \
--name auto-fix-public-s3 \
--event-pattern '{
"source": ["aws.config"],
"detail-type": ["Config Rules Compliance Change"],
"detail": {
"configRuleName": ["s3-bucket-public-read-prohibited"],
"newEvaluationResult": {
"complianceType": ["NON_COMPLIANT"]
}
}
}'
Lambda function logic (Python pseudocode):
def handler(event, context):
bucket_name = event['detail']['resourceId']
# Block all public access
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
# Notify security team
sns.publish(
TopicArn=SECURITY_TOPIC,
Subject=f"Public S3 bucket remediated: {bucket_name}",
Message=f"Bucket {bucket_name} was made public and has been automatically secured."
)
Exercise 5 — IAM Access Analyzer Audit
Run IAM Access Analyzer and describe how you would triage the findings. What’s the difference between intended and unintended external access?
Show Answer
# List all findings
$ aws accessanalyzer list-findings \
--analyzer-arn arn:aws:access-analyzer:ap-south-1:123456789012:analyzer/account-analyzer
Triage process:
| Finding Type | Example | Action |
|---|---|---|
| Unintended public | S3 bucket with Principal: "*" |
Fix immediately — block public access |
| Intended cross-account | Role trusted by partner account | Archive — document the business reason |
| Unintended cross-account | KMS key accessible by unknown account | Investigate — update key policy |
| Overly broad | Lambda accessible by all accounts | Restrict — limit to specific accounts |
For each finding, ask:
- Is this access intentional? → Archive the finding with a reason
- Is this access unintentional? → Remediate (restrict or remove)
- Is this access too broad? → Narrow down (specific accounts, specific actions)
Best practice: Review findings weekly. Archive intentional ones so the dashboard shows only unresolved issues.
Next Chapter → Cost Optimization