By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For AWS Solutions Architect – Associate & Real-World Production)
You’re a cloud engineer at a fintech startup. Your team just migrated a monolithic app to AWS, and now every developer, CI/CD pipeline, and Lambda function needs access to AWS services—but no one should have more permissions than absolutely necessary. If you get IAM wrong: - Security breach: A junior dev accidentally deletes a production DynamoDB table because their IAM user had dynamodb:* permissions.- Downtime: Your CI/CD pipeline fails because the IAM role attached to the EC2 runner lacks s3:GetObject for deployment artifacts.- Cost explosion: A misconfigured IAM policy grants ec2:RunInstances to a test account, and someone spins up 100 p3.8xlarge instances overnight.
dynamodb:*
s3:GetObject
ec2:RunInstances
p3.8xlarge
IAM is the gatekeeper of AWS. It controls who (users, services) can do what (actions) on which resources. Mastering IAM means: ✅ Least privilege: No "god mode" permissions—only what’s needed.✅ Scalability: Manage 100+ users without manually attaching policies to each.✅ Auditability: Track who did what (CloudTrail) and rotate credentials automatically.✅ Automation: Grant temporary access to services (e.g., Lambda, EC2) without hardcoding keys.
Real-world scenario: You inherit a legacy AWS account where: - The root user is used for daily tasks.- Developers share a single IAM user with admin permissions.- EC2 instances have hardcoded AWS keys in their ~/.aws/credentials file.Your mission: Refactor IAM to be secure, scalable, and auditable—without breaking production.
~/.aws/credentials
Developers
Admins
ReadOnly
arn:aws:s3:::my-bucket/*
Deny
Allow
AmazonS3ReadOnlyAccess
AWSLambdaBasicExecutionRole
123456789012
Principal
s3:*
aws --version
Refactor IAM for a serverless app (API Gateway + Lambda + DynamoDB) to follow least privilege. Current state: - Lambda uses a hardcoded access key in its environment variables.- Developers share an IAM user with AdministratorAccess.- No groups or roles exist.
AdministratorAccess
# Create groups for developers, admins, and read-only users aws iam create-group --group-name Developers aws iam create-group --group-name Admins aws iam create-group --group-name ReadOnly # Attach managed policies to groups aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::aws:policy/PowerUserAccess aws iam attach-group-policy --group-name Admins --policy-arn arn:aws:iam::aws:policy/AdministratorAccess aws iam attach-group-policy --group-name ReadOnly --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Verify:
aws iam list-attached-group-policies --group-name Developers
Expected output:
{ "AttachedPolicies": [ { "PolicyName": "PowerUserAccess", "PolicyArn": "arn:aws:iam::aws:policy/PowerUserAccess" } ] }
# Create a developer user (no console access) aws iam create-user --user-name alice-dev aws iam add-user-to-group --user-name alice-dev --group-name Developers # Create an admin user (with console access) aws iam create-user --user-name bob-admin aws iam create-login-profile --user-name bob-admin --password TempPass123! --password-reset-required aws iam add-user-to-group --user-name bob-admin --group-name Admins # Generate access keys for alice-dev (for CLI/SDK) aws iam create-access-key --user-name alice-dev > alice-dev-keys.json
⚠️ Security note: Never commit alice-dev-keys.json to Git. Use AWS Secrets Manager or ~/.aws/credentials instead.
alice-dev-keys.json
Create a role for Lambda: bash aws iam create-role --role-name LambdaDynamoDBRole --assume-role-policy-document file://trust-policy.json trust-policy.json: json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
bash aws iam create-role --role-name LambdaDynamoDBRole --assume-role-policy-document file://trust-policy.json
trust-policy.json
json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Attach a policy to the role: bash aws iam attach-role-policy --role-name LambdaDynamoDBRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole aws iam put-role-policy --role-name LambdaDynamoDBRole --policy-name DynamoDBAccess --policy-document file://dynamodb-policy.json dynamodb-policy.json (least privilege): json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem" ], "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/MyAppTable" } ] }
bash aws iam attach-role-policy --role-name LambdaDynamoDBRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole aws iam put-role-policy --role-name LambdaDynamoDBRole --policy-name DynamoDBAccess --policy-document file://dynamodb-policy.json
dynamodb-policy.json
json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem" ], "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/MyAppTable" } ] }
Update Lambda to use the role:
LambdaDynamoDBRole
aws lambda get-function --function-name MyLambdaFunction | jq '.Configuration.Role'
"arn:aws:iam::123456789012:role/LambdaDynamoDBRole"
# Enable MFA for bob-admin aws iam enable-mfa-device --user-name bob-admin --serial-number arn:aws:iam::123456789012:mfa/bob-admin --authentication-code1 123456 --authentication-code2 789012
⚠️ Note: Replace 123456 and 789012 with codes from your MFA device (e.g., Google Authenticator).
123456
789012
aws iam list-mfa-devices --user-name bob-admin
# Create a permission boundary policy aws iam create-policy --policy-name DeveloperBoundary --policy-document file://boundary-policy.json
boundary-policy.json:
boundary-policy.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*", "dynamodb:*", "lambda:*" ], "Resource": "*" } ] } # Attach the boundary to the Developers group aws iam put-group-policy --group-name Developers --policy-name DeveloperBoundary --policy-document file://boundary-policy.json
Why this matters: Even if a developer attaches AdministratorAccess to their user, the boundary caps their permissions to s3:*, dynamodb:*, and lambda:*.
lambda:*
*
EC2S3ReadRole
Environment=Prod
Team=Backend
CreateAccessKey
DeleteUser
AttachUserPolicy
root
InvalidClientTokenId
aws iam list-access-keys
"A Lambda function needs to read from an S3 bucket. Which policy should you attach?"
IAM roles vs. users:
"An EC2 instance needs to write to DynamoDB. Should you use an IAM user or role?"
Cross-account access:
"Account A needs to assume a role in Account B. What must you configure?"
sts:AssumeRole
MFA enforcement:
aws:MultiFactorAuthPresent: true
"You need to grant a third-party vendor read-only access to an S3 bucket for 24 hours. What’s the most secure way?" - ✅ Create an IAM role with a trust policy allowing the vendor’s AWS account to assume it, and attach a policy granting s3:GetObject. Set a 24-hour session duration.- ❌ "Create an IAM user and share the access key" (long-term credentials, hard to revoke).- ❌ "Grant s3:* to the vendor’s account" (over-permissive).
Challenge: A developer (alice-dev) needs to deploy a Lambda function but gets AccessDenied when trying to create a CloudWatch Logs group. Fix the IAM permissions without granting AdministratorAccess.
alice-dev
AccessDenied
Solution: 1. Attach the managed policy AWSLambdaBasicExecutionRole to alice-dev: bash aws iam attach-user-policy --user-name alice-dev --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 2. Why it works: This policy grants logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents—exactly what Lambda needs for logging.
bash aws iam attach-user-policy --user-name alice-dev --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
logs:CreateLogGroup
logs:CreateLogStream
logs:PutLogEvents
aws iam create-user --user-name alice
aws iam create-group --group-name Developers
aws iam attach-group-policy --group-name Developers --policy-arn arn:aws:iam::aws:policy/PowerUserAccess
aws iam create-role --role-name LambdaRole --assume-role-policy-document file://trust-policy.json
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/LambdaRole --role-session-name TestSession
aws iam list-attached-user-policies --user-name alice
aws iam enable-mfa-device --user-name alice --serial-number arn:aws:iam::123456789012:mfa/alice --authentication-code1 123456 --authentication-code2 789012
aws iam put-user-policy --user-name alice --policy-name Boundary --policy-document file://boundary-policy.json
Explicit Deny
Explicit Allow
Default Deny
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.