AWS for DevOps — Security Exercises

3 minute read

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):

  1. Verify the finding — Check if a team member logged in from that location
    $ aws guardduty get-findings --detector-id DID --finding-ids FID
    
  2. If unauthorized — Disable the IAM user’s console access:
    $ aws iam delete-login-profile --user-name compromised-user
    
  3. Deactivate access keys:
    $ aws iam update-access-key --user-name compromised-user \
        --access-key-id AKIA... --status Inactive
    
  4. 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):

  1. 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"
    
  2. Review created resources — Look for EC2 instances (crypto mining), IAM users, access keys
  3. Check for data exfiltration — S3 GetObject events, large data transfers

Recovery:

  1. Reset the user’s password and MFA
  2. Rotate all secrets the user had access to
  3. Remove the deny-all policy and re-enable access after investigation
  4. 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:

  1. AWS Config rule: s3-bucket-public-read-prohibited
  2. EventBridge rule to catch non-compliance
  3. 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:

  1. Is this access intentional? → Archive the finding with a reason
  2. Is this access unintentional? → Remediate (restrict or remove)
  3. 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

Updated: