DEV Community

Pavan Reddy cheedeti
Pavan Reddy cheedeti

Posted on

Build a VPC With EC2 On Terraform!

✅ TASK 2 — Build a VPC With EC2 (Step-by-Step Guide)

Folder structure:

terraform-vpc/
 ├── main.tf
 ├── variables.tf
 ├── outputs.tf
 └── terraform.tfvars

Enter fullscreen mode Exit fullscreen mode

STEP 1 — Create main.tf

provider "aws" {
  region = var.aws_region
}

# -----------------------
# VPC
# -----------------------
resource "aws_vpc" "main_vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "main-vpc"
  }
}

# -----------------------
# Public Subnet
# -----------------------
resource "aws_subnet" "public_subnet" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = var.public_subnet_cidr
  map_public_ip_on_launch = true
  availability_zone       = var.az

  tags = {
    Name = "public-subnet"
  }
}

# -----------------------
# Internet Gateway
# -----------------------
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "main-igw"
  }
}

# -----------------------
# Route Table
# -----------------------
resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.main_vpc.id

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

  tags = {
    Name = "public-route-table"
  }
}

# -----------------------
# Route Table Association
# -----------------------
resource "aws_route_table_association" "public_assoc" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public_rt.id
}

# -----------------------
# Security Group
# -----------------------
resource "aws_security_group" "ec2_sg" {
  name        = "ec2_public_sg"
  description = "Allow SSH"
  vpc_id      = aws_vpc.main_vpc.id

  ingress {
    from_port   = 22
    to_port     = 22
    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"]
  }

  tags = {
    Name = "EC2 Public SG"
  }
}

# -----------------------
# Key Pair
# -----------------------
resource "aws_key_pair" "my_key" {
  key_name   = "task2-key"
  public_key = file(var.public_key_path)
}

# -----------------------
# EC2 Instance
# -----------------------
resource "aws_instance" "public_ec2" {
  ami           = var.ami_id
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public_subnet.id
  key_name      = aws_key_pair.my_key.key_name
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  tags = {
    Name = "public-ec2"
  }
}
Enter fullscreen mode Exit fullscreen mode
STEP 2 — Create variables.tf
variable "aws_region" {
  type = string
}

variable "vpc_cidr" {
  type = string
}

variable "public_subnet_cidr" {
  type = string
}

variable "az" {
  type = string
}

variable "ami_id" {
  type = string
}

variable "public_key_path" {
  type = string
}
Enter fullscreen mode Exit fullscreen mode
STEP 3 — Create outputs.tf
output "vpc_id" {
  value = aws_vpc.main_vpc.id
}

output "public_subnet_id" {
  value = aws_subnet.public_subnet.id
}

output "ec2_public_ip" {
  value = aws_instance.public_ec2.public_ip
}
Enter fullscreen mode Exit fullscreen mode
STEP 4 — Create terraform.tfvars
aws_region          = "ap-south-1"
vpc_cidr            = "10.0.0.0/16"
public_subnet_cidr  = "10.0.1.0/24"
az                  = "ap-south-1a"
ami_id              = "ami-0f5ee92e2d63afc18"
public_key_path     = "~/.ssh/id_rsa.pub"

Enter fullscreen mode Exit fullscreen mode

STEP 5 — Initialize Terraform

terraform init
Enter fullscreen mode Exit fullscreen mode

STEP 6 — Validate Configuration

terraform validate
Enter fullscreen mode Exit fullscreen mode

STEP 7 — Generate Execution Plan

terraform plan
Enter fullscreen mode Exit fullscreen mode

STEP 8 — Apply and Build VPC + EC2

terraform apply
Enter fullscreen mode Exit fullscreen mode

Type yes.

🎉 RESULT

Terraform will create:

✔ VPC
✔ Public Subnet
✔ Internet Gateway
✔ Route Table
✔ Route Table Association
✔ Security Group
✔ Key Pair
✔ EC2 Instance in Public Subnet

You will get:

ec2_public_ip = "13.x.x.x"
Enter fullscreen mode Exit fullscreen mode

SSH into EC2:

ssh -i ~/.ssh/id_rsa ec2-user@<PUBLIC-IP>
Enter fullscreen mode Exit fullscreen mode

🎉 RESULT

      + region          = "ap-south-1"
      + tags_all        = (known after apply)
    }

  # aws_route_table.public_rt will be created
  + resource "aws_route_table" "public_rt" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + region           = "ap-south-1"
      + route            = [
          + {
              + cidr_block                 = "0.0.0.0/0"
              + gateway_id                 = (known after apply)
                # (11 unchanged attributes hidden)
            },
        ]
      + tags             = {
          + "Name" = "public-route-table"
        }
      + tags_all         = {
          + "Name" = "public-route-table"
        }
      + vpc_id           = (known after apply)
    }

  # aws_route_table_association.public_assoc will be created
  + resource "aws_route_table_association" "public_assoc" {
      + id             = (known after apply)
      + region         = "ap-south-1"
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_security_group.ec2_sg will be created
  + resource "aws_security_group" "ec2_sg" {
      + arn                    = (known after apply)
      + description            = "Allow SSH"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
                # (1 unchanged attribute hidden)
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
                # (1 unchanged attribute hidden)
            },
        ]
      + name                   = "ec2_public_sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "ap-south-1"
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "EC2 Public SG"
        }
      + tags_all               = {
          + "Name" = "EC2 Public SG"
        }
      + vpc_id                 = (known after apply)
    }

  # aws_subnet.public_subnet will be created
  + resource "aws_subnet" "public_subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-south-1a"    
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"    
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + region                                         = "ap-south-1"     
      + tags                                           = {
          + "Name" = "public-subnet"
        }
      + tags_all                                       = {
          + "Name" = "public-subnet"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.main_vpc will be created
  + resource "aws_vpc" "main_vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = true
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + region                               = "ap-south-1"
      + tags                                 = {
          + "Name" = "main-vpc"
        }
      + tags_all                             = {
          + "Name" = "main-vpc"
        }
    }

Plan: 8 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + ec2_public_ip    = (known after apply)
  + public_subnet_id = (known after apply)
  + vpc_id           = (known after apply)

Enter fullscreen mode Exit fullscreen mode

Top comments (0)