Skip to main content

Command Palette

Search for a command to run...

AWS EC2 Explained: 12 Things Every Backend Developer Should Know

What I learned going through EC2 piece by piece

Updated
•8 min read•View as Markdown

Why I wrote this

I spent the last few weeks learning AWS EC2 properly. Not skimming a tutorial, but going piece by piece until each part actually made sense.

These are the 12 things I wish someone had told me on day one. If you are a backend developer who has only ever run mvn spring-boot:run on your laptop, this one is for you.

1. EC2 is just a computer you rent

EC2 stands for Elastic Compute Cloud. Underneath the name, it is a computer sitting in Amazon's data centre that runs 24/7 and has a public IP address.

The word "elastic" means you can resize it whenever you want. More CPU today, less tomorrow.

2. An instance is one rented machine

One physical server in the data centre gets split into many virtual machines. Each one of those is an instance.

You connect to it over SSH. Terminal only. There is no desktop and no mouse.

3. An AMI is a saved disk image

An AMI (Amazon Machine Image) is a snapshot of a full disk. The OS plus whatever was already installed on it.

It only works in one direction:

AMI  ->  Instance

Recipe to dish. You cannot turn a dish back into a recipe, but you can write a new recipe from one. Set up an instance exactly how you want it, click Create Image, and AWS saves the whole disk as a new AMI. Then you can launch 50 identical servers from it.

If you already know Docker, this is the same idea as an image and a container.

4. Instance types: learn the letters, not the numbers

Prefix Meaning
t tiny, cheap, burstable
m balanced
c CPU heavy
r RAM heavy

t2.micro is free tier for 12 months. t3.medium handles small production. m5.large is real production.

Do not memorise the exact vCPU and GB numbers. Nobody does that. You look them up when you need them.

5. Security groups are a firewall, not a permission system

A security group controls which ports are open and which source IPs can reach them.

Three things worth remembering:

  • Everything is blocked by default

  • There are no deny rules, only allow rules

  • It is stateful, so if you allow traffic in, the reply goes back out automatically

For a Spring Boot app:

Port 8080  ->  0.0.0.0/0     (the whole internet)
Port 22    ->  my IP only    (SSH)

The part that took me longest to get: a security group knows nothing about users, tokens, or what your API is doing. It filters ports and IPs. That is the whole job.

Also, never open port 3306 to the internet.

6. Key pairs: nothing secret travels across the network

AWS puts the public key on the instance. You download the private key (.pem) exactly once. If you lose it, it is gone.

Login works like this:

  1. The instance sends your machine a random number

  2. Your private key signs it

  3. The public key on the instance checks the signature

Your private key never leaves your laptop.

One thing that will waste your first hour:

chmod 400 mykey.pem

SSH will reject a perfectly valid key just because other users on your machine could read the file. The error you get is UNPROTECTED PRIVATE KEY FILE. The 400 means owner read only, where 4 is read, 2 is write and 1 is execute.

Default usernames are ec2-user on Amazon Linux and ubuntu on Ubuntu.

7. Your public IP changes when you stop the instance

Stop an instance and start it again, and AWS gives you a different public IP from its pool. Anything pointing at the old address breaks.

An Elastic IP is a permanent address that belongs to you. The part nobody expects:

An Elastic IP is free while it is attached to a running instance, and you get billed when it is not attached.

AWS charges you for the address you are holding on to, not the one you are using.

The private IP never changes. That is the one your app uses to reach the database.

One instance has one public IP and one private IP. If you run several services on the same machine, they are separated by port, not by IP.

8. EBS is a disk attached over the network

The disk your instance uses is not physically inside the server. It is EBS, attached over the network.

  • It survives a stop and start

  • It gets deleted on terminate by default, which catches everyone once

  • A snapshot is a backup copy stored in S3, and the original volume stays where it is

  • gp3 is the sensible default, io2 is for high performance

  • One volume attaches to one instance, in the same availability zone

9. User Data runs once, on first boot

User Data is a script you paste in at launch time. It runs automatically the first time the instance boots and never again. Not on reboot, not on stop and start.

The logs end up in /var/log/cloud-init-output.log.

AMI versus User Data is a real trade off:

Prepare time Boot time
Custom AMI around 25 min (copying GBs) around 1 min
User Data around 5 sec (edit a line) around 4 min

Production usually uses both. The AMI holds the stable layer like Linux, Java and Docker. User Data pulls down the one thing that keeps changing, which is your jar.

Since neither of them runs again on reboot, you need a systemd service if you want your app to come back up after a restart.

10. IAM roles mean you never hardcode credentials

You do not put AWS access keys in application.properties. You attach an IAM role to the instance instead.

AWS then writes temporary credentials, valid for about an hour and rotating on their own, to the instance metadata endpoint:

169.254.169.254

That address is only reachable from inside the instance.

So when you write this:

S3Client s3 = S3Client.create();

the SDK goes looking in this order:

  1. Environment variables

  2. ~/.aws/credentials

  3. Instance metadata, which is the one that works on EC2

One instance gets one role, and that role can carry many permissions. A policy is the JSON document that describes them. Give it the minimum that works, which is what least privilege means.

Worth keeping separate in your head: IAM roles have nothing to do with the ADMIN and CUSTOMER roles in your Spring Security config. Same word, completely different layer.

11. Four pricing models

Model Discount Use for
On-Demand none Testing, unpredictable load
Reserved around 40 to 60% Steady production, 1 to 3 year commitment
Spot around 70 to 90% Batch jobs only
Savings Plan varies Commit to $X per hour, stay flexible

Spot instances can be taken away from you with a 2 minute warning, so only run work there that can save its progress and resume.

What you actually get billed for, including the parts people miss:

  • Running instances

  • EBS volumes, even while the instance is stopped

  • Unattached Elastic IPs

  • Data transfer going out

In AWS, "stopped" does not mean free.

12. The deployment flow from start to finish

Phase 1, on your laptop

mvn clean package

Upload the jar to S3. The instance downloads it itself, so it has to be somewhere reachable first.

Phase 2, in the console

  1. Choose the AMI

  2. Choose the instance type for CPU and RAM

  3. Attach an IAM role with S3 read access

  4. Set the security group, with 8080 open to the internet and 22 open to your IP only

  5. Select the key pair

  6. Paste the User Data script that pulls the jar from S3 and runs it

  7. Launch

Phase 3, verify

http://<public-ip>:8080

Real production puts a Load Balancer in front and an Auto Scaling Group behind it.

That is EC2 from start to finish. S3 is next.