🌟 Getting Started with Terraform: A beginner's Guide
16 min read

đź’ˇ Introduction
Hey there, welcome to the exciting world of Cloud and DevOps! If you’re new to this space, don’t worry—I’m here to guide you like a friend who’s just a step ahead. Today, we’re diving into Terraform, one of the coolest and most widely used Infrastructure as Code (IaC) tools out there. Big companies like Adobe, Airbnb, and Red Hat rely on Terraform to manage their infrastructure using something called HashiCorp Configuration Language (HCL). Sounds fancy, right? Don’t sweat it—we’ll break it all down!
In this blog, we’re going on a beginner-friendly journey. First, we’ll unpack what terms like IaC, HCL, and Terraformactually mean (no jargon overload, I promise). Then, we’ll peek under the hood to see how Terraform works its magic. Finally, we’ll roll up our sleeves and use Terraform to create an EC2 instance (a virtual server on AWS) with an Nginx server to host a simple portfolio webpage. By the end, you’ll have a real, working project to show off!
Ready to jump in? Let’s get started without further ado!
đź’ˇ Pre-Requsities
Before we dive into the fun stuff, let’s make sure you’re set up for success. Since we’ll be using Amazon Web Services (AWS) as our cloud provider in this blog, you’ll need an AWS account. No worries if you don’t have one yet—it’s easy to create! Just head over to aws.amazon.com, sign up, and follow the steps to set up your free-tier account. This will let you experiment with Terraform without breaking the bank. Make sure you have your account ready, as we’ll be using it to spin up our EC2 instance and Nginx server later.
Psst—don’t forget to keep your AWS credentials safe! We’ll talk more about how to use them securely with Terraform soon.
💡 What is IaC, HCL, and Terraform? A Beginner’s Peek Under the Hood
Alright, let’s break this down like we’re chatting over coffee. Imagine you visit google.com and see that familiar search bar. You type a query, hit enter, and boom—results! On the surface, it’s just a website, but behind the scenes, it’s a whole different world. That webpage you’re seeing? It’s likely running on a Linux server tucked away in a data center somewhere across the globe. Pretty cool, right?
Now, most companies don’t want the hassle (or cost!) of building and maintaining their own data centers. Instead, they turn to cloud providers like AWS, Azure, or Google Cloud Platform (GCP). These providers let companies rent resources like compute power (think virtual servers), storage (for files or databases), security (to keep things safe), and networking (to connect everything). It’s like renting a fully equipped apartment instead of building a house from scratch!
So, how do companies set up these resources on the cloud? There are a few ways:
ClickOps: You log into the cloud provider’s website (like the AWS console) and manually click around to create servers, storage, or whatever you need. It’s straightforward but slow and prone to mistakes.
SDKs: These are tools like Boto3 (a Python library) that let you write code to create resources programmatically. It’s faster than clicking but requires coding skills.
Infrastructure as Code (IaC): This is where things get really slick, and it’s what we’re focusing on today!
What is IaC?
Infrastructure as Code (IaC) is like writing a recipe for your cloud setup. Instead of manually creating resources, you write code that describes exactly what you want—servers, networks, databases, you name it. This code is stored in files, so you can reuse, share, or even version it (like tracking changes in a Google Doc). The big win? It reduces errors, saves time, and makes your infrastructure repeatable and predictable.
What is HCL?
Now, let’s talk about HCL—HashiCorp Configuration Language. Think of HCL as the special language used to write these “recipes” for Terraform. It looks a bit like JSON (if you’ve seen that before), but it’s designed specifically for Terraform. HCL is a declarative language, which means you describe what you want (e.g., “I want a server with 2 CPUs and 4GB of RAM”) rather than how to build it step-by-step. Terraform takes your HCL code and figures out how to make it happen on your cloud provider. Pretty neat, huh?
What is Terraform?
Finally, let’s meet the star of the show: Terraform. It’s the most popular IaC tool out there, created by HashiCorp. With Terraform, you can write HCL code to provision and manage cloud resources—like spinning up a server or setting up a database—in a safe and efficient way. Here’s why it’s awesome:
No accidental deletions: Since everything is defined in code, you’re less likely to mess things up by clicking the wrong button.
Version control: You can track changes to your infrastructure like you would with code in Git.
Repeatability: Want to recreate the same setup in another environment? Just run the same code!
Terraform works with tons of cloud providers (AWS, Azure, GCP, and more), so it’s super versatile. In this blog, we’ll use it to create an AWS EC2 instance and set up an Nginx server to host a portfolio webpage. Trust me, it’s going to be fun!
đź’ˇ How Terraform Works?
Okay, let’s get into the nitty-gritty of how Terraform actually does its magic! Don’t worry, I’ll keep it simple and break it down step-by-step so it feels like we’re just chatting about a cool tool. Terraform is all about turning your infrastructure dreams (like servers or storage) into reality by reading your code and talking to your cloud provider. Here’s how it works, in a way that even a beginner can follow:
Terraform reads configuration files you write (in HCL, remember?) that describe the desired state of your infrastructure—like “I want one AWS EC2 server with Nginx installed.” Then, it uses providers (think of them as translators) to talk to the cloud provider’s APIs (like AWS’s) to create, update, or delete resources to match what you described. Let’s walk through the process:
1. Configuration
This is where you tell Terraform what you want. You write HCL code to define your infrastructure’s desired state—like setting up an AWS EC2 instance, a storage bucket, or security roles. For example, you might say, “Hey, I need a virtual machine with 2 CPUs and a firewall rule.” Your code can include all sorts of resources: virtual machines, storage, networking, you name it!
Terraform also has this cool feature called modules. Think of modules like reusable templates (similar to Python modules). They let you package your code so you can reuse it across projects, keeping things organized and saving you time.
2. Initialization
Once you’ve written your HCL code, you kick things off with the terraform init
command. This sets up your project by:
Downloading the provider plugins (like the AWS plugin if you’re using AWS) so Terraform can talk to your cloud provider.
Setting up the state file (more on this later) location. You can store this file remotely, like in an AWS S3 bucket, to keep it safe and share it with your team.
3. Planning
Next up is the terraform plan
command. This is like Terraform’s “preview mode.” It compares your HCL code (what you want) with the current state of your infrastructure (what you have), which is tracked in the state file. Then, it shows you a plan of what it’ll do—like “I’ll create one EC2 instance and a security group.” This step is super helpful because it lets you double-check everything before making changes, avoiding any “oops, I didn’t mean to delete that!” moments.
4. Applying
When you’re ready to make things happen, you run terraform apply
. This command takes the plan from the previous step and tells Terraform to go for it! It talks to your cloud provider’s API (like AWS) to create, update, or delete resources to match your HCL code. For example, it might spin up that EC2 instance or configure a storage bucket exactly as you specified.
5. Destroying
Need to clean up? The terraform destroy
command is your friend. It reads the state file, figures out all the resources Terraform is managing, and deletes them in the right order (taking dependencies into account so nothing breaks). It’s like hitting the reset button on your infrastructure.
Key Terraform Terms to Know
Let’s quickly cover some words you’ll hear a lot when working with Terraform:
Providers: These are like plugins that let Terraform talk to different platforms (AWS, Azure, GCP, etc.). For example, the AWS provider knows how to interact with AWS’s APIs to create resources.
State File: This is a file (usually called
terraform.tfstate
) that keeps track of the current state of your infrastructure. It’s like Terraform’s memory, storing details about what resources exist. Storing it in a remote location (like an S3 bucket) is a good idea to avoid accidental changes and make it easier to collaborate.Modules: These are reusable chunks of Terraform code. Just like Python modules, they help you organize your code and reuse it across projects, making your life way easier.
đź’ˇ How to Write Code in HCL?
Alright, let’s talk about writing code in HashiCorp Configuration Language (HCL)—don’t worry, it’s way simpler than it sounds! HCL is the language Terraform uses, and it’s designed to be easy to read and write, even for beginners. Think of it like writing a clear set of instructions for Terraform to follow. In HCL, you’ll work with a few key concepts: resources, variables, and data sources. Let’s break them down and look at some examples to make it crystal clear!
Resources: Building Blocks of Your Infrastructure
Resources are the actual pieces of infrastructure you want to create or manage—like virtual machines, storage buckets, security roles, databases, or even serverless functions. Each resource is defined in HCL with a specific type and configuration. For example, if you want to create an AWS EC2 instance, you’d use the aws_instance
resource.
Here’s an example of creating a t2.micro EC2 instance in AWS:
resource "aws_instance" "example" {
ami = "ami-0c94855ba95c71c99"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
In this code:
resource "aws_instance" "example"
tells Terraform you’re creating an EC2 instance named “example.”ami
specifies the Amazon Machine Image (think of it as the OS template for your server).instance_type = "t2.micro"
sets the size of the server (t2.micro is a small, free-tier option).tags
adds labels to help you identify the instance later.
Variables: Making Your Code Flexible
Variables (or “vars” in HCL) are like placeholders that make your code reusable and dynamic. Instead of hardcoding values, you define them once in a variable and use them wherever needed. Variables can hold different types of data, like strings, numbers, booleans, lists, maps, objects, tuples, or sets.
Here’s an example where we use variables to define the AWS region and instance tags:
variable "region" {
description = "AWS region to deploy resources"
type = string
default = "us-east-1"
}
variable "instance_tags" {
description = "Tags for the EC2 instance"
type = map(string)
default = {
Environment = "Dev"
Project = "MyWebApp"
}
}
resource "aws_instance" "example" {
ami = "ami-0c94855ba95c71c99"
instance_type = "t2.micro"
region = var.region
tags = var.instance_tags
}
Here’s what’s happening:
variable "region"
defines a variable for the AWS region, with a default value ofus-east-1
.variable "instance_tags"
defines a map (key-value pairs) for tags, with defaults forEnvironment
andProject
.In the
aws_instance
resource,var.region
andvar.instance_tags
pull in those variable values, making the code flexible (you can change the region or tags without rewriting the resource).
Data Sources: Fetching External Info
Data sources let Terraform grab information from outside your configuration—like details about existing resources or dynamic data from your cloud provider. This is super useful when you need to work with resources that already exist or fetch the latest info, like the ID of the most recent Amazon Linux AMI.
Here’s an example of using a data source to fetch the latest Amazon Linux AMI:
data "aws_ami" "latest_amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
resource "aws_instance" "example" {
ami = data.aws_ami.latest_amazon_linux.id
instance_type = "t2.micro"
}
In this code:
data "aws_ami" "latest_amazon_linux"
tells Terraform to find the latest Amazon Linux AMI owned by Amazon.most_recent = true
ensures you get the newest version.The
filter
narrows it down to AMIs with names matchingamzn2-ami-hvm-*-x86_64-gp2
.In the
aws_instance
resource,data.aws
_ami.latest_amazon_
linux.id
uses the fetched AMI ID, so you don’t have to hardcode it.
Why This Matters
Using resources, variables, and data sources in HCL makes your Terraform code powerful yet simple. Resources define what you want, variables make it reusable, and data sources keep it dynamic. Together, they let you build infrastructure that’s easy to manage and adapt.
đź’ˇ Practical Demo: Deploying an Nginx Server on AWS with Terraform
Alright, it’s time to roll up our sleeves and get hands-on! In this section, we’re going to use Terraform to deploy an Nginx server on an AWS EC2 instance and host a simple portfolio webpage. Don’t worry if this sounds like a lot—we’ll go step-by-step, and by the end, you’ll have a live webpage you can show off! Let’s dive in.
Step 1: Install the AWS CLI
First, we need the AWS Command Line Interface (CLI) to connect our local machine to AWS. If you’re using Ubuntu (AMD64), run these commands in your terminal:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
This downloads, unzips, and installs the AWS CLI. If you’re on a different OS, check the AWS CLI installation guide for the right commands.
Step 2: Set Up an AWS IAM User
To let Terraform talk to AWS, we need an IAM user with the right permissions. Here’s how to set it up:
Go to the AWS Console (log in at aws.amazon.com).
Search for IAM and click on Users > Create User.
Give the user a name, like
terra-user
.Under permissions, choose Attach permissions directly and select AmazonEC2FullAccess (this lets the user manage EC2 instances).
Review and create the user.
Select the
terra-user
in the IAM console, go to Security Credentials, and click Create Access Key.Choose CLI as the use case, then create the access key. Copy the Access Key ID and Secret Access Key (you’ll need these soon!).
Now, let’s configure the AWS CLI with those credentials. In your terminal, run:
aws configure
You’ll be prompted to enter:
Access Key ID: Paste the one you copied.
Secret Access Key: Paste this too.
Default region: Enter
us-east-1
.Output format: Enter
json
.
This sets up your AWS CLI to work with your terra-user
account.
Step 3: Install Terraform
Next, we need Terraform on your system. For Ubuntu (AMD64), run these commands:
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt-get install terraform
These commands add HashiCorp’s repository and install Terraform. If you’re on another OS, check the official Terraform installation guide.
Step 4: Set Up the Project
Let’s create a project folder to organize our Terraform files:
mkdir basic-terra
cd basic-terra
Step 5: Create a User Data Script
We’ll create a script to install Nginx and set up our portfolio webpage. Inside the basic-terra
directory, create a file called userdata.sh
with this content (Make sure to change the Name and Links in the Body of HTML with your name and links):
#!/bin/bash
## Change the Name and Links accordingly
# Update the package list and install Nginx
apt update -y
apt install nginx -y
# Enable and start nginx
systemctl enable nginx
systemctl start nginx
# Create portfolio content
cat <<EOF > /var/www/html/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pravesh Sudha | Portfolio</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
text-align: center;
padding: 50px;
}
h1 {
color: #333;
}
p {
font-size: 18px;
color: #666;
}
a {
color: #007BFF;
text-decoration: none;
}
</style>
</head>
<body>
<h1>Hi, I'm Pravesh Sudha</h1>
<p>DevOps · Cloud · Content Creator</p>
<p>
<a href="https://blog.praveshsudha.com" target="_blank">Blog</a> |
<a href="https://x.com/praveshstwt" target="_blank">Twitter</a> |
<a href="https://www.youtube.com/@pravesh-sudha" target="_blank">YouTube</a> |
<a href="https://www.linkedin.com/in/pravesh-sudha/" target="_blank">LinkedIn</a>
</p>
</body>
</html>
EOF
This script installs Nginx, starts it, and creates a simple portfolio webpage at /var/www/html/index.html
.
Step 6: Write Terraform Configuration
Now, let’s create the Terraform files to define our infrastructure.
- Create a
provider.tf
file to configure the AWS provider:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "6.4.0"
}
}
}
provider "aws" {
# Configuration options
}
- Create a
main.tf
file to define the EC2 instance, security group, and output:
resource "aws_security_group" "sg" {
name = "Basic-Security Group"
description = "Allow port 80 for HTTP"
tags = {
Name = "Basic-sg"
}
}
resource "aws_vpc_security_group_egress_rule" "example" {
security_group_id = aws_security_group.sg.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1"
}
resource "aws_vpc_security_group_ingress_rule" "example" {
security_group_id = aws_security_group.sg.id
cidr_ipv4 = "0.0.0.0/0"
from_port = 80
ip_protocol = "tcp"
to_port = 80
}
resource "aws_instance" "web" {
ami = "ami-020cba7c55df1f615" # Change the AMI accordingly
instance_type = "t2.micro"
security_groups = [aws_security_group.sg.name]
user_data = file("userdata.sh")
tags = {
Name = "basic-terra"
}
}
output "instance_public_ip" {
value = aws_instance.web.public_ip
description = "Website is running on this address:"
}
Note: The AMI ID (ami-020cba7c55df1f615
) is region-specific and may change. To find the correct AMI for Ubuntu in us-east-1
:
Go to the AWS Console > EC2 Dashboard > Launch Instance.
Select Ubuntu (e.g., Ubuntu Server 22.04 LTS).
Copy the AMI ID displayed there and update the
ami
field inmain.tf
.
Step 7: Deploy with Terraform
Now, let’s bring it all to life! In the basic-terra
directory, run these commands one by one:
terraform init
This initializes the project and downloads the AWS provider plugin.
terraform plan
This shows you what Terraform will do (like creating an EC2 instance and security group). Double-check the plan to make sure it looks right.
terraform apply --auto-approve
Type yes
when prompted. Terraform will create the resources, and after a few minutes, it’ll output the public IP address of your EC2 instance.
Step 8: See Your Portfolio in Action!
Copy the public IP address from the output, paste it into your browser (e.g., http://<public-ip>
), and voilà ! You should see your portfolio webpage running on Nginx, complete with your name and links to your blog, Twitter, YouTube, and LinkedIn. Congrats—you just built infrastructure with Terraform!
What You Did
You used Terraform to:
Set up an EC2 instance with an Ubuntu AMI.
Configure a security group to allow HTTP traffic (port 80).
Install Nginx and deploy a portfolio webpage using a user data script.
Output the public IP to access your site.
đź’ˇ Conclusion
Wow, what a journey! You’ve just taken your first steps into the world of Terraform and Infrastructure as Code (IaC), and look at what you accomplished! From understanding the basics of HCL and Terraform to deploying a live Nginx server on AWS with your very own portfolio webpage, you’ve got some serious DevOps skills to brag about now. We covered how Terraform works under the hood, wrote HCL code to define resources, and used it to spin up an EC2 instance like a pro.
Before we wrap up, let’s make sure you avoid any surprise AWS bills. Run this command in your basic-terra
directory to clean up all the resources we created:
terraform destroy --auto-approve
This will delete your EC2 instance, security group, and anything else Terraform managed. Always double-check your AWS Console to confirm everything’s gone!
I hope this guide sparked your curiosity about Terraform and DevOps. Keep experimenting, building, and learning—there’s so much more to explore! If you want to connect or dive deeper into cloud and DevOps, feel free to follow me on my socials:
LinkedIn: Pravesh Sudha
Twitter/X: praveshstwt
YouTube: Pravesh Sudha
Thanks for following along, and happy coding! What’s next? Let me know if you want to tackle another project or dive deeper into Terraform!