How to Deploy VPC & EC2 with Terraform

https://github.com/Ngwaabanjong/terraform-projects/tree/main/deploy-vpc-ec2-with-terraform

Introduction to Terraform:
  • HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files.
How Terraform works:
  • Terraform’s primary function is to create, modify, and destroy infrastructure resources to match the desired state described in the Terraform configuration.
  • Desire state is the code definition.
  • Current state is the resource when it’s deployed.
What we will do:
  1. We will create a basic VPC and its components.
  2. We will create a security group
  3. We will create an ec2 instance in the VPC.
Prerequisites:
  1. Install Terraform – https://www.terraform.io/
  2. Install AWS CLI – https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
  3. Install SDK tool: exp – Visual Studio Code
  4. Configure IAM access to AWS: $ aws configure

To Configure authentication to your AWS Console, you need to create an IAM user and use it’s credentials on the CLI.

0 – Configure Provider:
provider "aws" {
  region = "us-east-1"

}
Configure Variables and tags
  • There are other ways of passing variables but here we go.
  • Create 2 files named variables.tf & terraform.tfvars.
  • We will pass the variables in the variables file.
  • We will pass the value in the .tfvars file.
  • Not to confuse you, we will create just one variable and pass it on the tags, you could create more.

variables.tf

variable "project-name" {
    description = "Write the project name as value in the .tfvars file"
}

terraform.tfvars

  • This filename shouldn’t be change. It’s unique.
project-name = "my-project-name"

Tag Syntax on resources:

  • We will use the project name variable to tag our resources.
     tags = {
      Name = "${var.project-name}-vpc"
   }
1 – Configure VPC:
  • (Optional) Select a specific CIDR Range for your infrastructure with the Mask Calculator. 
  • Subnet Mask Calculator: Link – https://www.site24x7.com/tools/ipv4-subnetcalculator.html
  • Every resource has a resource name and a given name.
  • Example: the resource name is aws_vpc then I gave MyVpc.
  • Create a file in the root folder called 1-vpc.tf
resource "aws_vpc" "MyVpc" {
     cidr_block = "10.1.0.0/16"
     tags = {
      Name = "${var.project-name}-vpc"
   }
}
2 – Create Internet Gateway:
  • A VPC always needs an internet gateway to access the internet. 
  • We need to create an IGW and link it to the VPC ID dynamically.
  • Syntax: “resource_name.given_name.id” = aws_vpc.MyVpc.id
  • Create a file in the root folder and name it 2-internetgw.tf 
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.MyVpc.id
  tags = {
    Name = "${var.project-name}-igw"
  }
}
3 – Configure Subnets:
  • To create the subnet we need the VPC ID and a CIDR Block. 
  • We need to link the VPC ID dynamically by following the syntax.
  • Syntax: “resource_name.given_name.id” = aws_vpc.MyVpc.id
  • Create a file in the root folder and name it 3-subnets.tf 
resource "aws_subnet" "public1" {
  vpc_id             = aws_vpc.MyVpc.id
  cidr_block         = "10.1.1.0/24"
  availability_zone = "us-east-1a"

  tags = {
    Name = "${var.project-name}-public1"
  }
}

resource "aws_subnet" "public2" {
  vpc_id            = aws_vpc.MyVpc.id
  cidr_block        = "10.1.2.0/24"
  availability_zone = "us-east-1b"

  tags = {
    Name = "${var.project-name}-public2"
  }
}
4 – Create Route Tables:
  • Our VPC has an implicit router which must be attached to a subnet. 
  • We need route tables to control where network traffic is directed.
  • Dynamically link the internet gateway ID and VPC ID to the route.
  • Create a file in the root folder and name it 4-routetb.tf 
resource "aws_route_table" "public_custom_route_table" {
  vpc_id = aws_vpc.MyVpc.id

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

  tags = {
    Name = "${var.project-name}-public-rt"
  }
}
5 – Configure Route Table Association:
  • Create the route table association. 
  • Dynamically link the Route tb ID & Subnet ID to the association.
  • Create a file in the root folder and name it 5-rtassociation.tf 
resource "aws_route_table_association" "pub1" {
  subnet_id      = aws_subnet.public1.id
  route_table_id = aws_route_table.public_custom_route_table.id
}

resource "aws_route_table_association" "pub2" {
  subnet_id      = aws_subnet.public2.id
  route_table_id = aws_route_table.public_custom_route_table.id
}
6 – Create a security group for our instance:
  • We need a security group to control traffic to our ec2 instance. 
  • Dynamically link the VPC ID to the security group.
  • We will open port 80 for http and 22 for SSH.
  • Create a file in the root folder and name it 6-securitygroup.tf 
resource "aws_security_group" "MySg" {
 name        = "my-tf-sg"
 description = "Allow HTTP to web server"
 vpc_id      = aws_vpc.MyVpc.id

ingress {
   description = "SSH ingress"
   from_port   = 22
   to_port     = 22
   protocol    = "tcp"
   cidr_blocks = ["0.0.0.0/0"]
 }

ingress {
   description = "HTTP ingress"
   from_port   = 80
   to_port     = 80
   protocol    = "tcp"
   cidr_blocks = ["0.0.0.0/0"]
 }

egress {
   from_port   = 0
   to_port     = 0
   protocol    = "-1"
   cidr_blocks = ["0.0.0.0/0"]
 }
}
7 – Create a .pem Key Pair:
  • Login to AWS Console EC2.
  • Resource on the left side – Click: Key pair.
  • Click: Create Key pair.
  • Give name -> select .pem
  • Create – it will download on your pc.
8 – Create and EC2 Instance in our VPC:
  • We know an EC2 instance is a virtual server in the Cloud. 
  • We can install our web app by bootstrapping during provisioning.
  • We can also install our applications after the instance is created.
  • We will link multiple resources to the ec2 for it to reside in our VPC.
  • Pick an AMI ID per your template region by login into AWS Console ec2 -> click create instance and copy AMI ID.
  • Create a file in the root folder and name it 7-ec2instance.tf
resource "aws_instance" "MyServer" {
  ami                         = "ami-0ff8a91507f77f867"
  instance_type               = "t2.micro"
  key_name                    = "your pem key name without .pem on it"
  monitoring                  = true
  subnet_id                   = aws_subnet.public2.id
  vpc_security_group_ids      = [aws_security_group.MySg.id]
  associate_public_ip_address = true

  //CODE//
# for_each = toset(["node-1", "node-2"])
#    tags = {
#      Name = "${each.key}-${var.project-name}-ec2"
#    }

  tags = {
    Name = "${var.project-name}-ec2"
  }
}
Add multiple instances:
  • You may have a request to create multiple instances.
  • For each argument is used to add more resources.
  • Add the code snippet below to create multiple instances.
  • name them differently.
 for_each = toset(["node-1", "node-2"])
    tags = {
      Name = "${each.key}-${var.project-name}-ec2"
    }
Terraform CLI Commands:
  • terraform init = will initialize the directory by installing independencies.
  • terraform validate = will help validate if your code is well written.
  • terraform plan = will output the entire plan of the resources that will be created after apply.
  • terraform apply = will deploy the resources in your cloud platform.
  • terraform destroy = will destroy the whole infrastructure. 
$ terraform init
$ terraform validate
$ terraform plan
$ terraform apply
$ terraform destroy

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
%d bloggers like this: