Create an IAM Role and Policy for EC2 and Lambda Step by Step
Build least-privilege access for S3 read: one customer-managed policy, an EC2 instance role, and a Lambda execution role. Prove both, then clean up.
What you'll learn in this chapter
- Create a tight S3 read policy
- EC2 instance profile / role
- Lambda execution role + basic logs
- Verify with CLI and a tiny function
- Cleanup roles and policy
1. Lab: click by click
How to do it (step by step)
Region ap-south-1. Create a private bucket yourname-iam-lab and upload hello.txt with body ok. Replace names/account id.
A. Customer managed policy
- IAM → Policies → Create policy → JSON.
- Paste (replace BUCKET):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::BUCKET"
},
{
"Sid": "ReadObjects",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::BUCKET/*"
}
]
}
- Name:
lab-s3-read-one-bucket. Create.
B. EC2 role
- IAM → Roles → Create role → AWS service → EC2.
- Attach
lab-s3-read-one-bucketonly (not Admin). Role name:lab-ec2-s3-read. - EC2 → instance → Actions → Security → Modify IAM role →
lab-ec2-s3-read. - On EC2:
aws sts get-caller-identity
aws s3 cp s3://BUCKET/hello.txt -
# expect: ok
# aws s3 cp s3://SOME-OTHER-BUCKET/x . # should fail AccessDenied
C. Lambda role
- IAM → Roles → Create role → Lambda. Attach
lab-s3-read-one-bucketandAWSLambdaBasicExecutionRole. Name:lab-lambda-s3-read. - Lambda → Create function
lab-s3-get, Python 3.12, use existing rolelab-lambda-s3-read. - Code:
import boto3, os
def lambda_handler(event, context):
b = os.environ["BUCKET"]
body = boto3.client("s3").get_object(Bucket=b, Key="hello.txt")["Body"].read().decode()
return {"ok": True, "body": body}
- Env
BUCKET=your bucket. Deploy → Test. Expected JSON with"body": "ok".
Cleanup
- Delete Lambda function. Remove IAM role from EC2 (or terminate lab instance).
- Delete roles
lab-ec2-s3-read,lab-lambda-s3-read. Delete policylab-s3-read-one-bucket. - Empty and delete the lab bucket.
2. Interview angles
Q. Why instance role not access keys?
Keys get stolen from disk; role creds rotate via metadata.
Q. Why two statements List + Get?
ListBucket on bucket ARN; GetObject on object ARN.
Q. Basic execution role?
Writes CloudWatch Logs.
Q. Admin policy on Lambda?
Breaks least privilege — avoid.
Try at home
- Add s3:PutObject for a prefix only and test deny outside prefix.
- Try the same role pattern for DynamoDB GetItem.
In short
- Customer managed policy → attach to roles.
- EC2 instance role + Lambda execution role.
- Prove allow and deny; then delete lab artifacts.
Practice Tasks
Bavaria Motors is a automobile business in Munich. Lukas Becker looks after its IT and cloud work. They count money in EUR and run their AWS resources in the eu-central-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.
0 / 12
Easy List functions
Why: See which functions exist in this Region.
What to do: List the Lambda functions in eu-central-1.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Medium Trust policy for a Lambda role
Why: The trust policy says WHO may take the role.
What to do: Write a trust policy that lets lambda.amazonaws.com assume the role.
- Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
- In each statement write Effect, Action and Resource.
- Give only what the task needs (least privilege).
- Use double quotes and commas correctly. Click Check answer.
Medium Invoke a function
Why: Invoke runs the function now and saves its answer in a file.
What to do: Invoke bavariamotors-orders-fn and save the response to out.json.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Medium Change timeout and memory
Why: More memory also gives more CPU; timeout stops runaway runs.
What to do: Set bavariamotors-orders-fn to timeout 30 seconds and memory 512 MB.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Medium Let a function write logs
Why: Without these actions, Lambda logs never appear in CloudWatch.
What to do: Allow logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents on arn:aws:logs:*:*:* only.
- Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
- In each statement write Effect, Action and Resource.
- Give only what the task needs (least privilege).
- Use double quotes and commas correctly. Click Check answer.
Medium Trust policy for an EC2 role
Why: The trust policy says WHO may take the role.
What to do: Write a trust policy that lets ec2.amazonaws.com assume the role.
- Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
- In each statement write Effect, Action and Resource.
- Give only what the task needs (least privilege).
- Use double quotes and commas correctly. Click Check answer.
Hard Create a Lambda function
Why: Lambda needs the code zip, a runtime, a handler name and an execution role.
What to do: Create function bavariamotors-orders-fn: runtime python3.12, handler app.handler, role arn:aws:iam::106249807804:role/lambda-basic, code in function.zip.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Hard Set environment variables
Why: Keep settings like table names out of the code.
What to do: Set the environment variable TABLE=bavariamotors-orders on bavariamotors-orders-fn.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Hard Invoke with a JSON payload
Why: In CLI v2, raw JSON needs --cli-binary-format raw-in-base64-out.
What to do: Invoke bavariamotors-orders-fn with payload {"orderId":"o-101"} (raw JSON) and save the reply in out.json.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Hard Lambda GB-seconds
Why: Lambda bills memory × time.
What to do: 1,000,000 invocations, 512 MB memory, 200 ms each. How many GB-seconds?
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Connect an SQS queue to Lambda
Why: An event source mapping makes Lambda poll the queue and process messages in batches.
What to do: Create an event source mapping from queue arn:aws:sqs:eu-central-1:106249807804:bavariamotors-orders to bavariamotors-orders-fn with batch size 10.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Hard Let S3 call your function
Why: A resource-based permission is needed before S3 can invoke the function.
What to do: Add permission statement s3invoke to bavariamotors-orders-fn so s3.amazonaws.com can call lambda:InvokeFunction from bucket arn:aws:s3:::bavariamotors-uploads.
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Revision, comparison and interview cards
Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.






More cards: Ravi Sir's Cards.