Skip to main content
DevOps Insightsguides & answers

Amazon EC2 explained

Virtual servers on AWS: how to choose one, get into it, and know what you keep and what you lose when it stops.

Checked against the AWS documentation · 21 October 2026

On this page · 17 sections

The short answer

Amazon EC2 (Elastic Compute Cloud) rents you virtual servers, called instances. You choose an instance type (how much CPU and memory), an AMI (the disk image it boots from), a subnet in a VPC, a security group, and how you will log in. Seconds later it is running, and it bills until you stop or terminate it.

The two things that surprise people most: stopping and starting an instance gives it a new public IP address, and terminating it deletes its root disk by default.

An analogy, and where it breaks

An instance is like a rented desk in a co-working space. You pick the size of desk (the instance type) and arrive with your laptop already set up (the AMI). Your locker (the EBS root volume) stays yours when you go home for the night (stop), but someone else may get your desk tomorrow, and your desk phone number (the public IP) changes. Hand back the keys (terminate) and the locker is emptied.

Where it breaks:

  • Some instances have a drawer that is emptied every night. Instance store volumes are fast local disks whose data is erased on stop, hibernate and terminate. Only a reboot keeps it.
  • You can rent a phone number that follows you. An Elastic IP stays associated through stop and start, but it is charged, as every public IPv4 address now is.
  • Going home does not stop the locker rent. A stopped instance stops instance charges; its EBS volumes are still billed.

Instance types and their names

A name such as m7g.large reads in parts. The first letter is the series: m general purpose, c compute optimized, r memory optimized, t burstable, g and p GPU. The number is the generation. The letters after it are options: g AWS Graviton (Arm), a AMD, i Intel, d local instance store disks, n network and EBS optimized. After the dot comes the size, from nano to metal.

The T family (current generations T8i, T4g, T3a and T3; T2 is previous generation) gives a baseline of CPU with the ability to burst above it, which suits web servers and small databases that are mostly idle. Graviton (g) types run Arm, so your software and container images must be built for arm64.

What a launch needs

  • An AMI: the operating system image. Its default username matters later.
  • A subnet and security group: where it lives and what may reach it. The VPC guide explains both.
  • A way in: a key pair for SSH, or nothing at all if you use Session Manager.
  • An IAM role (through an instance profile) if software on it calls AWS. Never put access keys on an instance; the IAM guide explains roles.
  • Storage: an EBS root volume, which by default is deleted when the instance is terminated.

Connecting to an instance

MethodNeedsGood for
SSH clientPublic IP (or a route to the private one), port 22 open to you, the key pair’s .pemQuick access you already know
EC2 Instance Connect EndpointAn endpoint in the VPC; no public IP on the instanceSSH to private instances without a bastion host
Session ManagerThe instance managed by Systems Manager, and an IAM role with AmazonSSMManagedInstanceCoreNo open inbound ports and no keys to manage

For SSH, the username depends on the AMI:

AMIUsername
Amazon Linuxec2-user
Ubuntuubuntu
Debianadmin
RHELec2-user or root
SUSEec2-user or root
Fedorafedora or ec2-user
CentOScentos or ec2-user
FreeBSDec2-user
chmod 400 my-key.pem
ssh -i my-key.pem ec2-user@203.0.113.10

Stop, reboot, hibernate, terminate: what survives

From the EC2 User Guide’s own comparison. Stop and hibernate work only for instances whose root volume is EBS.

RebootStop, then startHibernateTerminate
Host computerSame hostUsually a new hostUsually a new hostNone
Private IPv4KeptKeptKeptNone
Public IPv4KeptNew addressNew addressNone
Elastic IPStays associatedStays associatedStays associatedDisassociated
IPv6KeptKeptKeptNone
Instance store dataKeptErasedErasedErased
Root EBS volumeKeptKeptKeptDeleted by default
Memory (RAM)ErasedErasedSaved to the root volumeErased
Instance chargesUnchangedStop at stoppingStop at stoppedStop at shutting-down
  • A start after a stop begins a new billing period with a minimum of one minute.
  • An instance keeps its public IPv4 address through stop and start only through an Elastic IP associated with it (or with a secondary network interface or private address).
  • Shutting down from inside the OS stops an EBS-backed instance by default; that can be changed to terminate. An instance store-backed instance always terminates.

Copy anything on instance store volumes to EBS or S3 before you stop an instance: the data is erased, not paused.

Public and Elastic IP addresses

An instance in a subnet that assigns public addresses gets a public IPv4 address from AWS’s pool. It is released when the instance stops or terminates, which is why a start brings a new one. An Elastic IP is an address you allocate and keep until you release it. AWS charges for all public IPv4 addresses, in use or idle, including Elastic IPs; the Amazon VPC pricing page lists the rate.

Instance metadata and IMDSv2

From inside an instance, 169.254.169.254 answers questions about it: its ID, its Region and the temporary credentials of its IAM role. Version 2 (IMDSv2) answers only with a session token, which must be fetched with a PUT first. AWS describes it as defence in depth against open firewalls, reverse proxies and server-side request forgery: a bug that lets an attacker make your application fetch a URL with a plain GET is no longer enough to read the role’s credentials. Amazon Linux 2023 disables IMDSv1 by default; require IMDSv2 everywhere.

# On the instance: get a token, then use it.
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
# From your machine: refuse IMDSv1 on an existing instance.
aws ec2 modify-instance-metadata-options --instance-id "$ID" --http-tokens required

User data

User data is a script (or cloud-init configuration) you pass at launch. It runs as root, once, on the first boot by default, is limited to 16 KB before base64 encoding, and writes its output to /var/log/cloud-init-output.log. Because it runs once, treat it as setup for a fresh instance, not as configuration you can change later and reboot to apply.

Ways to pay

  • On-Demand: pay by the second for what you run.
  • Savings Plans: commit to an hourly spend for 1 or 3 years, for any instance type.
  • Reserved Instances: commit to an instance configuration in a Region for 1 or 3 years.
  • Spot: spare capacity at a large discount, which AWS can reclaim with a two-minute notice. For work that can be interrupted.
  • Dedicated Hosts and Instances, Capacity Reservations: for licensing, isolation or guaranteed capacity.

Try it with the AWS CLI

Inspecting, stopping and starting an instance you already have, and giving it a stable address. These commands were checked against the AWS CLI’s own help (version 2.32.5); they were not run against a live account for this page.

ID=i-1234567890abcdef0

aws ec2 describe-instances --instance-ids "$ID" \
  --query 'Reservations[].Instances[].[State.Name,InstanceType,PublicIpAddress,PrivateIpAddress]' --output table
aws ec2 stop-instances --instance-ids "$ID"
aws ec2 start-instances --instance-ids "$ID"
# Same query again: the public IP has changed, the private IP has not.
# A stable public address: allocate an Elastic IP and associate it.
ALLOC=$(aws ec2 allocate-address --domain vpc --query AllocationId --output text)
aws ec2 associate-address --instance-id "$ID" --allocation-id "$ALLOC"

An Elastic IP is charged until you release it, associated or not. Release it with aws ec2 release-address --allocation-id "$ALLOC" when the lab is done.

Troubleshooting

ssh: Connection timed out

Nothing answered on port 22. That is the network, not the key: no security group rule for your address, no route to an internet gateway, no public IP, or a network ACL in the way.

aws ec2 describe-instances --instance-ids "$ID" \
  --query 'Reservations[].Instances[].[State.Name,PublicIpAddress,SubnetId,SecurityGroups[].GroupId]'

Running, with a public IP? Then check that one of the security groups allows TCP 22 from your current public address, which changes on many home and office networks.

  • Allow port 22 from your address (or your network's range) in the security group.
  • Check the subnet's route table sends 0.0.0.0/0 to an internet gateway: the VPC guide explains why a subnet is public.
  • Or skip the public address entirely: EC2 Instance Connect Endpoint or Session Manager.

Permission denied (publickey)

The server answered and refused the key. Almost always the wrong username for the AMI, or the wrong .pem file for the key pair the instance was launched with.

ssh -i my-key.pem ec2-user@203.0.113.10

Amazon Linux uses ec2-user, Ubuntu ubuntu, Debian admin: the table above lists the rest.

  • Use the AMI's username and the key pair named on the instance's Details tab.

WARNING: UNPROTECTED PRIVATE KEY FILE

OpenSSH refuses a private key that other users can read, and then reports Permission denied (publickey).

chmod 400 my-key.pem

Readable by you only. On Windows, remove inherited permissions so only your user can read the file.

  • Run the chmod, then connect again.

The public IP changed after a restart

Stopping and starting gives an instance a new public IPv4 address, by design. A reboot keeps it.

aws ec2 describe-instances --instance-ids "$ID" --query 'Reservations[].Instances[].PublicIpAddress'

The current address.

  • Point DNS at an Elastic IP, which stays with the instance through stop and start (and is charged like every public IPv4 address).
  • Better still, put a load balancer in front and stop caring about the instance's address.

The user data script did not run (or ran only once)

By default, user data runs once, on the first boot after launch, as root. Editing it later and rebooting runs nothing.

sudo tail -n 50 /var/log/cloud-init-output.log

Everything the script printed, and its errors.

  • Fix the script and launch a new instance, or configure cloud-init to run it on every boot.

A status check is failing

A failed system check is AWS's hardware or network; a failed instance check is your instance, such as a full disk, a kernel that will not boot or a broken network configuration.

aws ec2 describe-instance-status --instance-ids "$ID"

SystemStatus and InstanceStatus separately.

aws ec2 get-console-output --instance-id "$ID" --latest --output text

The boot log, readable even when you cannot connect.

  • System check: stop and start an EBS-backed instance, which usually moves it to a new host.
  • Instance check: read the console output, then fix the configuration; a reboot helps only some causes.

Production practice

  • No inbound SSH from the internet. Use Session Manager or an Instance Connect Endpoint, and keep port 22 closed.
  • Roles, never keys. Software on the instance gets credentials from its IAM role through the metadata service, with IMDSv2 required.
  • Treat instances as replaceable. Build them from an AMI and user data, keep state on EBS, S3 or a database, and run more than one behind a load balancer across Availability Zones.
  • Alarm on status checks, and read the console output before rebooting a sick instance.
  • Right-size and commit. Burstable types for mostly idle servers; Savings Plans for the steady baseline; Spot for interruptible batch work.

Common mistakes

  • Hard-coding an instance’s public IP in DNS or config, then stopping it.
  • Keeping data on instance store volumes and stopping the instance.
  • Terminating an instance and expecting its root volume to remain.
  • Opening port 22 to 0.0.0.0/0 “for now”.
  • Editing user data and rebooting, expecting the script to run again.
  • Running x86 container images on a Graviton (g) instance.
  • Leaving an Elastic IP allocated after the instance is gone.

Interview questions

What is the difference between stopping and terminating an instance?

Stop keeps the instance and its EBS volumes, stops instance charges and gives it a new public IP when started again. Terminate deletes the instance and, by default, its root volume. Neither keeps instance store data.

How do you keep an instance’s public IP across a stop and start?

Associate an Elastic IP. Or, better, do not depend on it: put a load balancer or DNS name in front.

Why require IMDSv2?

Its session token must be fetched with a PUT first, so a server-side request forgery that can only make a plain GET cannot read the instance role’s credentials.

A status check failed. What do you do?

If it is the system check, stop and start the instance to move it to new hardware. If it is the instance check, read the console output and fix what the OS reports: disk, kernel, network configuration.

Questions people ask

Does a stopped instance cost anything?

No instance charges, but its EBS volumes and any Elastic IP are still billed.

Can I change an instance’s type?

Yes, for an EBS-backed instance: stop it, change the type, start it. The new type must be compatible with the instance’s configuration, such as its architecture, and the stop means downtime.

Why can I not SSH into an instance in a private subnet?

It has no route from the internet, by design. Use an EC2 Instance Connect Endpoint or Session Manager.

Where to go next

Sources

Every fact on this page comes from these AWS pages, read on 21 October 2026.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it