EC2 Virtual Servers
Amazon Elastic Compute Cloud (EC2) rents you virtual servers, called instances, in minutes. You choose the operating system, the CPU and memory, the disk and the network, and you get a machine that behaves like a computer in a data centre, except you can create ten of them for a busy day and delete them that evening.
In this lesson you will learn the parts of an instance, how to read instance type names, how to launch a small web server with the CLI, how to connect to it safely, and the difference between stopping and terminating.
The parts of an instance
- AMI (Amazon Machine Image): the template for the root disk, including the operating system. Amazon Linux 2023 (AL2023) is AWS's current Linux, supported until 2029; Ubuntu, Red Hat, Windows Server and many others are also available.
- Instance type: the hardware size (CPU, memory, network).
- EBS volume: the network disk that holds the operating system and data (see EBS Volumes & Snapshots).
- Security group: the virtual firewall around the instance (see Security Groups & Network ACLs).
- Subnet: where in your network (VPC) the instance lives, which fixes its Availability Zone.
- IAM role (through an instance profile): permissions for code running on the instance.
- User data: a script that runs on first boot.
Reading instance type names
An instance type name such as t4g.micro packs in several facts:
| Part | Example | Meaning |
|---|---|---|
| Family | t | Burstable general purpose (others: m general, c compute, r memory, g GPU) |
| Generation | 4 | Higher is newer and usually better value |
| Attributes | g | Processor: g = AWS Graviton (Arm), i = Intel, a = AMD |
| Size | micro | nano, micro, small, medium, large, xlarge, 2xlarge... |
So m8g.large is a general-purpose, 8th-generation Graviton instance of size large. Graviton instances use Arm processors, so choose an Arm (arm64) AMI for them. Burstable t types are good for small, mostly idle workloads such as a test site.
Launch a web server with the CLI
First write a user data script, setup.sh, that installs and starts the nginx web server on Amazon Linux 2023:
#!/bin/bash
dnf install -y nginx
echo "<h1>Hello from Ananya's EC2 server in Mumbai</h1>" > /usr/share/nginx/html/index.html
systemctl enable --now nginxThen launch the instance. Instead of copying an AMI ID (which differs per Region and changes with every update), the resolve:ssm: prefix asks AWS for the latest AL2023 Arm image:
aws ec2 run-instances --region ap-south-1 \
--image-id resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-arm64 \
--instance-type t4g.micro \
--subnet-id subnet-0a1b2c3d4e5f67890 \
--security-group-ids sg-0123456789abcdef0 \
--iam-instance-profile Name=web-server-profile \
--metadata-options HttpTokens=required \
--user-data file://setup.sh \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=ananya-web}]" \
--query "Instances[0].{Id: InstanceId, State: State.Name, Zone: Placement.AvailabilityZone}"{
"Id": "i-1234567890abcdef0",
"State": "pending",
"Zone": "ap-south-1a"
}The instance starts in the pending state. Wait for it, then ask for its public IP address:
aws ec2 wait instance-running --instance-ids i-1234567890abcdef0
aws ec2 describe-instances --instance-ids i-1234567890abcdef0 \
--query "Reservations[0].Instances[0].[State.Name, PublicIpAddress]" --output textrunning 203.0.113.25
Opening http://203.0.113.25 in a browser now shows the heading, as long as the security group allows port 80. The subnet and security group IDs here are placeholders; use your own from the VPC console.
Connect safely
There are three ways to get a shell on an instance:
- Session Manager (part of AWS Systems Manager): a browser or CLI shell with no open inbound ports and no SSH keys. The instance role needs the
AmazonSSMManagedInstanceCoremanaged policy. This is the safest choice. - EC2 Instance Connect: pushes a short-lived SSH key for one connection; port 22 must be reachable from the Instance Connect service or your IP address.
- SSH with a key pair: the classic way, covered in the Linux SSH lesson. Allow port 22 only from your own IP address, never from
0.0.0.0/0.
aws ssm start-session --target i-1234567890abcdef0(This needs the Session Manager plugin installed next to the CLI.)
Instance metadata and IMDSv2
Code on an instance can ask the instance metadata service for facts about itself and for its role credentials, at the special address 169.254.169.254. Version 2 (IMDSv2) requires a session token first, which blocks many server-side request forgery attacks. That is why the launch command set HttpTokens=required, and AL2023 images default to IMDSv2.
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/placement/availability-zoneap-south-1a
Stop, start and terminate
- Stop: the instance shuts down; you are not billed for compute time, but EBS volumes (and any public IPv4 address you keep) are still billed. Start it again later.
- Terminate: the instance is deleted. Its root volume is deleted too by default. This cannot be undone.
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0{
"TerminatingInstances": [
{
"CurrentState": {
"Code": 32,
"Name": "shutting-down"
},
"InstanceId": "i-1234567890abcdef0",
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}Pricing models and scaling
- On-Demand: pay per second or hour with no commitment. Good for learning and unpredictable work.
- Savings Plans and Reserved Instances: commit to steady usage for one or three years in exchange for a lower rate.
- Spot Instances: use spare capacity at a large discount, but AWS can reclaim them with a two-minute warning. Good for batch jobs and CI builds.
- Dedicated Hosts: a whole physical server for licensing or compliance needs.
Real applications rarely run on one instance. An Auto Scaling group keeps a set number of instances running across Availability Zones, replaces unhealthy ones and adds more under load, using a launch template that stores the settings you typed above. An Application Load Balancer spreads traffic across them.
Common mistakes
- Opening SSH (22) or RDP (3389) to the whole internet. Use Session Manager or restrict to your IP.
- Choosing an x86 AMI for a Graviton (
g) instance type. The launch fails; match the architecture. - Storing access keys on the instance. Attach an IAM role instead.
- Stopping instead of terminating practice instances and paying for disks for months.
- Running one instance in one AZ for production. Use an Auto Scaling group across at least two AZs.
Key points
- An EC2 instance combines an AMI, an instance type, EBS storage, a security group, a subnet and optionally an IAM role.
- In
t4g.micro,tis the family,4the generation,gthe Graviton processor andmicrothe size. - Use
resolve:ssm:parameters for current AMIs, user data for first-boot setup andHttpTokens=requiredfor IMDSv2. - Prefer Session Manager over SSH, and never open admin ports to
0.0.0.0/0. - Stopped instances still pay for storage; terminated instances are gone for good.
- Choose On-Demand, Savings Plans, Spot or Dedicated Hosts to match the workload.
Exercise
Write a user data script that installs nginx on Amazon Linux 2023 and writes a page saying "Lucknow Library Catalogue". Then write the run-instances command to launch it on an x86 t3.micro instance in Hyderabad (ap-south-2) with IMDSv2 required and a Name tag of library-web. Use placeholder subnet and security group IDs.
Show solution
#!/bin/bash
dnf install -y nginx
echo "<h1>Lucknow Library Catalogue</h1>" > /usr/share/nginx/html/index.html
systemctl enable --now nginxaws ec2 run-instances --region ap-south-2 \
--image-id resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
--instance-type t3.micro \
--subnet-id subnet-0a1b2c3d4e5f67890 \
--security-group-ids sg-0123456789abcdef0 \
--metadata-options HttpTokens=required \
--user-data file://library.sh \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=library-web}]"t3 is an Intel x86 type, so the AMI parameter ends in x86_64 instead of arm64. Remember to enable the Hyderabad Region first.
Quick Quiz
1. In the instance type c7g.xlarge, what does the g mean?
The letter after the generation number shows processor or extra features; g means Graviton.
2. What happens to compute charges when you stop an instance?
A stopped instance uses no compute time, but its volumes still exist.
3. Why set HttpTokens=required?
IMDSv2 protects metadata and role credentials from many SSRF attacks.
4. Which way of connecting needs no inbound port open on the instance?
Session Manager uses the SSM agent's outbound connection, so no inbound ports are required.
Learn AWS with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
