Yes, Terraform can deploy applications by provisioning the required infrastructure and automating setup processes.
How to deploy an application on EC2 using Terraform
Key takeaways:
Terraform provisions infrastructure as code (IaC), facilitating safe, efficient infrastructure management.
A security group is created to allow only public port
3000, ensuring limited access to the EC2 instance.EC2 instance configuration includes setting AMI, instance type, and storage, attaching the security group.
Ingress allows incoming TCP traffic on port
3000; egress permits all outbound traffic.An EC2 instance is created to run a React app, cloned from GitHub, using a user data script.
The user data script installs Git, Node.js, and the app upon instance launch.
Terraform blocks define an output variable for the instance’s public IP.
After writing and configuring Terraform code, initialize (
terraform init), plan (terraform plan), and apply (terraform apply) to provision infrastructure.The app can be accessed via the instance’s public IP with port
3000post-provisioning.
Terraform is a software tool utilized to provision Infrastructure as code (IaC). Terraform is used for building, editing, and versioning infrastructure safely and efficiently.
Now, we will create a security group and set up a React application on an EC2 instance. The security group will only use public port 3000 to ensure the security of the EC2 instance.
First, we will look into the code and then provision the infrastructure. At the end, let's look at how we can create a security group. Then, we’ll launch an EC2 instance to host a React application. We’ll configure the instance by specifying its
Here is an architecture diagram of the provisioned infrastructure.
Create a security group
A security group controls the inbound and outbound traffic for an associated resource. In other words, it acts as a firewall for the resource. We will create a security group to allow limited access to our EC2 instance; the security group instance_sg will only use public port 3000 to ensure the security of the EC2 instance.
resource "aws_security_group" "instance_sg" {name = "allow-port-3000"description = "Allow incoming traffic on port 3000"ingress {from_port = 3000to_port = 3000protocol = "tcp"cidr_blocks = ["0.0.0.0/0"] # Allow traffic from any source IP}egress {from_port = 0to_port = 0protocol = "-1" # Allow all outbound trafficcidr_blocks = ["0.0.0.0/0"]}}
Note: Ingress refers to the rules that control incoming traffic to your instances. In the provided example, the
ingressblock allows incoming TCP traffic on port3000from any source IP address (0.0.0.0/0)Egress refers to the rules that control outgoing traffic from your instances. In the provided example, the
egressblock allows all outbound traffic to any IP address (0.0.0.0/0) on all ports and protocols.
Explanation
Let’s take a look at the above code and understand it block by block.
Lines 1–17: This block defines an AWS security group named
allow-port-3000that allows incoming TCP traffic on port3000from any source IP and allows all outbound traffic.Lines 5–10: Allows incoming TCP traffic on port
3000from any IP address (0.0.0.0/0).Lines 11–16: Permits all outbound traffic on any port and protocol to any IP address (
0.0.0.0/0).
Create an EC2 instance
We have created a security group that only allows inbound traffic on port 3000. Now, we will create an EC2 instance, such that we will add a script to clone the application from GitHub and run it in the user data of our EC2 instance.
resource "aws_instance" "my_app"{ami= "ami-0fa1ca9559f1892ec"instance_type= "t2.micro"key_name= nullsecurity_groups = [aws_security_group.instance_sg.name]user_data=<<-EOF#!/bin/bashsudo yum -y update &&\sudo yum -y install git &&\sudo yum install https://rpm.nodesource.com/pub_16.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm -y &&\sudo yum install nodejs -y --setopt=nodesource-nodejs.module_hotfixes=1 &&\git clone https://github.com/Educative-Content/my-reactapp.git &&\cd my-reactapp &&\npm install &&\npm startEOFtags={Name="clab-app"}}output "public_ip" {value = aws_instance.my_app.public_ip}
Explanation
Let’s take a look at the above code and understand it block by block.
Lines 1–23: This block defines an AWS EC2 instance named
my_app. It specifies the , instance type, security group, user data script, and tags. The user data script installs Git, Node.js, and a React app from a GitHub repository when the instance is launched.Amazon Machine Image (AMI) An Amazon Machine Image (AMI) is a pre-configured template for EC2 instances that includes the operating system, application server, and applications. It allows you to quickly launch new instances with identical configurations. Lines 24–26: This block defines an output variable named
public_ipthat retrieves the public IP address of the EC2 instance.
Now that we have a clear understanding of each Terraform block we are going to use, let’s provision the infrastructure.
Configure resources
We have put together the above-discussed code and a new Terraform provider block that uses credentials to access the mentioned AWS account and deploy infrastructure in the specified region.
provider "aws"{
region="us-east-1"
}
resource "aws_security_group" "instance_sg" {
name = "allow-port-3000"
description = "Allow incoming traffic on port 3000"
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allow traffic from any source IP
}
egress {
from_port = 0
to_port = 0
protocol = "-1" # Allow all outbound traffic
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "my_app"{
ami= "ami-0fa1ca9559f1892ec"
instance_type= "t2.micro"
key_name= null
security_groups = [aws_security_group.instance_sg.name]
user_data=<<-EOF
#!/bin/bash
sudo yum -y update &&\
sudo yum -y install git &&\
sudo yum install https://rpm.nodesource.com/pub_16.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm -y &&\
sudo yum install nodejs -y --setopt=nodesource-nodejs.module_hotfixes=1 &&\
git clone https://github.com/Educative-Content/my-reactapp.git &&\
cd my-reactapp &&\
npm install &&\
npm start
EOF
tags={
Name="clab-app"
}
}
output "public_ip" {
value = aws_instance.my_app.public_ip
}Click the “Run” button and type the following command to initialize the terraform directory, terraform init is used to resolve and install dependencies.
After initializing the directory, use terraform plan to see the execution plan; it’s an optional step. After this, execute the configuration file using terraform apply, it asks for confirmation, then type yes, and then Terraform will create the requested infrastructure.
terraform initterraform apply
Note: The application may take upto three minutes to be available after running the EC2 instance.
Copy the public IP from the terminal, paste it into the address bar of the new web page, and add the port 3000 at the end.
<Public_IP_Address>:3000
Congratulations! Our application is live.
Conclusion
In conclusion, deploying an application on EC2 using Terraform allows for a streamlined and automated infrastructure setup.
By defining resources such as security groups and EC2 instances in code, we not only ensure a consistent deployment process but also gain flexibility to easily scale or modify the infrastructure. This approach simplifies application management, enabling secure, efficient, and repeatable deployments directly from the command line.
With Terraform’s infrastructure-as-code capabilities, we can focus more on application functionality while leaving infrastructure provisioning and management to automated, reliable scripts.
Frequently asked questions
Haven’t found what you were looking for? Contact Us
Can Terraform be used for application deployment?
What is a 3-tier application using Terraform?
What is the API limit for Terraform?
Is Terraform an API?
Is Terraform written in YAML or JSON?
Free Resources