How to deploy an Nginx web server on EC2 instance with Terraform (Fully Automated)

In this guide, I’ll walk you through the steps involved in deploying a basic HTML page on an EC2 instance using a Ngnix server and fully automating this process using Terraform.

There are a few Prerequisites you might need to know before continuing into this guide

  1. Must have an active AWS account. Here is a guide on how you can create one for free.
  2. Have Terraform installed. You can follow the steps here to install it on your computer
  3. A text editor of your choice (I’ll be using VSCode)

Terraform is an IaC (Infrastructure as a Code) tool that helps you automate tasks on the cloud. Things like going to GUI dashboards and manually selecting all the options. Automating this process with Terraform will increase your productivity and make it easier to migrate between cloud providers.

Enough theory, let’s get our hands dirty with a hands-on example that will help you understand terraform better.

Setting Up the Terraform Project

First, let’s make all the files required for our Terraform project and initialize Terraform for the first time.

Start by creating these 4 files in your folder

  • terraform.tfvars
  • main.tf
  • outputs.tf
  • commands.tpl

The first .tfvar file is where all the variables stay in your terraform project, we use this file to easily edit parameters of our infrastructure without going through the long files.

Main.tf file is where the primary definitions for the infrastructure reside. You can name it anything you want. Commands that need to be run after the ec2 instance is deployed are to be placed in commands.tpl file.

Defining the provider for our infrastructure

Let’s start by defining the provider that we want to use to deploy our project. In our case let’s use AWS.

You must setup and configure AWS CLI on your computer before continuing, here is a guide on how to do it.

Now that you’ve configured AWS CLI, let’s continue. In your main.tf file add the below snippet

Provider

provider "aws" {
  profile = "default"
  region  = "ap-south-1"
}

The profile here is the profile defined in your AWS CLI configuration, if you set the CLI following the guide I provided above, you can leave it as “default”.

The region, choose the one closest to the place where you live. I live in India, so I chose ap-south-1.

Resources

resource "aws_instance" "aws_ubuntu" {
  instance_type = "t2.micro"
  ami           = "ami-09298640a92b2d12c"
  user_data     = file("commands.tpl")
}

Here we’re defining all the resources we want to start for our project.

“aws_instance” is the type of the resource, you can find more details about it in Terraform docs here

You can scroll down to AWS EC2 configurations to check other options for the resource config.

Instance Type: It is the t2.micro machine that is to be hosted on AWS.

AMI: AMI is the Amazon Machine Image which is different for each region, so you can go to the AWS console to see the AMI id for the machine image you want to deploy.

Go to AWS Console > EC2 > Images > AMI Catalog

User Data – the commands that run after deployment starts

For the user data, we’re referencing the commands file we created earlier. These will be executed after the machine is spun up.

#!/bin/bash -ex
amazon-linux-extras install nginx1 -y
echo "<h1>Hello World</h1>" > /usr/share/nginx/html/index.html
systemctl enable nginx
systemctl start nginx

These are the commands that will run when the ec2 machine is up and running. In simple terms, the first command will install the nginx package (we use the amazon command as we are using the amazon linux image) and add “Hello World” text to the html file which will be hosted with nginx.

now let’s define the other resources required for the service.

resource "aws_default_vpc" "default" {

}

This will choose the default VPC for our EC2 and apply it to our instance.

resource "aws_security_group" "demo_sg" {
  name        = "demo_sg"
  description = "allow ssh on 22 & http on port 80"
  vpc_id      = aws_default_vpc.default.id

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

  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"]
  }
}

These will configure the security rules which will help us access our website from the internet opening the ports.

Outputs

# OUTPUT
output "aws_instance_public_dns" {
  value = aws_instance.aws_ubuntu.public_dns
}

Outputs will print the information about our instance to the console after the completion of the deployment.


Initialise and Deploy with Terraform

Now that the configuration is complete, let’s start by initializing terraform on our project.

terraform init

This will download the provider files and configure the project for deployment.

Run, the validation command to check if everything is right without configuration.

terraform validate

This will validate the config file and tell you if there are any typos or errors in the files.

Now that everything is validated and ready to deploy, run the final deploy command.

terraform apply

This will show information about all the changes it will make and ask you for confirmation. Just input “yes” and the deployments will be made.

Commands will run sequentially after the start of the machine. Give it a few minutes and the site will be live.

Destroy everything with one Command

If you want to stop all the resources, you can do it with a single command by running

terraform destroy -auto-approve

This will remove all the deployments from the cloud and terminate your instance.

Hope this gave you a glance into the Terraform world, it sure does simplify the deployment of the cloud resources for developers.

Leave a Reply

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


This site uses Akismet to reduce spam. Learn how your comment data is processed.

You May Also Like