1. Overview & Scenario
๐ข The Scenario
A small company called CloudNova is onboarding a new development team. You are the cloud administrator. Your job is to set up secure access, enforce least privilege, and verify the setup using the AWS CLI.
Two new hires โ alex.dev
and priya.dev โ
need accounts grouped together, a strong password policy, MFA, and just enough permissions to do their jobs.
๐ฏ Your Mission
- โธ Explore AWS Regions & AZs
- โธ Build IAM groups, users, and policies
- โธ Enforce strong passwords + MFA
- โธ Grant least-privilege access to S3
- โธ Create an EC2 role + instance profile
- โธ Audit everything with credential reports
"Least privilege is not a one-time task โ it is a continuous discipline of granting only the permissions required to perform a task."
2. Learning Objectives
Explore Global Infrastructure
Use CLI to list Regions and AZs, understanding where your workloads live.
Create Group, User & Password Policy
Set up the dev team structure with enforced password complexity.
Write Least-Privilege JSON Policy
Craft a custom policy that grants only what the team needs โ nothing more.
Enable MFA for a User
Add a second authentication factor via the AWS Console.
Create EC2 Role & Instance Profile
Grant EC2 instances permissions without embedding long-term credentials.
Generate Credential Report
Audit password age, MFA status, and access key rotation across the account.
3. Prerequisites & Setup
โ What You Need
- โ AWS account (free tier eligible)
- โ IAM user with admin permissions (not root)
- โ AWS CLI v2 installed and configured
- โ A text editor for JSON policy files
- โ An authenticator app (Google Auth, Authy, 1Password)
โ๏ธ Verify Your Setup
๐ก Tip: If you see an error about missing credentials, run aws configure and enter your Access Key ID, Secret Access Key, default Region (e.g., us-east-1), and output format (json).
โ ๏ธ Warning: Never use your root account for everyday work. If you're currently logged in as root, create an admin IAM user first and switch to it. Root should only be used for billing and account-level tasks.
๐ Create Your Working Directory
4. Step-by-Step Tasks
10 TasksExplore AWS Global Infrastructure
๐ฏ Goal
Discover which AWS Regions and Availability Zones exist, and identify the closest Region to CloudNova's headquarters.
๐ป CLI Commands
โ Expected Output
๐ก Tip: Region codes follow a pattern: us-east-1 = US East (N. Virginia). AZ codes append a letter, e.g., us-east-1a.
๐ก Why It Matters
Choosing the right Region reduces latency, meets data-residency requirements, and affects service availability and cost. Understanding AZs is essential for high availability design.
Create IAM Group & Set Password Policy
๐ฏ Goal
Create a Developers group and enforce a strong account-wide password policy.
๐ฅ๏ธ Console Steps (Optional)
- Go to IAM โ User groups โ Create group
- Name it
Developers - Skip attaching policies for now (we'll do that in Task 3)
- Go to IAM โ Account settings โ Password policy โ Edit
๐ป CLI Commands
โ Expected Output
โ ๏ธ Warning: Changing the account password policy affects all IAM users. Confirm with your organization before enforcing a 90-day maximum age.
๐ก Why It Matters
Groups simplify permission management at scale. A strong password policy is the first line of defense against credential-based attacks.
Write & Attach a Least-Privilege JSON Policy
๐ฏ Goal
Create a custom policy that lets the Developers group read/write only to a specific S3 bucket prefix โ nothing else.
๐ Create the Policy File
Save this as policies/cloudnova-dev-s3-policy.json:
๐ป CLI Commands
โ Expected Output
๐ก Tip: Notice the policy grants ListBucket only when the prefix is projects/*. This is the essence of least privilege โ scoping both action and resource.
๐ก Why It Matters
Broad policies like s3:* on * are a common cause of data breaches. Scoped policies reduce blast radius if a credential is compromised.
Create IAM Users & Add Them to the Group
๐ฏ Goal
Create alex.dev and priya.dev, and add them to the Developers group.
๐ป CLI Commands
โ Expected Output
๐ก Why It Matters
Tags make it easy to filter, audit, and automate. Group membership ensures both users inherit the exact same permissions โ no drift.
Enable MFA for a User (Console)
๐ฏ Goal
Add a virtual MFA device to alex.dev so login requires both password and a TOTP code.
๐ฅ๏ธ Console Steps
- Sign in to AWS Console as admin
- Go to IAM โ Users โ alex.dev โ Security credentials
- Under Multi-factor authentication (MFA), click Assign MFA device
- Name it
alex-dev-phone, choose Authenticator app - Scan the QR code with Google Authenticator / Authy / 1Password
- Enter two consecutive 6-digit codes from the app
- Click Add MFA
๐ป CLI Verification
โ Expected Output
โ ๏ธ Warning: Save backup codes or set up a secondary MFA device. If the phone is lost, account recovery requires contacting AWS Support or another admin with permissions to deactivate MFA.
๐ก Why It Matters
MFA blocks the vast majority of account takeover attempts, even when passwords are leaked or reused. It is one of the highest-ROI security controls you can enable.
Create an IAM Role for EC2 & Instance Profile
๐ฏ Goal
Create a role that EC2 instances can assume to read from the CloudNova S3 bucket โ no hard-coded access keys required.
๐ Trust Policy File
Save as policies/ec2-trust-policy.json:
๐ป CLI Commands
โ Expected Output
๐ก Tip: An instance profile is the container EC2 actually uses. You can only have one role per instance profile, but a profile can be reused across many instances.
๐ก Why It Matters
Roles eliminate the need to store long-term access keys on EC2 instances. Credentials are rotated automatically by AWS, drastically reducing leak risk.
Attach the Role to a Stopped EC2 Instance
๐ฏ Goal
Demonstrate role attachment using a stopped instance (no compute charges while stopped).
โ ๏ธ Warning: You can only attach or replace an instance profile while the instance is stopped. Attaching to a running instance will fail. Terminate the instance after this task to avoid storage charges (EBS volumes persist).
๐ป CLI Commands
โ Expected Output
๐ก Why It Matters
This is the real-world pattern: applications running on EC2 use temporary role credentials via IMDS, not static keys. No secrets to rotate, no secrets to leak.
Create an S3 Bucket & Test Access Boundaries
๐ฏ Goal
Create the cloudnova-dev-artifacts bucket and verify the least-privilege policy behaves as intended.
๐ป CLI Commands
โ Expected Output
๐ก Tip: The developers group can only access projects/*. Try creating an object at the bucket root as alex.dev โ it should fail with AccessDenied. That is the policy working as designed.
๐ก Why It Matters
Encryption and public-access blocks are baseline hygiene. Verifying both allowed and denied operations proves your least-privilege policy actually works.
Generate & Interpret a Credential Report
๐ฏ Goal
Audit every IAM user's password age, MFA status, access key rotation, and console access.
๐ป CLI Commands
๐ Key Columns to Inspect
| Column | What It Means | Healthy Value |
|---|---|---|
| user | IAM user name | โ |
| password_enabled | Console login enabled | as needed |
| password_last_used | Last console login | recent if active |
| mfa_active | MFA enabled | true |
| access_key_1_active | Long-term key exists | prefer false |
๐ก Tip: Automate this audit weekly. Any user with mfa_active=false and password_enabled=true is a priority finding.
๐ก Why It Matters
You can't secure what you can't see. Credential reports surface stale passwords, unused keys, and missing MFA โ all common audit findings.
Simulate Least-Privilege with IAM Policy Simulator
๐ฏ Goal
Prove that your policy grants exactly the intended permissions and denies everything else โ without affecting real users.
๐ป CLI Commands
โ Expected Output
๐ก Why It Matters
The Policy Simulator lets you validate changes safely before deployment. It's the fastest way to catch overly permissive policies without waiting for an incident.
5. Checkpoints / Self-Check Questions
๐ Checkpoint 1 โ Group Membership
Run a command that shows exactly which users belong to the Developers group. What is the ARN of the group?
๐ Checkpoint 2 โ Password Policy
What is the minimum password length, and how many previous passwords cannot be reused?
๐ Checkpoint 3 โ Least Privilege
Which S3 prefix can Developers read/write? What happens if they try to write to /private/?
๐ Checkpoint 4 โ MFA Status
Which user has MFA enabled? What command shows this?
๐ Checkpoint 5 โ Instance Profile
Which role is inside the CloudNovaEC2InstanceProfile? Which instance is it attached to?
๐ Checkpoint 6 โ Credential Report
List all users with mfa_active=false and password_enabled=true. Are any of them a risk?
6. Troubleshooting Common Errors
โ AccessDenied when creating policies or users
Your IAM user lacks iam:* permissions. Confirm you're using an admin user with AdministratorAccess, not a restricted one. Run aws sts get-caller-identity to confirm who you are.
โ InvalidClientTokenId or SignatureDoesNotMatch
Your Access Key ID or Secret Access Key is incorrect, expired, or contains a typo. Re-run aws configure and paste the keys carefully. Also check the system clock โ signature mismatches occur when the local time is skewed by more than 5 minutes.
โ MalformedPolicyDocument
Your JSON has a syntax error โ often a trailing comma, missing quote, or wrong bracket. Validate with python -m json.tool policies/cloudnova-dev-s3-policy.json before submitting.
โ BucketAlreadyExists
S3 bucket names are globally unique. Add a suffix such as your account ID or initials: cloudnova-dev-artifacts-12345. Remember to update your JSON policy ARNs too.
โ IncorrectState when attaching an instance profile
The EC2 instance is still running. Stop it first with aws ec2 stop-instances and wait for the stopped state using aws ec2 wait instance-stopped. Only then run associate-iam-instance-profile.
โ Credential report shows "not_supported" for the root user
This is normal โ root-level MFA and access key status are reported differently. Focus your audit on non-root IAM users.
โ MFA codes rejected during setup
Enter two consecutive codes, and make sure your phone's time is set to automatic. TOTP codes rotate every 30 seconds; if the window closes while typing, wait for the next one.
7. Cleanup Instructions
โ ๏ธ Warning: Run cleanup in the exact order below. IAM will refuse to delete groups or roles that still have policies or users attached. S3 buckets must be empty before deletion.
๐๏ธ Step 1 โ Remove users from the group & delete them
๐๏ธ Step 2 โ Detach policy & delete the group
๐๏ธ Step 3 โ Delete the custom policy
๐๏ธ Step 4 โ Remove role from instance profile & clean up EC2
๐๏ธ Step 5 โ Detach & delete the role
๐๏ธ Step 6 โ Empty & delete the S3 bucket
๐ก Tip: After cleanup, run aws iam list-users, aws iam list-roles, and aws s3 ls to confirm nothing is left behind.
8. Knowledge Check
7 QuestionsQ1. What is the difference between an IAM group and an IAM role?
Q2. Why should you avoid storing long-term access keys on an EC2 instance?
Q3. What is an instance profile and why is it required?
Q4. In the policy you wrote, why is s3:ListBucket applied to the bucket ARN while s3:GetObject is applied to the object ARN?
Q5. What is the difference between an Availability Zone and a Region?
Q6. What information can you extract from a credential report?
Q7. Why does least privilege matter even within a single AWS account?
Instructor Answer Key
A1. Groups are containers of users that share permissions; you assign policies to the group and users inherit them. Roles are temporary identities assumed by users, services, or applications โ they use short-lived credentials via STS and have a trust policy defining who can assume them. Users/groups cannot assume a role to get permissions the way an EC2 instance does.
A2. Long-term keys are static, often committed to code, and never rotate automatically. If leaked, they provide indefinite access. Roles provide temporary credentials rotated by AWS (typically every few hours), shrinking the blast radius of any compromise.
A3. An instance profile is the wrapper that carries a single IAM role to an EC2 instance. EC2 APIs require an instance profile name, not a role name, when associating permissions with an instance. You create the role, then add it to a profile, then attach the profile.
A4. ListBucket is a bucket-level action โ it operates on the bucket as a whole, so the ARN is the bucket. GetObject is an object-level action โ it operates on individual objects, so the ARN includes /*. Mixing these up is a very common mistake.
A5. A Region is a geographic cluster (e.g., us-east-1) containing multiple isolated Availability Zones. An AZ is one or more discrete data centers within a Region, with independent power, cooling, and networking. AZs within a Region are connected by low-latency links.
A6. Password age, password last used, MFA status per user, access key 1 & 2 active status and last rotated/used, console access, and root account usage. It is the standard source of truth for IAM hygiene audits.
A7. A compromised low-privilege user should not be able to escalate to admin. If alex.dev can only write to projects/*, a leaked credential cannot delete production buckets or tamper with IAM. Least privilege limits lateral movement and blast radius.
9. Further Reading & References
๐ AWS IAM Best Practices
Official guidance on users, groups, roles, MFA, and least privilege.
https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html
๐ IAM Policy Simulator
Test policies safely before deploying them.
https://policysim.aws.amazon.com/
๐ EC2 IAM Roles for Instances
How instance profiles and temporary credentials work.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html
๐ Credential Reports
Generate, download, and interpret account credential reports.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html
๐ AWS Global Infrastructure
Regions, AZs, edge locations, and Local Zones.
https://aws.amazon.com/about-aws/global-infrastructure/
๐ Well-Architected โ Security Pillar
Design principles for identity, detection, and least privilege.
https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/