<?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[Hishcodes Blog]]></title><description><![CDATA[Hishcodes Blog]]></description><link>https://blog.hishcodes.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 01:57:42 GMT</lastBuildDate><atom:link href="https://blog.hishcodes.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Terraform : Remote backend using S3 and DynamoDB]]></title><description><![CDATA[In this guide we will configure Terraform to use a remote backend on S3 and DynamoDB. We will use S3 to store the .tfstate file rather than storing locally. DynamoDB here is used to create a locking mechanism.
Create an S3 bucket to store the tfstate...]]></description><link>https://blog.hishcodes.com/terraform-remote-backend-using-s3-and-dynamodb</link><guid isPermaLink="true">https://blog.hishcodes.com/terraform-remote-backend-using-s3-and-dynamodb</guid><category><![CDATA[Terraform]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Devops]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[DynamoDB]]></category><dc:creator><![CDATA[Hisham Moideen]]></dc:creator><pubDate>Sat, 28 Sep 2024 11:09:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727521616239/96c78f00-659e-4b71-b9a3-ec9a1dec8d90.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this guide we will configure Terraform to use a remote backend on S3 and DynamoDB. We will use S3 to store the .tfstate file rather than storing locally. DynamoDB here is used to create a locking mechanism.</p>
<p>Create an S3 bucket to store the tfstate file.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_s3_bucket"</span> <span class="hljs-string">"terraform_state"</span> {
  bucket = <span class="hljs-string">"demo-tf-state"</span>

  lifecycle {
    prevent_destroy = <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>Enable versioning for the bucket.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_s3_bucket_versioning"</span> <span class="hljs-string">"version_tf_bucket"</span> {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = <span class="hljs-string">"Enabled"</span>
  }
}
</code></pre>
<p>Create KMS keys to encrypt the bucket</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_kms_key"</span> <span class="hljs-string">"mykey"</span> {
  description             = <span class="hljs-string">"This key is used to encrypt bucket objects"</span>
  deletion_window_in_days = 10
}
</code></pre>
<p>Enable bucket encryption using KMS key.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_s3_bucket_server_side_encryption_configuration"</span> <span class="hljs-string">"example"</span> {
  bucket = aws_s3_bucket.terraform_state.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.mykey.arn
      sse_algorithm     = <span class="hljs-string">"aws:kms"</span>
    }
  }
}
</code></pre>
<p>Create DynamoDB table to enable locking mechanism.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"aws_dynamodb_table"</span> <span class="hljs-string">"tf-state-locking"</span> {
  name         = <span class="hljs-string">"tf-state-locking"</span>
  billing_mode = <span class="hljs-string">"PAY_PER_REQUEST"</span>
  hash_key     = <span class="hljs-string">"LockID"</span>

  attribute {
    name = <span class="hljs-string">"LockID"</span>
    <span class="hljs-built_in">type</span> = <span class="hljs-string">"S"</span>
  }
}
</code></pre>
<p>Apply the code using the command <code>terraform apply</code> . The resources are now created on AWS. Now, configure your terraform to use the remote backend.<br />Add the below code inside <code>terraform {}</code></p>
<pre><code class="lang-bash">backend <span class="hljs-string">"s3"</span> {
    bucket         = <span class="hljs-string">"demo-tf-state"</span>
    key            = <span class="hljs-string">"global/s3/terraform/tfstate"</span>
    region         = <span class="hljs-string">"us-east-1"</span>
    dynamodb_table = <span class="hljs-string">"tf-state-locking"</span>
    encrypt        = <span class="hljs-literal">true</span>
  }
</code></pre>
<p>Now initialise terraform so that it changes the backend from local to AWS using the command <code>terraform init</code> enter <code>yes</code> whenever asked.</p>
<p>Your terraform project now uses AWS S3 bucket and DynamoDB as remote backend.</p>
<p>The entire code I wrote for this guide is as follow,</p>
<pre><code class="lang-bash">terraform {
  required_providers {
    aws = {
      <span class="hljs-built_in">source</span>  = <span class="hljs-string">"hashicorp/aws"</span>
      version = <span class="hljs-string">"~&gt; 5.0"</span>
    }
  }
  required_version = <span class="hljs-string">"&gt;=1.9.1"</span>

  <span class="hljs-comment"># Configure s3 as backend</span>
  backend <span class="hljs-string">"s3"</span> {
    bucket         = <span class="hljs-string">"demo-tf-state"</span>
    key            = <span class="hljs-string">"global/s3/terraform/tfstate"</span>
    region         = <span class="hljs-string">"us-east-1"</span>
    dynamodb_table = <span class="hljs-string">"tf-state-locking"</span>
    encrypt        = <span class="hljs-literal">true</span>
  }
}

<span class="hljs-comment"># Configure the AWS Provider</span>
provider <span class="hljs-string">"aws"</span> {
  region = <span class="hljs-string">"us-east-1"</span>
}

<span class="hljs-comment"># Create s3 bucket to store tfstate file</span>
resource <span class="hljs-string">"aws_s3_bucket"</span> <span class="hljs-string">"terraform_state"</span> {
  bucket = <span class="hljs-string">"demo-tf-state"</span>

  lifecycle {
    prevent_destroy = <span class="hljs-literal">true</span>
  }
}

<span class="hljs-comment"># enable bucket version</span>
resource <span class="hljs-string">"aws_s3_bucket_versioning"</span> <span class="hljs-string">"version_tf_bucket"</span> {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = <span class="hljs-string">"Enabled"</span>
  }
}

<span class="hljs-comment"># create kms key for s3 bucket</span>
resource <span class="hljs-string">"aws_kms_key"</span> <span class="hljs-string">"mykey"</span> {
  description             = <span class="hljs-string">"This key is used to encrypt bucket objects"</span>
  deletion_window_in_days = 10
}

<span class="hljs-comment"># enable bucket encryption</span>
resource <span class="hljs-string">"aws_s3_bucket_server_side_encryption_configuration"</span> <span class="hljs-string">"example"</span> {
  bucket = aws_s3_bucket.terraform_state.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.mykey.arn
      sse_algorithm     = <span class="hljs-string">"aws:kms"</span>
    }
  }
}

<span class="hljs-comment"># create dynamodb table for locking mechanism</span>
resource <span class="hljs-string">"aws_dynamodb_table"</span> <span class="hljs-string">"tf-state-locking"</span> {
  name         = <span class="hljs-string">"tf-state-locking"</span>
  billing_mode = <span class="hljs-string">"PAY_PER_REQUEST"</span>
  hash_key     = <span class="hljs-string">"LockID"</span>

  attribute {
    name = <span class="hljs-string">"LockID"</span>
    <span class="hljs-built_in">type</span> = <span class="hljs-string">"S"</span>
  }
}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Ansible Essentials: Setting Up and Running Your First Commands]]></title><description><![CDATA[Ansible is an open-source, robust automation tool that makes job automation, application deployment, and configuration management easier. To assist you in automating your infrastructure, we'll go over the fundamentals of setting up Ansible and lead y...]]></description><link>https://blog.hishcodes.com/ansible-essentials-setting-up-and-running-your-first-commands</link><guid isPermaLink="true">https://blog.hishcodes.com/ansible-essentials-setting-up-and-running-your-first-commands</guid><category><![CDATA[ansible]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Devops]]></category><category><![CDATA[automation]]></category><dc:creator><![CDATA[Hisham Moideen]]></dc:creator><pubDate>Sat, 21 Sep 2024 15:54:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727521904513/f367d596-2e42-432b-b16e-d678ccc9e4b1.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ansible is an open-source, robust automation tool that makes job automation, application deployment, and configuration management easier. To assist you in automating your infrastructure, we'll go over the fundamentals of setting up Ansible and lead you through executing your first commands in this tutorial. Let's explore the fundamentals and unleash Ansible's potential.</p>
<p><strong>Step 1 :</strong> Launch 2 Ubuntu instance with the name ‘Ansible server’ and ‘Target’.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726930368484/a071d5bb-49e3-4252-a92e-cb805616a0d9.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2 :</strong> Setup ansible server</p>
<p>For easy and quick connection, I use ‘EC2 instance connect’</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726930497876/80b4ad36-08b4-49c0-a344-de2491d01c23.png" alt class="image--center mx-auto" /></p>
<p>Before we start, let’s refresh the local package index by running the following in the EC2 terminal.</p>
<pre><code class="lang-plaintext">sudo apt update
</code></pre>
<p>Install Ansible on EC2 server.</p>
<pre><code class="lang-plaintext">sudo apt install ansible -y
</code></pre>
<p>Since the ansible server needs to communicate with the target server, we need to make sure they both are accessible. Let’s create a key in both the instances.</p>
<p>In ansible-server, enter the following command.</p>
<pre><code class="lang-plaintext">ssh-keygen
</code></pre>
<p>Just press enter until it creates new key-pair. The terminal should look like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726931038136/136d1686-a6fa-4094-81d7-41d91541c2a7.png" alt class="image--center mx-auto" /></p>
<p>Go to the directory where the key is located. In my case it is “/home/ubuntu/.ssh/”</p>
<pre><code class="lang-plaintext">cd /home/ubuntu/.ssh/
ls
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726931142829/e24c61df-81c4-480b-bcac-d81b866b9838.png" alt class="image--center mx-auto" /></p>
<p>Let’s view the contents of the file id_ed25519.pub. Copy the contents of the file as well.</p>
<pre><code class="lang-plaintext">cat id_ed25519.pub
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726931250189/c88b2cc2-92d4-4d32-8eb6-b7ec1568cceb.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 3 :</strong> Setting up the target.</p>
<p>Now let’s add the public key of ansible-server in authorized keys file of target server.</p>
<pre><code class="lang-plaintext">cd /home/ubuntu/.ssh/
ls
vi authorized_keys
</code></pre>
<p>Paste the key which you copied from the last command of previous step.</p>
<p>Press Esc :wq to save and exit the file.</p>
<p><strong>Step 4 :</strong> Writing first ansible code.</p>
<p>On the ansible-server, create a file named ‘inventory’ and enter the private IP of the target. (You may use public IP as well)</p>
<pre><code class="lang-plaintext">vi inventory
</code></pre>
<p>Save and exit the file.</p>
<p>Let’s run a command which creates a new directory on the target.</p>
<pre><code class="lang-plaintext">ansible -i inventory all -m "shell" -a "mkdir test-dir"
</code></pre>
<p>-i inventory - The <code>-i</code> flag specifies the inventory file. The <code>inventory</code> file contains a list of hosts or groups of hosts where Ansible will run the specified command.</p>
<p>all - This refers to all hosts in the inventory file.</p>
<p>-m shell - The <code>-m</code> option is used to specify the module that Ansible should use. In this case, the <code>shell</code> module is used, which allows you to run shell commands on the remote hosts.</p>
<p>-m “shell” - The <code>-m</code> option is used to specify the module that Ansible should use. In this case, the <code>shell</code> module is used, which allows you to run shell commands on the remote hosts.</p>
<p>-a "mkdir test-dir" : The <code>-a</code> flag specifies the argument passed to the module. In this case, the shell command being executed is <code>mkdir test-dir</code>, which creates a directory named <code>test-dir</code> on each of the remote hosts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726932096582/32176ec5-620a-40bd-bedd-aa7ffc688f3a.png" alt class="image--center mx-auto" /></p>
<p>Now, if you run <code>ls</code> command on target, you’ll see a new directory is created.</p>
<p>You may explore the command by running similar functions.</p>
<p><strong>Note :</strong> You can also group the target IP in inventory file as follow,</p>
<pre><code class="lang-plaintext">[ec2]
172.31.47.117

[database]
33.205.108.149
15.107.96.143

[webserver]
67.20.137.175
38.93.52.161
</code></pre>
<p>Here, ec2, database, webserver are the names of the groups. The target ec2 instance is in the group ‘ec2’. To run the command for the group ‘ec2’ only,</p>
<pre><code class="lang-plaintext">ansible -i inventory "ec2" -m "shell" -a "mkdir test-dir"
</code></pre>
<p><strong>Note :</strong> To run multiple lines of commands, we generally use ansible playbook.</p>
<p><strong>Step 5 :</strong> Create a playbook</p>
<p>Let’s create an ansible playbook which installs nginx on target and starts the server.</p>
<p>Create a new directory, for example ‘book’ and create a new file named ‘first.yml’</p>
<pre><code class="lang-plaintext">mkdir book
cd book
vi first.yml
</code></pre>
<p>In the first.yml, paste the following code.</p>
<pre><code class="lang-plaintext">---
- name: Install and start nginx
  hosts: all
  become: true

  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
    - name: Start ngnix
      service:
        name: nginx
        state: started
</code></pre>
<p>1. ---</p>
<p>This denotes the beginning of a YAML file.</p>
<p>2. - name: Install and start nginx</p>
<p>This is a descriptive name for the playbook. It summarizes what the playbook will do—install and start the Nginx service.</p>
<p>3. hosts: all</p>
<p>This tells Ansible to run the playbook on all hosts specified in the inventory file. You can specify specific host groups if needed.</p>
<p>4. become: true</p>
<p>This enables privilege escalation, meaning Ansible will run the tasks as a superuser (like root). It is required for tasks that need elevated permissions, such as installing packages or starting services.</p>
<p>5. tasks:</p>
<p>This section lists the tasks Ansible will perform. Each task is a step in the automation process.</p>
<p><strong>Step 6 :</strong> Run the playbook</p>
<p>To run the playbook enter the following command.</p>
<pre><code class="lang-plaintext">ansible-playbook -i inventory ec2 first.yml
</code></pre>
<hr />
<p>When you want to write complex playbook, use the command <code>ansible-galaxy</code> . For example <code>ansible-galaxy role init kubernetes</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726933726455/aacc573f-e05c-4cd0-9bbc-f60aebbbb081.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><strong>defaults/</strong>: Contains default variable definitions for the role.</p>
</li>
<li><p><strong>files/</strong>: Holds static files to be copied to remote hosts.</p>
</li>
<li><p><strong>handlers/</strong>: Defines tasks that are triggered by notifications.</p>
</li>
<li><p><strong>meta/</strong>: Stores metadata about the role, including dependencies.</p>
</li>
<li><p><strong>tasks/</strong>: Contains the main tasks that the role will execute.</p>
</li>
<li><p><strong>templates/</strong>: Contains Jinja2 templates for dynamic file generation.</p>
</li>
<li><p><strong>tests/</strong>: Includes files and playbooks for testing the role.</p>
</li>
<li><p><strong>vars/</strong>: Contains variables specific to the role that shouldn’t be overridden.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Simple EC2 Web Server using Terraform]]></title><description><![CDATA[In this project, we are going to setup the following using Terraform,

VPC

Public subnet

Internet gateway

Route table

Security group

EC2 instance

Elastic IP


The complete terraform code for this project is available on github
The project folde...]]></description><link>https://blog.hishcodes.com/simple-ec2-web-server-using-terraform</link><guid isPermaLink="true">https://blog.hishcodes.com/simple-ec2-web-server-using-terraform</guid><dc:creator><![CDATA[Hisham Moideen]]></dc:creator><pubDate>Thu, 01 Aug 2024 16:38:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727521881548/b9ab3c66-cdcb-4dec-8521-6b9c75509096.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this project, we are going to setup the following using Terraform,</p>
<ul>
<li><p>VPC</p>
</li>
<li><p>Public subnet</p>
</li>
<li><p>Internet gateway</p>
</li>
<li><p>Route table</p>
</li>
<li><p>Security group</p>
</li>
<li><p>EC2 instance</p>
</li>
<li><p>Elastic IP</p>
</li>
</ul>
<p>The complete terraform code for this project is available on <a target="_blank" href="https://github.com/hishcodes/Simple-ec2-web-server">github</a></p>
<p>The project folder contains 4 files as represented in the below structure.</p>
<pre><code class="lang-plaintext">simple-ec2-web-server/
├── main.tf
├── providers.tf
├── datasources.tf
└── user-data.tpl
</code></pre>
<h3 id="heading-step-1-providers-tf">Step 1 : providers .tf</h3>
<p>The providers .tf file allows Terraform to connect and interact with AWS Cloud.</p>
<pre><code class="lang-json">terraform {
  required_providers {
    aws = {
      source = <span class="hljs-attr">"hashicorp/aws"</span>
    }
  }
}

provider <span class="hljs-string">"aws"</span> {
  region                   = <span class="hljs-attr">"us-east-1"</span>
  shared_credentials_files = [<span class="hljs-attr">"~/.aws/credentials"</span>]
  profile                  = <span class="hljs-attr">"vscode"</span>
}
</code></pre>
<h3 id="heading-step-2-datasources-tf">Step 2 : datasources .tf</h3>
<p>This file is used to provide the latest ec2 instance ami id to the main .tf file.</p>
<pre><code class="lang-json">data <span class="hljs-string">"aws_ami"</span> <span class="hljs-string">"instance_ami"</span> {
  most_recent = true
  owners      = [<span class="hljs-attr">"137112412989"</span>]
  filter {
    name   = <span class="hljs-attr">"name"</span>
    values = [<span class="hljs-attr">"al2023-ami-2023.5.20240722.0-kernel-6.1-x86_64"</span>]
  }
}
</code></pre>
<h3 id="heading-step-3-user-data-tpl">Step 3 : user-data .tpl</h3>
<p>We need to provide user data for the ec2, so that it can download and setup server and display the instance's private ip in the webpage.</p>
<pre><code class="lang-plaintext">#!/bin/bash
# Use this for your user data (script from top to bottom)
# install httpd (Linux 2 version)
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "&lt;h1&gt;Hello World from $(hostname -f)&lt;/h1&gt;" &gt; /var/www/html/index.html
</code></pre>
<h3 id="heading-step-4-main-tf">Step 4 : main .tf</h3>
<p>First we need to create a VPC.</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_vpc"</span> <span class="hljs-string">"demo_vpc"</span> {
  cidr_block = <span class="hljs-attr">"10.0.0.0/16"</span>

  tags = {
    name = <span class="hljs-attr">"demo-vpc"</span>
  }
}
</code></pre>
<p>Then create a public subnet inside the VPC</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_subnet"</span> <span class="hljs-string">"pub_sub_1"</span> {
  vpc_id                  = aws_vpc.demo_vpc.id
  cidr_block              = <span class="hljs-attr">"10.0.1.0/24"</span>
  availability_zone       = <span class="hljs-attr">"us-east-1a"</span>
  map_public_ip_on_launch = true

  tags = {
    name = <span class="hljs-attr">"public-subnet-1"</span>
  }
}
</code></pre>
<p>Attach an internet gateway to the vpc</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_internet_gateway"</span> <span class="hljs-string">"demo_internet_gateway"</span> {
  vpc_id = aws_vpc.demo_vpc.id

  tags = {
    Name = <span class="hljs-attr">"dev-igw"</span>
  }
}
</code></pre>
<p>Create a public route table for the vpc</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_route_table"</span> <span class="hljs-string">"demo_public_rt"</span> {
  vpc_id = aws_vpc.demo_vpc.id

  tags = {
    Name = <span class="hljs-attr">"dev-public-rt"</span>
  }
}
</code></pre>
<p>Add a route in the route table which directs 0.0.0.0/0 traffic to internet gateway</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_route"</span> <span class="hljs-string">"default_route"</span> {
  route_table_id         = aws_route_table.demo_public_rt.id
  destination_cidr_block = <span class="hljs-attr">"0.0.0.0/0"</span>
  gateway_id             = aws_internet_gateway.demo_internet_gateway.id
}
</code></pre>
<p>Associate the route table to the subnet</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_route_table_association"</span> <span class="hljs-string">"demo_public_assoc"</span> {
  subnet_id      = aws_subnet.pub_sub_1.id
  route_table_id = aws_route_table.demo_public_rt.id
}
</code></pre>
<p>Create a security group for the vpc. It should allow inbound HTTP traffic on port 80 and all traffic for outbound.</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_security_group"</span> <span class="hljs-string">"demo_sg"</span> {
  name        = <span class="hljs-attr">"dev-sg"</span>
  description = <span class="hljs-attr">"dev security group"</span>
  vpc_id      = aws_vpc.demo_vpc.id

# Allow only port 80 inbound
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = <span class="hljs-attr">"tcp"</span>
    cidr_blocks = [<span class="hljs-attr">"0.0.0.0/0"</span>]
  }

# Allow all traffic for outbound
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = <span class="hljs-attr">"-1"</span>
    cidr_blocks = [<span class="hljs-attr">"0.0.0.0/0"</span>]
  }
}
</code></pre>
<p>Create an ec2 instance with user data</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_instance"</span> <span class="hljs-string">"demo"</span> {
  instance_type          = <span class="hljs-attr">"t2.micro"</span>
  ami                    = data.aws_ami.instance_ami.id
  user_data              = file(<span class="hljs-attr">"user-data.tpl"</span>)
  vpc_security_group_ids = [aws_security_group.demo_sg.id]
  subnet_id              = aws_subnet.pub_sub_1.id
}
</code></pre>
<p>Output the public ip of instance in the terminal</p>
<pre><code class="lang-json">output <span class="hljs-string">"ec2_public_ip"</span> {
  description = <span class="hljs-attr">"The public IP of the EC2 instance"</span>
  value       = aws_instance.demo.public_ip
}
</code></pre>
<p>Create and define the elastic ip is for use in vpc</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_eip"</span> <span class="hljs-string">"elastic_ip"</span>{
    instance = aws_instance.demo.id
    domain = <span class="hljs-attr">"vpc"</span>
}
</code></pre>
<p>Associate the elastic ip with the ec2 instance</p>
<pre><code class="lang-json">resource <span class="hljs-string">"aws_eip_association"</span> <span class="hljs-string">"eip_assoc"</span>{
    instance_id = aws_instance.demo.id
    allocation_id = aws_eip.elastic_ip.id
}
</code></pre>
<p>Output the elastic ip in the terminal (Just for you to know the elastic IP)</p>
<pre><code class="lang-json">output <span class="hljs-string">"ec2_eip"</span> {
  description = <span class="hljs-attr">"The Elastic IP of the EC2 instance"</span>
  value       = aws_eip.elastic_ip.public_ip
}
</code></pre>
<h3 id="heading-step-5-result">Step 5 : Result</h3>
<p>Now when you access the public IP of the instance OR the elastic IP (both should be the same) from your browser, you'll see similar webpage. (Please note to access the ip in http:// and not https://)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722960915678/0c6d8bfd-87b0-45ea-9ecd-dd09107a4cfa.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item></channel></rss>