All HowTo's Ansible & Terraform Automation Terraform

Terraform – Creating a VPC with an EC2 (With Examples)

This article shows how to create an ec2 in a VPC with an Internet Gateway, Subnet, Route Table and Security Gateway, in AWS. See our “Getting started with Terraform” article for basic information about getting started with Terraform and voiding issues.

The Terraform manifest “main.tf” file looks like the following. The following sample manifest has comments throughout.

We’re going to create:

  1. A new VPC named “agix_vpc”.
  2. A subnet for our ec2 host named “agix_subnet”ec2”.
  3. Associate our route table named “agix_route_table” with the internet gateway. This resource name is  “agix_rt_assoc_subnet_ec2”.
  4. Two identical ec2 hosts names “agix_ec2_host1” and “agix_ec2_host2”.
  5. A security group for the ec2’s named “agix_sg_ec2”.
  6. An internet gateway named “agix_gw”.
  7. A route table named “agix_route_table”.
# Where we're deploying to.
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "3.47.0"
    }
  }
}

# Credentials and the default region.
# For AWS, this is the IAM key and secret.
provider "aws" {
  region = "ap-southeast-2"
  access_key = "XXXX"
  secret_key = "YYYY"
}

# The name of the VPC we're replying into (and creating if need be).
# We also decide on our network structure. Our subnet will be derived from this network.
resource "aws_vpc" "agix_vpc" {
  cidr_block = "10.2.0.0/16"
  enable_dns_hostnames = true
  tags = {
    Name = "agix_vpc"
    Terraform = "true"
  }
}

# This subnet will house our ec2 hosts.
resource "aws_subnet" "agix_subnet_ec2" {
  vpc_id     = aws_vpc.agix_vpc.id
  cidr_block = "10.2.0.0/24"
  availability_zone = "ap-southeast-2c"
  tags = {
    Name = "agix_subnet_ec2"
    Terraform = "true"
  }
}

# Create our route table for each subnet.
resource "aws_route_table_association" "agix_rt_assoc_subnet_ec2" {
  subnet_id      = aws_subnet.agix_subnet_ec2.id
  route_table_id = aws_route_table.agix_route_table.id
}

# Create N number of ec2 hosts. Here we're creating 2 identical ec2 hosts.
resource "aws_instance" "agix_ec2_host" {
  count = 2
  instance_type     = "t3.small"
  availability_zone = "ap-southeast-2c"
  subnet_id = aws_subnet.agix_subnet_ec2.id
  ami = "ami-0a443decce6d88dc2"
  associate_public_ip_address = true
  vpc_security_group_ids = [aws_security_group.agix_sg_ec2.id]
  key_name         = "agix_key_pair"
  root_block_device {
    volume_size           = "20"
    volume_type           = "gp2"
    encrypted             = false
    delete_on_termination = true
  }
  tags = {
    Name = "agix_ec2_host${count.index}"
    Terraform = "true"
  }
}

# Create the security groups.
resource "aws_security_group" "agix_sg_ec2" {
  vpc_id = aws_vpc.agix_vpc.id
  ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow ssh from any"
  }
  ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow http from any"
  }
  ingress {
    from_port = 443
    to_port = 443
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow https from any"
  }
  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 8
    to_port     = 0
    protocol    = "icmp"
    description = "Allow ping from any"
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow out to any"
  }
}

# Create the Internet gateway for the VPC.
resource "aws_internet_gateway" "agix_gw" {
  vpc_id = aws_vpc.agix_vpc.id
  tags = {
    Name = "agix_gw"
    Terraform = "true"
  }
}

# Update the route table to link the subnets and Internet gateway.
resource "aws_route_table" "agix_route_table" {
  vpc_id = aws_vpc.agix_vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.agix_gw.id
  }
  tags = {
    Name = "agix_route_table"
    Terraform = "true"
  }
}

Leave a Reply

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