8 min read

Getting Started with Terraform: A Beginner’s Guide to AWS Infrastructure as Code

Nasrul Hasan
Nasrul Hasan
Nasrul Hasan
Cover Image for Getting Started with Terraform: A Beginner’s Guide to AWS Infrastructure as Code

What Is Terraform?

Terraform is an infrastructure provisioning tool developed by HashiCorp. It follows the Infrastructure as Code (IaC) approach, allowing you to define, manage, and version infrastructure using configuration files.

Terraform:

  • Manages infrastructure using code

  • Maintains infrastructure state

  • Supports multiple cloud providers


Terraform AWS Provider

Terraform supports multiple providers such as AWS, Azure, Google Cloud, and Kubernetes. In this guide, we’ll use the AWS provider.

Configure AWS Credentials

Generate AWS access keys and export them in your terminal.

export AWS_ACCESS_KEY_ID=<your-aws-access-key>
export AWS_SECRET_ACCESS_KEY=<your-aws-secret-key>
routeros

💡 On Windows, use Git Bash or PowerShell.

Terraform Basics

Provider

Providers allow Terraform to interact with cloud platforms.

provider "aws" {
  region = "us-east-1"
}
nginx

Resources

Resources are the core building blocks of Terraform.

resource "aws_instance" "server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}
abnf

Here:

  • aws_instance → Resource type

  • server → Logical name


Variables

Variables help parameterize Terraform configurations.

variable "instance_type" {
  description = "EC2 instance type"
  default     = "t2.micro"
}
gams

Usage:

instance_type = var.instance_type


Outputs

Outputs expose important values.

output "instance_ip" {
  value = aws_instance.server.public_ip
}
nginx

Terraform Lifecycle

Terraform follows a predictable lifecycle:

Initialize

terraform init
csharp

Plan

terraform plan
ebnf

Apply

terraform apply
coq

Destroy

terraform destroy
ebnf

These stages ensure safe, predictable infrastructure changes.


Provisioning an EC2 Instance Using Terraform (Modular Approach)

Instead of placing everything in a single file, we’ll follow a modular Terraform structure, which is a best practice for real-world projects.


Recommended Project Structure

terraform-ec2/
├── main.tf
├── variables.tf
├── outputs.tf
├── provider.tf
├── terraform.tfvars
├── modules/
│   └── ec2/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
stylus

Root Module Configuration

provider.tf

provider "aws" {
  region = "us-east-1"
}
nginx

main.tf

module "ec2" {
  source         = "./modules/ec2"
  instance_type  = "t2.micro"
  key_name       = "tf-webserver"
  ingress_ports  = [80, 443, 22, 3000]
  egress_ports   = [80, 443]
}
nginx

variables.tf

variable "region" {
  default = "us-east-1"
}
ceylon

outputs.tf

output "ec2_public_ip" {
  value = module.ec2.public_ip
}
lua

EC2 Module Configuration

modules/ec2/variables.tf

variable "instance_type" {}
variable "key_name" {}

variable "ingress_ports" {
  type = list(number)
}

variable "egress_ports" {
  type = list(number)
}
gams

modules/ec2/main.tf

resource "aws_security_group" "sg" {
  name = "allow-web-traffic"
  dynamic "ingress" {
    for_each = var.ingress_ports
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  dynamic "egress" {
    for_each = var.egress_ports
    content {
      from_port   = egress.value
      to_port     = egress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}
resource "aws_instance" "webserver" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = var.instance_type
  key_name      = var.key_name
  security_groups = [aws_security_group.sg.name]
  tags = {
    Name = "flask-app"
  }
}
abnf

modules/ec2/outputs.tf

output "public_ip" {
  value = aws_instance.webserver.public_ip
}
nginx

Deploy the Infrastructure

terraform init
terraform plan
terraform apply --auto-approve
coq

Destroy the Infrastructure

terraform destroy
ebnf

Conclusion

In this guide, you learned:

  • What Terraform is and why it’s important

  • Core Terraform concepts

  • Terraform lifecycle

  • How to provision an EC2 instance

  • How to structure Terraform using modules (best practice)

In upcoming blogs, we’ll cover Terraform state files, remote backends, and best practices.

Until then—happy learning ✌️