Create an Instance with an Elastic IP Attached using Terraform
Tags: cloud, terraform, aws, networkengineer
Published: 2023-03-06 18:56:22

On my journey to explore the Kubernetes networking ecosystem, I decided to take my first step by completing the AWS Networking course outline using Terraform. I am attempting to gain an understanding of how things work at this layer.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pw7t0eprt5xy9xuws1j6.png)

#Laying the Ground Work for My Code
The first thing I did was to install Terraform using this [tutorial](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).

##Defining the Backend for Storing Infrastructure Information
The next thing I did was to create a "Terraform.tf" file so I can set up the backend where all the information about this infrastructure will be stored. The information is mapped to the real infrastructure on AWS. I use a local backend, meaning the information is stored on my computer. This information is in JSON format.

```terraform
terraform {
    backend "local" {
      path = ""
    }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
```
The above code in this file specifies that I am using a local backend, and also that I am using an “AWS provider.” The provider is a plugin for interacting with the AWS APIs so the infrastructure can be built.

## Specifying the Cloud Provider
Next I created a "main.tf" file where I will specify the cloud provider and also the architecture as code.

```terraform
# Configure the AWS Provider
provider "aws" {
  region = "us-west-2"
  access_key = ""
  secret_key = ""
}
```

#Algorithm of the Architecture
1. Create a VPC
2. Specify the default NACL
3. Specify the default security group
4. Create an Internet Gateway
5. Specify the default route table, and add a new route to the Internet Gateway.
6. Create a subnet
7. Create an instance
8. Create an elastic IP address

## Create a VPC
VPC = 10.0.0.0/16
```terraform
# Create VPC
resource "aws_vpc" "VPC_A" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    name = "VPC_A"
  }
}
```
When a VPC is created, AWS uses an overlay network to offer multi-tenancy for implementation. I wrote some words about this on my [substack](https://charlesuneze.substack.com/p/exploring-the-broadcom-tomahawk-5).

## Specify the default NACL
```terraform
# Specify the default NACL, regardless if the VPC creates it on default
resource "aws_default_network_acl" "Default_VPC_A_NACL" {
  default_network_acl_id = aws_vpc.VPC_A.default_network_acl_id

  ingress {
    protocol   = -1
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = -1
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  tags = {
    "name" = "Default_VPC_A_NACL"
  }
}
```

## Specify the default security group

```terraform
# Specify the default SG, regardless if the VPC creates it on default
resource "aws_default_security_group" "Default_VPC_A_SG" {
  vpc_id = aws_vpc.VPC_A.id

  ingress {
    protocol  = -1
    from_port = 0
    to_port   = 0
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = -1
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    "name" = "Default_VPC_A_SG"
  }
}
```

## Create an Internet Gateway

```terraform
# Create the Internet Gateway
resource "aws_internet_gateway" "VPC_A_IGW" {
  vpc_id = aws_vpc.VPC_A.id

  tags = {
    name = "VPC_A_IGW"
  }
}
```
## Specify the default route table, and add a new route to the Internet Gateway

```terraform
# Create the default route table
resource "aws_default_route_table" "VPC_A_Default_RT" {
  default_route_table_id = aws_vpc.VPC_A.default_route_table_id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.VPC_A_IGW.id
  }

  tags = {
    name = "VPC_A_Default_RT"
  }
}
```

## Create a subnet

```terraform
# Create Subnet
resource "aws_subnet" "VPC_A_Subnet_A" {
  vpc_id                  = aws_vpc.VPC_A.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "us-west-2a"

  tags = {
    name = "VPC_A_Subnet_A"
  }
}
```

## Create an Instance

```terraform
# Create AWS instance
resource "aws_instance" "VPC_A_Subnet_A_AWS_Linux" {
  ami               = "ami-0b029b1931b347543"
  instance_type     = "t2.micro"
  tenancy           = "default"
  availability_zone = "us-west-2a"
  subnet_id = aws_subnet.VPC_A_Subnet_A.id

  tags = {
    name = "VPC_A_Subnet_A_AWS_Linux"
  }
}
```
## Create an elastic IP address

```terraform
# Create an Elastic IP
resource "aws_eip" "VPC_A_EIP" {
  instance = aws_instance.VPC_A_Subnet_A_AWS_Linux.id
  vpc      = true
  tags = {
    name = "VPC_A_EIP"
  }
}

# Associate the Elastic IP to the instance
resource "aws_eip_association" "VPC_A_EIP-Association" {
  instance_id   = aws_instance.VPC_A_Subnet_A_AWS_Linux.id
  allocation_id = aws_eip.VPC_A_EIP.id
}
```

After applying the configuration, check for the public IP address of the script via the command below
`terraform state show aws_eip.VPC_A_EIP`
Then do a ping to the public IP address, make sure it is successful.

Do make a comment if you experience any issue in the code or article.

## Follow my AWS Advanced Networking Journey on Github
AWS Advanced Networking
https://github.com/Its-All-About-the-Journey/AWS-Advanced-Networking