Provision an AWS ec2 instance using terraform

In this article, you will learn how to provision an AWS EC2 instance in AWS using Terraform.

Prerequisites.
1. Terraform is locally installed, head to the official website for installation instructions.
2. An AWS account, if you do not have one, create one here.
3. A GitHub account, you can create one here.
4. A basic knowledge of Terraform as the article has majorly pieces of code.

1.0 Base application.

This tutorial is based on the GitHub project. To clone it, head over to your desired folder by the commands

cd Desktop

And clone the application by the commands

git clone https://github.com/manulangat1/social_media_invest.git

Navigate to the `feat-donations` branch to follow along with the tutorial

1.0 Initialize your terraform project.

On the project root folder, create a new directory named terraform_config or name it as per your liking and navigate inside the newly created directory.

mkdir terraform-config
cd terraform-config

Create a new file named main.tf and inside it add the following lines of code.

provider "aws" { 
  region = "us-east-1" 
  access_key = ""
  secret_key = ""
}

The AWS secret and access keys can be obtained by navigating to the IAM profile, selecting a user and navigating to the Security credentials tab.

Run the command terraform init - This command creates a state file that tracks the changes in our infrastructure and also downloads the provider from the terraform registry.

terraform init

At this stage, your folder should look as the image attached below.

2.0 Create a development vpc

Head over to the main.tf and add the following lines of code.

variable "cidr_block" {

  description = "This is the cidr block defination"
  default     = "10.0.0.0/16" # default variable.
  type        = string # the type of variable declared.

}

This line of code declares a variable cidr_block that you can reuse throughout your terraform file. Once done, add the following additional lines of code.

resource "aws_vpc" "my-development-vpc" {
  cidr_block = var.cidr_block

  tags = {
    "Name" : "development-vpc"
  }
}

These lines of code declare a resource - aws vpc which you named 'my development vpc'.
Head over to your terminal and run the *terraform plan* command. This command prints out the changes that will be made to your infra.

terraform plan

To effect the changes, run the terraform apply command, this will prompt a confirmation to approve/stop the process, to go around this, you can use the command

terraform init --auto-approve

Head over to the aws vpc dashboard and the newly created vpc should be there

3.0 Create a subnet.

Go to the main.tf file and add in the following lines of code.

resource "aws_subnet" "my-subnet-1" {
  availability_zone = "us-west-1b"
  vpc_id            = aws_vpc.my-development-vpc.id
  cidr_block        = "10.0.10.0/24"

  tags = {
    "Name" : "development-subnet"
  }
}

These additional lines of code create an aws subnet resource named my-subnet-1 and it is associated with the previously created vpc with the vpc_id param.

4.0 Create an internet gateway.

Add the following lines of code to the main.tf file.

resource "aws_internet_gateway" "my-app_igw" {
  vpc_id = aws_vpc.my-development-vpc.id
  tags = {
    "Name" : "My app igw"
  }
}
resource "aws_route_table" "my-app-route-table" {
  vpc_id = aws_vpc.my-development-vpc.id


  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.my-app_igw.id

  }
  tags = {
    "Name" : "Route table",
    "CreatedBy" : "Your name"
  }
}

resource "aws_route_table_association" "a-rtb" {
  route_table_id = aws_route_table.my-app-route-table.id
  subnet_id      = aws_subnet.my-subnet-1.id
}

5.0 Create a security group.

At this stage, your main.tf file should resemble the one below.

provider "aws" { 
  region = "us-east-1" 
  access_key = ""
  secret_key = ""
}

variable "cidr_block" {

  description = "This is the cidr block defination"
  default     = "10.0.0.0/16" # default variable.
  type        = string # the type of variable declared.

}

resource "aws_vpc" "my-development-vpc" {
  cidr_block = var.cidr_block

  tags = {
    "Name" : "development-vpc"
  }
}

resource "aws_subnet" "my-subnet-1" {
  availability_zone = "us-west-1b"
  vpc_id            = aws_vpc.my-development-vpc.id
  cidr_block        = "10.0.10.0/24"

  tags = {
    "Name" : "development-subnet"
  }
}

resource "aws_internet_gateway" "my-app_igw" {
  vpc_id = aws_vpc.my-development-vpc.id
  tags = {
    "Name" : "My app igw"
  }
}
resource "aws_route_table" "my-app-route-table" {
  vpc_id = aws_vpc.my-development-vpc.id


  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.my-app_igw.id

  }
  tags = {
    "Name" : "Route table",
    "CreatedBy" : "Your name"
  }
}

resource "aws_route_table_association" "a-rtb" {
  route_table_id = aws_route_table.my-app-route-table.id
  subnet_id      = aws_subnet.my-subnet-1.id
}

Add the following lines of code to the main.tf file to create a security group that opens port 22 for ssh connections and port 8080 for an Nginx server that will be run in the next part of this tutorial series. It also opens the port to allow for incoming requests for any IP address.

resource "aws_security_group" "my-app-sg" {
  name   = "my-sg"
  vpc_id = aws_vpc.my-development-vpc.id


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

  }

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

  tags = {
    "Name" : "dev-sg"
  }

}

6.0 Create the ec2 instance.

At this stage, you will now create the ec2 instance and apply the changes to create the using the terraform apply command. Navigate to the main.tf file and add the following lines of code.

resource "aws_instance" "my-ec2-instance" {

  ami           = "ami-0bd4d695347c0ef88" # using a static ami , in the next article you shall learn how to do this programatically.
  instance_type = "t2.micro"

  subnet_id = aws_subnet.my-subnet-1.id

  vpc_security_group_ids = [aws_security_group.my-app-sg.id]

  availability_zone = "us-east-1a"

  associate_public_ip_address = true

  tags = {
    "Name" : "Dev-ec2"
  }

}

Head over to the terminal and run the command.

terraform apply --auto-approve

Navigate to your aws ec2 dashboard and you will see the newly created ec2 instance.
To delete the instance, run

terraform destroy --auto-approve

In this article, you have learned how to use variables and resources in Terraform to create an ec2 instance. In the next article, you will learn how to use terraform variable files, data commands and provisioners to run an Nginx container in the newly created ec2 instance.

Happy hacking.