<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ashwarya</title>
    <description>The latest articles on DEV Community by Ashwarya (@xcl1br).</description>
    <link>https://dev.to/xcl1br</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F457058%2F26ba00e1-b6ac-4852-b815-105c50cf9915.jpg</url>
      <title>DEV Community: Ashwarya</title>
      <link>https://dev.to/xcl1br</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xcl1br"/>
    <language>en</language>
    <item>
      <title>Today I Learnt: Ansible Basics — Passwordless SSH, Ad-hoc Commands, My First Playbook, and Roles</title>
      <dc:creator>Ashwarya</dc:creator>
      <pubDate>Sun, 11 Oct 2026 08:22:09 +0000</pubDate>
      <link>https://dev.to/xcl1br/today-i-learnt-ansible-passwordless-ssh-between-two-ec2s-and-my-first-playbook-a16</link>
      <guid>https://dev.to/xcl1br/today-i-learnt-ansible-passwordless-ssh-between-two-ec2s-and-my-first-playbook-a16</guid>
      <description>&lt;p&gt;Today's topic was Ansible — one of the most common tools that comes up in DevOps interviews and real jobs. I practiced everything on 2 EC2 machines: one acts as the "control machine" (where Ansible is installed and commands are run from), and the other is the "target machine" (the one Ansible actually manages).&lt;/p&gt;

&lt;p&gt;I'm writing this down step by step, in the same order I actually did it, along with the real errors I hit and what they meant — so future-me (and anyone else reading this before an interview) doesn't get confused by the same things.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: Setting up passwordless SSH login into the target EC2
&lt;/h2&gt;

&lt;p&gt;Before Ansible can manage a remote server, it needs to be able to SSH into it &lt;strong&gt;without asking for a password every single time&lt;/strong&gt;. Here's how I set that up between my 2 EC2 machines.&lt;/p&gt;

&lt;h3&gt;
  
  
  First, connecting to EC2 at all (the normal way)
&lt;/h3&gt;

&lt;p&gt;There are two common ways people connect to an EC2 instance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browser / AWS Console:&lt;/strong&gt; Open the EC2 instance in the AWS console → click &lt;strong&gt;Connect&lt;/strong&gt; → choose "EC2 Instance Connect" → it opens a terminal right in your browser. No extra software needed, good for quick checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MobaXterm (on Windows):&lt;/strong&gt; A terminal app that lets you SSH in using the &lt;code&gt;.pem&lt;/code&gt; key file you downloaded when you created the EC2 instance. You create a new SSH session, enter the public IP, username (like &lt;code&gt;ec2-user&lt;/code&gt; or &lt;code&gt;ubuntu&lt;/code&gt;), and point it to your &lt;code&gt;.pem&lt;/code&gt; file as the private key — then it logs you in, same as a terminal would.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Either way, from a terminal, connecting with a &lt;code&gt;.pem&lt;/code&gt; file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; /path/to/mykey.pem ec2-user@&amp;lt;target-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to leave the session, you simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why passwordless SSH matters for Ansible
&lt;/h3&gt;

&lt;p&gt;Ansible works by SSH-ing into target machines and running commands. If it has to ask for a password (or a &lt;code&gt;.pem&lt;/code&gt; file path) every time, automation breaks. So the fix is: generate our own SSH key pair on the control machine, and tell the target machine to trust it permanently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps I followed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Generate a key pair on the control machine (not the target):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This asks a few questions (where to save the key, a passphrase) — I just pressed Enter to accept the defaults. This creates two files inside &lt;code&gt;~/.ssh/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id_rsa&lt;/code&gt; → the &lt;strong&gt;private&lt;/strong&gt; key (never shared, stays on the control machine)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;id_rsa.pub&lt;/code&gt; → the &lt;strong&gt;public&lt;/strong&gt; key (safe to share, this is what goes on the target)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Copy the public key's content:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This just prints the public key text on screen so I can copy it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Log into the target machine using the &lt;code&gt;.pem&lt;/code&gt; file (the old way, one last time):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; mykey.pem ec2-user@&amp;lt;target-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4 — On the target machine, add the control machine's public key to its trusted list:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;code&gt;i&lt;/code&gt; to start typing, paste the public key text from Step 2 on a new line, then press &lt;code&gt;Esc&lt;/code&gt;, type &lt;code&gt;:x&lt;/code&gt;, and hit Enter to save and exit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Exit the target machine, and test passwordless login:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit
&lt;/span&gt;ssh ec2-user@&amp;lt;target-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice — no &lt;code&gt;-i mykey.pem&lt;/code&gt; needed this time, and no password prompt. That's because the control machine's private key now matches the public key sitting in the target's &lt;code&gt;authorized_keys&lt;/code&gt; file, so SSH logs you in automatically.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good to know:&lt;/strong&gt; &lt;code&gt;authorized_keys&lt;/code&gt; on the target is basically a list of "these public keys are allowed in, no password needed." You can add more than one key here if more than one machine needs access.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Part 2: Installing Ansible and the Inventory File
&lt;/h2&gt;

&lt;p&gt;Once passwordless SSH was working, next was installing Ansible on the control machine (on Ubuntu, this is usually &lt;code&gt;sudo apt install ansible&lt;/code&gt;), and then creating an &lt;strong&gt;inventory file&lt;/strong&gt; — a simple text file listing which machines Ansible should manage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the inventory file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"172.31.16.176 ansible_user=ec2-user"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; inventory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a file named &lt;code&gt;inventory&lt;/code&gt; with one line: the target's private IP, and which username Ansible should log in as on that machine.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have more servers, you simply &lt;strong&gt;add more lines&lt;/strong&gt; to the same file — one IP (or hostname) per line. You don't need a separate file per server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Running my first ad-hoc command
&lt;/h3&gt;

&lt;p&gt;An "ad-hoc command" is a single, one-time instruction you give Ansible directly from the terminal — no file needed, no YAML, just one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible &lt;span class="nt"&gt;-i&lt;/span&gt; inventory all &lt;span class="nt"&gt;-m&lt;/span&gt; shell &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"touch devopsclass"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking this down in plain words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-i inventory&lt;/code&gt; → "use this inventory file to know which servers to talk to"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;all&lt;/code&gt; → "target every server listed in the inventory" (you could also target a specific group name instead of &lt;code&gt;all&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-m shell&lt;/code&gt; → "use the shell module" (meaning: run this like a normal terminal command)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a "touch devopsclass"&lt;/code&gt; → "here's the actual command to run" — in this case, create an empty file called &lt;code&gt;devopsclass&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I ran it, Ansible printed a warning about which Python interpreter it found on the target (&lt;code&gt;/usr/bin/python3.9&lt;/code&gt;). This is just Ansible being transparent about which Python it's using to run its modules on the target — it's not an error, just a heads-up.&lt;/p&gt;

&lt;p&gt;The result &lt;code&gt;CHANGED | rc=0&lt;/code&gt; means: the command ran successfully (&lt;code&gt;rc=0&lt;/code&gt; = return code 0 = success), and it actually changed something on the target machine (a new file was created).&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: An error I hit, and what it actually meant
&lt;/h2&gt;

&lt;p&gt;While testing, I tried this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/mykey.pem ec2-user@172.31.16.176
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And got this warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning: Identity file /home/ubuntu/.ssh/mykey.pem not accessible: No such file or directory.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this means in plain words:&lt;/strong&gt; I told SSH to use a &lt;code&gt;.pem&lt;/code&gt; file at a path that doesn't actually exist on this machine (wrong path, or the file was never copied there). Normally, this would block the login completely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But here's the interesting part&lt;/strong&gt; — the login still succeeded right after (&lt;code&gt;Last login: ...&lt;/code&gt;). Why? Because I had &lt;em&gt;already&lt;/em&gt; set up passwordless SSH in Part 1. So even though the specific &lt;code&gt;.pem&lt;/code&gt; file I pointed to was missing, SSH automatically fell back to its default key (&lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;) — which was already trusted by the target — and logged in anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; this warning is not always a dead-end. If passwordless SSH is already configured, SSH can quietly succeed using your default key even if the exact file you mentioned doesn't exist. Good to recognize so you don't panic during a demo or interview scenario.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: Ad-hoc commands vs Playbooks
&lt;/h2&gt;

&lt;p&gt;This came up a lot, so here's the simple difference:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Ad-hoc command&lt;/th&gt;
&lt;th&gt;Playbook&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What it is&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One single command, typed directly&lt;/td&gt;
&lt;td&gt;A YAML file with multiple steps written out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Command used&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ansible ...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ansible-playbook ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quick, one-time checks or fixes&lt;/td&gt;
&lt;td&gt;Repeatable, documented, multi-step setups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Just create this one file on all servers"&lt;/td&gt;
&lt;td&gt;"Install nginx, start it, and open the firewall port"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Simple way to remember it:&lt;/strong&gt; ad-hoc is like typing a command directly into someone's terminal. A playbook is like handing them a written recipe they can follow (and re-run) anytime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the shell module for multiple commands
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shell&lt;/code&gt; module isn't limited to one simple command — you can chain several together, just like you would directly in a terminal, using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; or &lt;code&gt;;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible &lt;span class="nt"&gt;-i&lt;/span&gt; inventory all &lt;span class="nt"&gt;-m&lt;/span&gt; shell &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"touch file1.txt &amp;amp;&amp;amp; cat file1.txt &amp;amp;&amp;amp; rm -f file1.txt"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One useful detail I noticed: &lt;code&gt;rm -rf&lt;/code&gt; doesn't throw an error even if the file is already gone (running it twice in a row both returned &lt;code&gt;rc=0&lt;/code&gt;, success). That's different from a plain &lt;code&gt;rm&lt;/code&gt; without &lt;code&gt;-f&lt;/code&gt;, which would complain if the file doesn't exist. The &lt;code&gt;-f&lt;/code&gt; (force) flag quietly ignores that.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 5: Writing my first Ansible Playbook
&lt;/h2&gt;

&lt;p&gt;A playbook is a YAML file describing exactly what should happen, step by step. Here's the one I wrote, to install and start nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install and start nginx&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install nginx&lt;/span&gt;
      &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start nginx&lt;/span&gt;
      &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;started&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What each part means, in plain words:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name:&lt;/code&gt; → just a label/description, purely for readability.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hosts:&lt;/code&gt; → which machine(s) this playbook runs on. I used &lt;code&gt;localhost&lt;/code&gt; here, meaning it runs on the control machine itself.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;connection: local&lt;/code&gt; → tells Ansible "don't SSH anywhere, just run this directly on the machine you're already on." This pairs with &lt;code&gt;hosts: localhost&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;become: yes&lt;/code&gt; → "run this with admin (sudo) privileges," since installing software needs that.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tasks:&lt;/code&gt; → the actual list of steps, done top to bottom.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apt: name: nginx state: present&lt;/code&gt; → "make sure nginx is installed" (using the &lt;code&gt;apt&lt;/code&gt; module, for Debian/Ubuntu systems).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;service: name: nginx state: started&lt;/code&gt; → "make sure the nginx service is running."&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; because this playbook uses &lt;code&gt;hosts: localhost&lt;/code&gt; + &lt;code&gt;connection: local&lt;/code&gt;, it installs nginx on the control machine, not on a remote target. To run it against your actual target server(s) instead, you'd change &lt;code&gt;hosts: localhost&lt;/code&gt; to match a group from your inventory file (e.g., &lt;code&gt;hosts: all&lt;/code&gt;) and remove the &lt;code&gt;connection: local&lt;/code&gt; line — then Ansible will SSH into the target(s) to do the work, the same way the ad-hoc commands did.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Running the playbook
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; inventory firstplaybook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output, step by step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TASK [Gathering Facts] → ok        (Ansible first collects basic info about the machine)
TASK [Install nginx]   → changed   (nginx wasn't installed, so this step changed something)
TASK [Start nginx]     → ok        (nginx was already running, or started with no issue)

PLAY RECAP: ok=3  changed=1  unreachable=0  failed=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;PLAY RECAP&lt;/strong&gt; line is the summary — always check this first. &lt;code&gt;failed=0&lt;/code&gt; and &lt;code&gt;unreachable=0&lt;/code&gt; means everything went smoothly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Double-checking it actually worked
&lt;/h3&gt;

&lt;p&gt;On the actual server, I confirmed nginx was really running with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which showed &lt;code&gt;Active: active (running)&lt;/code&gt; — confirming the playbook did its job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting more detail with verbose mode
&lt;/h3&gt;

&lt;p&gt;If something isn't clear from the normal output, add &lt;code&gt;-v&lt;/code&gt; (or stack more &lt;code&gt;v&lt;/code&gt;s for more detail: &lt;code&gt;-vv&lt;/code&gt;, &lt;code&gt;-vvv&lt;/code&gt;, up to &lt;code&gt;-vvvv&lt;/code&gt; for maximum detail):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook &lt;span class="nt"&gt;-vvvv&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; inventory firstplaybook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is extremely useful for debugging — it shows exactly what Ansible is doing behind the scenes, including the full SSH connection details and raw module output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 6: Scaling up — why Ansible Roles exist
&lt;/h2&gt;

&lt;p&gt;A realistic scenario we discussed: using &lt;strong&gt;Terraform&lt;/strong&gt; to spin up 3 EC2 instances, then using &lt;strong&gt;Ansible&lt;/strong&gt; to configure 1 of them as a "master" and the other 2 as "workers" (a common pattern for setting up something like Kubernetes).&lt;/p&gt;

&lt;p&gt;The problem: a real setup like this isn't 3 lines of YAML — it can easily be 50-60 tasks per playbook (installing packages, configuring files, setting environment variables, opening ports, and so on). Writing all of that in one giant playbook file becomes messy and hard to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is exactly what Ansible Roles solve&lt;/strong&gt; — they let you organize a big playbook into clean, reusable folders instead of one huge file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a role
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-galaxy role init kubernetes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This instantly creates a proper folder structure for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubernetes/
├── README.md
├── defaults/
├── files/
├── handlers/
├── meta/
├── tasks/
├── templates/
├── tests/
└── vars/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What each folder is for, in plain words:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tasks/&lt;/strong&gt; → the actual list of steps to run (this is the heart of the role — like the &lt;code&gt;tasks:&lt;/code&gt; section in a playbook, but organized separately).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;defaults/&lt;/strong&gt; → default values for variables, which can be easily overridden later. Lowest priority variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vars/&lt;/strong&gt; → other variables used by the role, usually meant to stay fixed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;files/&lt;/strong&gt; → any static files you want to copy over to the target machine as-is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;templates/&lt;/strong&gt; → files that have placeholders inside them, which Ansible fills in with real values before copying (for config files that change based on variables).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;handlers/&lt;/strong&gt; → actions that only run &lt;em&gt;when triggered&lt;/em&gt; by a task — most commonly "restart this service" after a config file changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;meta/&lt;/strong&gt; → information about the role itself (author, dependencies on other roles, supported platforms).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tests/&lt;/strong&gt; → sample files for testing the role on its own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; instead of one 60-task file that's hard to read, you can split work into roles — like a &lt;code&gt;kubernetes-master&lt;/code&gt; role and a &lt;code&gt;kubernetes-worker&lt;/code&gt; role — each with its own clean &lt;code&gt;tasks/main.yml&lt;/code&gt;, and your main playbook just says "apply this role to these servers." Much easier to read, reuse, and debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick recap (for revision before interviews)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ad-hoc command&lt;/strong&gt; = one quick instruction (&lt;code&gt;ansible ...&lt;/code&gt;). &lt;strong&gt;Playbook&lt;/strong&gt; = a written, repeatable set of steps (&lt;code&gt;ansible-playbook ...&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inventory file&lt;/strong&gt; = a plain text list of the servers Ansible manages; add more lines for more servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passwordless SSH&lt;/strong&gt; = generate a key pair with &lt;code&gt;ssh-keygen&lt;/code&gt;, then add the public key to the target's &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; so no password or &lt;code&gt;.pem&lt;/code&gt; is needed on future logins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hosts: localhost&lt;/code&gt; + &lt;code&gt;connection: local&lt;/code&gt;&lt;/strong&gt; = run the playbook on the control machine itself, not a remote target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-vvvv&lt;/code&gt;&lt;/strong&gt; = verbose mode, for seeing exactly what Ansible is doing when something isn't working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roles&lt;/strong&gt; = the standard way to organize large, complex playbooks into clean, reusable folders (&lt;code&gt;tasks&lt;/code&gt;, &lt;code&gt;vars&lt;/code&gt;, &lt;code&gt;defaults&lt;/code&gt;, &lt;code&gt;handlers&lt;/code&gt;, &lt;code&gt;templates&lt;/code&gt;, etc.), created instantly with &lt;code&gt;ansible-galaxy role init &amp;lt;name&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ansible</category>
      <category>automation</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>Top AWS Services Every DevOps Engineer Should Know</title>
      <dc:creator>Ashwarya</dc:creator>
      <pubDate>Sun, 23 Aug 2026 10:30:04 +0000</pubDate>
      <link>https://dev.to/xcl1br/top-aws-services-every-devops-engineer-should-know-3hg9</link>
      <guid>https://dev.to/xcl1br/top-aws-services-every-devops-engineer-should-know-3hg9</guid>
      <description>&lt;p&gt;Today I learnt about the AWS services that come up again and again in DevOps work — and also in DevOps interviews.One thing the video I watched said, which I really liked: you don't need to know &lt;em&gt;every&lt;/em&gt; AWS service deeply. You need to know the ones your job actually uses, but you should at least understand what each major service does, because interviewers love asking "what is X and when would you use it."&lt;/p&gt;

&lt;p&gt;For each service below, I've covered: what it is in plain words, a real example, important commands, and how to think about it if it comes up in an interview.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. EC2 (Elastic Compute Cloud)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A virtual computer that you rent from AWS. This is the most basic and most used service — it's literally a server in the cloud that you can install anything on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; You built a website on your laptop. To make it live for the world, you rent an EC2 "instance" (a virtual computer), put your code on it, and now anyone can visit it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Hosting websites, running backend applications, running any software that normally needs a physical server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 run-instances &lt;span class="nt"&gt;--image-id&lt;/span&gt; ami-xxxx &lt;span class="nt"&gt;--instance-type&lt;/span&gt; t2.micro   &lt;span class="c"&gt;# launch a new server&lt;/span&gt;
aws ec2 describe-instances                                          &lt;span class="c"&gt;# list your servers&lt;/span&gt;
aws ec2 start-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-xxxx                       &lt;span class="c"&gt;# turn a server on&lt;/span&gt;
aws ec2 stop-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-xxxx                        &lt;span class="c"&gt;# turn a server off&lt;/span&gt;
aws ec2 terminate-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; i-xxxx                   &lt;span class="c"&gt;# delete a server permanently&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; If asked "what is EC2," say it in one line: &lt;em&gt;"EC2 gives you a virtual server in the cloud that you fully control, like your own computer, but rented."&lt;/em&gt; Interviewers often follow up by asking about instance types (like t2.micro, t3.medium) — these just decide how powerful (CPU/RAM) your server is, and cost more as they get bigger.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. VPC (Virtual Private Cloud)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Your own private, isolated network inside AWS. Think of it as a fenced-off area where only your resources live, and you decide what can enter or leave.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Two companies can both have servers in AWS, but their VPCs keep them completely separate — like two different buildings, even though both are on the same street (AWS's data center).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Controlling which parts of your app can talk to the internet, and which parts should stay hidden (like a database that should never be public).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-vpc &lt;span class="nt"&gt;--cidr-block&lt;/span&gt; 10.0.0.0/16              &lt;span class="c"&gt;# create a private network&lt;/span&gt;
aws ec2 create-subnet &lt;span class="nt"&gt;--vpc-id&lt;/span&gt; vpc-xxxx &lt;span class="nt"&gt;--cidr-block&lt;/span&gt; 10.0.1.0/24   &lt;span class="c"&gt;# divide it into smaller sections&lt;/span&gt;
aws ec2 describe-security-groups                          &lt;span class="c"&gt;# see the "firewall" rules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; A common question is "what is a CIDR block?" — simple answer: it's just a range of IP addresses (like 10.0.0.0/16), a way of saying "these many addresses belong to my network." Also expect: "difference between security group and NACL" — a security group is like a guard checking each visitor at your door (per server), while a NACL checks everyone entering the whole building (per subnet).&lt;/p&gt;




&lt;h2&gt;
  
  
  3. EBS (Elastic Block Store)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A hard disk (storage) that you attach to your EC2 server. Just like you can plug in a pen drive to your laptop, you can attach an EBS "volume" to your virtual server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your EC2 server crashed, but your EBS volume (where all the data was saved) is untouched — you can detach it and attach it to a brand-new server, and all your files are still there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Storing data that needs to stay even if the server restarts, taking backups (called "snapshots"), and moving data between servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-volume &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; us-east-1a &lt;span class="nt"&gt;--size&lt;/span&gt; 20    &lt;span class="c"&gt;# create a new disk&lt;/span&gt;
aws ec2 attach-volume &lt;span class="nt"&gt;--volume-id&lt;/span&gt; vol-xxxx &lt;span class="nt"&gt;--instance-id&lt;/span&gt; i-xxxx &lt;span class="nt"&gt;--device&lt;/span&gt; /dev/sdf   &lt;span class="c"&gt;# attach it to a server&lt;/span&gt;
aws ec2 create-snapshot &lt;span class="nt"&gt;--volume-id&lt;/span&gt; vol-xxxx                      &lt;span class="c"&gt;# take a backup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Be ready for "EBS vs S3" — EBS is like a disk attached to one server (block storage), while S3 is more like a big shared online locker for files (object storage), accessible from anywhere without attaching to a specific server.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. S3 (Simple Storage Service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Cloud storage for files — images, videos, backups, logs, anything. It's cheap, and it doesn't need to be "attached" to any server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Instead of saving user-uploaded profile photos on your server's disk (which is risky, since a server could go down), you save them in an S3 "bucket," and your app just fetches them from there whenever needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Storing backups, hosting static websites, storing logs, storing any file your app needs to keep long-term. AWS also pushes everyone to keep S3 encrypted for security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 mb s3://my-bucket-name         &lt;span class="c"&gt;# create a new storage bucket&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;myfile.txt s3://my-bucket-name/     &lt;span class="c"&gt;# upload a file&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;ls &lt;/span&gt;s3://my-bucket-name/        &lt;span class="c"&gt;# list files in the bucket&lt;/span&gt;
aws s3 &lt;span class="nb"&gt;sync&lt;/span&gt; ./localfolder s3://my-bucket-name/   &lt;span class="c"&gt;# upload/sync an entire folder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; A favorite interview question: "Is S3 storage or a database?" Answer clearly: it's storage for files (called "objects"), not a database — you can't run SQL-style queries on it directly.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. EFS (Elastic File System)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A shared file storage system that many EC2 servers can use &lt;em&gt;at the same time&lt;/em&gt;. Unlike EBS (which connects to just one server), EFS can be shared across many.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; You have 5 EC2 servers all running the same application, and all 5 need access to the same set of uploaded files at once. EBS can't do that (one disk, one server), but EFS can.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Applications that generate or need a lot of shared data across multiple servers — like content management systems, shared logs, or big data processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws efs create-file-system                          &lt;span class="c"&gt;# create shared storage&lt;/span&gt;
aws efs create-mount-target &lt;span class="nt"&gt;--file-system-id&lt;/span&gt; fs-xxxx &lt;span class="nt"&gt;--subnet-id&lt;/span&gt; subnet-xxxx   &lt;span class="c"&gt;# connect it to your network&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Remember the one-line difference: &lt;em&gt;EBS = one server, one disk. EFS = many servers, one shared disk.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. IAM (Identity and Access Management)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; AWS's system for controlling who is allowed to do what. You create "users" or "roles" and give them specific permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; In a company, a developer might get permission to only view and edit code deployment, while the QA (testing) team only gets "read-only" access — they can look but not change anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Keeping your AWS account safe by giving each person or each application only the access they truly need — never giving everyone full control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws iam create-user &lt;span class="nt"&gt;--user-name&lt;/span&gt; john             &lt;span class="c"&gt;# create a new user&lt;/span&gt;
aws iam attach-user-policy &lt;span class="nt"&gt;--user-name&lt;/span&gt; john &lt;span class="nt"&gt;--policy-arn&lt;/span&gt; arn:aws:iam::aws:policy/ReadOnlyAccess   &lt;span class="c"&gt;# give permission&lt;/span&gt;
aws iam list-users                                &lt;span class="c"&gt;# see all users&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; This is one of the most-asked topics. Learn the term &lt;strong&gt;"principle of least privilege"&lt;/strong&gt; — meaning give the smallest amount of access needed to do the job, nothing extra. Interviewers love hearing this exact phrase.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. CloudWatch
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; AWS's monitoring and alerting tool. It watches your servers and services, and tells you if something looks wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; If someone accidentally creates an EBS volume without encryption, CloudWatch can be set up to instantly send you a notification about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Tracking server health (CPU usage, memory), setting up alarms (e.g., "alert me if CPU usage goes above 90%"), and collecting logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudwatch put-metric-alarm &lt;span class="nt"&gt;--alarm-name&lt;/span&gt; high-cpu &lt;span class="nt"&gt;--metric-name&lt;/span&gt; CPUUtilization &lt;span class="nt"&gt;--threshold&lt;/span&gt; 90 ...
aws logs describe-log-groups        &lt;span class="c"&gt;# see what logs are being collected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Be ready to explain "alarms" simply: &lt;em&gt;"An alarm is a rule — if a value crosses a limit I set, CloudWatch notifies me automatically, instead of me having to check manually all the time."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Lambda
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A way to run small pieces of code without managing any server at all. You just upload your code, and AWS runs it only when needed — this is called "serverless."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Every time a new file is uploaded to S3, you want to automatically resize the image. Instead of running a server 24/7 just waiting for uploads, you use Lambda — it wakes up only when a file is uploaded, does the job, and then shuts down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Small, event-driven tasks — like processing an uploaded file, sending a notification, or running a scheduled job — without paying for a server that's idle most of the time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws lambda create-function &lt;span class="nt"&gt;--function-name&lt;/span&gt; myFunction &lt;span class="nt"&gt;--runtime&lt;/span&gt; python3.9 &lt;span class="nt"&gt;--handler&lt;/span&gt; index.handler ...
aws lambda invoke &lt;span class="nt"&gt;--function-name&lt;/span&gt; myFunction output.json    &lt;span class="c"&gt;# manually run/test the function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; The key phrase interviewers want to hear is &lt;strong&gt;"serverless"&lt;/strong&gt; — meaning you don't manage or pay for a server sitting idle; you only pay for the exact time your code actually runs.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. AWS CodePipeline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A tool that automates your entire release process — from code being pushed, to being tested, to being deployed — step by step, automatically. It's AWS's version of a CI/CD pipeline (similar to Jenkins pipelines).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; A developer pushes code to GitHub. CodePipeline automatically detects this, runs the tests, and if everything passes, deploys the new version — no manual steps needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Automating the full journey of code from "written" to "live," reducing human error and saving time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws codepipeline create-pipeline &lt;span class="nt"&gt;--cli-input-json&lt;/span&gt; file://pipeline.json
aws codepipeline get-pipeline-state &lt;span class="nt"&gt;--name&lt;/span&gt; my-pipeline    &lt;span class="c"&gt;# check pipeline status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Know the difference between CodePipeline (the overall automation flow / orchestrator) versus CodeBuild and CodeDeploy (specific jobs within that flow) — interviewers often check if you understand how these three connect.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. AWS CodeBuild
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A managed service that takes your code, compiles/builds it, runs your tests, and packages it — ready to be deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your code needs to be converted from source files into a runnable package (like a &lt;code&gt;.jar&lt;/code&gt; or a Docker image) — CodeBuild does this step automatically every time new code comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Automatically building and testing code as part of your CI/CD pipeline, instead of doing it manually on your own laptop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws codebuild create-project &lt;span class="nt"&gt;--name&lt;/span&gt; my-build-project &lt;span class="nt"&gt;--source&lt;/span&gt; ... &lt;span class="nt"&gt;--artifacts&lt;/span&gt; ...
aws codebuild start-build &lt;span class="nt"&gt;--project-name&lt;/span&gt; my-build-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Simple one-liner to remember: &lt;em&gt;"CodeBuild = compiles code and runs tests. CodeDeploy = takes that finished package and installs it on servers."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  11. AWS CodeDeploy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A service that automatically installs (deploys) your finished application onto EC2 servers or your own on-site servers, after CodeBuild has prepared it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Once your app is built and tested, CodeDeploy pushes the new version onto all your live servers, ideally without any downtime for users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Rolling out new versions of your app safely and consistently across many servers at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws deploy create-deployment &lt;span class="nt"&gt;--application-name&lt;/span&gt; myApp &lt;span class="nt"&gt;--deployment-group-name&lt;/span&gt; myGroup &lt;span class="nt"&gt;--s3-location&lt;/span&gt; &lt;span class="nv"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-bucket,key&lt;span class="o"&gt;=&lt;/span&gt;app.zip,bundleType&lt;span class="o"&gt;=&lt;/span&gt;zip
aws deploy get-deployment &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; d-xxxx    &lt;span class="c"&gt;# check deployment status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Interviewers may ask about deployment strategies here — like "rolling deployment" (update servers a few at a time) vs "blue-green deployment" (run the new version alongside the old one, then switch traffic over). Knowing these terms shows real understanding, not just memorized definitions.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. AWS Config
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A service that keeps a constant eye on how your AWS resources are configured, and flags anything that doesn't follow the rules you set — like a safety guardrail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; If someone creates an S3 bucket without encryption, or leaves it publicly open by mistake, AWS Config can detect this and flag it as a violation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Making sure your whole AWS setup stays compliant with your company's security rules, even as many people make changes over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws configservice describe-config-rules            &lt;span class="c"&gt;# see the rules currently being checked&lt;/span&gt;
aws configservice get-compliance-details-by-config-rule &lt;span class="nt"&gt;--config-rule-name&lt;/span&gt; my-rule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Simple way to explain it: &lt;em&gt;"AWS Config doesn't stop bad configurations from happening — it detects and reports them, so you know something needs fixing."&lt;/em&gt; This is different from IAM, which actually prevents access in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. AWS KMS (Key Management Service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A service for creating and managing encryption keys — the "locks and keys" used to protect your sensitive data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your database stores customer information. KMS provides the encryption key that scrambles this data, so even if someone gets access to the raw files, they can't read anything without the key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Encrypting sensitive data (like S3 files, EBS volumes, or database fields) and controlling exactly who has permission to use the key to unlock that data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws kms create-key &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"My encryption key"&lt;/span&gt;       &lt;span class="c"&gt;# create a new key&lt;/span&gt;
aws kms list-keys                                           &lt;span class="c"&gt;# see all your keys&lt;/span&gt;
aws kms encrypt &lt;span class="nt"&gt;--key-id&lt;/span&gt; xxxx &lt;span class="nt"&gt;--plaintext&lt;/span&gt; &lt;span class="s2"&gt;"secret data"&lt;/span&gt;     &lt;span class="c"&gt;# encrypt something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; A common question: "Why not just encrypt data yourself?" Good answer: &lt;em&gt;"KMS securely manages and rotates the keys for you, and tightly controls who can use them — doing this yourself is much riskier and harder to audit."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  14. CloudTrail
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A service that records every single action taken in your AWS account — who did what, and when. Think of it as a security camera for your whole AWS account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Someone deleted an important S3 bucket. CloudTrail lets you look back and see exactly which user (or automated process) did it, and at what time — useful for investigating what went wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Auditing, compliance checks, and investigating security incidents by reviewing a full history of account activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudtrail describe-trails               &lt;span class="c"&gt;# see trails currently recording activity&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="nt"&gt;--max-results&lt;/span&gt; 10   &lt;span class="c"&gt;# view recent account activity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Know the difference clearly: &lt;em&gt;"CloudWatch monitors performance and can alert on it. CloudTrail records who did what — it's about accountability and audit history, not performance."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  15. EKS (Elastic Kubernetes Service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; AWS's managed version of Kubernetes — a system for running and managing many containers (small, packaged pieces of an application) automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example:&lt;/strong&gt; Your app is broken into 10 small services (microservices), each running in its own container. Managing all of them manually is a nightmare, so EKS handles starting, stopping, scaling, and healing them automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case:&lt;/strong&gt; Running large, container-based applications that need to scale up and down automatically, and recover on their own if something crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important commands:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks create-cluster &lt;span class="nt"&gt;--name&lt;/span&gt; my-cluster &lt;span class="nt"&gt;--role-arn&lt;/span&gt; arn:xxxx &lt;span class="nt"&gt;--resources-vpc-config&lt;/span&gt; &lt;span class="nv"&gt;subnetIds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;...
aws eks update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; my-cluster        &lt;span class="c"&gt;# connect your local kubectl tool to this cluster&lt;/span&gt;
kubectl get pods                                   &lt;span class="c"&gt;# see running containers (once connected)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview point of view:&lt;/strong&gt; Interviewers often ask "why use EKS instead of running Kubernetes yourself?" Answer: &lt;em&gt;"EKS manages the hard, ongoing operational work of running Kubernetes (like patching and scaling the control plane) for you, so you just focus on your applications."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: Containers &amp;amp; Logging (also mentioned in the video)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ECS (Elastic Container Service)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; AWS's own, simpler alternative to Kubernetes for running containers — built and managed entirely by AWS.&lt;br&gt;
&lt;strong&gt;Interview tip:&lt;/strong&gt; If asked "ECS vs EKS," say: &lt;em&gt;"ECS is AWS's own simpler container system. EKS is AWS's managed version of Kubernetes, the industry-standard tool — EKS is heavier but more portable across cloud providers."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fargate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A way to run containers (through ECS or EKS) without managing any servers at all — fully serverless containers.&lt;br&gt;
&lt;strong&gt;Interview tip:&lt;/strong&gt; One-liner: &lt;em&gt;"Fargate removes the need to manage the underlying EC2 servers for your containers — AWS handles that completely."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ELK Stack (Elasticsearch, Logstash, Kibana)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A popular open-source combo for collecting, storing, and visualizing logs from many services at once.&lt;br&gt;
&lt;strong&gt;Real example:&lt;/strong&gt; With 50 microservices all producing logs, ELK lets you search "show me all errors from the last hour across every service" in one place, instead of checking each server one by one.&lt;br&gt;
&lt;strong&gt;Interview tip:&lt;/strong&gt; Mention that ELK isn't AWS-only — it's an industry-standard logging setup, and many companies use it alongside AWS services like CloudWatch.&lt;/p&gt;




&lt;h2&gt;
  
  
  My takeaway from today
&lt;/h2&gt;

&lt;p&gt;The biggest lesson wasn't the list of services itself — it was realizing that most of these services solve one of just a few basic problems: where do I run my code (EC2, Lambda, EKS, ECS), where do I store my data (S3, EBS, EFS), who's allowed to do what (IAM, KMS), and how do I know what's happening (CloudWatch, CloudTrail, Config). Once you group them like that, they're much easier to remember — and much easier to explain in an interview.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/leWJypzVyQ4" rel="noopener noreferrer"&gt;Original video&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cloud</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>My First Time Putting an App on AWS (A Beginner's Story)</title>
      <dc:creator>Ashwarya</dc:creator>
      <pubDate>Sun, 16 Aug 2026 12:29:39 +0000</pubDate>
      <link>https://dev.to/xcl1br/my-first-time-putting-an-app-on-aws-a-beginners-story-41d3</link>
      <guid>https://dev.to/xcl1br/my-first-time-putting-an-app-on-aws-a-beginners-story-41d3</guid>
      <description>&lt;p&gt;Today I did something I've wanted to do for a while — I took an app running on my own laptop and put it "live" on the internet using AWS. It sounds scary when you read about it online, but once I actually did it, it was just a bunch of small, simple steps, one after another.&lt;/p&gt;

&lt;p&gt;This post is me writing down everything I did, in plain, easy words, so that if you're a beginner like me, you can follow along without getting confused by fancy tech terms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is AWS, in simple words?&lt;/strong&gt;&lt;br&gt;
AWS (Amazon Web Services) is basically Amazon renting out computers over the internet. Instead of buying your own physical server and keeping it running 24/7 at home, you "rent" a computer from Amazon. That computer runs your app, and anyone with the internet can visit it.&lt;br&gt;
The specific service I used is called &lt;strong&gt;EC2&lt;/strong&gt;. Think of EC2 as one virtual computer that lives in Amazon's data center, and you get to control it like it's your own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 1: Set up IAM first&lt;br&gt;
&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
Before touching any servers, I went to IAM (Identity and Access Management). This is AWS's way of managing "who is allowed to do what" in your account.&lt;/p&gt;

&lt;p&gt;In simple words: instead of using your main AWS login for everything (which is risky), IAM lets you create a separate user with its own permissions. It's like giving someone a spare key instead of your master key. I set this up first so my account stays safer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 2: Launch an EC2 instance&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, I went to the EC2 section and launched a new instance (a fancy word for "a virtual computer"). During this step, AWS also lets you create a .pem file — this is basically a secret key file. It's like a digital key to a lock. Only someone with this file can get into the server. I downloaded it and kept it safe, because if you lose it, you can't easily get back in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 3: Login to the server using SSH&lt;br&gt;
&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
Once the server (EC2 instance) was ready, I needed a way to "log in" to it from my own laptop. For that, I used something called SSH, along with the .pem key file I downloaded earlier.&lt;/p&gt;

&lt;p&gt;In simple words: SSH is like a secure phone call between your laptop and the AWS server, and the .pem file is the password that proves it's really you calling.&lt;/p&gt;

&lt;p&gt;Once connected, my laptop's terminal was now basically "inside" the AWS computer. Anything I typed from here on ran on the AWS server, not my own laptop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 4: Update the server&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The very first thing to do on a fresh server is:&lt;/p&gt;

&lt;p&gt;sudo apt update&lt;/p&gt;

&lt;p&gt;In simple words: this just checks for the latest versions of software so everything installed after this is up to date. Think of it like checking for updates before installing new apps on your phone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 5: Install the dependencies&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, I installed the "dependencies" — these are just the extra tools and programs my app needs to actually run (things like Node.js, npm, git, etc., depending on the app). Without these, the app's code would have nowhere to run, kind of like trying to play a video game without installing the game console first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 6: Bring the code onto the server&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get my actual project code onto this AWS server, I used:&lt;/p&gt;

&lt;p&gt;git clone &lt;/p&gt;

&lt;p&gt;This downloads a copy of my project (that was sitting on GitHub) directly onto the AWS server. Now the server has all my app's files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 7: Set up the .env file (the secret settings file)&lt;br&gt;
&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
Most apps need some private settings — like passwords, API keys, or database links — that should never be shared publicly on GitHub. These usually go in a file called .env.&lt;/p&gt;

&lt;p&gt;Here's exactly what I did:&lt;/p&gt;

&lt;p&gt;touch .env&lt;/p&gt;

&lt;p&gt;This creates a new, empty file named .env.&lt;/p&gt;

&lt;p&gt;ls -a&lt;/p&gt;

&lt;p&gt;This lists all files, including hidden ones (files starting with a dot are hidden by default), just to confirm .env was really created.&lt;/p&gt;

&lt;p&gt;vim .env&lt;/p&gt;

&lt;p&gt;This opens the file in a text editor called Vim, right inside the terminal.&lt;/p&gt;

&lt;p&gt;Inside Vim, I pressed i to switch into "insert mode" (this lets you actually type text — Vim doesn't let you type by default, which confused me at first). Then I typed in my credentials (my secret settings, like API keys).&lt;/p&gt;

&lt;p&gt;After typing everything, I pressed Esc to leave insert mode, then typed :x and hit Enter. This saves the file and closes Vim.&lt;/p&gt;

&lt;p&gt;In simple words: Vim feels strange the first time because you can't just start typing like Notepad — you have to "unlock" typing mode with i, and then "save and exit" with a special command. It trips up almost every beginner once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 8: Open the door — editing the Security Group&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even after all this, my app still wasn't visible on the internet. That's because AWS blocks all traffic by default, for safety. You have to manually tell AWS which "doors" (ports) are allowed to be opened.&lt;/p&gt;

&lt;p&gt;Here's what I did:&lt;/p&gt;

&lt;p&gt;Went to my EC2 instance page.&lt;br&gt;
Clicked on the Security tab.&lt;br&gt;
Clicked Edit inbound rules.&lt;br&gt;
Added a new rule and set the port to 3000 (since that's the port my app runs on).&lt;br&gt;
Saved the rule.&lt;/p&gt;

&lt;p&gt;In simple words: a "port" is like a specific door number on the server. My app was listening on door number 3000, but AWS had that door locked. This step unlocked it so people from outside could knock and get in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Step 9: The moment it goes live&lt;br&gt;
&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
After all that, I just opened a browser and typed:&lt;/p&gt;

&lt;p&gt;:3000&lt;/p&gt;

&lt;p&gt;And there it was — my app, running live on the internet, for anyone in the world to open.&lt;/p&gt;

&lt;p&gt;What I learned&lt;/p&gt;

&lt;p&gt;Honestly, none of these steps were individually hard. What made it feel scary before doing it was not knowing the order things happen in, and not knowing what each command actually does. Once I understood that:&lt;/p&gt;

&lt;p&gt;IAM is about who can access what&lt;br&gt;
EC2 is just a rented computer&lt;br&gt;
SSH + .pem is how you securely log into that computer&lt;br&gt;
The .env file holds your app's secrets&lt;br&gt;
The Security Group is basically a locked door that you have to manually open&lt;/p&gt;

&lt;p&gt;...it all made a lot more sense. If you're trying this for the first time, don't worry about memorizing every command. Just understand what each step is trying to do, and the commands will make sense on their own.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>ec2</category>
      <category>iam</category>
    </item>
    <item>
      <title>Setting Up an EC2 Instance and Logging In With MobaXterm</title>
      <dc:creator>Ashwarya</dc:creator>
      <pubDate>Thu, 17 Oct 2024 07:27:27 +0000</pubDate>
      <link>https://dev.to/xcl1br/security-principles-33ho</link>
      <guid>https://dev.to/xcl1br/security-principles-33ho</guid>
      <description>&lt;p&gt;This one's shorter — just the actual process of creating an EC2 instance from the AWS console, and then getting into it from a Windows laptop using MobaXterm, plus the handful of things that actually go wrong when you try this for the first time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launching the instance
&lt;/h2&gt;

&lt;p&gt;Nothing too dramatic here, it's mostly filling in a form on the EC2 page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to EC2 → &lt;strong&gt;Launch Instance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Give it a name.&lt;/li&gt;
&lt;li&gt;Pick an AMI — this is just the operating system image, Ubuntu and Amazon Linux are the common picks for practice.&lt;/li&gt;
&lt;li&gt;Pick an instance type — &lt;code&gt;t2.micro&lt;/code&gt; is the usual free-tier choice for messing around.&lt;/li&gt;
&lt;li&gt;Create (or pick) a &lt;strong&gt;key pair&lt;/strong&gt;. This downloads a &lt;code&gt;.pem&lt;/code&gt; file to your laptop — this is the only copy AWS gives you, so don't lose it. If you do, there's no "re-download," you just have to make a new key pair.&lt;/li&gt;
&lt;li&gt;Leave network settings as default for a first try, but make sure "Allow SSH traffic" is ticked, since that's what lets you log in later at all.&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Launch Instance&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Give it a minute to go from "pending" to "running" before trying to connect — it won't accept SSH connections until it's actually up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the pieces together before connecting
&lt;/h2&gt;

&lt;p&gt;Two things you need in hand before opening MobaXterm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The instance's &lt;strong&gt;public IPv4 address&lt;/strong&gt; — on the instance's details page.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;.pem file&lt;/strong&gt; you downloaded in step 5.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Worth knowing: if you ever stop and restart the instance (not terminate, just stop/start), the public IP usually changes unless you've attached an Elastic IP. So don't be surprised if an IP that worked yesterday doesn't work today — go grab the new one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting with MobaXterm
&lt;/h2&gt;

&lt;p&gt;MobaXterm is basically the Windows equivalent of a terminal, and it can use &lt;code&gt;.pem&lt;/code&gt; files directly — no need to convert them to &lt;code&gt;.ppk&lt;/code&gt; like you would for old-school PuTTY.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open MobaXterm → &lt;strong&gt;Session&lt;/strong&gt; → &lt;strong&gt;SSH&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Remote host: paste the public IP.&lt;/li&gt;
&lt;li&gt;Specify username: &lt;code&gt;ubuntu&lt;/code&gt; for an Ubuntu AMI, &lt;code&gt;ec2-user&lt;/code&gt; for Amazon Linux. Getting this wrong is more common than you'd think.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced SSH Settings&lt;/strong&gt; tab → tick &lt;strong&gt;Use private key&lt;/strong&gt; → Browse → select your &lt;code&gt;.pem&lt;/code&gt; file → OK.&lt;/li&gt;
&lt;li&gt;Click OK to connect. First time around, it'll ask if you trust the host — accept it, and you're in.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To close the session, just type &lt;code&gt;exit&lt;/code&gt; or hit &lt;code&gt;Ctrl+D&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're doing this from a regular terminal instead of MobaXterm (Mac/Linux), the equivalent is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;400 mykey.pem
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; mykey.pem ubuntu@&amp;lt;public-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What actually goes wrong
&lt;/h2&gt;

&lt;p&gt;A few things trip people up almost every time on the first attempt:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connection timed out&lt;/strong&gt; — nine times out of ten, this is the security group, not MobaXterm. Go to the instance's Security tab → inbound rules, and make sure port 22 (SSH) is open to your IP (or 0.0.0.0/0 for practice, though that's not something you'd leave open in anything real). If your IP changed since you set the rule — which happens a lot on home Wi-Fi — update it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication failed / wrong username&lt;/strong&gt; — this one's just a wrong guess on &lt;code&gt;ubuntu&lt;/code&gt; vs &lt;code&gt;ec2-user&lt;/code&gt;. Check which AMI you actually launched and match the username to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt; — usually means you're pointing at the wrong &lt;code&gt;.pem&lt;/code&gt; file, or using a key that doesn't match the instance it was created for. Each key pair only works with the instance(s) it was attached to at launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Bad permissions" error on the key file&lt;/strong&gt; — only happens on Mac/Linux terminals, not really in MobaXterm itself. SSH refuses to use a private key file that's too open, which is what the &lt;code&gt;chmod 400&lt;/code&gt; step above fixes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It worked yesterday, not today&lt;/strong&gt; — almost always the IP address changing after a stop/start, as mentioned above. Re-check the current public IP before assuming something's broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session just freezes or hangs&lt;/strong&gt; — sometimes it's a shaky network or a corporate VPN/firewall quietly blocking outbound port 22. Worth testing from a different network if nothing else explains it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick mention: there's also a CLI way
&lt;/h2&gt;

&lt;p&gt;Instead of clicking around the console every time, you can also manage EC2 from your own terminal using the AWS CLI — install it, run &lt;code&gt;aws configure&lt;/code&gt; with your access key, secret key, and region, and then commands like &lt;code&gt;aws ec2 describe-instances&lt;/code&gt; or &lt;code&gt;aws s3 ls&lt;/code&gt; talk straight to your AWS account. It's worth knowing this exists even if console + MobaXterm is where most people start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Almost every "it's not connecting" problem traces back to one of three things: the security group not allowing your IP on port 22, the wrong username for the AMI, or an IP address that quietly changed after a restart. Once you've hit each of these once, they stop being mysterious.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
