<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Arish Writes: Engineering & Systems]]></title><description><![CDATA[Practical articles on backend development, cloud systems, and software engineering fundamentals, written to help developers build scalable, reliable, and production-grade applications.]]></description><link>https://blog.arishahmad.in</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 10:43:38 GMT</lastBuildDate><atom:link href="https://blog.arishahmad.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Go Channels: Complete Guide to Communication Patterns in Go]]></title><description><![CDATA[1. Introduction to Concurrency in Go
Concurrency means multiple tasks making progress at the same time.
It does not always mean running at the exact same moment (that is parallelism). Instead, concurr]]></description><link>https://blog.arishahmad.in/go-channels-complete-guide-to-communication-patterns-in-go</link><guid isPermaLink="true">https://blog.arishahmad.in/go-channels-complete-guide-to-communication-patterns-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[concurrency-in-go]]></category><category><![CDATA[channels in go]]></category><category><![CDATA[golang]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Wed, 18 Mar 2026 21:50:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/640cddfdb1e4eb4512040ddf/d6e5031d-4bdb-451c-839a-458113468390.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. Introduction to Concurrency in Go</h2>
<p><strong>Concurrency</strong> means <strong>multiple tasks making progress at the same time</strong>.</p>
<p>It does <strong>not always mean running at the exact same moment</strong> (that is parallelism). Instead, concurrency is about <strong>structuring programs so many tasks can progress independently</strong>.</p>
<h2>2. Why Go Uses Goroutines + Channels?</h2>
<p>Go was designed to <strong>make concurrency simple and scalable</strong>.</p>
<p>Instead of relying on heavy threads and complicated locking, Go introduced two core primitives:</p>
<h3>2.1 Goroutines</h3>
<p>Lightweight concurrent functions. A goroutine is much cheaper than a traditional thread. You can run <strong>hundreds of thousands</strong> of them.</p>
<h3>2.2 Channels</h3>
<p>A <strong>channel</strong> in Go is a <strong>communication mechanism that allows goroutines to send and receive data safely</strong>.</p>
<p>Think of a channel as a <strong>typed pipe</strong> through which values flow between goroutines.</p>
<p>Channels are powerful because they provide <strong>three guarantees</strong>:</p>
<h3>2.2.1. Safe Communication</h3>
<p>Channels synchronize goroutines automatically. Send blocks until receive happens, this ensures safe coordination.</p>
<h3>2.2.2. Built-in Synchronization</h3>
<p>Channels remove the need for:</p>
<ul>
<li><p>mutexes</p>
</li>
<li><p>locks</p>
</li>
<li><p>condition variables</p>
</li>
</ul>
<h3>2.2.3. Structured Concurrency Patterns</h3>
<p>Channels enable powerful patterns such as:</p>
<ul>
<li><p><strong>One-to-One communication</strong></p>
</li>
<li><p><strong>Fan-Out (one producer, many workers)</strong></p>
</li>
<li><p><strong>Fan-In (many producers, one consumer)</strong></p>
</li>
<li><p><strong>Pipelines</strong></p>
</li>
<li><p><strong>Broadcast</strong></p>
</li>
<li><p><strong>Worker pools</strong></p>
</li>
</ul>
<p>These patterns make Go programs <strong>clean, scalable, and easy to reason about</strong>.</p>
<h2>3. Channel Type Safety</h2>
<p>Channels in Go are <strong>strongly typed</strong>. This means a channel can only send and receive <strong>one specific type of data</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int)
</code></pre>
<p>This channel can <strong>only transmit integers</strong>.</p>
<p><strong>Valid:</strong></p>
<pre><code class="language-plaintext">ch &lt;- 10
</code></pre>
<p><strong>Invalid:</strong></p>
<pre><code class="language-plaintext">ch &lt;- "hello"   // compile-time error
</code></pre>
<p>This <strong>type safety prevents many runtime bugs</strong> and makes concurrent code more predictable.</p>
<h2>4. Channel Syntax</h2>
<p>Channels have a simple syntax consisting of three main operations.</p>
<h3>4.1. Creating a Channel</h3>
<p>Channels are created using the <code>make</code> function.</p>
<pre><code class="language-plaintext">make(chan T)
</code></pre>
<p><strong>Where:</strong></p>
<ul>
<li><code>T</code> = type of data the channel carries</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int)
</code></pre>
<p>This creates a channel capable of sending and receiving <strong>integers</strong>.</p>
<h3>4.2. Sending Data to a Channel</h3>
<p>Data is sent to a channel using the <strong>arrow operator</strong>.</p>
<pre><code class="language-plaintext">ch &lt;- value
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch &lt;- 5
</code></pre>
<p><strong>This means:</strong> send value 5 into channel ch</p>
<p>Usually this is done inside a <strong>goroutine</strong>.</p>
<pre><code class="language-plaintext">go func() {
    ch &lt;- 5
}()
</code></pre>
<h3>4.3. Receiving Data from a Channel</h3>
<p>To receive a value from a channel:</p>
<pre><code class="language-plaintext">value := &lt;-ch
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">num := &lt;-ch
fmt.Println(num)
</code></pre>
<p><strong>This means:</strong> take a value from channel ch and store it in num</p>
<h2>5. Blocking Behavior of Channels</h2>
<p>One of the most important characteristics of channels is <strong>blocking behavior</strong>.</p>
<p>Channels automatically <strong>synchronize goroutines</strong>.</p>
<h3>5.1. Send Blocks</h3>
<p>When sending:</p>
<pre><code class="language-plaintext">ch &lt;- value
</code></pre>
<p>The goroutine <strong>waits until another goroutine receives the value</strong>.</p>
<h3>5.2. Receive Blocks</h3>
<p>When receiving:</p>
<pre><code class="language-plaintext">value := &lt;-ch
</code></pre>
<p>The goroutine <strong>waits until a value is available in the channel</strong>.</p>
<h3>5.3. Visualization</h3>
<pre><code class="language-plaintext">Sender --- waiting ---&gt; Channel &lt;--- waiting --- Receiver
</code></pre>
<p>Both sides must be ready.</p>
<p>This property is what makes channels <strong>safe for concurrency without locks</strong>.</p>
<h2>6. Channel Direction in Go</h2>
<p>Channels in Go can <strong>restrict how they are used</strong>.</p>
<p>A channel can be:</p>
<ul>
<li><p><strong>Bidirectional</strong> : send and receive</p>
</li>
<li><p><strong>Send-only</strong> : only send values</p>
</li>
<li><p><strong>Receive-only</strong> : only receive values</p>
</li>
</ul>
<p>This restriction happens <strong>at compile time</strong>, preventing misuse of channels.</p>
<h3>6.1. Bidirectional Channels</h3>
<p>A <strong>bidirectional channel</strong> allows both sending and receiving.</p>
<p><strong>Syntax:</strong></p>
<pre><code class="language-plaintext">chan T
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int)

ch &lt;- 10        // send
value := &lt;-ch   // receive
</code></pre>
<p>Here the channel can perform <strong>both operations</strong>.</p>
<p>This is the <strong>default channel type</strong> in Go.</p>
<h3>6.2. Send-Only Channels</h3>
<p>A <strong>send-only channel</strong> allows <strong>only sending data</strong>.</p>
<p><strong>Syntax:</strong></p>
<pre><code class="language-plaintext">chan&lt;- T
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">func sendData(ch chan&lt;- int) {
    ch &lt;- 10
}
</code></pre>
<p><strong>Inside this function:</strong></p>
<p>Sending is allowed</p>
<pre><code class="language-plaintext">ch &lt;- 10
</code></pre>
<p>Receiving is NOT allowed</p>
<pre><code class="language-plaintext">value := &lt;-ch   // compile-time error
</code></pre>
<p>This restriction ensures the function <strong>only produces data</strong>.</p>
<h3>6.3. Receive-Only Channels</h3>
<p>A <strong>receive-only channel</strong> allows <strong>only receiving data</strong>.</p>
<p><strong>Syntax:</strong></p>
<pre><code class="language-plaintext">&lt;-chan T
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">func receiveData(ch &lt;-chan int) {
    value := &lt;-ch
    fmt.Println(value)
}
</code></pre>
<p><strong>Inside this function:</strong></p>
<p>Receiving is allowed</p>
<pre><code class="language-plaintext">value := &lt;-ch
</code></pre>
<p>Sending is NOT allowed</p>
<pre><code class="language-plaintext">ch &lt;- 10   // compile-time error
</code></pre>
<h2>7. Converting Channel Direction</h2>
<p>A <strong>bidirectional channel can be converted</strong> to a directional one.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">func producer(ch chan&lt;- int) {
    ch &lt;- 5
}

func consumer(ch &lt;-chan int) {
    value := &lt;-ch
    fmt.Println(value)
}

func main() {
    ch := make(chan int)

    go producer(ch)
    consumer(ch)
}
</code></pre>
<p><strong>Here:</strong></p>
<pre><code class="language-plaintext">main -&gt; bidirectional channel
producer -&gt; send-only channel
consumer -&gt; receive-only channel
</code></pre>
<p>Go automatically converts the channel type.</p>
<h2>8. Channel Behavior in Go</h2>
<p>Channels in Go can behave in <strong>two different ways depending on how they are created</strong>:</p>
<ol>
<li><p><strong>Unbuffered Channels</strong> : synchronous communication</p>
</li>
<li><p><strong>Buffered Channels</strong> : asynchronous communication</p>
</li>
</ol>
<p>The difference lies in whether the channel has <strong>storage capacity (a buffer)</strong>.</p>
<p>This behavior directly affects <strong>how goroutines coordinate with each other</strong>.</p>
<h3>8.1. Synchronous Communication (Unbuffered Channels)</h3>
<p>An <strong>unbuffered channel</strong> has <strong>no storage capacity</strong>.</p>
<p>This means a value <strong>cannot exist in the channel alone</strong>.<br />A <strong>sender and receiver must meet at the same time</strong> for communication to occur.</p>
<p>Since no capacity is provided, the channel is <strong>unbuffered by default</strong>.</p>
<p>Flow:</p>
<pre><code class="language-plaintext">Receiver ---- waiting ---&gt; Channel &lt;--- waiting --- Sender
</code></pre>
<h3>8.2. Asynchronous Communication (Buffered Channels)</h3>
<p>A <strong>buffered channel</strong> has <strong>internal storage capacity</strong>.</p>
<p>This allows values to be <strong>stored temporarily inside the channel</strong>.</p>
<p><strong>Creation syntax:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int, 3)
</code></pre>
<p><strong>Here:</strong> channel capacity = 3</p>
<p>The channel can hold <strong>3 values before blocking</strong>.</p>
<p><strong>Buffer Capacity</strong></p>
<p>The number given during creation defines the <strong>buffer size</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int, 2)
</code></pre>
<p>This channel can store <strong>[ value1 | value2 ]</strong> inside its internal buffer.</p>
<p><strong>Queue-like Behavior</strong></p>
<p>Buffered channels behave like a <strong>FIFO queue (First-In-First-Out)</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">ch := make(chan int, 3)

ch &lt;- 1
ch &lt;- 2
ch &lt;- 3
</code></pre>
<p><strong>Internal buffer: [1 | 2 | 3]</strong></p>
<p><strong>Receiving values:</strong></p>
<pre><code class="language-plaintext">fmt.Println(&lt;-ch)
fmt.Println(&lt;-ch)
fmt.Println(&lt;-ch)
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">1
2
3
</code></pre>
<p>Values come out <strong>in the same order they were sent</strong>.</p>
<h2>9. Basic Communication Patterns</h2>
<p>Channels enable different <strong>communication patterns between goroutines</strong>.<br />These patterns define <strong>how data flows between concurrent tasks</strong>.</p>
<p>The most basic patterns are:</p>
<ol>
<li><p><strong>One-way communication</strong></p>
</li>
<li><p><strong>Two-way communication (Request–Response)</strong></p>
</li>
</ol>
<p>Understanding these patterns helps design <strong>structured concurrent systems</strong>.</p>
<h3>9.1. One-way Communication</h3>
<p>In <strong>one-way communication</strong>, data flows <strong>in a single direction</strong> between goroutines.</p>
<p>There is <strong>one sender and one receiver</strong>, and no response is expected.</p>
<p>Two common forms are:</p>
<ol>
<li><p><strong>Main -&gt; Goroutine</strong></p>
</li>
<li><p><strong>Goroutine -&gt; Main</strong></p>
</li>
</ol>
<h3>9.1.1. Main -&gt; Goroutine</h3>
<p>In this pattern, the <strong>main goroutine acts as the producer</strong>, sending data to another goroutine that performs some work.</p>
<p><strong>Flow:</strong></p>
<pre><code class="language-plaintext">Main ---&gt; Channel ---&gt; Worker Goroutine
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func worker(ch &lt;-chan int) {
	value := &lt;-ch
	fmt.Println("Worker received:", value)
}

func main() {

	ch := make(chan int)

	go worker(ch)

	ch &lt;- 10
}
</code></pre>
<p><strong>Execution flow:</strong></p>
<ol>
<li><p>Main creates the channel</p>
</li>
<li><p>Worker goroutine starts and waits for data</p>
</li>
<li><p>Main sends value <code>10</code></p>
</li>
<li><p>Worker receives and processes it</p>
</li>
</ol>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Worker received: 10
</code></pre>
<p>Here the <strong>worker only consumes data</strong>.</p>
<h3>9.1.2. Goroutine -&gt; Main</h3>
<p>In this pattern, a <strong>worker goroutine produces a result</strong>, and the main goroutine receives it.</p>
<p><strong>Flow:</strong></p>
<pre><code class="language-plaintext">Worker Goroutine ---&gt; Channel ---&gt; Main
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func compute(ch chan&lt;- int) {
	result := 5 * 5
	ch &lt;- result
}

func main() {

	ch := make(chan int)

	go compute(ch)

	result := &lt;-ch

	fmt.Println("Result:", result)
}
</code></pre>
<h2>9.2. Two-way Communication (Request–Response)</h2>
<p>A component sends a <strong>request</strong>, and another component sends a <strong>response</strong>.</p>
<p>This pattern is called <strong>request–response communication</strong>.</p>
<p><strong>Flow:</strong></p>
<pre><code class="language-plaintext">Client --&gt; Request Channel --&gt; Worker --&gt; Response Channel --&gt; Client
</code></pre>
<h3>9.2.1. Using Two Channels</h3>
<p>The simplest approach uses <strong>two separate channels</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func worker(requests &lt;-chan int, responses chan&lt;- int) {
	req := &lt;-requests
	responses &lt;- req * 2
}

func main() {

	requestCh := make(chan int)
	responseCh := make(chan int)

	go worker(requestCh, responseCh)

	requestCh &lt;- 10

	result := &lt;-responseCh

	fmt.Println("Response:", result)
}
</code></pre>
<p><strong>Execution flow:</strong></p>
<ol>
<li><p>Main sends a request</p>
</li>
<li><p>Worker receives the request</p>
</li>
<li><p>Worker processes it</p>
</li>
<li><p>Worker sends response</p>
</li>
<li><p>Main receives result</p>
</li>
</ol>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Response: 20
</code></pre>
<h3>9.2.2. Reply Channels (More Scalable)</h3>
<p>A more advanced approach uses <strong>reply channels embedded in the request</strong>.</p>
<p><strong>Flow:</strong></p>
<pre><code class="language-plaintext">Client --&gt; Request{data, replyChannel} --&gt; Worker --&gt; replyChannel --&gt; Client
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

type Request struct {
	data  int
	reply chan int
}

func worker(reqCh &lt;-chan Request) {

	req := &lt;-reqCh

	result := req.data * 2

	req.reply &lt;- result
}

func main() {

	reqCh := make(chan Request)

	go worker(reqCh)

	replyCh := make(chan int)

	reqCh &lt;- Request{
		data:  10,
		reply: replyCh,
	}

	result := &lt;-replyCh

	fmt.Println("Response:", result)
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">Response: 20
</code></pre>
<h2>10. Channel Communication Topologies</h2>
<p>These describe <strong>how goroutines are connected through channels</strong>.</p>
<h3>10.1. One to One</h3>
<p><strong>Single producer -&gt; single consumer</strong></p>
<p>Similar concept as the One Way Communication</p>
<h3>10.2. One to Many (Fan-Out)</h3>
<p>In this topology, <strong>one producer distributes work to multiple workers</strong>.</p>
<p><strong>Key Idea:</strong></p>
<p>Multiple goroutines <strong>compete to receive from the same channel</strong>.</p>
<p><strong>Important Rule:</strong></p>
<p><strong>Each job is processed by exactly one worker</strong> because a channel delivers a value to <strong>only one receiver</strong>.</p>
<p><strong>Use Case</strong></p>
<ul>
<li><p>Parallel processing</p>
</li>
<li><p>CPU-intensive tasks</p>
</li>
<li><p>Worker pools</p>
</li>
</ul>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import (
	"fmt"
	"time"
)

func worker(id int, jobs &lt;-chan int) {
    // Keep receiving values from the channel until it is closed
	for job := range jobs { 
		fmt.Println("Worker", id, "processing job", job)
		time.Sleep(time.Millisecond * 500)
	}
}

func main() {

	jobs := make(chan int)

	// Start 3 workers
	for i := 1; i &lt;= 3; i++ {
		go worker(i, jobs)
	}

	// Send jobs
	for j := 1; j &lt;= 5; j++ {
		jobs &lt;- j
	}

	close(jobs)
	time.Sleep(time.Second * 2)
}
</code></pre>
<p>Work is <strong>distributed automatically</strong>.</p>
<h3>10.3. Many to One (Fan-In)</h3>
<p>In this topology, <strong>multiple producers send data to a single consumer</strong>.</p>
<p><strong>Key Idea</strong></p>
<p>Many goroutines produce results, and <strong>one goroutine collects them</strong>.</p>
<p><strong>Use Case</strong></p>
<ul>
<li><p>Aggregating results</p>
</li>
<li><p>Merging streams</p>
</li>
<li><p>Logging systems</p>
</li>
</ul>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func worker(id int, results chan&lt;- int) {
	results &lt;- id * 10
}

func main() {

	results := make(chan int)

	for i := 1; i &lt;= 3; i++ {
		go worker(i, results)
	}

	for i := 1; i &lt;= 3; i++ {
		fmt.Println("Result:", &lt;-results)
	}
}
</code></pre>
<h3>10.4. Many to Many</h3>
<p>This is the most flexible topology.</p>
<ul>
<li><p><strong>Multiple producers</strong></p>
</li>
<li><p><strong>Multiple consumers</strong></p>
</li>
<li><p>All connected through shared channels</p>
</li>
</ul>
<p><strong>Use Case</strong></p>
<ul>
<li><p>Worker pools</p>
</li>
<li><p>Distributed processing</p>
</li>
<li><p>Task queues</p>
</li>
<li><p>High-throughput systems</p>
</li>
</ul>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func producer(id int, ch chan&lt;- int) {
	for i := 1; i &lt;= 3; i++ {
		ch &lt;- id*10 + i
	}
}

func consumer(id int, ch &lt;-chan int) {
	for val := range ch {
		fmt.Println("Consumer", id, "received", val)
	}
}

func main() {

	ch := make(chan int)

	// Producers
	for i := 1; i &lt;= 2; i++ {
		go producer(i, ch)
	}

	// Consumers
	for i := 1; i &lt;= 3; i++ {
		go consumer(i, ch)
	}

	// Let it run briefly
	select {}
}
</code></pre>
<h2>11. Coordination and Control</h2>
<p>Channels are not just for passing data — they are powerful tools for <strong>coordinating goroutines</strong>.</p>
<p>They help answer questions like:</p>
<ul>
<li><p>When should a goroutine stop?</p>
</li>
<li><p>How do multiple goroutines react to a single event?</p>
</li>
<li><p>How do we wait for multiple events?</p>
</li>
</ul>
<p>This section covers <strong>control-oriented patterns</strong> using channels.</p>
<h3>11.1. Broadcast Communication</h3>
<p>Broadcast means <strong>one signal wakes up multiple goroutines</strong>.</p>
<p><strong>Concept:</strong> <code>close(channel)</code></p>
<p>When a channel is <strong>closed</strong>, all goroutines waiting to receive from it are <strong>unblocked immediately</strong>.</p>
<pre><code class="language-plaintext">close(ch)
</code></pre>
<p><strong>Any receive operation:</strong></p>
<pre><code class="language-plaintext">&lt;-ch
</code></pre>
<p>will now <strong>proceed instantly</strong>.</p>
<p><strong>Key Idea:</strong> Closing a channel acts like a <strong>broadcast signal</strong></p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import (
	"fmt"
	"time"
)

func worker(id int, done &lt;-chan struct{}) {
	&lt;-done
	fmt.Println("Worker", id, "stopping")
}

func main() {

	done := make(chan struct{})

	for i := 1; i &lt;= 3; i++ {
		go worker(i, done)
	}

	time.Sleep(time.Second)

	close(done) // broadcast signal

	time.Sleep(time.Second)
}
</code></pre>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>Graceful shutdown</p>
</li>
<li><p>Cancellation signals</p>
</li>
<li><p>Stopping worker pools</p>
</li>
</ul>
<h3>11.2. Signal-Only Communication</h3>
<p>Sometimes you <strong>don’t need to send data</strong>, only a signal.</p>
<p><strong>Concept:</strong> <code>chan struct{}</code></p>
<pre><code class="language-plaintext">done := make(chan struct{})
</code></pre>
<p><strong>Here:</strong></p>
<pre><code class="language-plaintext">struct{} = empty type (no data)
</code></pre>
<p><strong>Why use</strong> <code>struct{}</code><strong>?</strong></p>
<ul>
<li><p>Zero allocation</p>
</li>
<li><p>No memory overhead</p>
</li>
<li><p>Pure signaling</p>
</li>
</ul>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func main() {

	done := make(chan struct{})

	go func() {
		fmt.Println("Work done")
		done &lt;- struct{}{}
	}()

	&lt;-done
	fmt.Println("Received signal")
}
</code></pre>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>Done signals</p>
</li>
<li><p>Event notifications</p>
</li>
<li><p>Synchronization triggers</p>
</li>
</ul>
<h3>11.3. Non-Blocking Communication</h3>
<p>By default, channel operations <strong>block</strong>.</p>
<p>Sometimes you want to <strong>avoid waiting</strong>.</p>
<p><strong>Concept:</strong> <code>select + default</code></p>
<pre><code class="language-plaintext">select {
case ch &lt;- value:
	// sent successfully
default:
	// fallback (non-blocking)
}
</code></pre>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import "fmt"

func main() {

	ch := make(chan int)

	select {
	case ch &lt;- 10:
		fmt.Println("Sent")
	default:
		fmt.Println("Channel not ready, skipping")
	}
}
</code></pre>
<p><strong>Behavior</strong></p>
<ul>
<li><p>If send/receive is possible -&gt; it executes</p>
</li>
<li><p>Otherwise -&gt; <code>default</code> runs immediately</p>
</li>
</ul>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>Polling systems</p>
</li>
<li><p>Avoiding deadlocks</p>
</li>
<li><p>Building responsive systems</p>
</li>
</ul>
<h3><strong>11.4. Multiplexed Communication (select)</strong></h3>
<p>The <code>select</code> statement allows a goroutine to <strong>wait on multiple channels simultaneously</strong>.</p>
<p><strong>Concept</strong></p>
<pre><code class="language-plaintext">select {
case &lt;-ch1:
	// event from ch1
case &lt;-ch2:
	// event from ch2
}
</code></pre>
<p><strong>Key Idea:</strong> Whichever channel is ready first wins</p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import (
	"fmt"
	"time"
)

func main() {

	ch1 := make(chan string)
	ch2 := make(chan string)

	go func() {
		time.Sleep(time.Second)
		ch1 &lt;- "from ch1"
	}()

	go func() {
		time.Sleep(2 * time.Second)
		ch2 &lt;- "from ch2"
	}()

	select {
	case msg := &lt;-ch1:
		fmt.Println(msg)
	case msg := &lt;-ch2:
		fmt.Println(msg)
	}
}
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="language-plaintext">from ch1
</code></pre>
<p><strong>With Timeout</strong></p>
<pre><code class="language-plaintext">select {
case res := &lt;-ch:
	fmt.Println(res)
case &lt;-time.After(time.Second):
	fmt.Println("timeout")
}
</code></pre>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>Orchestration between goroutines</p>
</li>
<li><p>Timeout handling</p>
</li>
<li><p>Cancellation patterns</p>
</li>
<li><p>Event-driven systems</p>
</li>
</ul>
<h2>12. Time-Based Communication</h2>
<p>In Go, time is not just a utility — it becomes part of your <strong>concurrency model</strong>.</p>
<p>Instead of writing blocking logic like:</p>
<pre><code class="language-plaintext">sleep(5 seconds)
</code></pre>
<p>Go lets you <strong>communicate with time using channels</strong>.</p>
<p><strong>Core Idea:</strong> Go’s <code>time</code> package provides <strong>channels that send signals based on time</strong>.</p>
<h3>12.1. Timeout using <code>time.After</code></h3>
<p><strong>Concept:</strong> <code>time.After(duration)</code> returns a channel that sends a signal <strong>after a delay</strong>.</p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">select {
case msg := &lt;-ch:
    fmt.Println("Received:", msg)

case &lt;-time.After(2 * time.Second):
    fmt.Println("Timeout!")
}
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>If <code>ch</code> responds -&gt; success</p>
</li>
<li><p>If nothing happens for 2 seconds -&gt; timeout triggers</p>
</li>
</ul>
<p>This prevents <strong>goroutine blocking forever</strong></p>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>API calls</p>
</li>
<li><p>Worker jobs</p>
</li>
<li><p>Waiting for responses</p>
</li>
</ul>
<h3>12.2. Periodic Tasks using <code>time.Tick</code></h3>
<p><strong>Concept:</strong> <code>time.Tick(interval)</code> returns a channel that sends signals <strong>repeatedly</strong>.</p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">ticker := time.Tick(1 * time.Second)

for {
    select {
    case &lt;-ticker:
        fmt.Println("Running every second")
    }
}
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>Every 1 second -&gt; signal is received</p>
</li>
<li><p>Loop keeps running forever</p>
</li>
</ul>
<p><strong>Important:</strong> <code>time.Tick</code> <strong>cannot be stopped</strong></p>
<p><strong>Better approach:</strong></p>
<pre><code class="language-plaintext">ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
</code></pre>
<p><strong>Use Cases</strong></p>
<ul>
<li><p>Background jobs</p>
</li>
<li><p>Metrics collection</p>
</li>
<li><p>Polling systems</p>
</li>
</ul>
<h3>12.3. Fine Control using <code>time.Timer</code></h3>
<p><strong>Concept</strong>: A <code>Timer</code> gives you <strong>manual control over timing</strong></p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">timer := time.NewTimer(2 * time.Second)

&lt;-timer.C
fmt.Println("Executed after delay")
</code></pre>
<p><strong>Advanced Control</strong></p>
<pre><code class="language-plaintext">timer := time.NewTimer(2 * time.Second)

go func() {
    time.Sleep(1 * time.Second)
    timer.Stop()
}()

&lt;-timer.C // may or may not fire
</code></pre>
<p><strong>Why use Timer?</strong></p>
<ul>
<li><p>Can <strong>stop</strong> or <strong>reset</strong></p>
</li>
<li><p>Better control than <code>time.After</code></p>
</li>
</ul>
<h2>13. Pipeline Communication</h2>
<p>Pipeline communication is about <strong>processing data in stages</strong>, where each stage does one job and passes the result forward.</p>
<p><strong>Core Idea</strong></p>
<p>A pipeline looks like this:</p>
<pre><code class="language-plaintext">source --&gt; stage1 --&gt; stage2 --&gt; stage3 --&gt; output
</code></pre>
<p>Each stage:</p>
<ul>
<li><p>Runs in its own <strong>goroutine</strong></p>
</li>
<li><p>Communicates via <strong>channels</strong></p>
</li>
<li><p>Processes and forwards data</p>
</li>
</ul>
<p>This creates a <strong>streaming flow of data</strong></p>
<p><strong>Why Pipelines?</strong></p>
<p>Pipelines help you:</p>
<ul>
<li><p><strong>Break complex work into smaller steps</strong></p>
</li>
<li><p><strong>Process data concurrently</strong></p>
</li>
<li><p><strong>Stream data instead of waiting for everything</strong></p>
</li>
</ul>
<p>Example</p>
<pre><code class="language-plaintext">func generator(nums ...int) &lt;-chan int {
    out := make(chan int)

    go func() {
        for _, n := range nums {
            out &lt;- n
        }
        close(out)
    }()

    return out
}

func square(in &lt;-chan int) &lt;-chan int {
    out := make(chan int)

    go func() {
        for n := range in {
            out &lt;- n * n
        }
        close(out)
    }()

    return out
}

func main() {
    nums := generator(1, 2, 3, 4)

    squared := square(nums)

    for result := range squared {
        fmt.Println(result)
    }
}
</code></pre>
<h2>14. Context-Based Communication in Go</h2>
<p>Context is how goroutines <strong>communicate control signals</strong> like:</p>
<ul>
<li><p>Cancellation</p>
</li>
<li><p>Deadlines</p>
</li>
<li><p>Request-scoped data</p>
</li>
</ul>
<p><strong>Core Idea:</strong> Context is not for data — it’s for <strong>control</strong></p>
<p><strong>What is</strong> <code>context.Context</code><strong>?</strong></p>
<p>It’s an interface provided by Go that allows you to:</p>
<ul>
<li><p>Cancel operations</p>
</li>
<li><p>Set timeouts</p>
</li>
<li><p>Pass request-level metadata</p>
</li>
</ul>
<p><strong>Key Concept:</strong> <code>ctx.Done()</code></p>
<pre><code class="language-plaintext">ctx.Done()
</code></pre>
<p>returns a channel that is <strong>closed when cancellation happens</strong></p>
<p><strong>Mental Model</strong></p>
<pre><code class="language-plaintext">ctx.Done() -&gt; "Stop everything now"
</code></pre>
<p><strong>Example (Cancellation)</strong></p>
<pre><code class="language-plaintext">ctx, cancel := context.WithCancel(context.Background())

go func() {
    for {
        select {
        case &lt;-ctx.Done():
            fmt.Println("Stopped!")
            return
        default:
            fmt.Println("Working...")
            time.Sleep(500 * time.Millisecond)
        }
    }
}()

time.Sleep(2 * time.Second)
cancel()
</code></pre>
<p><strong>What’s happening?</strong></p>
<ul>
<li><p>Goroutine keeps working</p>
</li>
<li><p><code>cancel()</code> is called</p>
</li>
<li><p><code>ctx.Done()</code> channel closes</p>
</li>
<li><p>Goroutine exits gracefully</p>
</li>
</ul>
<h2>15. Shared Memory Communication</h2>
<p>Sometimes, using channels is <strong>not the best choice</strong>.</p>
<p>In those cases, goroutines <strong>share memory directly</strong>, and we control access using:</p>
<ul>
<li><p><code>sync.Mutex</code></p>
</li>
<li><p><code>sync/atomic</code></p>
</li>
</ul>
<p><strong>Core Idea:</strong> Multiple goroutines access the <strong>same variable</strong>, but in a <strong>controlled way</strong></p>
<h3>15.1. sync.Mutex</h3>
<p>A mutex ensures: “Only one goroutine can access this critical section at a time”</p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">var mu sync.Mutex
counter := 0

go func() {
    mu.Lock()
    counter++
    mu.Unlock()
}()
</code></pre>
<p><strong>What’s happening?</strong></p>
<ul>
<li><p><code>Lock()</code> → enter critical section</p>
</li>
<li><p><code>Unlock()</code> → release access</p>
</li>
</ul>
<p>Prevents race conditions</p>
<p><strong>Important Rule</strong></p>
<p>Always unlock:</p>
<pre><code class="language-plaintext">mu.Lock()
defer mu.Unlock()
</code></pre>
<h3>15.2. sync/atomic</h3>
<p><strong>Concept</strong></p>
<p>Atomic operations are: “Low-level, lock-free, super-fast operations”</p>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">var counter int32

go func() {
    atomic.AddInt32(&amp;counter, 1)
}()
</code></pre>
<p><strong>Why atomic?</strong></p>
<ul>
<li><p>No locking overhead</p>
</li>
<li><p>Faster than mutex</p>
</li>
<li><p>Safe for simple operations</p>
</li>
</ul>
<h2>16. Waiting for Goroutines (sync.WaitGroup)</h2>
<p><strong>Basic Usage</strong></p>
<p>A WaitGroup has three main methods:</p>
<ul>
<li><p><code>Add(n)</code> → number of goroutines to wait for</p>
</li>
<li><p><code>Done()</code> → called when a goroutine finishes</p>
</li>
<li><p><code>Wait()</code> → blocks until all are done</p>
</li>
</ul>
<p><strong>Example</strong></p>
<pre><code class="language-plaintext">package main

import (
	"fmt"
	"sync"
)

func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done() // signal completion
	fmt.Println("Worker", id, "done")
}

func main() {

	var wg sync.WaitGroup

	for i := 1; i &lt;= 3; i++ {
		wg.Add(1) // register goroutine
		go worker(i, &amp;wg)
	}

	wg.Wait() // wait for all workers
	fmt.Println("All workers finished")
}
</code></pre>
<p><strong>Execution Flow</strong></p>
<p><code>wg.Add(1)</code> increases the counter</p>
<ul>
<li><p>Each goroutine calls <code>wg.Done()</code> when finished</p>
</li>
<li><p><code>wg.Wait()</code> blocks until the counter becomes zero</p>
</li>
</ul>
<p><strong>Important Rules</strong></p>
<ul>
<li><p>Always call <code>Add()</code> <strong>before starting the goroutine</strong></p>
</li>
<li><p>Always use <code>defer wg.Done()</code> inside goroutines</p>
</li>
<li><p>Do not copy a WaitGroup (always pass by pointer)</p>
</li>
</ul>
<p><strong>When to Use WaitGroup</strong></p>
<ul>
<li><p>Waiting for multiple goroutines to finish</p>
</li>
<li><p>Coordinating parallel tasks</p>
</li>
<li><p>Ensuring graceful program completion</p>
</li>
</ul>
<p><strong>WaitGroup vs Channels</strong></p>
<ul>
<li><p><strong>WaitGroup</strong> -&gt; used for <em>waiting</em></p>
</li>
<li><p><strong>Channels</strong> -&gt; used for <em>communication</em></p>
</li>
</ul>
<p>They are often used together in real-world systems.</p>
<h2><strong>17. Conclusion</strong></h2>
<p>Go’s concurrency model is both simple and powerful. With goroutines and channels, you can build systems where tasks run independently while staying safely coordinated. Instead of managing threads and locks, Go encourages a design based on communication and data flow.</p>
<p>Channels act as both data pipelines and synchronization points, making concurrent programs easier to understand and scale. Combined with tools like <code>select</code>, <code>time</code>, and <code>context</code>, they help handle real-world challenges like timeouts and cancellation.</p>
<p>The key idea is: <strong>share memory by communicating</strong>. Once you adopt this mindset, writing clean and efficient concurrent systems in Go becomes much more intuitive.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Goroutines & The Go Scheduler (GMP Model)]]></title><description><![CDATA[Go’s concurrency model is one of the main reasons behind its popularity for building scalable systems. While launching a goroutine looks trivial using the go keyword, the internal mechanics behind it ]]></description><link>https://blog.arishahmad.in/understanding-goroutines-the-go-scheduler-gmp-model</link><guid isPermaLink="true">https://blog.arishahmad.in/understanding-goroutines-the-go-scheduler-gmp-model</guid><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[GMP]]></category><category><![CDATA[go-scheduler]]></category><category><![CDATA[coroutines]]></category><category><![CDATA[go-gmp]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Sun, 01 Mar 2026 11:46:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/640cddfdb1e4eb4512040ddf/eb59d5c7-30f6-41db-8f87-dd093d8b942e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Go’s concurrency model is one of the main reasons behind its popularity for building scalable systems. While launching a goroutine looks trivial using the go keyword, the internal mechanics behind it are powerful and carefully designed.</p>
<p>This blog explains goroutines from the ground up and then dives deep into how Go schedules them using the GMP scheduler model. Everything here focuses on how things actually work.</p>
<h2>What is Goroutine?</h2>
<p>A goroutine is a lightweight unit of execution managed entirely by the Go runtime, not by the operating system.</p>
<p>Key characteristics of goroutines:</p>
<ul>
<li><p>Lightweight compared to OS threads</p>
</li>
<li><p>Dynamically growing stack</p>
</li>
<li><p>User-space threads</p>
</li>
<li><p>Exist within the same address space</p>
</li>
<li><p>Managed by the Go runtime scheduler</p>
</li>
<li><p>Multiplexed onto OS threads</p>
</li>
<li><p>Initial stack size is ~2 KB</p>
</li>
<li><p>Communicate via channels or shared memory</p>
</li>
</ul>
<p>Go promotes a strong concurrency principle:</p>
<blockquote>
<p><strong>Do not communicate by sharing memory; instead, share memory by communicating.</strong></p>
</blockquote>
<p>This philosophy is central to Go’s design and is the reason channels are preferred over locks in many cases.</p>
<h2>Goroutines vs OS Threads</h2>
<p>Goroutines are not OS threads.</p>
<ul>
<li><p>OS threads are <strong>heavyweight</strong>, expensive to create, and managed by the OS</p>
</li>
<li><p>Goroutines are <strong>lightweight</strong>, cheap to create, and managed by Go</p>
</li>
</ul>
<p>A Go program can run <strong>thousands or even millions of goroutines</strong>, which would be impossible with OS threads alone.</p>
<h2>Goroutines Are Managed by the Go Runtime</h2>
<p>Some important points:</p>
<ul>
<li><p>Goroutines are scheduled in <strong>user space</strong></p>
</li>
<li><p>The OS does <strong>not</strong> know about goroutines</p>
</li>
<li><p>The Go runtime maps goroutines onto OS threads</p>
</li>
<li><p>Multiple goroutines can run on a single OS thread</p>
</li>
<li><p>Multiple OS threads can exist inside one Go process</p>
</li>
</ul>
<p>This mapping is handled using the <strong>GMP scheduler model</strong>.</p>
<h2>The GMP Scheduler Model</h2>
<p>The Go scheduler internally uses the <strong>GMP model</strong>:</p>
<ul>
<li><p><strong>G</strong> : Goroutine</p>
</li>
<li><p><strong>M</strong> : Machine (OS Thread)</p>
</li>
<li><p><strong>P</strong> : Processor (Logical scheduling context)</p>
</li>
</ul>
<p>This model defines how goroutines are executed efficiently across CPU cores.</p>
<h3>G : Goroutine</h3>
<p>A <strong>G</strong> represents a goroutine.</p>
<p>It contains:</p>
<ul>
<li><p>Stack</p>
</li>
<li><p>Program Counter</p>
</li>
<li><p>CPU registers</p>
</li>
<li><p>Metadata (state, ID, etc.)</p>
</li>
</ul>
<p>A goroutine <strong>cannot execute by itself</strong>. It must be:</p>
<ul>
<li><p>Assigned to a <strong>P (processor)</strong></p>
</li>
<li><p>Executed by an <strong>M (machine)</strong></p>
</li>
</ul>
<h3>M : Machine (OS Thread)</h3>
<ul>
<li><p>Represents an <strong>OS thread</strong></p>
</li>
<li><p>Created by the Go runtime</p>
</li>
<li><p>Executes Go code</p>
</li>
<li><p>An <strong>M</strong> must acquire a <strong>P</strong> to run goroutines</p>
</li>
</ul>
<h3>P : Processor (Logical Execution Context)</h3>
<p>A <strong>P</strong> represents execution capacity.</p>
<p>Each <strong>P</strong> :</p>
<ul>
<li><p>Holds a <strong>local run queue of goroutines,</strong> when a goroutine is created, it is added to the <strong>local queue of the currently running P,</strong> initially, many goroutines may accumulate on a single <strong>P</strong>.</p>
</li>
<li><p>Contains scheduler state</p>
</li>
<li><p>Controls parallel execution</p>
</li>
</ul>
<p>Key rule:</p>
<blockquote>
<p><strong>Parallelism is limited by the number of P, not by goroutines or OS threads.</strong></p>
</blockquote>
<p>The number of <strong>P</strong> is controlled by: GOMAXPROCS, by default, it equals the number of logical CPUs.</p>
<p>Important detail:</p>
<blockquote>
<p>The number of OS threads (M) can be <strong>greater than the number of processors (<strong>P</strong>)</strong>.</p>
</blockquote>
<p><strong>Why?</strong></p>
<ul>
<li><p>OS threads can block on system calls or I/O</p>
</li>
<li><p>Go creates extra threads to avoid stalling execution</p>
</li>
</ul>
<h2>How Goroutines Are Executed (High-Level Flow)</h2>
<ol>
<li><p>Many Goroutines (G) are created by the program</p>
</li>
<li><p>Each newly created goroutine is placed into the <strong>local run queue</strong> of a Processor (P)</p>
</li>
<li><p>Each Processor (P) manages its own queue of runnable goroutines</p>
</li>
<li><p>An OS thread (M) acquires a Processor (P)</p>
</li>
<li><p>The OS thread (M) picks a goroutine (G) from the P’s local run queue</p>
</li>
<li><p>The OS thread (M) executes the goroutine (G)</p>
</li>
<li><p>The goroutine runs on the CPU until it blocks, completes, or is preempted</p>
</li>
</ol>
<h2>Global Run Queue</h2>
<p>Go also maintains a <strong>global run queue</strong>.</p>
<p>Purpose:</p>
<ul>
<li><p>Ensure fairness</p>
</li>
<li><p>Handle load balancing</p>
</li>
<li><p>Support scheduling when local queues are empty or unsuitable</p>
</li>
</ul>
<p>The scheduler periodically pulls goroutines from the global queue to avoid starvation.</p>
<h2>Work Stealing</h2>
<p>If a <strong>P</strong> runs out of runnable goroutines:</p>
<ul>
<li><p>It <strong>steals half</strong> of the runnable goroutines</p>
</li>
<li><p>From another <strong>P</strong>’s local run queue</p>
</li>
<li><p>Keeps CPU cores busy</p>
</li>
<li><p>Maximizes parallelism</p>
</li>
</ul>
<p>This mechanism is called <strong>work stealing</strong> and is crucial for Go’s scalability.</p>
<h2>What Happens When a Goroutine Blocks?</h2>
<p>When a goroutine:</p>
<ul>
<li><p>Performs a blocking system call</p>
</li>
<li><p>Waits on I/O</p>
</li>
<li><p>Sleeps</p>
</li>
<li><p>Waits on a channel</p>
</li>
</ul>
<p>Then:</p>
<ul>
<li><p>The <strong>M</strong> releases its <strong>P</strong></p>
</li>
<li><p>Another <strong>M</strong> can acquire that <strong>P</strong></p>
</li>
<li><p>Execution continues without blocking the entire scheduler</p>
</li>
</ul>
<p>This design ensures that blocking operations do not reduce parallelism.</p>
<h2>M and P Relationship</h2>
<p>Important observations:</p>
<ul>
<li><p>An OS thread (<strong>M</strong>) holds a <strong>P</strong> <strong>only while executing Go code</strong></p>
</li>
<li><p>Blocking, preemption, or scheduling can cause it to release the <strong>P</strong></p>
</li>
<li><p>Each OS thread can execute <strong>many goroutines over time</strong></p>
</li>
<li><p>Only <strong>one goroutine runs at a time per P</strong></p>
</li>
</ul>
<h2>Goroutine Creation Timing</h2>
<p>A very common misconception:</p>
<blockquote>
<p>A goroutine is <strong>enqueued when the go statement executes</strong>, not when the function is declared.</p>
</blockquote>
<p><code>go doWork()</code></p>
<p>At this moment:</p>
<ul>
<li><p>A new <strong>G</strong> is created</p>
</li>
<li><p>It is placed into a <strong>P</strong>'s run queue</p>
</li>
<li><p>Scheduler decides when it runs</p>
</li>
</ul>
<h2>Program Startup Flow</h2>
<p>When a Go program starts:</p>
<ol>
<li><p>The runtime creates multiple <strong>P</strong> (based on <strong>GOMAXPROCS</strong>)</p>
</li>
<li><p>Each <strong>P</strong> gets its own local run queue</p>
</li>
<li><p>The initial OS thread acquires a <strong>P</strong></p>
</li>
<li><p>The <strong>main goroutine</strong> is placed into that <strong>P</strong>’s run queue</p>
</li>
<li><p>Execution begins</p>
</li>
</ol>
<p>Over time, goroutines are redistributed across <strong>P</strong> using work stealing and the global queue.</p>
<h2>Lifecycle of a Goroutine</h2>
<p>Created → Runnable → Running → Blocked → Runnable → Terminated</p>
<ul>
<li><p><strong>Created</strong>: Goroutine is instantiated</p>
</li>
<li><p><strong>Runnable</strong>: Waiting in a run queue</p>
</li>
<li><p><strong>Running</strong>: Actively executing</p>
</li>
<li><p><strong>Blocked</strong>: Waiting on I/O, syscall, channel, etc.</p>
</li>
<li><p><strong>Terminated</strong>: Execution finished</p>
</li>
</ul>
<h2>Why the GMP Model Works So Well</h2>
<p>The GMP scheduler allows Go to:</p>
<ul>
<li><p>Scale efficiently across CPU cores</p>
</li>
<li><p>Avoid excessive OS thread creation</p>
</li>
<li><p>Handle blocking operations gracefully</p>
</li>
<li><p>Maximize CPU utilization</p>
</li>
<li><p>Keep concurrency simple for developers</p>
</li>
</ul>
<p>All while writing code as simple as:</p>
<p><code>go func() { // concurrent work }()</code></p>
<h2>Final Thoughts</h2>
<p>Goroutines may look simple, but the Go scheduler is doing a huge amount of work behind the scenes.</p>
<p>Understanding:</p>
<ul>
<li><p>Goroutines (G)</p>
</li>
<li><p>OS threads (M)</p>
</li>
<li><p>Processors (P)</p>
</li>
<li><p>Local and global queues</p>
</li>
<li><p>Work stealing</p>
</li>
<li><p>Blocking behavior</p>
</li>
</ul>
<p>…gives you a <strong>clear mental model</strong> of how Go concurrency actually works.</p>
<p>Once you understand GMP, Go’s concurrency stops feeling magical and starts feeling <strong>predictable, powerful, and elegant</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Vol. 1 System Design Basics: Scaling from Zero to Millions]]></title><description><![CDATA[Introduction
The topics and theories of our favorite subject, system design, are inspired by the famous book "System Design Interview" by Alex Xu. This article aims to build the foundation of system design, covering basic concepts that will be used a...]]></description><link>https://blog.arishahmad.in/system-design-basics-vol1</link><guid isPermaLink="true">https://blog.arishahmad.in/system-design-basics-vol1</guid><category><![CDATA[alex xu]]></category><category><![CDATA[System Design]]></category><category><![CDATA[server]]></category><category><![CDATA[Databases]]></category><category><![CDATA[cache]]></category><category><![CDATA[scaling]]></category><category><![CDATA[horizontal scaling]]></category><category><![CDATA[vertical scaling]]></category><category><![CDATA[Load Balancer]]></category><category><![CDATA[database replication]]></category><category><![CDATA[mha]]></category><category><![CDATA[My Hero Academia]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Fri, 05 Sep 2025 07:54:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757054985709/66a47787-1f70-45bb-9da1-9744d7b36eb6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>The topics and theories of our favorite subject, system design, are inspired by the famous book "System Design Interview" by Alex Xu. This article aims to build the foundation of system design, covering basic concepts that will be used as we progress to designing systems that can handle users from zero to millions.</p>
<p>And since I’m a big <em>My Hero Academia</em> fan (guilty as charged!), you might notice a quote or two sneaking in along the way. As All Might says: <strong>“Go beyond! Plus Ultra!”</strong></p>
<h1 id="heading-why-basics-matter">Why Basics Matter</h1>
<p>These concepts are the foundation of every system design journey. Whether you’re building something simple like a <strong>rate limiter</strong> or designing a <strong>full-fledged application like Instagram</strong>, the same building blocks apply. It might be too soon to dive into Instagram-level systems but don’t worry, we’ll definitely get there.</p>
<p>As Midoriya once said:<br /><strong>“There was a time in my life when I would’ve given up, but I kept pushing forward.”</strong></p>
<p>That’s exactly how learning system design feels challenging at first, but step by step, you’ll go beyond.</p>
<h1 id="heading-core-concepts-of-system-design">Core Concepts of System Design</h1>
<p>Let's dive into the main part of the blog.</p>
<h2 id="heading-1-single-server-setup">1. Single Server Setup</h2>
<p>The adventure of computing and services begins with a <strong>single server</strong>, a <strong>user</strong>, and the <strong>all-knowing DNS server</strong>.</p>
<p>A user types in a domain name. The DNS translates this human-friendly name into the IP address of the server, and suddenly the user knows where to find it. It’s like the user only knows the <strong>nickname</strong> of the server, but the DNS knows its <strong>home address</strong>. And if you want to gossip with the server, you need to go knock at its door that’s the IP address.</p>
<p>In this setup, everything the application code, the database, and the storage lives on <strong>one machine</strong>.</p>
<p>Think of a <strong>single hero</strong> (like <strong>Midoriya</strong> in his early days) fighting all the villains alone. He can protect a small area, but if too many villains show up at once, he gets overwhelmed.<br />One server = one hero doing everything.</p>
<h2 id="heading-2-database">2. Database</h2>
<p>As more users join, a single server can’t handle everything both running the app and storing all the data. So, we bring in a <strong>database</strong> whose main job is to <strong>store and organize information</strong>. The server just asks the database whenever it needs to save or read something.</p>
<p>A hero might have <strong>amazing memory</strong> storing all the details about villains, battles, and strategies. But when the workload gets heavier, the hero writes everything down in a <strong>Hero Logbook</strong> (like All Might passing down his notebook to Midoriya).<br />The database = the hero’s logbook where all important info is stored.</p>
<p>There are mainly two kinds of databases:</p>
<h3 id="heading-relational-databases-sql"><strong>Relational Databases (SQL)</strong></h3>
<ul>
<li><p>Think of it like <strong>spreadsheets</strong> with rows and columns.</p>
</li>
<li><p>You can connect different tables (like a table of users and a table of orders).</p>
</li>
<li><p>Very organized, great when your data has a clear structure.</p>
</li>
<li><p>Examples: MySQL, PostgreSQL.</p>
</li>
</ul>
<h3 id="heading-non-relational-databases-nosql"><strong>Non-Relational Databases (NoSQL)</strong></h3>
<ul>
<li><p>Instead of tables, they store data more freely, often like <strong>JSON files</strong>.</p>
</li>
<li><p>Flexible, good for apps where the data shape changes a lot.</p>
</li>
<li><p>Easy to grow across many servers when traffic is huge.</p>
</li>
<li><p>Examples: MongoDB, DynamoDB.</p>
</li>
</ul>
<p><strong>In short:</strong></p>
<ul>
<li><p>Use <strong>SQL</strong> when your data is neat and well-organized.</p>
</li>
<li><p>Use <strong>NoSQL</strong> when your data is messy, flexible, or growing super fast.</p>
</li>
</ul>
<h2 id="heading-3-vertical-scaling-vs-horizontal-scaling">3. Vertical Scaling VS Horizontal Scaling</h2>
<p>Think about your own device — a laptop, PC, or even your smartphone. If it starts running slow because the <strong>CPU, RAM, or storage</strong> isn’t enough, you have two choices:</p>
<h3 id="heading-vertical-scaling-scale-up"><strong>Vertical Scaling (Scale Up)</strong></h3>
<ul>
<li><p>This is like upgrading your device with <strong>better parts</strong>.</p>
</li>
<li><p>Add more RAM, replace the CPU with a faster one, or upgrade to a bigger SSD.</p>
</li>
<li><p>In servers, vertical scaling means giving a single machine <strong>more power</strong>.</p>
</li>
<li><p>Simple to do.</p>
</li>
<li><p>But there’s a limit you can’t keep upgrading forever, and it gets expensive.</p>
</li>
</ul>
<h3 id="heading-horizontal-scaling-scale-out"><strong>Horizontal Scaling (Scale Out)</strong></h3>
<ul>
<li><p>Instead of buying one super-powerful laptop, imagine having <strong>multiple laptops</strong> working together.</p>
</li>
<li><p>Each laptop handles part of the workload, and together they can do much more.</p>
</li>
<li><p>In servers, this means <strong>adding more machines</strong> and distributing the traffic among them.</p>
</li>
<li><p>Much higher capacity, no single point of failure.</p>
</li>
<li><p>More complex to manage because you need load balancers and coordination.</p>
</li>
</ul>
<p><strong>In short:</strong></p>
<ul>
<li><p><strong>Vertical scaling</strong> = making <strong>one server stronger</strong>.</p>
</li>
<li><p><strong>Horizontal scaling</strong> = adding <strong>more servers to share the work</strong>.</p>
</li>
<li><p><strong>Vertical Scaling</strong>: Midoriya unlocking <strong>100% of One For All</strong> to become way stronger. One hero, but much more powerful.</p>
</li>
<li><p><strong>Horizontal Scaling</strong>: Instead of just Midoriya fighting, the <strong>entire Class 1-A joins in</strong>. Each hero handles part of the battle, and together they defeat the villains.</p>
</li>
</ul>
<p><strong>Vertical</strong> \= powering up one hero. <strong>Horizontal</strong> = teaming up multiple heroes.</p>
<h2 id="heading-4-load-balancer">4. Load Balancer</h2>
<p>Imagine this: your device is so popular that <strong>many people want to use it at the same time</strong>. But one device can’t handle everyone at once. So, instead of forcing them to fight over it, you give each person <strong>a different device</strong> to use.</p>
<p>That’s what a <strong>load balancer</strong> does in system design.</p>
<p>Think of <strong>Eraser Head (Aizawa)</strong> during training. When the students face too many combat exercises, he <strong>splits the class into groups</strong> and assigns each villain fight to the right student based on their quirk.<br />Load balancer = the teacher who distributes the workload to the right heroes.</p>
<p><strong>Here’s how it works step by step:</strong></p>
<ol>
<li><p>The user types in the website name.</p>
</li>
<li><p>DNS gives back the IP address of the <strong>load balancer</strong> (not the server directly).</p>
</li>
<li><p>The user sends the request to the load balancer.</p>
</li>
<li><p>The load balancer then decides which server should handle that request.</p>
</li>
</ol>
<p><strong>The load balancer makes sure that:</strong></p>
<ul>
<li><p>No single server is overloaded.</p>
</li>
<li><p>New servers can be added when traffic is high.</p>
</li>
<li><p>Extra servers can be removed when traffic is low (saving costs).</p>
</li>
</ul>
<p><strong>In short:</strong><br />A <strong>load balancer</strong> is like a <strong>traffic manager</strong> it takes all incoming requests and spreads them evenly across available servers so that the system stays fast and reliable.</p>
<h2 id="heading-5-database-replication">5. Database Replication</h2>
<p>Imagine you save important files on your laptop, but the hard drive crashes. If you had made a <strong>backup copy</strong> on an external drive, you’d still be safe.</p>
<p>That’s exactly the idea behind <strong>database replication</strong> in system design — making copies of your database so your system doesn’t break if one fails.</p>
<p><strong>Here’s how it usually works:</strong></p>
<p><strong>Master–Slave Setup</strong></p>
<ul>
<li><p><strong>Master Database</strong>: Handles all the <strong>write operations</strong> (adding, updating, or deleting data).</p>
</li>
<li><p><strong>Slave Databases</strong>: Receive <strong>copies of the master’s data</strong> and handle the <strong>read operations</strong>.</p>
</li>
<li><p>If the master fails, one of the slaves can be promoted to act as the new master.</p>
</li>
</ul>
<p><strong>Why it’s useful</strong></p>
<ul>
<li><p>Increases <strong>reliability</strong>, even if one database crashes, you don’t lose everything.</p>
</li>
<li><p>Improves <strong>performance</strong>, reads can be spread across many slaves, avoiding overload on a single database.</p>
</li>
<li><p>Helps with <strong>scaling</strong> as the system grows.</p>
</li>
</ul>
<p><strong>One trade-off:</strong> sometimes the slave might not have the very latest data at the exact moment of failure (called <strong>replication lag</strong>), but it’s usually close enough and can be fixed once the system recovers.</p>
<p><strong>In short:</strong><br /><strong>Database replication</strong> = <strong>having multiple copies of your database</strong> so your system stays safe, fast, and available</p>
<h2 id="heading-6-cache">6. Cache</h2>
<p>Imagine every time you open your laptop or phone, it has to load something important (like your wallpaper or your most-used app) from the <strong>hard drive (HDD)</strong>. Hard drives are slower, so this would take time.</p>
<p>But if the device keeps that data in a <strong>cache (a small, super-fast memory)</strong>, it can load it instantly.</p>
<p><strong>In system design, a cache works the same way:</strong></p>
<ul>
<li><p>It stores <strong>frequently accessed data</strong> in a faster storage layer (like in-memory).</p>
</li>
<li><p>So instead of going all the way to the database every time, the server can quickly fetch the data from the cache.</p>
</li>
</ul>
<p><strong>Benefits of caching</strong></p>
<ul>
<li><p><strong>Speed</strong>: Faster responses for users.</p>
</li>
<li><p><strong>Reduced load</strong>: Fewer trips to the database.</p>
</li>
<li><p><strong>Cost saving</strong>: Less strain on expensive resources.</p>
</li>
</ul>
<p><strong>Example:</strong><br />Think of logging into Instagram. Your profile picture, username, and bio don’t change every second. So instead of fetching them from the database every single time, Instagram puts them in a cache so they load instantly when you open the app.</p>
<p><strong>In short:</strong><br /><strong>Cache</strong> = <strong>a shortcut to the data you need most often</strong>. It makes systems faster and smoother.</p>
<h1 id="heading-how-these-fit-together">How These Fit Together</h1>
<p>All the pieces we’ve covered servers, databases, scaling, load balancers, replication, and caching work like parts of a small city:</p>
<ul>
<li><p><strong>Server</strong> = the office where work happens</p>
</li>
<li><p><strong>Database</strong> = the record room</p>
</li>
<li><p><strong>Scaling</strong> = making the office bigger or opening more branches</p>
</li>
<li><p><strong>Load balancer</strong> = the receptionist guiding visitors</p>
</li>
<li><p><strong>Replication</strong> = backup record rooms</p>
</li>
<li><p><strong>Cache</strong> = quick-access drawer with popular files</p>
</li>
</ul>
<p>Together, they form a <strong>basic but reliable system</strong> that can handle more users, stay available, and run faster.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>We’ve taken the first big step into system design, from a single server all the way to caching and replication. These building blocks form the foundation of any scalable system and will keep showing up no matter what you design.</p>
<p>But this is just the beginning. In the next blog, we’ll go beyond the basics and explore more advanced topics like CDNs, stateless web tiers, data centers, message queues, and what it really takes to scale to millions of users. Stay tuned things are about to get even more exciting! 🚀</p>
<p>As All Might says: <em>“When there’s nothing to be gained, rising to the challenge at those times… is surely the mark of a true hero.”</em> 🌟</p>
]]></content:encoded></item><item><title><![CDATA[Setting Up a Go Web Server on Amazon EC2]]></title><description><![CDATA[Launching EC2 with Amazon Linux

Open the AWS Management Console and navigate to the EC2.

Click “Launch instances”.
 

Enter an appropriate instance name.

Select “Amazon Linux” under “Application and OS Images”.
 

Select any “Free tier eligible” I...]]></description><link>https://blog.arishahmad.in/setting-up-a-go-web-server-on-amazon-ec2</link><guid isPermaLink="true">https://blog.arishahmad.in/setting-up-a-go-web-server-on-amazon-ec2</guid><category><![CDATA[ec2]]></category><category><![CDATA[EC2 instance]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[golang]]></category><category><![CDATA[Go]]></category><category><![CDATA[test]]></category><category><![CDATA[web servers]]></category><category><![CDATA[web server]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws ec2]]></category><category><![CDATA[gin-gonic]]></category><category><![CDATA[gin]]></category><category><![CDATA[Testing]]></category><category><![CDATA[ssh]]></category><category><![CDATA[cmd]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Thu, 19 Sep 2024 20:36:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726777988694/776b625a-0491-4007-b934-01ef8fc03971.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-launching-ec2-with-amazon-linux">Launching EC2 with Amazon Linux</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>EC2.</strong></p>
</li>
<li><p>Click “<strong>Launch instances”</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726769000527/aeef113e-f502-462f-9ebc-5763017df517.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter an appropriate instance name.</p>
</li>
<li><p>Select “<strong>Amazon Linux</strong>” under “<strong>Application and OS Images”.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726769073771/d2bb842e-1e2a-4dc2-8295-90173d433680.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select any “<strong>Free tier eligible”</strong> Instance type.</p>
</li>
<li><p>Create and select any <strong>“ppk key”</strong> of the “<strong>RSA</strong>” type.</p>
</li>
<li><p>Allow “<strong>SSH traffic</strong>”, “<strong>HTTPS traffic</strong>” and “<strong>HTTP traffic</strong>” under “<strong>Network settings”.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726769330360/af8da0d5-04fd-4b6c-bb10-0d8554a8f6e9.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click “<strong>Launch instance”</strong>.</p>
</li>
</ol>
<h3 id="heading-convert-pem-key-to-ppk-key">Convert pem Key to ppk Key</h3>
<ol>
<li><p>Open “<strong>PuTTYgen”</strong>.</p>
</li>
<li><p>Click “<strong>Load”</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726772394839/28b9579b-b67d-472e-bfe1-05e4cc6148db.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now select the pem key you use instance.</p>
</li>
<li><p>Click on “<strong>Conversions”</strong> → “<strong>Export OpenSSH key</strong>” → “<strong>Yes</strong>”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726772584130/8f108d50-b4a6-408d-9547-53ec7bed0ed7.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter an appropriate key name. (Eg. go-pem-key.ppm)</p>
<p> Note: Make sure the save as type is “<strong>All Files</strong>” and to you use the “<strong>.ppm</strong>“ at the end of the key name as given in the example.</p>
</li>
<li><p>Click “<strong>Save”</strong>.</p>
</li>
</ol>
<h3 id="heading-connecting-to-ec2-instance">Connecting to EC2 instance</h3>
<ol>
<li><p>Copy this</p>
<pre><code class="lang-bash"> ssh -i <span class="hljs-string">"your-key.pem"</span> ec2-user@&lt;your-ec2-public-ip&gt;
</code></pre>
</li>
<li><p>Paste in the Command Prompt.</p>
</li>
<li><p>Edit the pem key with the absolute path and the key name you just created. (Eg. If the absolute path is “<strong>C:\Users\username</strong>” and the key name is <strong>“go-pem-key.pem</strong>”. Then replace “<strong>you-key.pem”</strong> to “<strong>C:\Users\username\go-pem-key.pem”</strong>.</p>
</li>
<li><p>Go back to <strong>AWS Management console</strong>, Select the newly created instance.</p>
</li>
<li><p>Copy “<strong>Public IPv4 address</strong>”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726777158376/0cd23e0f-4958-410d-a257-9775d150e473.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Replace <code>&lt;your-ec2-public-ip&gt;</code> to the copied address.</p>
</li>
<li><p>Press <strong>enter</strong>.</p>
</li>
<li><p>Type “<strong>yes”</strong> then again press <strong>enter</strong>.</p>
</li>
</ol>
<h3 id="heading-uploading-go-webserver-to-ec2-instance">Uploading Go webserver to EC2 instance</h3>
<p>Note: Before uploading the go server to the EC2 instance the go server must set to run on default IP and 8080 port.</p>
<ol>
<li><p>Copy and Paste the following one by one.</p>
<pre><code class="lang-bash"> sudo yum update -y
 sudo yum install -y golang
</code></pre>
</li>
<li><p>You can use <strong>scp</strong> to transfer your <strong>main.go</strong>, <strong>.env</strong>, and any other required files from your local machine to the EC2 instance.</p>
<p> Copy the following</p>
<pre><code class="lang-bash"> scp -i <span class="hljs-string">"your-key.pem"</span> -r <span class="hljs-string">"/path/to/your/project"</span> ec2-user@&lt;your-ec2-public-ip&gt;:/home/ec2-user/
</code></pre>
</li>
<li><p>Paste this in another Command Prompt Terminal which is not connected to the EC2 instance.</p>
</li>
<li><p>Replace the <code>"your-key.pem"</code> to the pem key you created with the absolute path.</p>
</li>
<li><p>Replace the <code>“/path/to/your/project”</code> to the absolute path of your project (path to the root folder).</p>
</li>
<li><p>Replace the <code>&lt;your-ec2-public-ip&gt;</code> to the instance’s <strong>“Public IPv4 address”</strong>.</p>
</li>
<li><p>Hit Enter.</p>
</li>
</ol>
<h3 id="heading-build-the-application">Build the application</h3>
<ol>
<li><p>Copy and Paste</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">cd</span> /home/ec2-user/your-project-folder
</code></pre>
<p> Replace you-project-folder to the name of the root folder.</p>
</li>
<li><p>Hit enter.</p>
</li>
<li><p>Build your Go application to ensure it compiles properly:</p>
<pre><code class="lang-bash"> go build -o app main.go
</code></pre>
</li>
</ol>
<h3 id="heading-run-the-application">Run the application</h3>
<p>Once the build is successful, run the application:</p>
<pre><code class="lang-bash">./app
</code></pre>
<h3 id="heading-run-your-application-in-the-background">Run Your Application in the Background</h3>
<p>To keep your application running after logging out, use a process manager like screen or tmux, or run the app as a background process.</p>
<pre><code class="lang-bash">nohup ./app &amp;
</code></pre>
<h3 id="heading-configure-security-group-for-http-access">Configure Security Group for HTTP Access</h3>
<ol>
<li><p>Select the EC2 instance.</p>
</li>
<li><p>Under “<strong>Security</strong>” click on the “<strong>Security groups</strong>”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726776182555/7ebf7fb4-2a5b-4f89-b243-3af0f5eab8d3.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726775828601/2629aac3-e422-42c2-989d-9d800a66202a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click on “<strong>Inbound rules</strong>”.</p>
</li>
<li><p>Click on “<strong>Edit inbound rules</strong>”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726775952687/5d702c1a-fe57-4850-a4dd-bfc087947bae.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click “<strong>Add Rules</strong>”.</p>
</li>
<li><p>Select “<strong>Custom TCP</strong>” under “<strong>Type</strong>”, set “<strong>8080</strong>” in “<strong>Port range”</strong> and “<strong>Anywhere-IPv4”</strong> under <strong>“Destination”.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726776883068/8ea10133-3168-41c5-954c-0799e8c5ec7b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click “<strong>Save rules</strong>”.</p>
</li>
<li><p>Now Click on “<strong>Outbound Rules</strong>”.</p>
</li>
<li><p>Click “<strong>Edit outbound rules</strong>”.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726776412640/8f5245c7-1043-4ddc-a8ee-453933ccd002.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click “<strong>Add Rules</strong>”.</p>
</li>
<li><p>Select “<strong>Custom TCP</strong>” under “<strong>Type</strong>”, set “<strong>8080</strong>” in “<strong>Port range”</strong> and “<strong>Anywhere-IPv4”</strong> under <strong>“Destination”.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726776783176/b723208e-72c7-4a9f-8946-03476e7d4afa.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click “<strong>Save rules</strong>”.</p>
</li>
</ol>
<h3 id="heading-test-the-web-server">Test the Web Server</h3>
<p>Use the curl command with the public IP and port.</p>
<p>For example curl http://&lt;Public-IP&gt;:8080/path_to _service.</p>
<p>Replace <code>&lt;Public-IP&gt;</code> with the instance’s Public IPv4 address and <code>path-to-service</code> with the path where any GET request is sent.</p>
]]></content:encoded></item><item><title><![CDATA[Easy Explanation of Docker for Beginners]]></title><description><![CDATA[What is Docker?
Docker is a platform that allows developers to package their applications into containers. These containers include everything the application needs to run, such as code, system libraries, and dependencies, ensuring the application be...]]></description><link>https://blog.arishahmad.in/easy-explanation-of-docker-for-beginners</link><guid isPermaLink="true">https://blog.arishahmad.in/easy-explanation-of-docker-for-beginners</guid><category><![CDATA[cotainers vs virtual machines]]></category><category><![CDATA[docker use case]]></category><category><![CDATA[docker examples]]></category><category><![CDATA[Docker]]></category><category><![CDATA[containers]]></category><category><![CDATA[docker container]]></category><category><![CDATA[Docker Containers]]></category><category><![CDATA[docker for beginners]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Fri, 13 Sep 2024 03:17:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726197258558/1d498639-00a3-412d-9664-8202253f3738.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-is-docker">What is Docker?</h3>
<p>Docker is a platform that allows developers to package their applications into containers. These containers include everything the application needs to run, such as code, system libraries, and dependencies, ensuring the application behaves the same regardless of where it's executed.</p>
<p>Docker is a tool that makes it easier to create, deploy, and run applications in containers. It's widely used for packaging applications along with their dependencies and ensuring they run the same way on any machine.</p>
<h3 id="heading-the-problem-docker-solves">The Problem Docker Solves:</h3>
<p>Before Docker, developers faced a common issue called the “It works on my machine!” problem. This happens when an application works fine on a developer’s machine but encounters issues when run on another system or server. This is often caused by different software versions, missing dependencies, or environmental differences between systems.</p>
<p>Docker solves this problem by allowing developers to package their applications with all the necessary dependencies into a container. Since containers are consistent, lightweight, and isolated, the application will work the same no matter where it's run—on a developer's laptop, on a server, or in the cloud.</p>
<h3 id="heading-containers">Containers</h3>
<p><strong>Containers</strong> are like small, portable boxes that hold everything your application needs to run. Inside the container, you have the code, all its libraries, system tools, and settings. This ensures that the application runs the same way no matter where you execute it.</p>
<p>Containers are lightweight, portable, and isolated environments that bundle an application and all its dependencies (libraries, configuration files, etc.) so that it can run consistently across different environments (like your computer, a server, or the cloud).</p>
<h3 id="heading-why-use-containers">Why Use Containers?</h3>
<p>Because they isolate your application and its environment from the rest of the system.</p>
<p>Think of it like packaging a dish with all its ingredients and the specific kitchen tools you need. No matter where you cook it (at home, a friend's house, a different city), the dish will turn out the same because you brought everything needed with you.</p>
<h3 id="heading-how-containers-differ-from-virtual-machines-vms">How Containers Differ from Virtual Machines (VMs)?</h3>
<ul>
<li><p><strong>Virtual Machines (VMs)</strong> simulate an entire physical computer. They include a full operating system (OS), which takes up a lot of space and system resources. They’re like heavy boxes that simulate a full, separate computer.</p>
</li>
<li><p><strong>Containers</strong> share the host operating system, meaning they don’t need a full OS inside them. This makes containers <strong>lightweight</strong>, faster to start, and more efficient in resource usage.</p>
</li>
<li><p><strong>VMs</strong> each have their <strong>own OS</strong> and take longer to boot up because of this.</p>
</li>
</ul>
<h3 id="heading-use-cases-for-docker"><strong>Use Cases for Docker</strong></h3>
<p>Here’s where Docker shines—it helps you easily build, test, and deploy applications using containers.</p>
<ul>
<li><p><strong>Development</strong>: Developers use Docker to create containers on their local machines. These containers mimic the production environment (the server where the app will run for real), so developers can ensure their app works correctly before they deploy it.</p>
<p>  <strong>Example</strong>: You're building a website on your laptop and you want to be sure it works the same on the actual server. With Docker, you can create a container that has all the same dependencies as the server, so you know the website will run perfectly on both.</p>
</li>
<li><p><strong>Testing</strong>: Testers can run applications in isolated containers. This means they can test different configurations or features without breaking anything on the main system.</p>
<p>  <strong>Example</strong>: Think of it like testing new ingredients in your dish, but in a separate kitchen. If something goes wrong, you didn’t mess up your original kitchen—it’s all isolated.</p>
</li>
<li><p><strong>Deployment</strong>: When the time comes to send the application to the cloud or servers, Docker containers make this easy because they work the same way on any machine.</p>
<p>  <strong>Example</strong>: Once you’ve made your dish in one kitchen and it worked great, you can take your packed ingredients and tools (the container) and cook it in a different kitchen (the server) without any issues.</p>
</li>
</ul>
<h3 id="heading-example-to-relate">Example to Relate:</h3>
<p>Imagine you’re preparing a special dish at home. You gather all the ingredients, tools, and a recipe, and then you package everything in a neat box (container). You take this box to a friend’s kitchen, and it turns out exactly the same as it did at home. No surprises, no missing tools or ingredients. This is what Docker containers do for applications—they ensure the app behaves consistently no matter where it’s run, saving developers time and preventing errors.</p>
<p>Imagine you have an app that you developed on your computer, and it works perfectly. You then give it to a friend or deploy it to a server, but suddenly it starts breaking. The server might have a different operating system, or maybe some important libraries are missing. Docker helps you create a container that has your app, along with everything it needs, so when you run it on any machine, it will behave exactly the same as it did on your computer. It's like packing all the ingredients and tools to bake a cake into a box, so no matter whose kitchen you're in, the cake will turn out the same.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding JWTs: The Key to Secure User Authentication]]></title><description><![CDATA[What is JWT?
JWT stands for JSON Web Token. It’s a compact, URL-safe token format used to securely transmit information between parties as a JSON object.
How Does JWT Work?
Think of a JWT as a sealed envelope. This envelope contains some information ...]]></description><link>https://blog.arishahmad.in/understanding-jwts-the-key-to-secure-user-authentication</link><guid isPermaLink="true">https://blog.arishahmad.in/understanding-jwts-the-key-to-secure-user-authentication</guid><category><![CDATA[JWT]]></category><category><![CDATA[JSON Web Tokens (JWT)]]></category><category><![CDATA[jsonwebtoken]]></category><category><![CDATA[JSON Web Tokens]]></category><category><![CDATA[#JWTAuthentication]]></category><category><![CDATA[ #JWTtokens ]]></category><category><![CDATA[JSON Web Token]]></category><category><![CDATA[#JSONWebTokens]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Sun, 01 Sep 2024 17:14:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725213884046/678aaa37-6766-489c-90e1-bb4a3891ce0d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-jwt"><strong>What is JWT?</strong></h2>
<p>JWT stands for JSON Web Token. It’s a compact, URL-safe token format used to securely transmit information between parties as a JSON object.</p>
<h2 id="heading-how-does-jwt-work">How Does JWT Work?</h2>
<p>Think of a JWT as a sealed envelope. This envelope contains some information and a signature to make sure it hasn’t been tampered with. Here’s how it works:</p>
<ol>
<li><p><strong>Header</strong>: This part describes how the JWT is encoded and the algorithm used for the signature. It’s like the label on the envelope saying “Here’s how this envelope is sealed.”</p>
</li>
<li><p><strong>Payload</strong>: This is the main content of the JWT, like the letter inside the envelope. It contains the claims or information you want to share. For example, it might include user information or permissions.</p>
</li>
<li><p><strong>Signature</strong>: This part is used to verify that the JWT wasn’t altered after it was issued. It’s like the wax seal on the envelope. The server uses a secret key to create the signature, and when you receive the JWT, you can use the same key to check if the envelope has been tampered with.</p>
</li>
</ol>
<h3 id="heading-example">Example</h3>
<p>Here’s a very simplified JWT:</p>
<ul>
<li><p><strong>Header</strong>: <code>{"alg": "HS256", "typ": "JWT"}</code></p>
</li>
<li><p><strong>Payload</strong>: <code>{"id": "1234567890", "name": "John Doe", "message": "this is a secret message"}</code></p>
</li>
<li><p><strong>Signature</strong>: <code>HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)</code></p>
</li>
</ul>
<p>So a JWT might look like this (it’s base64-encoded):</p>
<p><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im5ld3VzZXIiLCJleHAiOjE3MjUxNzQ1MTF9.cue3_U6PCiGCY8RY-kX4Yi-9N5DNT0UbN0mmvTQt5mY</code></p>
<h2 id="heading-server-decode-and-verify-jwt">Server: Decode and Verify JWT</h2>
<p>If you send the JWT token to the server, the server can extract and read the information in the payload, including <code>id</code>, <code>name</code>, and <code>message</code>, as long as it can verify the token’s signature. Here’s how it works:</p>
<ol>
<li><p><strong>Receive the JWT</strong>: When you send the JWT to the server (usually in the <code>Authorization</code> header or cookies), the server gets the token.</p>
</li>
<li><p><strong>Decode the JWT</strong>: The server decodes the JWT to read its header and payload. This is possible because JWTs are encoded in Base64, which means the payload is just encoded text. Decoding it doesn’t require a key, but it doesn’t ensure the content hasn’t been tampered with.</p>
</li>
<li><p><strong>Verify the Signature</strong>: To make sure the JWT hasn’t been altered, the server checks the signature. It uses the same secret key that was used to create the signature. If the signature matches, the server can trust that the payload is valid and hasn’t been modified.</p>
</li>
<li><p><strong>Extract Information</strong>: Once verified, the server can access the information in the payload, such as <code>id</code>, <code>name</code>, and <code>message</code>, and use it to handle the request appropriately.</p>
</li>
</ol>
<h3 id="heading-important-points">Important Points</h3>
<ol>
<li><p><strong>Confidentiality</strong>: While JWTs are signed to ensure their integrity, they are not encrypted by default. Anyone who has the JWT can read its payload, so sensitive information should not be included in the payload unless you encrypt the JWT.</p>
</li>
<li><p><strong>Expiration</strong>: JWTs often include an expiration time (<code>exp</code> claim) to limit their validity period. The server checks this to ensure the JWT is still valid.</p>
</li>
</ol>
<h2 id="heading-sending-amp-receiving-jwt-token">Sending &amp; Receiving JWT Token</h2>
<ol>
<li><p><strong>User Sends Payload to Server</strong>:</p>
<p> The user sends a request to the server with their credentials (e.g., username and password) or some other form of data for authentication.</p>
</li>
<li><p><strong>Server Generates JWT</strong>:</p>
<ul>
<li><p>The server verifies the user's credentials or payload.</p>
</li>
<li><p>If the credentials are valid, the server creates a JWT that includes claims (like <code>id</code>) and signs it using a secret key or a private key (for asymmetric algorithms).</p>
</li>
</ul>
</li>
<li><p><strong>Server Sends JWT to User</strong>:</p>
<ul>
<li><p>The server sends the signed JWT back to the user as part of the response.</p>
</li>
<li><p>The JWT typically contains a claim (<code>id</code>) that specifies when the token expires.</p>
</li>
</ul>
</li>
<li><p><strong>User Saves JWT</strong>:</p>
<ul>
<li><p>The user stores the JWT securely, usually in local storage or a cookie.</p>
</li>
<li><p>The JWT can be stored in an HTTP-only cookie to protect it from XSS attacks.</p>
</li>
</ul>
</li>
<li><p><strong>User Uses JWT for Further Requests</strong>:</p>
<p> For any subsequent requests to protected resources, the user includes the JWT in the request, typically in the <code>Authorization</code> header like this: <code>Authorization: Bearer &lt;JWT&gt;</code>.</p>
</li>
<li><p><strong>Server Verifies JWT</strong>:</p>
<ul>
<li><p>Upon receiving a request with the JWT, the server verifies the token's signature to ensure it hasn’t been tampered with.</p>
</li>
<li><p>The server also checks the <code>exp</code> claim to ensure the token hasn’t expired.</p>
</li>
<li><p>If the JWT is valid, the server processes the request and sends back the response.</p>
</li>
</ul>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725213924430/0d11198e-2e39-436e-ad60-02f82b88c39a.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-understanding-jwts-and-https-encryption-why-your-jwt-isnt-encrypted">Understanding JWTs and HTTPS Encryption: Why Your JWT Isn’t Encrypted</h2>
<p>When dealing with JSON Web Tokens (JWTs), it's crucial to understand how they handle data and the security implications of their use. One common point of confusion is the difference between <strong>Base64 encoding</strong>, <strong>HTTPS encryption</strong>, and <strong>JWT confidentiality</strong>.</p>
<p>Base64 encoding transforms the JWT into a text format that’s easy to transmit, but it’s important to note that <strong>Base64 encoding is not encryption</strong>. This means that anyone who has access to the JWT can decode it to view its contents.</p>
<h3 id="heading-at-the-user-end">At the User End</h3>
<ul>
<li><strong>JWT Readability</strong>: On the user end, the JWT is indeed readable. If a user has the JWT (e.g., stored in local storage or cookies), they can decode it to see its contents. However, this assumes the JWT is not encrypted.</li>
</ul>
<h3 id="heading-at-the-server-end">At the Server End</h3>
<ul>
<li><strong>JWT Readability</strong>: On the server end, the JWT is also readable. The server decodes the JWT to access its payload (e.g., user ID) after verifying the signature.</li>
</ul>
<h3 id="heading-the-role-of-https-in-transit-during-transmission">The Role of HTTPS: In Transit (During Transmission)</h3>
<p><strong>HTTPS (HyperText Transfer Protocol Secure)</strong> is designed to protect data transmitted over the internet. Here’s what it does:</p>
<ul>
<li><p><strong>Protection by HTTPS</strong>: When the JWT is transmitted over the network (from the client to the server), HTTPS encrypts the entire communication channel. This means:</p>
<ul>
<li><p><strong>Encryption</strong>: HTTPS encrypts the data being sent, including the JWT. So, if someone intercepts the data during transmission, they would see encrypted information and not the actual JWT.</p>
</li>
<li><p><strong>Protection</strong>: This protects the JWT from being easily read or tampered with by attackers while it's in transit.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-additional-security-measures">Additional Security Measures</h3>
<p>If you need to ensure that the contents of the JWT remain confidential, especially if it contains sensitive information, consider the following:</p>
<ul>
<li><p><strong>Avoid Sensitive Data</strong>: Refrain from including highly sensitive information directly in the JWT payload.</p>
</li>
<li><p><strong>Encrypt the JWT</strong>: Use additional encryption to protect the JWT’s contents. This ensures that even if the JWT is intercepted or accessed, its payload remains secure.</p>
</li>
<li><p><strong>Use HTTPS</strong>: Always use HTTPS to transmit JWTs over the network to protect the data in transit.</p>
</li>
</ul>
<h2 id="heading-understanding-jwt-expiry-and-how-servers-handle-expired-tokens">Understanding JWT Expiry and How Servers Handle Expired Tokens</h2>
<p>A JWT typically includes an <code>exp</code> (expiry) claim, which specifies the timestamp at which the token will expire. This is usually set when the token is issued. For instance, if a JWT is issued with a 5-minute expiry, it will be valid for 5 minutes from the time of issuance.</p>
<h3 id="heading-example-jwt-payload"><strong>Example JWT Payload:</strong></h3>
<p><code>{ "sub": "1234567890", "name": "John Doe", "exp": 1700000000 }</code></p>
<p>In this example, the <code>exp</code> claim contains a Unix timestamp that represents the expiration time of the token.</p>
<h3 id="heading-what-happens-after-5-minutes">What Happens After 5 Minutes?</h3>
<p>After the specified expiry time has passed:</p>
<ol>
<li><p><strong>Token Becomes Invalid</strong>: The JWT is no longer valid. This means that any requests made with this token will be rejected by the server.</p>
</li>
<li><p><strong>Server Check</strong>: When the server receives a request with a JWT, it checks the <code>exp</code> claim to determine if the token has expired.</p>
</li>
<li><p><strong>Error Response</strong>: If the JWT has expired, the server typically responds with an error message, such as a 401 Unauthorized status, indicating that the token is no longer valid.</p>
</li>
</ol>
<h3 id="heading-how-does-the-server-check-jwt-expiry">How Does the Server Check JWT Expiry?</h3>
<p>Here’s how the server determines if a JWT has expired:</p>
<ol>
<li><p><strong>Receive the JWT</strong>: The server receives the JWT from the client, usually in the <code>Authorization</code> header or cookies.</p>
</li>
<li><p><strong>Decode the JWT</strong>: The server decodes the JWT to access its payload. This decoding allows the server to read the claims, including the <code>exp</code> claim.</p>
</li>
<li><p><strong>Extract and Compare</strong> <code>exp</code> Claim:</p>
<ul>
<li><p>The payload contains an <code>exp</code> claim with a Unix timestamp.</p>
</li>
<li><p>The server compares the current time with the <code>exp</code> timestamp.</p>
</li>
<li><p>If the current time is greater than the <code>exp</code> time, the token is considered expired.</p>
</li>
</ul>
</li>
<li><p><strong>Verify Token</strong>: In addition to checking the expiry, the server verifies the token’s signature to ensure that the token has not been tampered with.</p>
</li>
<li><p><strong>Respond to Client</strong>: If the token is expired, the server sends a response indicating that the token is no longer valid.</p>
</li>
</ol>
<h2 id="heading-secure-jwt-storage">Secure JWT Storage</h2>
<p>JWTs can be stored either on the client side or server side. Each approach has its own security implications and best practices. Here’s a detailed look at both:</p>
<ol>
<li><h3 id="heading-client-side-storage"><strong>Client-Side Storage</strong></h3>
</li>
</ol>
<p><strong>a. HTTP-Only Cookies</strong></p>
<ul>
<li><p><strong>Description</strong>: Storing JWTs in HTTP-only cookies is a highly secure method because these cookies cannot be accessed via JavaScript. This protects against Cross-Site Scripting (XSS) attacks.</p>
</li>
<li><p><strong>Implementation</strong>:</p>
<pre><code class="lang-plaintext">  httpCopy codeSet-Cookie: jwt=your_jwt_token; HttpOnly; Secure; SameSite=Strict
</code></pre>
<ul>
<li><p><code>HttpOnly</code>: Prevents JavaScript from accessing the cookie.</p>
</li>
<li><p><code>Secure</code>: Ensures the cookie is only sent over HTTPS.</p>
</li>
<li><p><code>SameSite=Strict</code>: Limits the cookie to same-site requests, reducing Cross-Site Request Forgery (CSRF) risks.</p>
</li>
</ul>
</li>
</ul>
<p><strong>b. Local Storage</strong></p>
<ul>
<li><p><strong>Description</strong>: Local Storage and Session Storage are more accessible via JavaScript, making them vulnerable to XSS attacks.</p>
</li>
<li><p><strong>Implementation</strong>:</p>
<pre><code class="lang-bash">  javascriptCopy codelocalStorage.setItem(<span class="hljs-string">'jwt'</span>, your_jwt_token);
</code></pre>
</li>
<li><p><strong>Risks</strong>: Not recommended due to susceptibility to XSS. HTTP-only cookies are preferred for enhanced security.</p>
</li>
</ul>
<ol start="2">
<li><h3 id="heading-server-side-storage"><strong>Server-Side Storage</strong></h3>
</li>
</ol>
<p><strong>a. Secure Server-Side Sessions</strong></p>
<ul>
<li><p><strong>Description</strong>: Store JWTs on the server side using sessions. This involves storing only a session identifier in a client-side cookie while keeping the actual JWT on the server.</p>
</li>
<li><p><strong>Implementation</strong>:</p>
<ul>
<li><p>Store the JWT securely in a database or in-memory store like Redis.</p>
</li>
<li><p>Store a session ID in an HTTP-only cookie.</p>
</li>
<li><p>Map the session ID to the JWT on the server.</p>
</li>
</ul>
</li>
</ul>
<p><strong>b. Token Storage in a Secure Database</strong></p>
<ul>
<li><p><strong>Description</strong>: Use a secure database or cache system (e.g., Redis) for storing JWTs, with an identifier (e.g., session ID) in the client-side cookie.</p>
</li>
<li><p><strong>Implementation</strong>:</p>
<ul>
<li><p>Securely store the JWT in the database or cache.</p>
</li>
<li><p>Use a unique identifier to refer to the JWT in client-side cookies.</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-preventing-unauthorized-requests">Preventing Unauthorized Requests</h2>
<p>To secure your server and prevent unauthorized access from bots or testing tools, follow these strategies:</p>
<ol>
<li><p><strong>Rate Limiting</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Limit the number of requests a client can make within a given timeframe.</p>
</li>
<li><p><strong>Implementation</strong>: Use middleware or libraries to enforce rate limits on your server.</p>
</li>
</ul>
</li>
<li><p><strong>CAPTCHA</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Verify that the request is made by a human, not a bot.</p>
</li>
<li><p><strong>Implementation</strong>: Integrate CAPTCHA services like Google reCAPTCHA on critical forms and authentication endpoints.</p>
</li>
</ul>
</li>
<li><p><strong>Authentication and Authorization</strong>:</p>
<ul>
<li><strong>JWT</strong>: Use JWTs to authenticate users and manage access. Ensure JWTs are validated and include necessary claims.</li>
</ul>
</li>
<li><p><strong>Referer and Origin Checking</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Validate that requests originate from your own website.</p>
</li>
<li><p><strong>Implementation</strong>: Check the <code>Referer</code> or <code>Origin</code> headers to confirm that requests come from your domain.</p>
</li>
</ul>
</li>
<li><p><strong>Secure Development Practices</strong>:</p>
<ul>
<li><p><strong>Regular Audits</strong>: Regularly audit your security practices and code.</p>
</li>
<li><p><strong>Penetration Testing</strong>: Perform penetration testing to identify and address vulnerabilities.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-summary">Summary</h2>
<p><strong>JWT (JSON Web Token)</strong> is a compact token format used to transmit information securely between parties. It consists of three parts:</p>
<ol>
<li><p><strong>Header</strong>: Describes how the JWT is encoded and the signature algorithm used.</p>
</li>
<li><p><strong>Payload</strong>: Contains the claims or information to be shared.</p>
</li>
<li><p><strong>Signature</strong>: Ensures the JWT hasn't been tampered with.</p>
</li>
</ol>
<p><strong>How JWT Works:</strong></p>
<ol>
<li><p><strong>User sends credentials</strong> to the server.</p>
</li>
<li><p><strong>Server generates a JWT</strong> and sends it back to the user.</p>
</li>
<li><p><strong>User stores the JWT</strong> (commonly in HTTP-only cookies).</p>
</li>
<li><p><strong>User includes JWT</strong> in requests for protected resources.</p>
</li>
<li><p><strong>Server verifies JWT</strong> and processes the request if valid.</p>
</li>
</ol>
<p><strong>Key Points:</strong></p>
<ul>
<li><p><strong>JWTs are not encrypted by default</strong>; they are encoded. To protect sensitive information, use HTTPS for transmission or encrypt the JWT.</p>
</li>
<li><p><strong>HTTP-only cookies</strong> are preferred for storing JWTs due to their protection against XSS attacks.</p>
</li>
<li><p><strong>Local Storage</strong> is less secure and susceptible to XSS.</p>
</li>
<li><p><strong>Server-side storage</strong> is an option for additional security.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Accessing S3 Bucket Images with API]]></title><description><![CDATA[Introduction
This blog will guide you through setting up an API to access images stored in Amazon S3. We’ll leverage AWS Lambda to create a serverless function that handles image retrieval, and API Gateway to expose this functionality as a RESTful AP...]]></description><link>https://blog.arishahmad.in/accessing-s3-bucket-images-with-api</link><guid isPermaLink="true">https://blog.arishahmad.in/accessing-s3-bucket-images-with-api</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[aws-apigateway]]></category><category><![CDATA[Postman]]></category><category><![CDATA[lambda]]></category><category><![CDATA[API Gateway]]></category><category><![CDATA[S3]]></category><category><![CDATA[REST API]]></category><category><![CDATA[#aws projects]]></category><category><![CDATA[AWS API Gateway]]></category><category><![CDATA[AWS lambda for beginners]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[Lambda function]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Sat, 10 Aug 2024 05:14:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723266679417/9b63f8b9-3601-4b6c-a570-6051737cbc8e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>This blog will guide you through setting up an API to access images stored in Amazon S3. We’ll leverage AWS Lambda to create a serverless function that handles image retrieval, and API Gateway to expose this functionality as a RESTful API. To ensure everything works as expected, we'll use Postman for testing and validation.</p>
<h2 id="heading-step-1-setting-up-the-s3-bucket">Step 1: Setting Up The S3 Bucket</h2>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723180942878/27d7d370-e3a8-4062-b07f-88f5951a019b.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Click <strong>Create Bucket</strong>.</p>
</li>
<li><p>Give it a suitable name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723263985617/dfadb10e-1cc8-4396-8af5-27ab49fa8e17.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Create Bucket</strong>.</p>
</li>
<li><p>Open the bucket.</p>
</li>
<li><p>Click Upload.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264041311/c9d071fc-fd55-4c7e-ae45-0f8cf76663a4.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Add files</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264083021/3c193559-6457-47f5-8074-242e487661de.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Upload an images.</p>
<p> Make sure to use smaller images (in kb) for faster access.</p>
</li>
</ol>
<h2 id="heading-step-2-creating-the-lambda-function">Step 2: Creating The Lambda Function</h2>
<ol>
<li><p>Open the <strong>Lambda</strong> and in <strong>AWS Management Console.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264097459/1268338f-75c2-4d6a-bb27-c553045be2af.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create a function</strong>.</p>
</li>
<li><p>Give a suitable function name.</p>
</li>
<li><p>Select <strong>Python 3.8</strong> in <strong>Runtime</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264127443/54089111-bce1-4d52-b20c-2dc744d99ee0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In <strong>Advanced settings</strong> enable <strong>Enable function URL</strong>, select <strong>NONE</strong> in <strong>Auth type,</strong> and enable <strong>Configure cross-origin resource sharing (CORS)</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264144520/f61ff290-f8de-4cf4-b16a-494d87a0b565.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264181603/4fb70275-6a51-426f-8df9-9728c9ce3daf.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the <strong>Create function</strong>.</p>
</li>
<li><p>Open the function.</p>
</li>
<li><p>In the code area paste this code, save it, and click Deploy.</p>
<pre><code class="lang-bash"> import base64
 import boto3

 s3 = boto3.client(<span class="hljs-string">'s3'</span>)

 def lambda_handler(event, context):
     try:
         <span class="hljs-comment"># Extract bucket name and file name from the event</span>
         bucket_name = event[<span class="hljs-string">"pathParameters"</span>][<span class="hljs-string">"bucket"</span>]
         file_name = event[<span class="hljs-string">"queryStringParameters"</span>][<span class="hljs-string">"file"</span>]

         <span class="hljs-comment"># Fetch the file from S3</span>
         response = s3.get_object(Bucket=bucket_name, Key=file_name)
         file_content = response[<span class="hljs-string">"Body"</span>].<span class="hljs-built_in">read</span>()

         <span class="hljs-comment"># Return the image as a base64 encoded string</span>
         <span class="hljs-built_in">return</span> {
             <span class="hljs-string">"statusCode"</span>: 200,
             <span class="hljs-string">"headers"</span>: {
                 <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"image/jpeg"</span>,  <span class="hljs-comment"># Adjust this if you have different image formats</span>
                 <span class="hljs-string">"Content-Disposition"</span>: f<span class="hljs-string">"inline; filename={file_name}"</span>  <span class="hljs-comment"># 'inline' displays the image in the browser</span>
             },
             <span class="hljs-string">"body"</span>: base64.b64encode(file_content).decode(<span class="hljs-string">'utf-8'</span>),
             <span class="hljs-string">"isBase64Encoded"</span>: True
         }

     except s3.exceptions.NoSuchKey:
         <span class="hljs-comment"># Handle the case where the file does not exist in the bucket</span>
         <span class="hljs-built_in">return</span> {
             <span class="hljs-string">"statusCode"</span>: 404,
             <span class="hljs-string">"body"</span>: f<span class="hljs-string">"File {file_name} not found in bucket {bucket_name}."</span>
         }

     except Exception as e:
         <span class="hljs-comment"># Handle any other exceptions</span>
         <span class="hljs-built_in">return</span> {
             <span class="hljs-string">"statusCode"</span>: 500,
             <span class="hljs-string">"body"</span>: f<span class="hljs-string">"An error occurred: {str(e)}"</span>
         }
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264211654/16028040-d20d-4dea-9373-57e6bf37a40b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now click on <strong>Configuration</strong> -&gt; <strong>Permissions</strong>.</p>
</li>
<li><p>Click on the Role name, and a new tab will open up.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264229561/481d0285-00be-4f87-a5e0-064ef79a79af.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Add permissions</strong> -&gt; <strong>Attach policies</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264263808/e9c0a788-9380-4a43-a80d-2a814054019f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Search and select <strong>AmazonS3FullAccess</strong> then click <strong>Add permissions</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264279736/0c56da78-51c1-4ff6-8867-fb84dbd13560.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h2 id="heading-step-3-setting-up-api-gateway"><strong>Step 3: Setting Up API Gateway</strong></h2>
<ol>
<li><p>Open the <strong>API Gateway</strong> and in <strong>AWS Management Console.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264300324/6a344f59-7c41-4599-8070-cda5dceb93a6.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Build</strong> on <strong>Rest API</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264318106/21e7104e-3a3d-4785-8390-a93e5d9d618b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>New API</strong> and give a suitable name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264339847/0a963424-2b3f-4bf8-8dbf-50e0982370dc.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on <strong>Create API</strong>.</p>
</li>
<li><p>Open the API.</p>
</li>
<li><p>Click on <strong>Create resource</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265524234/7ba502ec-b187-46fa-864f-1b0620edc499.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Give a resource name <strong>{bucket}</strong>.</p>
<p> <strong>Note</strong>: Do not remove the curly bracket it will hold the bucket name which will be sent with the API.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265576951/32ee20cf-5621-44b2-a286-50ca39cacb3f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create resource</strong>.</p>
</li>
<li><p>Now click on the <strong>Create method</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265650851/d5597e98-31c4-47e3-94a8-fcb499bd5481.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>GET</strong> for the method type and the <strong>Lambda function</strong> for the <strong>integration type</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264525862/cc2831d7-b319-45d5-865a-0b80520ba114.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>You can enable <strong>Lambda proxy integration and select the Lambda function from the drop-down.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264678355/1181ba64-43c0-4139-a802-7fe6552a39c2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In the <strong>Method request settings</strong>, select <strong>Validate query string parameters and headers</strong> under <strong>Request validator.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264551987/d042fa3b-176b-409e-b678-784fb9c98eb1.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In <strong>URL query string parameters</strong> click <strong>Add query string</strong>, type <strong>file</strong> under <strong>Name,</strong> and check <strong>Required.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264742356/a8534593-cf46-4da2-af33-6975d3705674.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create method.</strong></p>
</li>
<li><p>From the left navigation panel click <strong>API settings.</strong></p>
</li>
<li><p>Click on <strong>Manage media types</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723264779752/d9c4f24f-b5ad-4598-ac31-93d963174bed.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Then click on <strong>Add binary media types</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265738976/acbb939a-0f06-48fa-bbcb-db030a4282e0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter <strong>*/*</strong> and click on <strong>Save changes</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265717362/fdf89db6-6555-456c-86fb-ea8354cd6b5e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>From the left navigation panel click <strong>Resources.</strong></p>
</li>
<li><p>Click on <strong>Deploy API</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265945980/a071a1ef-8d32-41f9-bf0c-68aabe9296fd.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>*New Satge*</strong> and give a suitable name.</p>
</li>
<li><p>Click on <strong>Deploy</strong>.</p>
</li>
<li><p>From the left navigation panel click <strong>Stages.</strong></p>
</li>
<li><p>Click on <strong>+</strong> until to see <strong>GET</strong> then click on <strong>GET</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265977837/6e8dfcca-20be-4432-82c8-13ae80c0c7c0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Copy the <strong>Invoke URL.</strong></p>
</li>
</ol>
<h2 id="heading-step-4-testing-the-api-with-postman">Step 4: Testing the API with Postman</h2>
<ol>
<li><p>Open <strong>Postman</strong>.</p>
</li>
<li><p>Paste the link and replace <strong>{bucket}</strong> with the you s3 bucket name and add <strong>?file=file_name</strong>. Replace file_name with the file name that you upload in the s3 bucket (<strong>Example</strong>: if the <strong>URL</strong> is <strong>https://url.com</strong>, the <strong>s3 bucket name</strong> is <strong>images.xyz,</strong> and the <strong>file name</strong> is <strong>maths.jpg</strong> then use the link <strong>https://url.com/images.xyz?file=maths.jpg</strong>)</p>
</li>
<li><p>Click Send and you can see the file in Body section.</p>
<p> You can also use this link in a browser tab and fetch the image.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723266085056/c261f2e1-a8dc-43f4-aa0a-78c4e693b552.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723265193310/58f5b66b-c91f-4126-bd54-6b17cb343d93.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Hosting Your Serverless Website Using AWS]]></title><description><![CDATA[Note: This guide requires a web domain to host the website.
Step 1: Creating a S3 Bucket

Open the AWS Management Console and navigate to the S3.
 

Click Create Bucket.

Give it a suitable name.
 

Scroll and click Create Bucket.
 

Copy the followi...]]></description><link>https://blog.arishahmad.in/hosting-your-serverless-website-using-aws</link><guid isPermaLink="true">https://blog.arishahmad.in/hosting-your-serverless-website-using-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[Hosting static website using  AWS S3]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[S3 static website hosting]]></category><category><![CDATA[cloudfront]]></category><category><![CDATA[aws cloudfront]]></category><category><![CDATA[route53]]></category><category><![CDATA[Route 53]]></category><category><![CDATA[DynamoDB]]></category><category><![CDATA[AWS DynamoDB]]></category><category><![CDATA[ aws boto3 dynamodb]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[Lambda function]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Fri, 09 Aug 2024 06:56:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723186375254/40c205d5-4dc8-4f1d-b4cb-0e430e3b0946.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Note</strong>: This guide requires a web domain to host the website.</p>
<h2 id="heading-step-1-creating-a-s3-bucket">Step 1: Creating a S3 Bucket</h2>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723180942878/27d7d370-e3a8-4062-b07f-88f5951a019b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create Bucket</strong>.</p>
</li>
<li><p>Give it a suitable name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723180963058/5c5e37d2-4057-4eb5-841b-b8c1f034a179.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Create Bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723180989963/15364da7-a1d3-402e-94e6-c0802aef59f8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Copy the following and create an <strong>index.html file</strong>.</p>
<pre><code class="lang-bash"> &lt;!DOCTYPE html&gt;
 &lt;html lang=<span class="hljs-string">"en"</span>&gt;
 &lt;head&gt;
     &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
     &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
     &lt;title&gt;Demo Website&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
     &lt;div class=<span class="hljs-string">"container"</span>&gt;
         &lt;h1&gt;You<span class="hljs-string">'re truly welcome!&lt;/h1&gt;
         &lt;h2&gt;Do like the Blog if you find the tutorial helpful.&lt;/h2&gt;
         &lt;ul class="social-links"&gt;
             &lt;li&gt;&lt;a href="https://arishahmad.hashnode.dev/hosting-your-serverless-website-using-aws" target="_blank"&gt;Blog&lt;/a&gt;&lt;/li&gt;
         &lt;/ul&gt;
         &lt;h3 id="views"&gt;Views&lt;/h3&gt;
     &lt;/div&gt;
     &lt;script src="script.js"&gt;&lt;/script&gt;
 &lt;/body&gt;
 &lt;/html&gt;</span>
</code></pre>
</li>
<li><p>Upload this file in the S3 bucket.</p>
</li>
</ol>
<h2 id="heading-step-2-creating-cloudfront-distribution">Step 2: Creating CloudFront distribution.</h2>
<ol>
<li><p>Navigate to <strong>CloudFront</strong> in the AWS Management Console.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181014148/ecbfc07d-a021-4991-a6af-404d7a06dfe3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create a CloudFront distribution</strong>.</p>
</li>
<li><p>Select the S3 bucket you just created under the <strong>Origin domain</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181034428/dd9b307f-c703-42be-ae33-737d9d6d4d86.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Origin access</strong> click <strong>Origin access control settings</strong>.</p>
</li>
<li><p>Click <strong>Create new OAC</strong> -&gt; <strong>Create</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181080552/72728f42-3464-4523-bad7-834d11e31d21.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Web Application Firewall (WAF)</strong> select <strong>Do not enable security protections</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181100511/13bc2eb4-e04b-4bfd-92a2-94b88fb392c3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Create distribution</strong>.</p>
<p> This screen will pop up.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181210821/00889a72-1042-4d6e-9af9-f01d2d01a72b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Copy policy</strong>.</p>
<p> If the <strong>Copy policy</strong> option doesn't appear.</p>
<ol>
<li><p>Open the distribution.</p>
</li>
<li><p>Click on <strong>Origins</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181321099/f8e5e9b9-833e-4bca-9993-f07619e03530.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the origin and click <strong>Edit</strong>.</p>
</li>
<li><p>Scroll and click <strong>Copy policy</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181343292/31155ce6-11d8-4ce7-9a51-ca41ae6ea174.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
</li>
</ol>
<h2 id="heading-step-3-updating-s3-bucket-policy">Step 3: Updating S3 bucket policy</h2>
<ol>
<li><p>Navigate to <strong>S3</strong> in the AWS Management Console.</p>
</li>
<li><p>Open the bucket.</p>
</li>
<li><p>Click on <strong>Permissions</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181250009/b4bfb021-48b1-436f-9d14-47c5881b42ca.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>On <strong>Bucket policy</strong> click <strong>Edit</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181267320/d0b4423d-8fdd-4fd5-b580-0d7aac4b57bf.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Paste the policy and click <strong>Save changes</strong>.</p>
</li>
</ol>
<h2 id="heading-step-4-set-up-route53">Step 4: Set up Route53</h2>
<ol>
<li><p>Navigate to <strong>Route 53 Dashboard</strong> in the AWS Management Console.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181399514/030fcce2-2e14-423e-a4f3-e4bb1eb76843.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create hosted zone</strong>.</p>
</li>
<li><p>Enter the <strong>Domain name.</strong></p>
</li>
<li><p>Select <strong>Public hosted zone</strong> under <strong>Type</strong>.</p>
</li>
<li><p>Scroll and click <strong>Create hosted zone</strong>.</p>
</li>
<li><p>Select the record with NS type, Record details will open up.</p>
</li>
<li><p>Copy each <strong>value</strong> of this <strong>record</strong> and add this to the <strong>Nameserver</strong>. This option will be provided by the platform where you bought the domain.</p>
</li>
</ol>
<h2 id="heading-step-5-editing-the-cloudfront">Step 5: Editing the CloudFront</h2>
<ol>
<li><p>Open the CloudFront distribution.</p>
</li>
<li><p>Select the distribution and Click <strong>Edit</strong> on <strong>Settings</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181538084/dff92a15-0087-4d7a-b53e-3db2cb603b97.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>Add items</strong> under <strong>Alternate domain name (CNAME)</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181578394/215dc090-b5bb-455e-9697-1672da8eadea.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter the domain on which you want to host the website (Example: If your domain name is example.com then enter demo.example.com).</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181702881/656dd2a3-f43f-48db-98ef-33069b8a6633.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Request certificate</strong>. A new tab will open up.</p>
</li>
<li><p>Click <strong>Next</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181729807/dd90c575-519c-4710-983b-4459a28d577f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter <strong>.&lt;your domain name&gt;</strong> (Example: If your domain name is example.com, enter *.example.com).</p>
</li>
<li><p>Scroll and click <strong>Request</strong>.</p>
<p> Your new certificate might continue to display a status of <strong>Pending validation</strong> for <strong>up to 30 minutes.</strong></p>
</li>
<li><p>Open the Certificate.</p>
</li>
<li><p>Click <strong>Create records in Route 53</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181868451/1b3018bf-2ec8-4fe1-8930-29cb3542489a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create records</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723183474199/71171552-cabc-4f06-8eca-36c94f7bf951.png" alt class="image--center mx-auto" /></p>
<p>You can check the new route must be added in the hosted zone.</p>
<p>Now wait till the status of certificate is not <strong>Issued</strong>.</p>
</li>
<li><p>Go back to the CloudFront tab, and select the newly created Custom SSL certificate.</p>
</li>
<li><p>Enter <strong>index.html</strong> under the <strong>Default root object.</strong></p>
</li>
<li><p>Scroll and click <strong>Save changes</strong>.</p>
</li>
</ol>
<h2 id="heading-step-6-create-a-record-in-the-hosted-zone">Step 6: Create a record in the Hosted Zone.</h2>
<ol>
<li><p>Open the hosted zone in Route53.</p>
</li>
<li><p>Click <strong>Create record</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723181979984/8c6fd757-0303-4101-a34d-efd3e16e69c6.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In record name enter the subdomain. This should be same as the alternate domain name you entered in the CloudFront distribution.</p>
</li>
<li><p>Enable the <strong>Alias</strong>.</p>
</li>
<li><p>Choose <strong>Alias to CloudFront distribution</strong> and select the distribution you created.</p>
</li>
<li><p>Click <strong>Create Record</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182181976/99b7243f-59a1-41e2-9a39-7a50cf49275d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now visit the alternate domain name, and you will see the hosted website. This might take few minutes until the CloudFront distribution is ready.</p>
</li>
</ol>
<h2 id="heading-step-7-set-up-the-dynamodb">Step 7: Set up the DynamoDB</h2>
<ol>
<li><p>Navigate to <strong>DynamoDB</strong> in the <strong>AWS Management Console</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182313168/686f5a64-c8a2-4774-83ed-9ecc253ae034.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create table</strong>.</p>
</li>
<li><p>Enter a suitable name.</p>
</li>
<li><p>Endet <strong>id</strong> in <strong>Partition key</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182337519/c8a3e614-86ff-47dd-be61-919dafc05221.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Create Table</strong>.</p>
</li>
<li><p>Select the table, go to <strong>Actions</strong> -&gt; <strong>Explore items</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182357452/00e32686-08ca-4b14-ad8e-9ebc585a0f62.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create item</strong>.</p>
</li>
<li><p>Enter value <strong>0</strong> in id Attribute.</p>
</li>
<li><p>Select <strong>Add new attribute</strong> -&gt; <strong>Number</strong>.</p>
</li>
<li><p>Enter the Attribute name as views and enter value <strong>0</strong>.</p>
</li>
<li><p>Click <strong>Create item</strong>.</p>
</li>
</ol>
<h2 id="heading-step-8-create-the-lambda-function">Step 8: Create the Lambda Function</h2>
<ol>
<li><p>Navigate to <strong>AWS Lambda</strong> in the <strong>AWS Management Console</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182407141/9d8fec66-df7d-487c-a993-80efaabf26ff.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create a function</strong>.</p>
</li>
<li><p>Enter a suitable <strong>Function name</strong>.</p>
</li>
<li><p>Select Python 3.8 in Runtime.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182457575/e149f5ef-d6f2-4947-9421-0a071c8e0650.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>Create a new role with basic Lambda permissions</strong> in the <strong>Execution role</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182486414/2639886d-6292-474e-9d7e-eb06895d0ef8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>In Advanced settings click <strong>Enable function URL</strong> and <strong>NONE</strong> in <strong>Auth Type.</strong></p>
</li>
<li><p>Check the <strong>Configure cross-origin resource sharing (CORS)</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182587671/7971746b-3dfb-4315-b596-fb407f0ac71b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>the Create function</strong>.</p>
</li>
<li><p>Copy the following code.</p>
<pre><code class="lang-bash"> import json
 import boto3
 dynamodb = boto3.resource(<span class="hljs-string">'dynamodb'</span>)
 table = dynamodb.Table(<span class="hljs-string">'demo-table'</span>)
 def lambda_handler(event, context):
     response = table.get_item(Key={
         <span class="hljs-string">'id'</span>:<span class="hljs-string">'0'</span>
     })
     views = response[<span class="hljs-string">'Item'</span>][<span class="hljs-string">'views'</span>]
     views = views + 1

     <span class="hljs-built_in">print</span>(views)

     response = table.put_item(Item={
         <span class="hljs-string">'id'</span>:<span class="hljs-string">'0'</span>,
         <span class="hljs-string">'views'</span>: views
     })

     <span class="hljs-built_in">return</span> views
</code></pre>
</li>
<li><p>Paste this file in the code area.</p>
<p><strong>Note</strong>: Change the table name in this file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182623973/d02db530-6d0b-4318-8454-e8261e02d602.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Save the file then Click <strong>Deploy</strong>.</p>
</li>
<li><p>Click <strong>Configuration</strong> -&gt; <strong>Permissions</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182655650/d7f015b0-902c-48e3-8b97-9e04bada17dd.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click on the role, a new tab will open up.</p>
</li>
<li><p>Click <strong>Addpermissions</strong> -&gt; <strong>Attach policies</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182702653/9d9b3bd8-f05f-4a62-8bab-5d0109369616.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Search and select <strong>AmazonDynamoDBFullAccess</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182732723/82b65160-768c-4e04-8077-5a3bc3ffe2e2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Add permissions</strong>.</p>
</li>
<li><p>Now Come back to the Lambda tab.</p>
</li>
<li><p>Click Code and then click <strong>Test</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723182915105/59e3b824-23d8-4e15-b4a0-12dbf6bc3376.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a suitable name, then click <strong>Save</strong>.</p>
</li>
<li><p>Now click <strong>Test</strong> again, and you can see the response.</p>
</li>
</ol>
<h2 id="heading-step-9-creating-the-js-file">Step 9: Creating the JS file</h2>
<ol>
<li><p>Copy the following code.</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">let</span> counter = document.getElementById(<span class="hljs-string">"views"</span>);

 async <span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">updateCounter</span></span>() {
     try {
         <span class="hljs-built_in">let</span> response = await fetch(<span class="hljs-string">"lambda_function_url"</span>);
         <span class="hljs-keyword">if</span> (!response.ok) {
             throw new Error(<span class="hljs-string">'Network response was not ok'</span>);
         }
         <span class="hljs-built_in">let</span> data = await response.json();
         console.log(data);
         counter.innerHTML = `Views: <span class="hljs-variable">${data}</span>`;
     } catch (error) {
         console.error(<span class="hljs-string">'Failed to fetch data:'</span>, error);
         counter.innerHTML = <span class="hljs-string">'Failed to load views'</span>;
     }
 }

 updateCounter();
</code></pre>
</li>
<li><p>Create a file named script.js file, and paste the code.</p>
</li>
<li><p>Copy the Lambda function URL and replace lambda_function_url in the file with the URL.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723183074693/cc0d2f6e-8e61-4183-acbc-7022c562263c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now upload this script.js file in the S3 bucket.</p>
</li>
</ol>
<h2 id="heading-step-10-finishing-up">Step 10: Finishing Up</h2>
<p>Visit the Alternate domain name you entered in the CloudFront. You can see the hosted website and with each reload the view counter will increase. You can also check the increased value of views in the dynamoDB.</p>
<p>If the changes are not visible you may need to create an <strong>Invalidation.</strong></p>
<ol>
<li><p>Open the CloudFront distribution you created.</p>
</li>
<li><p>Click <strong>Invalidations</strong> -&gt; <strong>Create invalidation</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723183110249/cde7d336-e98b-4f13-8366-5f823298bc28.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Type /* and click <strong>Create invalidation</strong>.</p>
</li>
<li><p>Wait while the status is in progress.</p>
</li>
<li><p>Reload the website, and you'll be able to see the changes.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Modify IAM User Password Rules]]></title><description><![CDATA[Open the AWS Management Console and navigate to the Identity and Access Management (IAM).

Click on Account settings from the left navigation panel.
 

Click Edit.

Click Custom.
 

Set Password minimum length.

Select the required options under Pass...]]></description><link>https://blog.arishahmad.in/modify-iam-user-password-rules</link><guid isPermaLink="true">https://blog.arishahmad.in/modify-iam-user-password-rules</guid><category><![CDATA[IAM user password]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS IAM]]></category><category><![CDATA[IAM]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Mon, 05 Aug 2024 03:53:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722829820137/bb418c37-d024-46c3-a7e3-7f8270f532c4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>Identity and Access Management (IAM).</strong></p>
</li>
<li><p>Click on <strong>Account settings</strong> from the left navigation panel.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722829734327/4ca9e921-d876-4ad1-999d-8bcdc6153fe3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Edit</strong>.</p>
</li>
<li><p>Click <strong>Custom</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722829762667/d11fdf49-78cd-4b4c-92f4-86d95fa2c6ca.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Set <strong>Password minimum length</strong>.</p>
</li>
<li><p>Select the required options under <strong>Password strength</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722829806613/0e61ca93-e457-46de-9c5c-87e001af2015.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Save changes</strong>.</p>
</li>
<li><p>Try creating a new IAM user, the password will require newly set criteria.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How to Create and Attach IAM Policies in AWS]]></title><description><![CDATA[Introduction
You manage access in AWS by creating policies and attaching them to IAM identities (users, groups of users, or roles) or AWS resources. A policy is an object in AWS that, when associated with an identity or resource, defines their permis...]]></description><link>https://blog.arishahmad.in/how-to-create-and-attach-iam-policies-in-aws</link><guid isPermaLink="true">https://blog.arishahmad.in/how-to-create-and-attach-iam-policies-in-aws</guid><category><![CDATA[AWS IAM Policy]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS IAM]]></category><category><![CDATA[aws iam policies]]></category><category><![CDATA[iam policies]]></category><category><![CDATA[iam policy]]></category><category><![CDATA[IAM]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Mon, 05 Aug 2024 03:33:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828506644/3acb085a-7ded-4b0b-9b87-bec5d68b81b7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>You manage access in AWS by creating policies and attaching them to IAM identities (users, groups of users, or roles) or AWS resources. A policy is an object in AWS that, when associated with an identity or resource, defines their permissions. AWS evaluates these policies when an IAM principal (user or role) makes a request. Permissions in the policies determine whether the request is allowed or denied. Most policies are stored in AWS as JSON documents. AWS supports six types of policies: identity-based policies, resource-based policies, permissions boundaries, Organizations SCPs, ACLs, and session policies.</p>
<p>For more details <a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html">visit</a>.</p>
<h3 id="heading-create-iam-policies">Create IAM Policies</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>Identity and Access Management (IAM).</strong></p>
</li>
<li><p>Click on <strong>Policies</strong> from the left navigation panel.</p>
</li>
<li><p>Click <strong>Create policy</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826458792/d08e9f9a-cf6e-440b-8c7d-2aa8a2c55b40.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose <strong>S3</strong> from the down under <strong>Service</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826474942/967d6586-1c6a-4c9a-9b97-efcfadda9baa.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826488233/b8764485-b627-4a5b-b4d8-9a0d7d8438eb.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>All list actions</strong> under <strong>Access level.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826504259/11aff54a-4887-44f0-aa4b-49eead7392a0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>All</strong> under <strong>Resources</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826520183/568aeef7-b07e-44d9-809a-ec37715aef65.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Write a suitable policy name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826540857/bdf3d128-f3e1-4979-94c6-337dc9ae576d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click Create policy.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722826558541/3db5d935-8ab0-4972-b2fc-4caced5a336f.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-creating-and-attaching-policy-with-an-iam-user">Creating and attaching policy with an IAM user</h3>
<ol>
<li><p>Click on <strong>Users</strong> from the left navigation panel.</p>
</li>
<li><p>Click <strong>Create user</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828318677/a6131b2b-1823-4173-aaa1-2b0da41bee47.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Write a suitable user name.</p>
</li>
<li><p>Check <strong>Provide user access to the AWS Management Console</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828359677/749c2846-2cce-4f44-bcdf-c9138804c98f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>I want to create an IAM user</strong>.</p>
</li>
<li><p>Click <strong>Custom password</strong> and type a suitable password.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828415256/25647c05-e880-455d-847a-3d6d52168255.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Uncheck <strong>Users must create a new password at next sign-in</strong> for now.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828437402/8458ead9-add2-4c42-8780-daf2d717b322.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Select <strong>Attach policies directly</strong>.</p>
</li>
<li><p>Search and select the newly created policy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722828482318/6dae53ac-9568-4afa-916c-117bafcdad52.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong> -&gt; <strong>Create user</strong>.</p>
</li>
<li><p>Create an S3 bucket.</p>
</li>
<li><p>Login as an IAM user with newly created credentials.</p>
</li>
<li><p>The S3 bucket can be viewed by this IAM user.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How to Create and Attach IAM Roles in AWS]]></title><description><![CDATA[Introduction
An IAM role is an IAM identity that you can create in your account that has specific permissions. An IAM role is similar to an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cann...]]></description><link>https://blog.arishahmad.in/how-to-create-and-attach-iam-roles-in-aws</link><guid isPermaLink="true">https://blog.arishahmad.in/how-to-create-and-attach-iam-roles-in-aws</guid><category><![CDATA[AWS IAM role]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS IAM]]></category><category><![CDATA[IAM]]></category><category><![CDATA[iam role in aws]]></category><category><![CDATA[IAM Role]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Mon, 05 Aug 2024 02:40:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722825398065/07dd9d8c-35e0-42d5-ba74-fb2b8352683b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>An IAM <em>role</em> is an IAM identity that you can create in your account that has specific permissions. An IAM role is similar to an IAM user, in that it is an AWS identity with permission policies that determine what the identity can and cannot do in AWS. However, instead of being uniquely associated with one person, a role is intended to be assumable by anyone who needs it. Also, a role does not have standard long-term credentials such as a password or access keys associated with it. Instead, when you assume a role, it provides you with temporary security credentials for your role session.</p>
<p>For more details <a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html">visit</a>.</p>
<h3 id="heading-creating-iam-roles">Creating IAM Roles</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>Identity and Access Management (IAM).</strong></p>
</li>
<li><p>Click on <strong>Roles</strong> from the left navigation panel.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824606774/4e2009dd-12a6-4030-9935-6cdf05d908b8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create role</strong>.</p>
</li>
<li><p>Select <strong>AWS Service</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824638146/6a4ff80a-8389-4cf4-91af-cd44e3b5660b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>EC2</strong> in the <strong>Use case.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824661423/d4901825-a785-4628-8528-bc46e40b7cb0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Search <strong>AmazonS3FullAccess</strong> in <strong>Permissions policies, and select it.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824691317/77e82a8f-a6e2-4502-856e-6c2c12cba0ba.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Write a suitable role name.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824706169/e8330327-87fa-4964-b323-0337a75e092b.png" alt class="image--center mx-auto" /></p>
<p> Click <strong>Next</strong> -&gt; <strong>Create Role</strong>.</p>
</li>
<li><p>Open the role by clicking on its name.</p>
</li>
<li><p>Select <strong>Permissions</strong>, under <strong>Permissions policies</strong> you can check the policy names.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722824759891/fd068280-1b30-4a28-b11b-6812e8fd441f.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-attaching-role-to-a-service">Attaching role to a service</h3>
<ol>
<li><p>Create an EC2 instance.</p>
</li>
<li><p>Select the instance.</p>
</li>
<li><p>Go to <strong>Actions</strong> -&gt; <strong>Security</strong> -&gt; <strong>Modify IAM role</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722825352973/75091ce0-596a-4e02-bdd9-bb08c3c5d0d4.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the IAM role from the from down.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722825378456/663ac508-39b6-4274-a302-f485a2f81c26.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Update IAM role</strong>.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How to Easily Create and Manage IAM User Groups in AWS]]></title><description><![CDATA[Adding users to a User Group

Open the AWS Management Console and navigate to the Identity and Access Management (IAM).

Create 2-3 users, you can use Creating And Assigning Policy to IAM Users.

Click on User groups from the left navigation panel.

...]]></description><link>https://blog.arishahmad.in/how-to-easily-create-and-manage-iam-user-groups-in-aws</link><guid isPermaLink="true">https://blog.arishahmad.in/how-to-easily-create-and-manage-iam-user-groups-in-aws</guid><category><![CDATA[IAM user groups]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS IAM]]></category><category><![CDATA[aws iam policies]]></category><category><![CDATA[IAM]]></category><category><![CDATA[IAM users]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Sun, 04 Aug 2024 23:18:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722813366608/0945a863-774f-4bd8-b8c4-77e9952c1d7e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-adding-users-to-a-user-group">Adding users to a User Group</h2>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>Identity and Access Management (IAM).</strong></p>
</li>
<li><p>Create 2-3 users, you can use <a target="_blank" href="https://arishahmad.hashnode.dev/aws-creating-and-assigning-policy-to-iam-users">Creating And Assigning Policy to IAM Users</a>.</p>
</li>
<li><p>Click on <strong>User groups</strong> from the left navigation panel.</p>
</li>
<li><p>Click <strong>Create group</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812333763/6ee6dd63-caf3-44f0-86e8-64fd9da1e17c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Write a suitable name.</p>
</li>
<li><p>You can select all the users you want to add to this group.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812358495/71733ed6-c9bc-4559-892a-56ebb6acb86a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Search and check the policies you want to assign (Eg. <strong>AmazonEC2ReadOnlyAccess</strong>).</p>
</li>
<li><p>Click <strong>Create user group</strong>.</p>
</li>
<li><p>Now open the user and go to <strong>Permissions</strong>, you can check the policies given under <strong>Permissions policies.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812380432/2597da21-fce9-4769-bfdd-faeebe015057.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h2 id="heading-adding-users-to-multiple-user-groups">Adding users to multiple User Groups</h2>
<ol>
<li><p>Create another user group and add the same users that were added in the previous user group.</p>
</li>
<li><p>Search and select some other policies from the previous one (Eg. <strong>AmazonEC2ReadOnlyAccess</strong>).</p>
</li>
<li><p>Now open the user and go to <strong>Permissions</strong>, you can check the policies from different user groups given under <strong>Permissions policies.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812409438/e211b6ec-fff1-4d4d-af74-e1ef9763f467.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h2 id="heading-giving-permissions-to-a-specific-user">Giving permissions to a specific user</h2>
<ol>
<li><p>Open the user.</p>
</li>
<li><p>Under <strong>Permissions,</strong> click <strong>Add permissions</strong> -&gt; <strong>Add permissions</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812433689/89bd89b7-593f-457b-9d76-f9052af9933a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>Attach policies directly</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812449465/74ed4571-de52-40dd-8fa5-76e12c2906a9.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Search and select any policy (Eg. <strong>AmazonDynamoDBFullAccess</strong>).</p>
</li>
<li><p>Click <strong>Next</strong> -&gt; <strong>Add permissions</strong>.</p>
</li>
</ol>
<p>To check, open the user under <strong>Permissions</strong> and check the newly added permission.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722812475239/01cfc8cb-7782-4221-a9f1-5bb76b6a1dab.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-copy-permission-to-a-user">Copy permission to a user</h2>
<ol>
<li><p>Create a new user.</p>
</li>
<li><p>Open this user.</p>
</li>
<li><p>Under <strong>Permissions,</strong> click <strong>Add permissions</strong> -&gt; <strong>Add permissions</strong>.</p>
</li>
<li><p>Click Copy permissions.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722813238684/594b0bb3-e7b4-4ca4-a070-a3c7bd3e6fb3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select any user whose permissions are needed to be copied.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722813256207/ee6a345a-f9fb-4ed8-a801-73c1292a5b8a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong> -&gt; <strong>Add permissions</strong>.</p>
</li>
<li><p>Now open this user, and click <strong>Permissions</strong>, under <strong>Permissions policies</strong> you can check all the permissions given to this user which were given to the user from which the permissions are copied.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722813302640/67fb3856-c01d-4f43-9219-14d8f2fd3698.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[AWS: Creating And Assigning Policy to IAM Users]]></title><description><![CDATA[Open the AWS Management Console and navigate to the Identity and Access Management (IAM).

Click on Users from the left navigation panel.

Click Create user.
 

Assign a suitable name to the user.

Select Provide user access to the AWS Management Con...]]></description><link>https://blog.arishahmad.in/aws-creating-and-assigning-policy-to-iam-users</link><guid isPermaLink="true">https://blog.arishahmad.in/aws-creating-and-assigning-policy-to-iam-users</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS IAM]]></category><category><![CDATA[AWS IAM Identity Center]]></category><category><![CDATA[aws iam policies]]></category><category><![CDATA[AWS IAM Permissions]]></category><category><![CDATA[IAM]]></category><category><![CDATA[IAM Identities]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Fri, 02 Aug 2024 02:24:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563908893/2c7fd8b7-4408-4551-8165-cd96d96b9a4f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>Identity and Access Management (IAM).</strong></p>
</li>
<li><p>Click on <strong>Users</strong> from the left navigation panel.</p>
</li>
<li><p>Click <strong>Create user</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563141861/a440cfd9-f8ee-4cab-beb0-13b0c0872b71.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Assign a suitable name to the user.</p>
</li>
<li><p>Select <strong>Provide user access to the AWS Management Console</strong>.</p>
</li>
<li><p>Select <strong>I want to create an IAM user.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563169649/4008815b-2ce6-42ff-9213-41938128ca6d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>Custom password</strong> and enter a password fulfilling the criteria.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563206305/76f83cbe-7907-418a-98c5-20d18b1300d0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Uncheck <strong>Users must create a new password at next sign-in</strong> for now.</p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Select <strong>Attach policies directly</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563238564/81c17290-e71b-46e0-8231-a449bf8e2a51.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Search <strong>AmazonEC2ReadOnlyAccess</strong> and select it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722563281367/5147ecb0-ad8f-487c-b742-3c118699595f.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Scroll and click <strong>Create user</strong>.</p>
</li>
<li><p>Now create an EC2 instance and log in as an IAM user using the user name and password just created to check the newly created EC2 instances.</p>
</li>
<li><p>To delete a user, select the user -&gt; <strong>Delete</strong> -&gt; type the user name -&gt; <strong>Delete user</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722564067529/126ad059-d5c7-4d7b-8652-c7f926aecc0f.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722564083462/c240d68c-8746-4829-a4eb-65209767c69c.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Understanding Lifecycle rules in Amazon S3]]></title><description><![CDATA[Introduction
To manage your objects so that they're stored cost effectively throughout their lifecycle, create an Amazon S3 Lifecycle configuration. An Amazon S3 Lifecycle configuration is a set of rules that define actions that Amazon S3 applies to ...]]></description><link>https://blog.arishahmad.in/understanding-lifecycle-rules-in-amazon-s3</link><guid isPermaLink="true">https://blog.arishahmad.in/understanding-lifecycle-rules-in-amazon-s3</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[S3 Lifecycle]]></category><category><![CDATA[s3lifecycle]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Fri, 02 Aug 2024 01:09:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722560805096/e5ecd5fd-8585-4d10-a70b-66437c4d61e3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>To manage your objects so that they're stored cost effectively throughout their lifecycle, create an Amazon S3 Lifecycle configuration. An Amazon S3 Lifecycle configuration is a set of rules that define actions that Amazon S3 applies to a group of objects. For more information <a target="_blank" href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html">visit</a>.</p>
<h3 id="heading-steps-to-create-an-s3-lifecycle">Steps to Create an S3 Lifecycle</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3 dashboard</strong>.</p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299964480/fb19aa61-1dc5-4b42-86eb-23f7ce1980f4.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>General purpose</strong> bucket type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300008769/9a6f2b7a-ae48-4fe0-8d71-6bec71d585e1.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Write a bucket name, this name must be globally unique.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297511455/5a02b511-e7c3-4a42-b05b-34d15614f746.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>ACLs enabled Object Ownership.</strong></p>
</li>
<li><p>Uncheck <strong>Block all public access -&gt; Check the Acknowledgement.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302267197/d2338c6a-6027-482e-b590-291584bfe4c2.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Enable <strong>Bucket Versioning</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302343722/a08e7765-cdae-4a06-8010-486562292af1.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
</li>
<li><p>Click on <strong>Management</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722548155495/0a880881-a9f6-4426-b0ae-d5050db803c2.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Click on the <strong>Create lifecycle rule.</strong></p>
</li>
<li><p>Write a suitable name.</p>
</li>
<li><p>Select <strong>Apply to all the objects in the bucket</strong> under <strong>Choose a rule scope</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722559592348/6e20fb9f-680f-4ed6-96c6-58f2870d25d2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Lifecycle rule actions</strong> select <strong>Move current versions of objects between storage classes.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722559617107/3306d659-34cb-4e96-a624-738317ea8bac.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Transition current versions of objects between storage classes, In Choose storage class transitions</strong> each class has <strong>minimum storage duration</strong>.</p>
<p>The <strong>Days after object creation</strong> should match these minimum duration periods.</p>
<p>All the duration period with there classes will be shown in the drop down. Add the required number of transitions. Then check the acknowledgement.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722560537278/6efe93a6-032a-48df-b4e3-e06a295ce974.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create rule.</strong></p>
</li>
<li><p>To delete the rule, select the rule -&gt; <strong>Delete</strong> -&gt; <strong>Delete.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722560595854/36b86436-d012-4b20-8213-fcf0e308fb02.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722560631183/37e131fd-c5e9-4de5-a907-48938c5760b2.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Setting Up Amazon S3 Replication Rules]]></title><description><![CDATA[Open the AWS Management Console and navigate to the S3 dashboard.

Click Create bucket.
 

Select General purpose bucket type.
 

Write a bucket name, this name must be globally unique.
 

Select ACLs enabled Object Ownership.

Uncheck Block all publ...]]></description><link>https://blog.arishahmad.in/setting-up-amazon-s3-replication-rules</link><guid isPermaLink="true">https://blog.arishahmad.in/setting-up-amazon-s3-replication-rules</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[aws s3 versioning]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[s3 replication]]></category><category><![CDATA[S3Replication]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Thu, 01 Aug 2024 22:16:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722550400270/4f133ead-ac36-4a1f-896c-eddff3b770b7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3 dashboard</strong>.</p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299964480/fb19aa61-1dc5-4b42-86eb-23f7ce1980f4.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>General purpose</strong> bucket type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300008769/9a6f2b7a-ae48-4fe0-8d71-6bec71d585e1.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Write a bucket name, this name must be globally unique.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297511455/5a02b511-e7c3-4a42-b05b-34d15614f746.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>ACLs enabled Object Ownership.</strong></p>
</li>
<li><p>Uncheck <strong>Block all public access -&gt; Check the Acknowledgement.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302267197/d2338c6a-6027-482e-b590-291584bfe4c2.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Enable <strong>Bucket Versioning</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302343722/a08e7765-cdae-4a06-8010-486562292af1.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
</li>
<li><p>Create one more bucket with the same configuration.</p>
<p> One bucket will act as the source and the other as the destination bucket.</p>
</li>
<li><p>Open any bucket by clicking on its name. This bucket will act as a source bucket.</p>
</li>
<li><p>Click on <strong>Management</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722548155495/0a880881-a9f6-4426-b0ae-d5050db803c2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create replication rule.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722549027641/c59839ab-7a1f-4ea7-90e2-aeecdb920476.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter a suitable replication name.</p>
</li>
<li><p>Scroll and choose <strong>Apply to all objects in the bucket</strong> under <strong>Choose a rule scope</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722549075307/47367bc7-9e9a-4384-a0a9-12d763a17018.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Browse S3</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722549098144/e331792c-78d9-4383-b1b8-a74e724676dc.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose the destination bucket.</p>
</li>
<li><p>Click <strong>Choose path.</strong></p>
</li>
<li><p>Select <strong>Create new role</strong> under <strong>IAM role</strong>.</p>
</li>
<li><p>Click <strong>Save</strong>.</p>
</li>
<li><p>Select any under <strong>Replicate existing objects?</strong> objects click <strong>Submit</strong>.</p>
</li>
<li><p>Open the source bucket and upload a file.</p>
</li>
<li><p>Open the destination bucket, and you'll find the uploaded file there as well.</p>
</li>
<li><p>Go to the source bucket.</p>
</li>
<li><p>Select the bucket -&gt; <strong>Copy URL</strong> -&gt; Paste the URL in the other browser tab. You'll not be able to access the file. Try the same in the destination bucket too, you'll get the same result.</p>
</li>
<li><p>In the source bucket, Select the object, click on <strong>Action</strong> -&gt; <strong>Make public using ACL</strong> -&gt; <strong>Make public</strong>.</p>
</li>
<li><p>Now access the bucket. Select the bucket -&gt; <strong>Copy URL</strong> -&gt; Paste the URL in other browser tab, you'll see the contents of the file.</p>
</li>
<li><p>Navigate to the destination bucket, you'll be able to access the file there too.</p>
</li>
<li><p>Now, permanently delete the file in the source bucket.</p>
<p><strong>Note</strong>: Make sure <strong>Show versions</strong> is enabled when you delete; otherwise, the file will not be permanently deleted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722550065773/74f57f94-8d1c-42ac-b9d2-900c12379649.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now to go destination bucket, you'll see the file in the destination bucket is not deleted.</p>
</li>
<li><p>To delete the replication rule, open the source bucket, click <strong>Management</strong>, select the replication rule you want to delete under <strong>Replication rules</strong>, then click <strong>Delete</strong> and confirm by clicking <strong>Delete replication rule</strong>.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Understanding Object Lock for Amazon S3]]></title><description><![CDATA[Introduction
S3 Object Lock can help prevent Amazon S3 objects from being deleted or overwritten for a fixed amount of time or indefinitely. Object Lock uses a write-once-read-many (WORM) model to store objects. You can use Object Lock to help meet r...]]></description><link>https://blog.arishahmad.in/understanding-object-loack-for-amazon-s3</link><guid isPermaLink="true">https://blog.arishahmad.in/understanding-object-loack-for-amazon-s3</guid><category><![CDATA[S3 Object Lock]]></category><category><![CDATA[AWS S3 Object Lock]]></category><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[aws s3 versioning]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Thu, 01 Aug 2024 20:51:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722545331204/a6b88954-ef79-4228-ae64-ed1a08ff3d87.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction"><strong>Introduction</strong></h3>
<p>S3 Object Lock can help prevent Amazon S3 objects from being deleted or overwritten for a fixed amount of time or indefinitely. Object Lock uses a write-once-read-many (WORM) model to store objects. You can use Object Lock to help meet regulatory requirements that require WORM storage, or to add another layer of protection against object changes or deletion.</p>
<p>Object Lock provides two ways to manage object retention: retention periods and legal holds. An object version can have a retention period, a legal hold, or both.</p>
<ul>
<li><p><strong>Retention period</strong> – A retention period specifies a fixed period of time during which an object remains locked. You can set a unique retention period for individual objects.</p>
</li>
<li><p><strong>Legal hold</strong> – A legal hold provides the same protection as a retention period, but it has no expiration date. Instead, a legal hold remains in place until you explicitly remove it. Legal holds are independent from retention periods and are placed on individual object versions.</p>
</li>
</ul>
<p>Object Lock works only in buckets that have S3 Versioning enabled. When you lock an object version, Amazon S3 stores the lock information in the metadata for that object version. Placing a retention period or a legal hold on an object protects only the version that's specified in the request. Retention periods and legal holds don't prevent new versions of the object from being created, or delete markers to be added on top of the object. For information about S3 Versioning, see <a target="_blank" href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html">Using versioning in S3 buckets</a>.</p>
<p>If you put an object into a bucket that already contains an existing protected object with the same object key name, Amazon S3 creates a new version of that object. The existing protected version of the object remains locked according to its retention configuration.</p>
<h3 id="heading-steps-for-object-lock-in-amazon-s3"><strong>Steps for Object Lock in Amazon S3</strong></h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3 dashboard</strong>.</p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299964480/fb19aa61-1dc5-4b42-86eb-23f7ce1980f4.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>General purpose</strong> bucket type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300008769/9a6f2b7a-ae48-4fe0-8d71-6bec71d585e1.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Write a bucket name, this name must be globally unique.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297511455/5a02b511-e7c3-4a42-b05b-34d15614f746.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>ACLs enabledObject Ownership.</strong></p>
</li>
<li><p>Uncheck <strong>Block all public access -&gt; Check the Acknowledgement.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302267197/d2338c6a-6027-482e-b590-291584bfe4c2.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Enable <strong>Bucket Versioning.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302343722/a08e7765-cdae-4a06-8010-486562292af1.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Under <strong>Additional setting</strong>, enable <strong>Object Lock</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722543970053/18612ef8-ee13-4420-b0e4-4ec0f1f7eb55.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
</li>
<li><p>Open the newly created bucket by clicking on its name.</p>
</li>
<li><p>Click <strong>Properties</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722544761229/c3bf5766-e861-48b8-9ab4-2c73e1913acc.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Scroll and click <strong>Edit</strong> on <strong>Object Lock</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722544051307/277bd9c7-8aea-4327-97ba-8eb6c29fd1ef.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enable <strong>Default retention</strong>, set <strong>Default retention mode</strong> to <strong>Governance, and set Default retention period</strong> to 1 Days.</p>
<p><strong>Governance</strong>: Users with specific IAM permissions can overwrite or delete protected object versions during the retention period.</p>
<p><strong>Compliance</strong>: No users can overwrite or delete protected object versions during the retention period.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722544822675/250d20df-50ad-4b70-a2e0-dd98a0dc1191.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Save changes</strong>.</p>
</li>
<li><p>Now Click on <strong>Objects</strong>.</p>
</li>
<li><p>Click <strong>Upload</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297830670/adb55fb1-0c38-438d-a8b1-3aa3374511f0.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Now click on <strong>Add files</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297908287/836cfbcf-e114-4e23-86f5-c4bd71555c9e.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select any file you want to upload.</p>
</li>
<li><p>Scroll and click <strong>Upload</strong>.</p>
</li>
<li><p>Select the file and permanently delete the file. You'll see the file is permanently deleted. The reason for this is that the file is in <strong>Governance</strong> lock.</p>
<p><strong>Note</strong>: Make sure Show Versions is enabled while you delete the file. If it is not, while will not be permanently deleted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722549943585/759909d9-98d0-4c97-bc97-2ae49ebaac4a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now upload the file again.</p>
</li>
<li><p>Open the file by clicking on its name.</p>
</li>
<li><p>Under Properties, Edit <strong>Object Lock retention.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722545056265/737f7168-2c89-45b3-9e87-cf730bac4229.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Set Retention mode to Compliance mode.</p>
<p><strong>Note</strong>: You'll not be able to delete the file before the retention period.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722545064310/fd87f3e8-a52f-4d17-af36-abda98e170be.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Save Changes</strong>.</p>
</li>
<li><p>Now select the object and try to permanently delete the file. You'll get an error when you try. Wait until the retention period is over, then you will be able to delete it.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Understanding Versioning for Amazon S3 Buckets]]></title><description><![CDATA[Open the AWS Management Console and navigate to the S3 dashboard.

Click Create bucket.
 

Select General purpose bucket type.
 

Write a bucket name, this name must be globally unique.
 

Select ACLs enabledObject Ownership.

Uncheck Block all publi...]]></description><link>https://blog.arishahmad.in/understanding-versioning-for-amazon-s3-buckets</link><guid isPermaLink="true">https://blog.arishahmad.in/understanding-versioning-for-amazon-s3-buckets</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[aws s3 versioning]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[versioning]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Tue, 30 Jul 2024 01:44:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722303738910/fa4de092-7c74-4578-8d46-0276ccb92c48.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3 dashboard</strong>.</p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299964480/fb19aa61-1dc5-4b42-86eb-23f7ce1980f4.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>General purpose</strong> bucket type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300008769/9a6f2b7a-ae48-4fe0-8d71-6bec71d585e1.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Write a bucket name, this name must be globally unique.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297511455/5a02b511-e7c3-4a42-b05b-34d15614f746.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select <strong>ACLs enabledObject Ownership.</strong></p>
</li>
<li><p>Uncheck <strong>Block all public access -&gt; Check the Acknowledgement.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302267197/d2338c6a-6027-482e-b590-291584bfe4c2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enable <strong>Bucket Versioning</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302343722/a08e7765-cdae-4a06-8010-486562292af1.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
</li>
<li><p>Open the newly created bucket by clicking on its name.</p>
</li>
<li><p>Click <strong>Upload</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297830670/adb55fb1-0c38-438d-a8b1-3aa3374511f0.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Now click on <strong>Add files.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297908287/836cfbcf-e114-4e23-86f5-c4bd71555c9e.png?auto=compress,format&amp;format=webp" alt /></p>
</li>
<li><p>Select any file you want to upload, preferably a text file.</p>
</li>
<li><p>Scroll and click <strong>Upload</strong>.</p>
</li>
<li><p>Select the object -&gt; <strong>Actions</strong> -&gt; <strong>Make public ACL</strong> -&gt; <strong>Make Public</strong>.</p>
</li>
<li><p>Now select the object -&gt; <strong>Copy URL</strong> -&gt; Paste it into another tab, and the file should open.</p>
</li>
<li><p>Select the file -&gt; <strong>Delete</strong> -&gt; type "delete" -&gt; Click <strong>Delete objects</strong>.</p>
</li>
<li><p>Now enable <strong>Show versions</strong>. Now you'll be able to see the deleted text file and the Delete Marker. If this delete marker is deleted then the text file can be recovered.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722302633360/36c66a95-089a-4d3e-8870-ec756b27980e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select the delete marker -&gt; <strong>Delete</strong> -&gt; type "permanently delete" -&gt; Click <strong>Delete Objects</strong>.</p>
</li>
<li><p>Disable the Show version. You will see the text file is recovered. To delete the file permanently, delete the text file while Show versions is enabled before deleting the marker.</p>
<p><strong>Note</strong>: Deleting anything while Show versions is enabled will result in permanent deletion.</p>
</li>
<li><p>Now open this text file on your computer and make a few changes to it.</p>
</li>
<li><p>Now upload the file again. The file will be updated.</p>
</li>
<li><p>Select the object -&gt; <strong>Actions</strong> -&gt; <strong>Make public ACL</strong> -&gt; <strong>Make Public</strong>.</p>
</li>
<li><p>Now select the object -&gt; <strong>Copy URL</strong> -&gt; Paste it into another tab, and the file should open. You can see the changes made.</p>
</li>
<li><p>Now enable the Show version, and you'll see the same file name two times, the one with 'L' is the old file and the other one is the new file.</p>
</li>
<li><p>Delete the file without 'L'.</p>
</li>
<li><p>Disable the show version.</p>
</li>
<li><p>Now select the object -&gt; <strong>Copy URL</strong> -&gt; Paste it into another tab, and the file should open. You'll see that the older version of the file.</p>
</li>
<li><p>To delete the object, select the object -&gt;Click <strong>Delete</strong> -&gt; type permanently delete -&gt; Click <strong>Delete Objects.</strong></p>
</li>
<li><p>To delete the bucket, select the bucket -&gt; Click <strong>Delete</strong> -&gt; type the bucket name -&gt; Click <strong>Delete bucket</strong>.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How to Create an Amazon S3 Bucket: Step-by-Step Guide]]></title><description><![CDATA[Introduction

S3 stands for Simple Storage Service.

Amazon S3 is an object storage service that offers industry-leading scalability, data availability, security, and performance.

Store and protect any amount of data for a range of use cases, such a...]]></description><link>https://blog.arishahmad.in/how-to-create-an-amazon-s3-bucket-step-by-step-guide</link><guid isPermaLink="true">https://blog.arishahmad.in/how-to-create-an-amazon-s3-bucket-step-by-step-guide</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS s3]]></category><category><![CDATA[aws s3 for beginners]]></category><category><![CDATA[S3]]></category><category><![CDATA[S3-bucket]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Tue, 30 Jul 2024 00:59:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722301055364/7d441384-4b0c-46c5-95ad-68e4fdfad9d6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<ol>
<li><p>S3 stands for Simple Storage Service.</p>
</li>
<li><p>Amazon S3 is an object storage service that offers industry-leading scalability, data availability, security, and performance.</p>
</li>
<li><p>Store and protect any amount of data for a range of use cases, such as data lakes, websites, cloud-native applications, backups, archive, machine learning, and analytics.</p>
</li>
<li><p>Amazon S3 is designed for 99.999999999% (11 9's) of durability, and stores data for millions of customers all around the world.</p>
</li>
</ol>
<h3 id="heading-steps-to-create-an-s3-bucket">Steps to Create an S3 Bucket</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>S3 dashboard</strong>.</p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299964480/fb19aa61-1dc5-4b42-86eb-23f7ce1980f4.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>General purpose</strong> bucket type.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300008769/9a6f2b7a-ae48-4fe0-8d71-6bec71d585e1.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Write a bucket name, this name must be globally unique.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297511455/5a02b511-e7c3-4a42-b05b-34d15614f746.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select <strong>ACLs disabled</strong> under <strong>Object Ownership.</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297537994/b7a5f094-c8e8-4941-bfd5-357618f3d746.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Leave the <strong>Block all public access</strong> checked<strong>.</strong></p>
</li>
<li><p>Set <strong>Bucket Versioning</strong> disabled<strong>.</strong></p>
</li>
<li><p>Click <strong>Create bucket</strong>.</p>
</li>
<li><p>Open the newly created bucket by clicking on its name.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297808074/887d39dd-a1c3-4596-a1fd-ac268c6534c6.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Upload</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297830670/adb55fb1-0c38-438d-a8b1-3aa3374511f0.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now click on Add files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722297908287/836cfbcf-e114-4e23-86f5-c4bd71555c9e.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Select any file you want to upload, preferably a text file.</p>
</li>
<li><p>Scroll and click <strong>Upload</strong>.</p>
</li>
<li><p>Select the file -&gt; <strong>Actions</strong> -&gt; <strong>Download As</strong> -&gt; Click on the file name, A new tab will open and download will start -&gt; <strong>Close.</strong></p>
</li>
<li><p>Now Select the file -&gt; Click <strong>Copy URL</strong>. -&gt; Paste in a new browser tab, Unfortunately, you won't be able to view the file.</p>
</li>
<li><p>Now Select the file -&gt; Click <strong>Open</strong>, File will open up in a new tab.</p>
</li>
<li><p>You can see the file can be accessed only by this account and no one else can access it.</p>
</li>
<li><p>To make the Object's URL publically available -&gt; Select the bucket -&gt; Make public using ACL, this option must be disabled because we disabled ACLs in step 6.</p>
</li>
<li><p>To change it Go to permission.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722300158363/3436b808-1081-4d88-9d8b-fcf9ab98bf8c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Edit</strong> on <strong>Block public access (bucket settings) -&gt;</strong> Uncheck <strong>Block all public access -&gt; Save changes -&gt;</strong> type <strong>confirm -&gt; Confirm.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299478090/7c8695ff-7ba0-4715-824e-1db410f3645e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299495279/eca32f6b-d72c-4e77-9c02-3338a0630682.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Edit</strong> on <strong>Bucket Ownership</strong> -&gt; <strong>ACLs enabled</strong> -&gt; Check the acknowledgement -&gt; Save changes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722299346209/1b23e0ab-ddbc-489f-973b-4f46801f7c10.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now go back to <strong>Objects</strong>.</p>
</li>
<li><p>Select the object -&gt; <strong>Actions</strong> -&gt; <strong>Make public ACL</strong> -&gt; <strong>Make Public</strong>.</p>
</li>
<li><p>Now select the object -&gt; <strong>Copy URL</strong> -&gt; Paste it into another tab, and the file should open.</p>
</li>
<li><p>To delete the object, select the object -&gt;Click <strong>Delete</strong> -&gt; type permanently delete -&gt; Click <strong>Delete Objects.</strong></p>
</li>
<li><p>To delete the bucket, select the bucket -&gt; Click <strong>Delete</strong> -&gt; type the bucket name -&gt; Click <strong>Delete bucket</strong>.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Easy Steps to Create a Reliable Application Load Balancer]]></title><description><![CDATA[Introduction
Load balancing is the method of distributing network traffic equally across a pool of resources that support an application. Modern applications must process millions of users simultaneously and return the correct text, videos, images, a...]]></description><link>https://blog.arishahmad.in/easy-steps-to-create-a-reliable-application-load-balancer</link><guid isPermaLink="true">https://blog.arishahmad.in/easy-steps-to-create-a-reliable-application-load-balancer</guid><category><![CDATA[AWS]]></category><category><![CDATA[Load Balancing]]></category><category><![CDATA[Load Balancer]]></category><category><![CDATA[load-balancer-in-aws]]></category><category><![CDATA[aws ec2]]></category><category><![CDATA[AWS Applicaction Load Balancer]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Mon, 29 Jul 2024 01:26:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722216018236/1d5b23f8-4a82-4a13-a080-53f21fa190f1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>Load balancing is the method of distributing network traffic equally across a pool of resources that support an application. Modern applications must process millions of users simultaneously and return the correct text, videos, images, and other data to each user in a fast and reliable manner. To handle such high volumes of traffic, most applications have many resource servers with duplicate data between them. A load balancer is a device that sits between the user and the server group and acts as an invisible facilitator, ensuring that all resource servers are used equally.</p>
<h3 id="heading-steps-to-create-an-application-load-balancer">Steps to create an application load balancer</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>EC2 dashboard</strong>.</p>
</li>
<li><p>Create an instance and host a website, you can use an <a target="_blank" href="https://arishahmad.hashnode.dev/hosting-your-website-on-amazon-ec2-with-windows-a-complete-guide"><strong>EC2 instance with Windows</strong></a> or an <a target="_blank" href="https://arishahmad.hashnode.dev/hosting-your-website-launching-aws-ec2-instance-with-linux"><strong>EC2 instance with Linux</strong></a>.</p>
<p> <strong>NOTE:</strong> While launching the instance, increase the number of instances to the desired amount.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722213106112/532100be-cfb4-4554-a7c4-2a6beffe2787.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Connect to each of these instances and host the website.</p>
</li>
<li><p>In the left navigation panel, choose <strong>Load Balancers</strong> under <strong>Load Balancing.</strong></p>
</li>
<li><p>Click on <strong>Create load balancer</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722213136381/3486c4eb-08e9-493c-b3f6-c5a1bb58f5e8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Application Load Balancer</strong> click <strong>Create.</strong></p>
</li>
<li><p>Give a suitable <strong>Load balancer name.</strong></p>
</li>
<li><p>Select the desired Availability Zone under <strong>Mappings</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722214759302/182c0642-60b3-4bab-a9be-ec2705f5fe36.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Under <strong>Listeners and routing</strong> click <strong>Create target group</strong>. A new tab will open up.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722214827769/e337669d-2d13-47a1-85c9-2a2eaa4d3dfe.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Choose a <strong>target type</strong>, <strong>Instances</strong>.</p>
</li>
<li><p>Type a suitable <strong>Target group name</strong>.</p>
</li>
<li><p>Click Next.</p>
</li>
<li><p>Select the instances with which you want to make a load balancer.</p>
</li>
<li><p>Scroll and click on <strong>Include as pending below</strong>.</p>
</li>
<li><p>Click <strong>Create target group</strong>.</p>
</li>
<li><p>Please go ahead and return to the previous tab.</p>
</li>
<li><p>Refresh the default action.</p>
</li>
<li><p>Now select the newly created target group from the drop down.</p>
</li>
<li><p>Scroll and click <strong>Create load balancer</strong>.</p>
</li>
<li><p>Wait while the status is not Active.</p>
</li>
<li><p>Now copy the DNS Name to access the hosted website.</p>
<p>The website will be accessed from any of the instances previously created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722214380985/4398313f-9f5a-4b70-92a6-9ef948046b7c.png" alt class="image--center mx-auto" /></p>
<ol start="22">
<li><p>To delete the Load balancers, select the load balancer -&gt; Click <strong>Actions</strong> -&gt; <strong>Delete load balancer</strong> -&gt; type <strong>confirm</strong> -&gt; <strong>Delete</strong>.</p>
</li>
<li><p>To delete the Target group, select the target group -&gt; Click <strong>Actions</strong> -&gt; <strong>Delete</strong> -&gt; Click <strong>Yes, delete</strong></p>
</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Steps to Enable Horizontal Auto Scaling for AWS Web Applications]]></title><description><![CDATA[Introduction
AWS Auto Scaling monitors your applications and automatically adjusts capacity to maintain steady, predictable performance at the lowest possible cost. Using AWS Auto Scaling, it’s easy to setup application scaling for multiple resources...]]></description><link>https://blog.arishahmad.in/steps-to-enable-horizontal-auto-scaling-for-aws-web-applications</link><guid isPermaLink="true">https://blog.arishahmad.in/steps-to-enable-horizontal-auto-scaling-for-aws-web-applications</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws ec2]]></category><category><![CDATA[AWS-AMI]]></category><category><![CDATA[aws launch template]]></category><category><![CDATA[aws auto scaling]]></category><category><![CDATA[auto scaling]]></category><category><![CDATA[auto-scaling-aws]]></category><dc:creator><![CDATA[Arish Ahmad]]></dc:creator><pubDate>Sun, 28 Jul 2024 23:42:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722208191821/41b06e74-3d9c-4699-95d0-a7d221c2dbb2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>AWS Auto Scaling monitors your applications and automatically adjusts capacity to maintain steady, predictable performance at the lowest possible cost. Using AWS Auto Scaling, it’s easy to setup application scaling for multiple resources across multiple services in minutes.</p>
<p>Horizontal auto scaling in AWS is a way to scale a system by adding more machines or servers to an auto scaling group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722210017215/1c56dd39-4f23-4851-8952-5a6aa7aee15d.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-follow-these-steps-to-horizontally-auto-scale-an-aws-web-application">Follow these steps to horizontally auto scale an AWS web application</h3>
<ol>
<li><p>Open the <strong>AWS Management Console</strong> and navigate to the <strong>EC2 dashboard</strong>.</p>
</li>
<li><p>Create an instance and host a website, you can use an <a target="_blank" href="https://arishahmad.hashnode.dev/hosting-your-website-on-amazon-ec2-with-windows-a-complete-guide">EC2 instance with Windows</a> or an <a target="_blank" href="https://arishahmad.hashnode.dev/hosting-your-website-launching-aws-ec2-instance-with-linux">EC2 instance with Linux</a>.</p>
</li>
<li><p>Create an Image of this instance, you can use <a target="_blank" href="https://arishahmad.hashnode.dev/create-amazon-machine-images-amis-from-ec2-instances-an-easy-guide">Create AMIs from EC2 Instances</a>.</p>
</li>
<li><p>In the left navigation panel, choose <strong>Auto Scaling Groups</strong> under <strong>Auto Scaling.</strong></p>
</li>
<li><p>Click <strong>Create Auto Scaling group</strong>.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722196777803/ec2dd906-7d71-4e81-acfd-9f0ba0bd4cea.png" alt class="image--center mx-auto" /></p>
<p> Write a suitable name for the Auto scaling group.</p>
</li>
<li><p>Scroll down and click <strong>Create a launch template</strong>. A new tab will open up.</p>
</li>
<li><p>Write a suitable name for the template.</p>
</li>
<li><p>Scroll and click on <strong>My AMIs</strong> under <strong>Application and OS Images (Amazon Machine Image).</strong></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722200501954/b15d697d-2ad7-4b23-89ad-0d9e3cb13573.png" alt class="image--center mx-auto" /></p>
<p>Select the newly created AMI.</p>
</li>
<li><p>Select any free tier instance type (Example: t2.micro).</p>
</li>
<li><p>Select any <strong>Key pair</strong>.</p>
</li>
<li><p>Select any <strong>Security group</strong> under <strong>Network settings</strong></p>
</li>
<li><p>Now click on <strong>Create the launch template</strong>.</p>
</li>
<li><p>Please go ahead and return to the previous tab and refresh the launch template.</p>
</li>
<li><p>Now you can select the newly created launch template from the drop-down.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722200727179/f68eed56-c419-430d-844f-dd6c68b9dd24.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click <strong>Next</strong>.</p>
</li>
<li><p>Under <strong>Network</strong> select all the <strong>availability zones</strong> in which you want your instances.</p>
</li>
<li><p>Now click <strong>Next</strong>.</p>
</li>
<li><p>Scroll and hit <strong>Next</strong>.</p>
</li>
<li><p>Under the Group Size set <strong>Desired capacity</strong> to 3.</p>
<p><strong>Desired capacity:</strong> Represents the initial capacity of the Auto Scaling group at the time of creation. An Auto Scaling group attempts to maintain the desired capacity. It starts by launching the number of instances that are specified for the desired capacity, and maintains this number of instances as long as there are no scaling policies or scheduled actions attached to the Auto Scaling group.</p>
</li>
<li><p>Under Scaling set <strong>Min desired capacity</strong> to 2 and <strong>Max desired capacity</strong> to 5.</p>
<p><strong>Minimum desired capacity:</strong> This represents the minimum group size. When scaling policies are set, they cannot decrease the group's desired capacity lower than the minimum capacity.</p>
<p><strong>Maximum desired capacity:</strong> Represents the maximum group size. When scaling policies are set, they cannot increase the group's desired capacity higher than the maximum capacity.</p>
</li>
<li><p>Now click on the <strong>Target tracking scaling policy</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722201427034/0785705f-12be-4651-960e-1299985e1bd3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now scroll and hit <strong>Next</strong>.</p>
</li>
<li><p>Now click <strong>Next</strong> -&gt; <strong>Next</strong>.</p>
</li>
<li><p>Review all the changes made.</p>
</li>
<li><p>Click on <strong>Create auto scaling group</strong>.</p>
</li>
<li><p>You can go to the instances to check the creation on the EC2 instance with the same hosted website. To check, hit the <strong>Public IPv4 address</strong> of all the new instances.</p>
</li>
<li><p>To delete the auto-scaling group, select the group -&gt; <strong>Actions</strong> -&gt; <strong>Delete</strong> -&gt; type delete -&gt; <strong>Delete.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722202226799/df951f43-c60d-4b0d-953a-7566e05e31bc.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>To delete the template, select the launch template -&gt; <strong>Actions</strong> -&gt; <strong>Delete template</strong> -&gt; type delete -&gt; <strong>Delete</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722202291401/94057f9c-ed36-4fba-8da8-7a88d26ce808.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
]]></content:encoded></item></channel></rss>