Logo Banjong LLC
< Go back to Blogs Menu

How to Deploy VPC & EC2 with Terraform

Published on:

By: Ignatius Ngwaabanjong

How to Deploy VPC & EC2 with Terraform

Click: complete_code_in_github

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.

Code Source

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:

  • Start using this portion on the VPC and other resources below.
  • 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 -out main.tfplan = will output the entire plan of the resources that will be created after apply.
  • terraform apply "main.tfplan" = 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

Categories

  • Cloud Engineering
  • IAC Terraform