AWS
Beginner 14 min read AWS

EC2, SSH & IAM

EC2 is AWS's virtual server service; SSH is how you reach Linux servers; IAM is how you authorize every action. Learn AMIs, instance types and key pairs, the SSH connection flow, and how IAM users, groups, roles and policies keep access least-privileged.

EC2AMIinstance typekey pairSSHIAMpolicyroleleast privilegesecurity group
Introduction

What is this?

Amazon EC2 (Elastic Compute Cloud) is AWS's virtual server service. An EC2 instance is a virtual machine launched from an AMI (Amazon Machine Image) — a template containing the operating system and software. You size it with an instance type (for example t3.micro: 2 vCPU, 1 GB RAM), place it in a VPC subnet, and secure access with key pairs for SSH and security groups for traffic. IAM is the separate identity layer: users represent humans, groups bundle permissions, roles give machines or federated identities a set of permissions, and policies are JSON that define what each identity may do.

Motivation

Why do you need it?

  • EC2 is the compute workhorse of AWS — most production workloads, autoscaling groups and EKS nodes are EC2 under the hood.
  • SSH is the universal way to reach Linux servers; every troubleshooting session starts with it.
  • IAM mistakes (over-broad policies, shared keys, root usage) cause most real AWS security incidents.
  • Instance sizing and key management are daily DevOps decisions that affect cost and security.
  • Understanding AMIs, key pairs and IAM roles prepares you for services like EKS, Lambda and RDS that all build on them.
Think about it

Mental model

Imagine

Borrowing a company car

Think of

EC2 instances and IAM

The car is an EC2 instance: you pick the model (instance type), it runs a standard engine (AMI), and the ignition key is your SSH key pair. IAM is the fleet policy: a badge (user) grants access to the lot, group badges get the same permissions together, and a service role is like a valet card that lets the car itself request parts. The badge controls what you may drive and where — least privilege means the badge only opens the cars and garages you actually need.

Mechanics

How it works

  • You launch an instance by choosing an AMI, an instance type, a key pair, a subnet and a security group; AWS provisions a VM from a pooled fleet in seconds.
  • The instance boots the AMI's OS; user data scripts can run at first boot to install packages and configure the machine.
  • SSH access uses the private half of your key pair — you connect as a named user (ec2-user, ubuntu, admin) and the server checks your key against the public key it holds.
  • Traffic is filtered by security groups (stateful allow lists) attached to the instance, and by the subnet's route table and network ACLs.
  • IAM authenticates every action: your CLI or console call is checked against policies attached to your user, group or role, and every API action is recorded in CloudTrail.

Launching an EC2 instance and connecting over SSH.

Pick an AMI
Choose instance type
Key pair + security group
Launch into a subnet
Instance boots
SSH from your laptop
Reference

Key commands

aws ec2 describe-instances

List your instances with their state, type and public IPs.

aws ec2 describe-key-pairs

Show the key-pair names registered in the current region.

chmod 400 my-key.pem

Lock down a private key so SSH accepts it.

ssh -i my-key.pem ec2-user@<public-ip>

Open an SSH session to the instance using your key pair.

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519

Generate a new key pair for accounts that do not allow password auth.

Hands-on

Examples

Connect to a Linux instance over SSH

Connect to a Linux instance over SSH
$ chmod 400 my-key.pem
$ ssh -i my-key.pem ec2-user@54.198.11.22
The authenticity of host '54.198.11.22' can't be established.
Are you sure you want to continue connecting (yes/no)? yes
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
[ec2-user@ip-10-0-1-42 ~]$ whoami
ec2-user
[ec2-user@ip-10-0-1-42 ~]$ uname -a
Linux ip-10-0-1-42 5.10.192-amazon2.x86_64 #1 SMP ...

chmod 400 removes group and other permissions so OpenSSH accepts the key instead of warning it is 'too open'. ssh -i selects the private key, the server verifies it against the public key stored at first boot, and you land in an interactive shell. whoami confirms the OS user (ec2-user for Amazon Linux, ubuntu for Ubuntu AMIs).

Real world

In production

  • Run application servers in an Auto Scaling group across availability zones behind a load balancer.
  • Use IAM instance roles instead of access keys on the box — the instance fetches short-lived credentials from the metadata service.
  • Build immutable AMIs in a CI pipeline so long-lived, drift-prone servers are replaced instead of patched.
  • Use spot instances and capacity reservations to cut compute cost for batch and fault-tolerant workloads.
  • Provide access into private subnets through a bastion host or AWS Systems Manager Session Manager with full audit trails.
Guidelines

Best practices

  • Never store private keys in git or on shared drives; use ssh-agent and rotate keys on a schedule.
  • Follow least privilege in IAM: grant the minimum actions on the minimum resources.
  • Enable MFA on the root account and create IAM users (or an SSO integration) for every human.
  • Use instance roles for anything that runs on EC2 — no long-lived access keys on disk.
  • Right-size instances: start small, watch utilization, and scale out before scaling up.
Watch out

Common mistakes

  • Leaving a security group open to 0.0.0.0/0 on SSH and then wondering about brute-force login attempts.
  • Storing AWS access keys inside application code or config files.
  • Putting a key pair in the repo 'just for onboarding' — it grants access to every instance that uses it.
  • Using the root account for daily work because it is simpler than configuring IAM.
  • Choosing an oversized instance type 'to be safe' and paying for idle vCPUs.
Root cause analysis

Common issues

Error
Permission denied (publickey)
Root cause

The private key does not match the key pair on the instance, the username is wrong, or key permissions are too open.

Fix

chmod 400 the key, connect as the right user (ec2-user, ubuntu, admin), and confirm the key pair name was used at launch.

Error
Connection timed out on port 22
Root cause

The security group blocks SSH from your IP, or the instance has no public IP or route.

Fix

Add an inbound rule for port 22 from your IP, confirm a public IP is assigned, and verify the subnet has an internet gateway route.

Error
UnauthorizedOperation when launching an instance
Root cause

The IAM identity lacks ec2:RunInstances permission or the required resource tags.

Fix

Attach a policy allowing the action, or run as an identity with broader permissions and retry.

When things break

Debugging tips

  • Permission denied (publickey) almost always means wrong key, wrong user, or a key with incorrect permissions.
  • Check the security group allows your source IP on port 22 before blaming the key.
  • Confirm the instance has a public IP and is in a public subnet with a route to the internet.
  • Use aws ec2 get-console-output to read boot logs when SSH is not reachable.
  • Verify IAM with aws sts get-caller-identity before debugging a denied API call.
Interviews

Interview checkpoint

Practice

Hands-on lab

Prepare an SSH Workspace and Key Pair
25 min · beginner
In progress
Objectives
  • Create the standard ~/.ssh directory with correct permissions
  • Generate a key pair with ssh-keygen
  • Write an SSH config alias for a remote host
  • Verify the config parses without connecting

Prepare an SSH Workspace and Key Pair

25 min · beginner

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which identity type is designed to be assumed by an EC2 instance to get short-lived credentials?

2

An SSH private key can be shared among multiple developers to access an instance.

3

Your SSH connection times out even though the instance is running. What should you check first?

Quick reference

Cheat sheet

EC2 essentials
AMIOS template used to launch an instance
Instance typet3.micro, m5.large — CPU/RAM sizing
Key pairPublic/private keys for SSH
User dataScripts run at first boot
Security groupStateful allow list per instance
IAM building blocks
UserA human or app with long-term credentials
GroupBundles users with shared policies
RoleAssumed by services; short-lived credentials
PolicyJSON that grants actions on resources
Instance roleRole attached to EC2 via the metadata service
Go deeper

Official documentation