DEV Community

Tejas Shinkar
Tejas Shinkar

Posted on

IAM Essentials, Identity & Access Management: Roles, Policies, Groups, EC2 & Service Principals

🧭 What This Session Covers

Think of this session as answering one big question:

"Who can do what, on which AWS resource — and how do we control that?"

Topics flow in this order:

  1. Why IAM even exists (AAA Framework)
  2. Root vs IAM User
  3. MFA
  4. Groups, Roles, Service Principals
  5. Policies (Identity-based & Resource-based)
  6. ARN — What it is
  7. IAM Instance Profile → EC2 accessing S3
  8. Role Switching & Assume Role
  9. EC2 Basics + Key-Pair + AMI
  10. AWS Pricing Calculator

ā“ SECTION 1 — Why IAM? (Your Question Answered)

"I have my computer, my credentials, I'll just log into Root — why bother with IAM?"

Here's the honest answer:

Root has zero restrictions. It can delete your entire AWS account, rack up unlimited bills, create/destroy anything. When you're learning alone, that feels fine — but the moment anything goes wrong (compromised password, accidental command, someone else uses your laptop), the damage is total and irreversible.

IAM exists to answer: "What's the minimum access this person/service actually needs?"

Real-world example: A junior developer on your team should be able to deploy code — not delete production databases or view billing. IAM lets you give them exactly what they need and nothing more.

Also — AWS has a concept called AAA Framework which explains WHY access control systems exist:

A Name Question it answers AWS Tool
A Authentication Who are you? Username + Password + MFA
A Authorization What can you do? IAM Policies & Permissions
A Accounting What did you do? AWS CloudTrail (audit logs)

Without IAM: Every user = admin = massive security risk. One mistake wipes everything.


šŸ‘¤ SECTION 2 — Root User vs IAM User

Root User IAM User
Created When you open AWS account By Root or an admin
Access Unrestricted — everything Only what policies allow
Can be restricted? āŒ No āœ… Yes
Use for Initial setup only All daily tasks
MFA Enable immediately Strongly recommended

The rule is simple:

  • Root = lock it away with MFA, use only for billing or account recovery
  • IAM User = what you actually log in with daily

šŸ”‘ SECTION 3 — MFA (Multi-Factor Authentication)

Password alone isn't enough. MFA adds a second check — a time-based OTP from your phone.

Three types:

Type How Security Level
Virtual MFA Google Authenticator / Authy app āœ… Good — use this
Hardware MFA Physical YubiKey token āœ…āœ… Best — for Root
SMS/Voice OTP via text message āš ļø Avoid if possible

Steps to enable:

IAM Console → Security Credentials
→ Assign MFA Device
→ Choose: Virtual / Hardware / SMS
→ Scan QR code with authenticator app
→ Enter two consecutive 6-digit codes
→ Done
Enter fullscreen mode Exit fullscreen mode

šŸ‘„ SECTION 4 — IAM Groups

A Group is a collection of IAM users. Instead of attaching policies to every user individually, you attach to a Group once — all users in that group inherit those permissions.

Group: DevOpsTeam
Policy attached: PowerUserAccess
  ā”œā”€ā”€ User: tejas    → gets PowerUserAccess āœ…
  ā”œā”€ā”€ User: ravi     → gets PowerUserAccess āœ…
  └── User: priya    → gets PowerUserAccess āœ…
Enter fullscreen mode Exit fullscreen mode

Key rules:

  • One user can be in multiple groups
  • Groups cannot contain other groups (no nesting)
  • Default quota: 300 groups/account (can request increase up to 500)

When to use:
Use groups to manage teams — AdminGroup, DevGroup, ReadOnlyGroup. Adding someone to a team = add them to the group. Removing access = remove from group. Simple.


šŸŽ­ SECTION 5 — IAM Roles (Your Questions Answered)

"What is a Role? What is Assume? What is Trust Relationship? Why switch roles?"

Let's build understanding from scratch.

What is a Role?

A Role is like a temporary identity with permissions — it has no username or password. It's meant to be assumed (picked up and used temporarily) by a user or a service.

Think of it like a visitor badge at an office:

  • The visitor (IAM user or AWS service) picks up the badge
  • The badge gives access to specific areas (S3, EC2, etc.)
  • When done, they return the badge — access is gone
  • No permanent credentials involved

IAM User vs IAM Role

IAM User IAM Role
Has password? āœ… Yes āŒ No
Permanent? āœ… Yes āŒ Temporary (assumed)
For? Humans logging in Services or temporary access
Credentials Long-term Short-term, auto-rotated

What is "Assume Role"?

Assuming a Role = temporarily taking on a role's permissions.

Normal: IAM User (tejas) → has EC2FullAccess via direct policy

Assumes S3Role:
IAM User (tejas) → temporarily becomes S3Role → can now access S3
                 → EC2 access is SUSPENDED during this time
                 → Role session ends → back to original EC2 permissions
Enter fullscreen mode Exit fullscreen mode

This is exactly what you observed: "when you switched to S3 role, you couldn't access EC2 anymore" — correct! Role switching is temporary and replaces your current permissions for that session.


What is a Trust Relationship?

A Trust Relationship is the permission for an identity to assume a role.

It's a JSON document attached to the role that says: "Who is allowed to pick up this badge?"

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::123456789:user/tejas"
    },
    "Action": "sts:AssumeRole"
  }]
}
Enter fullscreen mode Exit fullscreen mode

This says: "Only the IAM user 'tejas' can assume this role."

Full flow of what you did in class:

1. Created a Role (e.g., S3AccessRole) with S3FullAccess permission
2. Edited the Trust Relationship JSON → added ARN of IAM user tejas
3. Tejas logs in as IAM user
4. Tejas switches to S3AccessRole (assumes the role)
5. Tejas can now access S3 — but EC2 access is gone (role replaced permissions)
6. Session ends or tejas switches back → original permissions restored
Enter fullscreen mode Exit fullscreen mode

What is a Service Principal?

A Service Principal is the identity of an AWS service — used in trust relationships to let services assume roles.

Examples:

ec2.amazonaws.com      → EC2 service identity
lambda.amazonaws.com   → Lambda service identity
s3.amazonaws.com       → S3 service identity
Enter fullscreen mode Exit fullscreen mode

When you want EC2 to access S3 automatically (without hardcoding credentials), you create a role with:

  • Trust policy: ec2.amazonaws.com can assume this role
  • Permission policy: S3FullAccess (or specific S3 access)

Then attach that role to EC2 → EC2 can now talk to S3. No passwords, no keys.


šŸ“‹ SECTION 6 — IAM Permissions & Policies

What is a Policy?

A Policy is a JSON document that defines what actions are allowed or denied on which resources.

When a new IAM user is created, they have zero permissions — they can log in but can't access any service. Policies are how you grant access.

Basic policy structure:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:GetObject", "s3:PutObject"],
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}
Enter fullscreen mode Exit fullscreen mode
Element What it means
Effect Allow or Deny
Action What API operation (e.g. s3:GetObject, ec2:*)
Resource Which specific resource (ARN)
Condition Optional — e.g. "only if MFA is enabled"
Principal Who this applies to (used in resource-based policies)

Critical rule:

Explicit Deny > No Policy (implicit deny) > Explicit Allow
Enter fullscreen mode Exit fullscreen mode

If a Deny exists anywhere, it always wins — even if an Allow exists too.


AmazonEC2FullAccess — What's Inside?

The policy you explored in class. It allows:

  • ec2:* — all EC2 actions (Describe, Start, Stop, Terminate, Launch, etc.)
  • Describe actions for related services (Auto Scaling, ELB, etc.)

ec2:* means every EC2 API action — that's why it's "Full Access". More restricted policies might only allow ec2:DescribeInstances (view only) or ec2:StartInstances + ec2:StopInstances (start/stop but not delete).


Two Types of Policies

Identity-Based Policy

  • Attached to a user, group, or role
  • Says: "This identity can do X"
  • Example: Attaching AmazonEC2FullAccess to user tejas

Resource-Based Policy

  • Attached to a resource (like an S3 bucket)
  • Says: "These identities can access me"
  • Example: S3 bucket policy allowing specific IAM user to read from it
  • Has a Principal field (who can access)

How You Can Assign Permissions (3 Ways)

Method 1 — Direct to User:
  IAM User → Attach Policy directly
  āœ… Quick | āŒ Hard to manage at scale

Method 2 — Via Group:
  IAM Group → Attach Policy → Add User to Group
  āœ… Best for teams | āœ… Easy to manage

Method 3 — Via Role (Assume):
  Create Role → User assumes Role → Gets temp permissions
  āœ… Best for temporary/cross-service access
Enter fullscreen mode Exit fullscreen mode

šŸ”– SECTION 7 — What is an ARN?

ARN = Amazon Resource Name

Every single resource in AWS has a unique ID called an ARN. It's like a URL but for AWS resources.

Format:

arn:aws:SERVICE:REGION:ACCOUNT-ID:RESOURCE
Enter fullscreen mode Exit fullscreen mode

Examples:

arn:aws:iam::123456789012:user/tejas          → IAM User
arn:aws:iam::123456789012:role/S3AccessRole   → IAM Role
arn:aws:s3:::my-bucket                         → S3 Bucket
arn:aws:ec2:ap-south-1:123456789:instance/i-abc123  → EC2 Instance
Enter fullscreen mode Exit fullscreen mode

ARNs are used in:

  • Trust relationship JSON (to say which user can assume a role)
  • Resource-based policies (to target specific resources)
  • CloudTrail logs (to identify what was accessed)

šŸ–„ļø SECTION 8 — IAM Instance Profile (EC2 → S3 Access)

"EC2 instance with EC2FullAccess wants to access S3 — how?"

The Problem with Hardcoding Credentials

Bad approach:

# hardcoded in your code — NEVER do this
s3 = boto3.client('s3',
    aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
    aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
Enter fullscreen mode Exit fullscreen mode

If this code goes to GitHub, your keys are exposed. Anyone can use them.

The Right Way — IAM Instance Profile

An Instance Profile is a container that holds one IAM Role and attaches it to an EC2 instance. The EC2 instance then automatically gets temporary credentials — no hardcoding needed.

IAM Role (S3AccessRole)
   ↓  wrapped in
Instance Profile
   ↓  attached to
EC2 Instance
   ↓  app code calls
AWS Metadata Service (169.254.169.254)
   ↓  returns
Temporary credentials (auto-rotated every hour)
   ↓  used to
Access S3 Bucket āœ…
Enter fullscreen mode Exit fullscreen mode

How to Set It Up

Step 1: Create IAM Role
  IAM Console → Roles → Create Role
  Trusted entity: EC2 (ec2.amazonaws.com as service principal)
  Attach policy: AmazonS3FullAccess (or specific S3 policy)
  Name: EC2-S3-AccessRole

Step 2: Attach to EC2 Instance
  EC2 Console → Select Instance → Actions
  → Security → Modify IAM Role
  → Select: EC2-S3-AccessRole → Update
  (Or set during launch: Advanced Settings → IAM Instance Profile)

Step 3: Test from EC2
  SSH into EC2 → run: aws s3 ls
  → Lists your S3 buckets āœ… (no credentials configured!)
Enter fullscreen mode Exit fullscreen mode

The Instance Profile is created automatically when you create a role for EC2 via the Console — you don't create it separately. One profile holds exactly one role.


āš™ļø SECTION 9 — EC2 Basics (What You Need to Know)

What is EC2?

EC2 = Elastic Compute Cloud — it's a virtual machine (server) running on AWS hardware. When you launch an EC2 instance, you're renting a slice of a physical server in an AWS data center.

Key EC2 Terms

AMI (Amazon Machine Image)

  • A pre-built template/snapshot that contains the OS + software for your EC2 instance
  • Like a blueprint — choose it once and EC2 launches with that OS ready
  • Examples: Amazon Linux 2, Ubuntu 22.04, Windows Server 2022
  • Free tier eligible: Amazon Linux 2 AMI or Ubuntu

Key Pair

  • Used to SSH into your EC2 instance securely
  • AWS generates a public-private key pair
  • AWS keeps the public key, you download the private key (.pem file)
  • You use the .pem file to connect: ssh -i key.pem ec2-user@<ip>
  • Download once — never available again. If you lose it, you lose SSH access.

Instance Type

  • Defines the CPU, RAM, and network capacity of your EC2
  • Free tier: t2.micro (1 vCPU, 1 GB RAM) or t3.micro
  • Naming: t3.medium → t=family, 3=generation, medium=size

User Data (Startup Script)

  • A script that runs once when EC2 first boots
  • Used to auto-install software, configure servers
  • Example: install Apache web server automatically on launch
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from EC2!</h1>" > /var/www/html/index.html
Enter fullscreen mode Exit fullscreen mode

Lab: Launch EC2 as Web Server

Step 1: EC2 Console → Launch Instance
Step 2: Choose AMI: Amazon Linux 2
Step 3: Instance type: t2.micro (free tier)
Step 4: Key pair: Create new → Download .pem file
Step 5: Security Group: Allow HTTP (port 80) + SSH (port 22)
Step 6: Advanced → User data → paste startup script above
Step 7: Launch

Access: http://<EC2-Public-IP>  → "Hello from EC2!" āœ…
Enter fullscreen mode Exit fullscreen mode

šŸ’° SECTION 10 — AWS Pricing Calculator

Before launching anything in AWS — estimate the cost first.

Tool: calculator.aws

How to use:

1. Go to calculator.aws → Create estimate
2. Search for a service (e.g., EC2)
3. Choose Region (ap-south-1 for India)
4. Select instance type, OS, hours/month
5. Add storage, data transfer if needed
6. View monthly + annual estimate
7. Share or export the estimate
Enter fullscreen mode Exit fullscreen mode

Why it matters for DevOps:
Before proposing any infrastructure to a client or manager, you run a cost estimate. "This architecture will cost ₹8,000/month" is far more useful than "I think it'll be cheap."


⚔ QUICK REVISION

WHY IAM
  Root = total power = total risk
  IAM = controlled, audited, least privilege access
  AAA = Authentication + Authorization + Accounting

KEY CONCEPTS
  Group     → Collection of users, attach policy once
  Role      → Temporary identity, no password, assumed by user/service
  Policy    → JSON doc defining Allow/Deny on which resource
  ARN       → Unique ID for every AWS resource
  Trust Rel → JSON saying who can assume a role
  Principal → Service identity (ec2.amazonaws.com)

POLICY RULE
  Explicit Deny > No Policy > Explicit Allow

INSTANCE PROFILE
  IAM Role → Instance Profile → EC2 → accesses S3
  No hardcoded credentials. Auto-rotated temp creds.

EC2 BASICS
  AMI        = OS template/blueprint
  Key Pair   = SSH access (.pem file — save it!)
  User Data  = startup script (runs once at boot)
  t2.micro   = free tier instance type

ROLE SWITCHING
  Assume Role = temporarily take on role's permissions
  Your original permissions are SUSPENDED during that session
  Session ends = back to original
Enter fullscreen mode Exit fullscreen mode

šŸ’¼ INTERVIEW QUESTIONS

Q1: What is the difference between an IAM User and an IAM Role?

A: An IAM User has permanent credentials (username + password). An IAM Role has no password — it provides temporary credentials and is assumed by users or services. Roles are the best practice for giving AWS services access to other AWS services.

Q2: An EC2 instance needs to read files from S3. How do you set this up securely?

A: Create an IAM Role with S3 read permissions and ec2.amazonaws.com as the trusted service principal. Attach this role to the EC2 instance via an Instance Profile. The EC2 instance automatically gets temporary, rotating credentials — no hardcoded access keys needed.

Q3: What is a Trust Relationship in IAM?

A: A Trust Relationship is a JSON policy on an IAM Role that defines who is allowed to assume that role — whether it's a specific IAM user (via ARN) or an AWS service (like ec2.amazonaws.com).

Q4: What happens if a Deny and an Allow both exist in IAM policies for the same action?

A: Deny always wins. The evaluation order is: Explicit Deny > No Policy (implicit deny) > Explicit Allow.

Q5: What is an Instance Profile?

A: An Instance Profile is a container that wraps an IAM Role and attaches it to an EC2 instance. It allows EC2 to call AWS services using temporary credentials from the metadata service — no hardcoded keys.

Q6: What's the difference between Identity-based and Resource-based policies?

A: Identity-based policies are attached to a user, group, or role and say "this identity can do X." Resource-based policies are attached to a resource (like S3) and say "these identities can access me." Resource-based policies have a Principal field; identity-based ones don't.


šŸ”¬ PRACTICE TASKS

  1. Create an IAM Group called DevOpsTeam, attach PowerUserAccess, create a user and add to the group. Log in as that user and verify access.
  2. Create an IAM Role for EC2 with AmazonS3ReadOnlyAccess. Launch an EC2 instance, attach this role, SSH in, and run aws s3 ls — confirm it works without any credentials configured.
  3. Open the AmazonEC2FullAccess policy JSON in IAM Console. Identify what ec2:* means and find 3 specific actions it covers.
  4. Create a Role, edit its Trust Relationship to allow your IAM user to assume it. Use "Switch Role" in the Console — observe what changes.
  5. Use the AWS Pricing Calculator to estimate monthly cost of: 1 x t3.micro EC2 (Linux, ap-south-1, running 24/7) + 20 GB EBS storage.

Top comments (0)