AWS Security, Governance, and Compliance: Foundational Controls Lab
AWS Cloud security, governance, and compliance concepts
AWS Security, Governance, and Compliance: Foundational Controls Lab
Welcome to this hands-on lab covering Domain 2 of the AWS Certified Cloud Practitioner (CLF-C02) exam. In this lab, you will apply the AWS Shared Responsibility Model by implementing critical security and compliance controls "IN" the cloud. You will enable threat detection, enforce encryption at rest, configure public access blocks, and practice least-privilege IAM policies.
Prerequisites
Before starting this lab, ensure you have the following:
- AWS Account: Access to an AWS account with Administrator privileges.
- AWS CLI Installed: The AWS Command Line Interface installed and configured on your local machine.
- IAM Credentials: Your CLI must be authenticated using
aws configurewith an Access Key and Secret Access Key. - Prior Knowledge: Basic understanding of Amazon S3, IAM, and the concepts of encryption.
Learning Objectives
By completing this lab, you will be able to:
- Enable and interpret findings in Amazon GuardDuty (Continuous Threat Detection).
- Secure an Amazon S3 bucket using Server-Side Encryption (Encryption at Rest) and Public Access Blocks.
- Implement IAM least-privilege access management for cloud resources.
- Understand the practical application of the AWS Shared Responsibility Model.
Architecture Overview
The following diagrams illustrate the infrastructure you will build and how it maps to the AWS Shared Responsibility Model.
Lab Infrastructure
AWS Shared Responsibility Context
Step-by-Step Instructions
Step 1: Enable Amazon GuardDuty for Threat Detection
Amazon GuardDuty is an intelligent threat detection service that continuously monitors for malicious activity and unauthorized behavior. As a customer, enabling it fulfills your responsibility to monitor your AWS environment.
# Enable GuardDuty in your current region and capture the detector ID
aws guardduty create-detector --enable
# Note the detectorId from the output. Replace <DETECTOR_ID> below with your ID.
aws guardduty create-sample-findings --detector-id <DETECTOR_ID>[!TIP] Generating sample findings populates the GuardDuty console with mock data (like simulated Bitcoin mining or unauthorized API calls) so you can see what actual threats look like without needing a real security incident.
▶Console alternative
- Navigate to the GuardDuty console.
- Click Get Started and then click Enable GuardDuty.
- In the left navigation pane, choose Settings.
- Scroll down to Sample findings and click Generate sample findings.
- Go back to the Findings page in the left pane to view the generated threats.
📸 Screenshot: A list of findings with severity tags (High, Medium, Low).
Step 2: Create a Secure, Encrypted S3 Bucket
Data security requires "Encryption at Rest." We will create an S3 bucket, enable default AES-256 encryption, and apply a strict "Block Public Access" configuration.
Note: Replace <YOUR_ACCOUNT_ID> with your actual 12-digit AWS account number to ensure the bucket name is globally unique.
# 1. Create the bucket
aws s3api create-bucket \
--bucket brainybee-secure-data-<YOUR_ACCOUNT_ID> \
--region us-east-1
# 2. Enable Default Server-Side Encryption (AES256)
aws s3api put-bucket-encryption \
--bucket brainybee-secure-data-<YOUR_ACCOUNT_ID> \
--server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
# 3. Block All Public Access (Governance & Compliance)
aws s3api put-public-access-block \
--bucket brainybee-secure-data-<YOUR_ACCOUNT_ID> \
--public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"▶Console alternative
- Navigate to the S3 console and click Create bucket.
- Enter
brainybee-secure-data-<YOUR_ACCOUNT_ID>for the Bucket name. - In the Block Public Access settings for this bucket section, ensure Block all public access is CHECKED.
- Scroll to Default encryption, ensure Server-side encryption is Enabled, and Encryption key type is Amazon S3 managed keys (SSE-S3).
- Click Create bucket.
📸 Screenshot: The S3 bucket creation screen highlighting the "Block all public access" checkbox.
Step 3: Implement Least Privilege with IAM
Identity and Access Management (IAM) is a core piece of the customer's shared responsibility. We will create a policy that grants only read access to the specific S3 bucket you just created.
# 1. Create the policy JSON file locally
cat <<EOF > s3-read-only-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::brainybee-secure-data-<YOUR_ACCOUNT_ID>",
"arn:aws:s3:::brainybee-secure-data-<YOUR_ACCOUNT_ID>/*"
]
}
]
}
EOF
# 2. Create the IAM Policy in AWS
aws iam create-policy \
--policy-name BrainyBeeS3ReadOnly \
--policy-document file://s3-read-only-policy.json▶Console alternative
- Navigate to the IAM console.
- In the left navigation pane, choose Policies, then click Create policy.
- Switch to the JSON tab and paste the JSON from the code block above (ensure you replace
<YOUR_ACCOUNT_ID>). - Click Next, name the policy
BrainyBeeS3ReadOnly, and click Create policy.
📸 Screenshot: The IAM visual editor showing "Limited: Read" access to a specific S3 resource.
Checkpoints
Verify that your configurations were applied correctly by running the following commands:
Checkpoint 1: Verify GuardDuty is Active
aws guardduty list-detectors
# Expected result: A JSON array containing your active DetectorId.Checkpoint 2: Verify S3 Encryption is Applied
aws s3api get-bucket-encryption --bucket brainybee-secure-data-<YOUR_ACCOUNT_ID>
# Expected result: JSON output showing "SSEAlgorithm": "AES256".Checkpoint 3: Verify Public Access is Blocked
aws s3api get-public-access-block --bucket brainybee-secure-data-<YOUR_ACCOUNT_ID>
# Expected result: JSON output showing all four Block/Ignore rules set to "true".Troubleshooting
| Error Message / Issue | Likely Cause | Solution |
|---|---|---|
BucketNameAlreadyExists | Another AWS user already took this S3 bucket name. | Ensure you appended your unique 12-digit AWS Account ID to the bucket name. |
AccessDenied when creating the IAM Policy | Your CLI user lacks IAM permissions. | Verify you are using credentials for a user with AdministratorAccess or IAMFullAccess. |
An error occurred (BadRequestException) in GuardDuty | GuardDuty might already be enabled in this region. | Run aws guardduty list-detectors to get the existing Detector ID instead of creating a new one. |
Clean-Up / Teardown
[!WARNING] Cost Warning: Amazon GuardDuty offers a 30-day free trial. If left running after the trial, you will incur ongoing charges based on the volume of CloudTrail and VPC Flow Logs analyzed. Run these teardown commands to avoid unexpected costs.
Execute the following commands to delete all resources provisioned in this lab:
# 1. Delete the IAM Policy (Replace <YOUR_ACCOUNT_ID>)
aws iam delete-policy --policy-arn arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/BrainyBeeS3ReadOnly
# 2. Delete the S3 Bucket (Bucket must be empty first!)
aws s3 rm s3://brainybee-secure-data-<YOUR_ACCOUNT_ID> --recursive
aws s3api delete-bucket --bucket brainybee-secure-data-<YOUR_ACCOUNT_ID>
# 3. Disable and Delete GuardDuty (Replace <DETECTOR_ID> with your detector ID)
aws guardduty delete-detector --detector-id <DETECTOR_ID>
# 4. Remove local file
rm s3-read-only-policy.json[!NOTE] If you enabled GuardDuty via the console, you can disable it by navigating to GuardDuty > Settings > Suspend or Disable GuardDuty and clicking Disable GuardDuty.