DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    AWS for DevOpsLesson 3 of 17
    Your progress · 0%
    On this page
    1. What you're building
    2. Name and AMI
    3. Instance type
    4. Key pair
    5. Firewall: the security group
    6. Storage and user data
    7. Launch
    8. What you just made
    9. Connect
    10. Inside the server
    11. What it costs
    12. Clean up
    ↖ Course roadmap
    Lesson 3 · EC2

    EC2: your first server in the cloud

    Launch a real server in the console step by step: pick an AMI and instance type, a key pair and a firewall, bootstrap it with user data, SSH in, then terminate it so it stops costing money.

    40 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 5 complete

    What you're building

    One small Linux server in Mumbai (ap-south-1) that serves a web page, reachable by SSH only from your own IP. Everything below was done in a real practice account, screen by screen, and deleted afterwards. The red numbered boxes show what to click or fill in.

    Open EC2 → Instances → Launch instances. It's one long page; work down it.

    Name and AMI

    (1) A name, which becomes the instance's Name tag. (2) The AMI: Amazon Linux 2023, free tier eligible.© Screenshot: DevOps Academy

    (1) A name, which becomes the instance's Name tag. (2) The AMI: Amazon Linux 2023, free tier eligible.© Screenshot: DevOps Academy

    An AMI (Amazon Machine Image) is the disk the server boots from: an operating system plus anything already installed. Amazon Linux 2023 is AWS's own distribution, tuned for EC2 and using dnf. Ubuntu and Debian work the same way; their default user is ubuntu or admin instead of ec2-user. Teams often build their own AMI with the app preinstalled so new servers start in seconds.

    Instance type

    (1) t3.micro: 2 vCPU, 1 GiB, with its hourly price per OS. (2) The key pair you'll log in with.© Screenshot: DevOps Academy

    (1) t3.micro: 2 vCPU, 1 GiB, with its hourly price per OS. (2) The key pair you'll log in with.© Screenshot: DevOps Academy

    The name says what you get: t3.micro is family t, generation 3, size micro.

    FamilyForExample
    t (burstable)small or spiky workloads: dev servers, small sitest3.micro, t4g.small
    m (general purpose)balanced apps and APIsm7i.large
    c (compute)CPU-heavy work: builds, encodingc7i.xlarge
    r (memory)databases, cachesr7i.large
    i, d (storage)fast local disksi4i.large

    Burstable t-types earn CPU credits while idle and spend them in bursts. A t-instance busy all day runs out and either slows down or, in the default unlimited mode, costs extra. A g in the name (t4g, m7g) means Graviton, AWS's Arm processor: usually cheaper for the same work, if your software has an Arm build.

    Key pair

    Choose a key pair you hold the private half of, or create one. AWS keeps only the public half.© Screenshot: DevOps Academy

    Choose a key pair you hold the private half of, or create one. AWS keeps only the public half.© Screenshot: DevOps Academy

    A key pair is an SSH key: AWS puts the public key on the server and you keep the private .pem file. Create new key pair downloads it exactly once; lose it and you can't log in with it again. From the CLI:

    $ aws ec2 create-key-pair --key-name academy-key --key-type ed25519 \
        --query KeyMaterial --output text > academy-key.pem
    $ chmod 400 academy-key.pem
    
    aws ec2 create-key-pair --key-name academy-key --key-type ed25519 \
    • awsthe AWS command line
    chmod 400 academy-key.pem
    • chmodchange permissions

    Firewall: the security group

    (1) A new security group. (2) SSH only from My IP. (3) HTTP from anywhere, for the web page.© Screenshot: DevOps Academy

    (1) A new security group. (2) SSH only from My IP. (3) HTTP from anywhere, for the web page.© Screenshot: DevOps Academy

    A security group is a firewall around the instance. It's stateful: allow a request in and its reply is allowed out automatically. By default nothing comes in and everything goes out. The wizard writes these rules for you:

    PortSourceWhy
    22 (SSH)your IP /32only you can even try to log in
    80 (HTTP)0.0.0.0/0the web page is public
    Never 0.0.0.0/0 on port 22

    The wizard's default for SSH is Anywhere. Bots scan every public IP for port 22 within minutes. Restrict it to your IP, and when your home IP changes, update the rule. Better: open no SSH port and use Session Manager.

    Storage and user data

    The root disk: an 8 GiB gp3 EBS volume.© Screenshot: DevOps Academy

    The root disk: an 8 GiB gp3 EBS volume.© Screenshot: DevOps Academy

    The root disk is an EBS volume: network storage that survives a stop and start, and is deleted on terminate by default. Some types also have an instance store: fast local disks that are wiped when the instance stops. Never keep data there that you can't lose. Lesson 7 covers storage in depth.

    Under Advanced details, the last field is User data: a script that runs once, as root, on first boot:

    The user data script installs and starts nginx with a page showing the server's hostname.© Screenshot: DevOps Academy

    The user data script installs and starts nginx with a page showing the server's hostname.© Screenshot: DevOps Academy
    #!/bin/bash
    dnf install -y nginx
    echo "<h1>Hello from $(hostname)</h1>" > /usr/share/nginx/html/index.html
    systemctl enable --now nginx
    

    Its output goes to /var/log/cloud-init-output.log on the instance: look there first when a server comes up without your software.

    Launch

    Check the summary, then Launch instance.© Screenshot: DevOps Academy

    Check the summary, then Launch instance.© Screenshot: DevOps Academy

    Launched. The instance ID starts with i-.© Screenshot: DevOps Academy

    Launched. The instance ID starts with i-.© Screenshot: DevOps Academy

    (1) academy-web. (2) Running. Status checks take a minute or two to pass.© Screenshot: DevOps Academy

    (1) academy-web. (2) Running. Status checks take a minute or two to pass.© Screenshot: DevOps Academy

    What you just made

    (1) The public IPv4 address. (2) Connect shows every way in.© Screenshot: DevOps Academy

    (1) The public IPv4 address. (2) Connect shows every way in.© Screenshot: DevOps Academy

    The instance has a private IP inside the VPC (lesson 4) and a public IP from AWS's pool. The public IP changes every time the instance stops and starts. An Elastic IP is a public address you keep, but AWS charges for every public IPv4 address, so release the ones you don't use.

    Connect

    (1) Instance Connect: SSH from the browser. (2) Session Manager: no open ports at all. (3) In SSH client, for your own terminal.© Screenshot: DevOps Academy

    (1) Instance Connect: SSH from the browser. (2) Session Manager: no open ports at all. (3) In SSH client, for your own terminal.© Screenshot: DevOps Academy

    (1) Lock down the key file. (2) The exact SSH command for this instance.© Screenshot: DevOps Academy

    (1) Lock down the key file. (2) The exact SSH command for this instance.© Screenshot: DevOps Academy

    Session Manager (part of AWS Systems Manager) opens a shell through the SSM agent and IAM, with no port 22, no key and every session logged. It needs the instance to have a role with AmazonSSMManagedInstanceCore (lesson 2's instance profile). For production it's the better default.

    Inside the server

    A real session: nginx is running, IMDSv2 needs a token, and the page answers from the internet.© Screenshot: DevOps Academy

    A real session: nginx is running, IMDSv2 needs a token, and the page answers from the internet.© Screenshot: DevOps Academy

    169.254.169.254 is the instance metadata service: the instance asks it who it is, what type it is, and for its role's temporary credentials. With IMDSv2 (required on this instance, as the details page showed) every request needs a token from a PUT first, so a request without one gets HTTP 401. That stops attacks that trick an app into fetching a URL and leaking the credentials.

    The page user data created, served by nginx from the instance.© Screenshot: DevOps Academy

    The page user data created, served by nginx from the instance.© Screenshot: DevOps Academy

    What it costs

    The instance type page showed the price: about $0.0112 an hour for a Linux t3.micro in Mumbai, around $8 a month if left on. Free tier offers depend on when your account was created; check Billing → Free Tier before relying on them.

    OptionPayGood for
    On-Demandper second, no commitmenttesting, unpredictable load
    Spotup to 90% less, but AWS can take it back with a 2-minute warningbatch jobs, CI runners, anything that can restart
    Savings Planslower rate for committing to $/hour for 1 or 3 yearssteady production load
    Reserved Instancesdiscount for committing to one instance typeolder alternative to Savings Plans

    Clean up

    Instance state → Terminate (delete) instance:

    (1) Stop keeps the disk; you still pay for EBS. (2) Terminate deletes the instance.© Screenshot: DevOps Academy

    (1) Stop keeps the disk; you still pay for EBS. (2) Terminate deletes the instance.© Screenshot: DevOps Academy

    Terminating can't be undone. Turn on termination protection for servers you must not lose.© Screenshot: DevOps Academy

    Terminating can't be undone. Turn on termination protection for servers you must not lose.© Screenshot: DevOps Academy

    A terminated instance leaves its security group and key pair behind; delete those too:

    $ aws ec2 terminate-instances --instance-ids i-0fc778d720d76ed3c
    $ aws ec2 wait instance-terminated --instance-ids i-0fc778d720d76ed3c
    $ aws ec2 delete-security-group --group-id sg-01ff1639efcb487b9
    $ aws ec2 delete-key-pair --key-name academy-key
    
    aws ec2 terminate-instances --instance-ids i-0fc778d720d76ed3c
    • awsthe AWS command line
    In production

    Nobody clicks through this wizard for production. Servers come from a launch template or Terraform (lesson 16), run in private subnets behind a load balancer (lessons 4 and 5), get an IAM role instead of keys, are reached through Session Manager, and are replaced rather than patched by hand.

    ⌘
    Mini mission

    A web server from one command

    Launch the same server from the CLI: a key pair, a security group with SSH from your IP and HTTP from anywhere, and a t3.micro running Amazon Linux 2023 with the nginx user data. Prove the page answers and that IMDSv2 rejects a request without a token, then delete everything.

    Input: An AWS account and the AWS CLI configured for ap-south-1Output: curl showing Hello from the instance, HTTP 401 without a metadata token, then no instance, security group or key pair left
    Reveal one safe solution
    $ MYIP=$(curl -s https://checkip.amazonaws.com)
    $ AMI=$(aws ssm get-parameter --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 --query Parameter.Value --output text)
    $ aws ec2 create-key-pair --key-name academy-key --key-type ed25519 --query KeyMaterial --output text > academy-key.pem && chmod 400 academy-key.pem
    $ SG=$(aws ec2 create-security-group --group-name academy-web --description "SSH from me, HTTP from all" --query GroupId --output text)
    $ aws ec2 authorize-security-group-ingress --group-id $SG --protocol tcp --port 22 --cidr $MYIP/32
    $ aws ec2 authorize-security-group-ingress --group-id $SG --protocol tcp --port 80 --cidr 0.0.0.0/0
    $ printf '#!/bin/bash\ndnf install -y nginx\necho "<h1>Hello from $(hostname)</h1>" > /usr/share/nginx/html/index.html\nsystemctl enable --now nginx\n' > user-data.sh
    $ ID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro --key-name academy-key --security-group-ids $SG \
        --user-data file://user-data.sh --metadata-options HttpTokens=required \
        --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=academy-web}]' --query 'Instances[0].InstanceId' --output text)
    $ aws ec2 wait instance-status-ok --instance-ids $ID
    $ IP=$(aws ec2 describe-instances --instance-ids $ID --query 'Reservations[0].Instances[0].PublicIpAddress' --output text)
    $ curl -s http://$IP
    $ ssh -o StrictHostKeyChecking=accept-new -i academy-key.pem ec2-user@$IP 'curl -s -o /dev/null -w "%{http_code}\n" http://169.254.169.254/latest/meta-data/instance-type'
    401
    $ aws ec2 terminate-instances --instance-ids $ID && aws ec2 wait instance-terminated --instance-ids $ID
    $ aws ec2 delete-security-group --group-id $SG && aws ec2 delete-key-pair --key-name academy-key && rm academy-key.pem
    
    aws ec2 create-key-pair --key-name academy-key --key-type ed25519 --query KeyMaterial --output text > academy-key.pem && chmod 400 academy-key.pem
    • awsthe AWS command line
    • --querypick fields from the JSON response
    • --outputoutput format
    • >write output to a file, replacing it
    • &&run the next command only if this one worked
    • chmodchange permissions
    curl -s http://$IP
    • curlmake an HTTP request
    • -ssilent: no progress bar
    ssh -o StrictHostKeyChecking=accept-new -i academy-key.pem ec2-user@$IP 'curl -s -o /dev/null -w "%{http_code}\n" http://169.254.169.254/latest/meta-data/instance-type'
    • sshlog in to another machine securely
    aws ec2 delete-security-group --group-id $SG && aws ec2 delete-key-pair --key-name academy-key && rm academy-key.pem
    • rmdelete files, with no undo

    instance-status-ok waits until both status checks pass, which can take a few minutes. The whole mission costs a cent or two at On-Demand prices, nothing within the free tier.

    Try it yourself

    0 of 6 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 5

    What is an AMI?

    Go deeper

    Official reading for this lesson

    • DocsAmazon EC2 user guideAWS Docs ↗
    • DocsAmazon EC2 instance typesAWS ↗
    • DocsUse IMDSv2AWS Docs ↗
    • DocsRun commands when you launch an instance (user data)AWS Docs ↗
    • DocsAWS Systems Manager Session ManagerAWS Docs ↗

    Or get every quiz answer right and it completes itself.

    ← PreviousIAM: who can do whatNext lesson →VPC: your own private network