100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
HomeBlogTerraform Basics: Infrastructure as Code on AWS
Cloud & Cybersecurity

Terraform Basics: Infrastructure as Code on AWS

SV

SkillVeris Team

Cloud & Security Team

May 3, 2026 10 min read
Share:
Terraform Basics: Infrastructure as Code on AWS
Key Takeaway

Terraform turns cloud infrastructure into code: declare resources in HCL, preview with terraform plan, then make it real with terraform apply.

In this guide, you'll learn:

  • The state file tracks what Terraform has created so it can plan incremental updates instead of recreating resources.
  • Store state remotely in S3 with DynamoDB locking so teams can collaborate without clobbering each other's changes.
  • Variables and outputs make configs reusable across environments, while modules package patterns for reuse.
  • A complete AWS example can range from a single S3 bucket to a full web server with a security group and user data.

1What Is Infrastructure as Code?

Infrastructure as Code (IaC) means defining your cloud resources — servers, databases, networks, storage — in code files instead of clicking through a cloud console. The benefits are transformative: your infrastructure is reproducible (run it again, get identical results), version-controlled (every change tracked in Git with a reviewer), automated (deploy from CI/CD with no manual steps), and self-documenting (the code describes exactly what exists).

Terraform is the most widely adopted IaC tool, supporting AWS, GCP, Azure, and 1,700+ other providers with a single consistent language (HCL — HashiCorp Configuration Language).

2Installing Terraform

Terraform installs cleanly on every major platform. Pick the command set for your operating system, then verify the install.

Install Commands

Install via Homebrew on macOS, the HashiCorp apt repository on Linux, or Chocolatey on Windows.

code
# macOS (Homebrew)
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
# Linux
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# Windows: use Chocolatey
choco install terraform
terraform version # verify installation

3Core Concepts

A handful of building blocks underpin every Terraform configuration. Understanding them makes the rest of the tool intuitive.

Why infrastructure as code: reproducible, version-controlled, automated, and self-documenting.
Why infrastructure as code: reproducible, version-controlled, automated, and self-documenting.
  • Provider: a plugin that talks to a cloud API (AWS, GCP, Azure, GitHub, Cloudflare). Declared in your config; downloaded by terraform init.
  • Resource: a single infrastructure component (an EC2 instance, an S3 bucket, a VPC). The main building block of Terraform configs.
  • Data source: reads existing infrastructure (not managed by this Terraform config) to use its values.
  • Variable: an input parameter making configs reusable across environments.
  • Output: a value exported from the config (e.g. the public IP of an EC2 instance).
  • State: a JSON file tracking what Terraform has created so it can plan incremental updates.
  • Module: a reusable group of resources packaged together.

4Your First Terraform File

A first configuration declares the AWS provider, creates an S3 bucket, and blocks all public access to it.

With the file written, the standard workflow is init, plan, apply, and — when you're done — destroy.

main.tf

Declare the required AWS provider, then define an S3 bucket and a public access block resource.

code
# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
provider "aws" {
  region = "ap-south-1" # Mumbai region
}
# Create an S3 bucket
resource "aws_s3_bucket" "blog_assets" {
  bucket = "skillveris-blog-assets-2026"
  tags = {
    Environment = "production"
    Project     = "SkillVeris"
  }
}
# Block all public access
resource "aws_s3_bucket_public_access_block" "blog_assets" {
  bucket                  = aws_s3_bucket.blog_assets.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

Workflow

The core lifecycle commands download the provider, preview changes, apply them, and tear them down.

code
terraform init    # download AWS provider
terraform plan    # preview: "1 to add, 0 to change, 0 to destroy"
terraform apply   # create the resources (type "yes" to confirm)
terraform destroy # tear everything down (dev/test environments)

5Variables and Outputs

Variables turn hardcoded values into reusable inputs, and outputs expose useful values like a bucket name or instance IP. You can override variables on the command line or pass a .tfvars file.

variables.tf

Declare typed input variables with descriptions and defaults.

code
# variables.tf
variable "environment" {
  description = "Deployment environment"
  type        = string
  default     = "dev"
}
variable "region" {
  description = "AWS region"
  type        = string
  default     = "ap-south-1"
}
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
}

outputs.tf

Export the bucket name and ARN so other configs or operators can read them.

code
# outputs.tf
output "bucket_name" {
  description = "Name of the created S3 bucket"
  value       = aws_s3_bucket.blog_assets.bucket
}
output "bucket_arn" {
  value = aws_s3_bucket.blog_assets.arn
}

Overriding Variables

Override variables inline at apply time, or keep them in a .tfvars file (never commit secrets).

code
# Override variables at apply time
terraform apply -var="environment=prod" -var="instance_type=t3.small"
# Or use a .tfvars file (never commit secrets)
# prod.tfvars:
#   environment   = "prod"
#   instance_type = "t3.small"
terraform apply -var-file="prod.tfvars"

6Deploying an EC2 Instance

A complete EC2 setup pairs a security group with an instance. The security group allows HTTP from anywhere and SSH only from your IP, while the instance bootstraps nginx via user data and exports its public IP.

EC2 with Security Group

Define the security group, the instance, and an output for the public IP.

code
# Complete EC2 setup with security group
resource "aws_security_group" "web" {
  name        = "web-sg-${var.environment}"
  description = "Allow HTTP and SSH"
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["YOUR_IP/32"] # restrict SSH to your IP
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
resource "aws_instance" "web" {
  ami                    = "ami-0f5ee92e2d63afc18" # Ubuntu 22.04 ap-south-1
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.web.id]
  key_name               = "my-keypair"
  user_data = <<-EOF
    #!/bin/bash
    apt-get update -y
    apt-get install -y nginx
    echo "<h1>Deployed by Terraform</h1>" > /var/www/html/index.html
    systemctl start nginx
  EOF
  tags = {
    Name        = "web-${var.environment}"
    Environment = var.environment
  }
}
output "public_ip" {
  value = aws_instance.web.public_ip
}

7State Management

Terraform state is a JSON file (terraform.tfstate) that maps your config to real infrastructure. It's how Terraform knows what exists and what needs to change. Without state, every terraform apply would create new resources instead of updating existing ones.

  • Never edit the state file manually.
  • Never commit terraform.tfstate to Git (it contains secrets). Add to .gitignore.
  • For teams, store state remotely (see the next section).
  • Use terraform state list to see what's in state; terraform state show resource for details.

8Remote State with S3

Remote state enables team collaboration: everyone reads and writes the same state, and DynamoDB locking prevents two people from running terraform apply simultaneously. You bootstrap the backing S3 bucket and DynamoDB table once, then point Terraform at them.

init, plan, apply, and destroy cover the complete Terraform lifecycle.
init, plan, apply, and destroy cover the complete Terraform lifecycle.

backend.tf

Configure the S3 backend with DynamoDB locking and encryption, after creating the bucket and table.

code
# backend.tf — store state in S3 with DynamoDB locking
terraform {
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "skillveris/production/terraform.tfstate"
    region         = "ap-south-1"
    dynamodb_table = "terraform-state-lock" # prevents concurrent applies
    encrypt        = true
  }
}
# Create the S3 bucket and DynamoDB table first (bootstrap)
# aws s3 mb s3://my-terraform-state-bucket --region ap-south-1
# aws dynamodb create-table --table-name terraform-state-lock ...

9Modules: Reusable Infrastructure

A module packages a group of resources so you can call it repeatedly with different inputs. Define the module once, then instantiate it for staging and production and read back its outputs.

Defining and Calling a Module

Define the web-server module, call it twice from the root config, and expose each instance's public IP.

code
# modules/web-server/main.tf
variable "environment" {}
variable "instance_type" { default = "t3.micro" }
resource "aws_instance" "this" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type
  tags          = { Environment = var.environment }
}
output "public_ip" { value = aws_instance.this.public_ip }
# Call the module from root main.tf
module "staging_web" {
  source        = "./modules/web-server"
  environment   = "staging"
  instance_type = "t3.micro"
}
module "prod_web" {
  source        = "./modules/web-server"
  environment   = "production"
  instance_type = "t3.small"
}
# Access module outputs
output "staging_ip" { value = module.staging_web.public_ip }
output "prod_ip" { value = module.prod_web.public_ip }

10Workspaces: Multiple Environments

Workspaces create separate state files per environment, letting you reuse one config across staging and production. An alternative is separate directories (staging/ and production/), each with its own .tfvars and backend config. For complex setups, separate directories are often cleaner than workspaces.

Workspace Commands

Create, list, and select workspaces, and reference the active one inside resources.

code
# Workspaces let you use the same config for different environments
terraform workspace new staging
terraform workspace new production
terraform workspace list   # shows all workspaces
terraform workspace select staging
# Use workspace name in resources
# resource "aws_instance" "web" {
#   tags = { Environment = terraform.workspace }
# }

11Best Practices

A short set of disciplines keeps Terraform projects safe, predictable, and easy to debug.

  • Run terraform plan before every apply: review exactly what will change. Never apply blindly.
  • Remote state for teams: always use S3 + DynamoDB locking when more than one person applies changes.
  • Pin provider versions: use version = "~> 5.0" to prevent surprise breaking changes from provider upgrades.
  • Tag all resources: include Environment, Project, and Owner tags on every resource for cost allocation and debugging.
  • Never hardcode secrets: use variables for sensitive values, and pass them via environment variables or a secrets manager, never in committed .tf files.
  • Format and validate: terraform fmt formats code; terraform validate checks for errors before plan.

12Key Takeaways

The essentials of Terraform distill into a few core principles.

  • Terraform config describes the desired state; terraform apply converges real infrastructure to that state.
  • Always terraform plan before apply — review every change before making it real.
  • Store state remotely (S3 + DynamoDB) for team use; never commit state files to Git.
  • Use variables and modules to avoid repeating infrastructure patterns.
  • Tag everything; use workspaces or separate directories for multiple environments.

13What to Learn Next

Extend your IaC knowledge with these related topics.

  • AWS for Beginners — understand the resources Terraform provisions.
  • CI/CD Explained — run terraform apply automatically in a pipeline.
  • Kubernetes Explained — provision EKS clusters with Terraform.

14Frequently Asked Questions

Is Terraform the same as AWS CloudFormation? Both are IaC tools, but Terraform is cloud-agnostic (works with AWS, GCP, Azure, and 1,700+ other providers) while CloudFormation is AWS-only. Terraform uses HCL (cleaner syntax); CloudFormation uses JSON/YAML. Terraform has a larger community and ecosystem of modules. If you're AWS-only and already use AWS heavily, CloudFormation is viable; for multi-cloud or simpler syntax, Terraform is the industry standard.

What happens if someone manually changes a resource outside Terraform? The state file no longer matches reality. The next terraform plan will show a diff. Running terraform apply will revert the manual change to match the config. To import a manually created resource into Terraform state: terraform import resource_type.resource_name resource_id. This is why "click-ops" (manual console changes) and Terraform don't mix well — pick one approach per resource.

Should I use Terraform or Pulumi? Terraform uses HCL (a domain-specific configuration language); Pulumi uses general-purpose languages (Python, TypeScript, Go). Terraform is more widely adopted and has more community modules. Pulumi is more flexible for complex logic but has a steeper learning curve for infrastructure teams unfamiliar with software development practices. For most teams starting IaC, Terraform is the safer choice; Pulumi is valuable when your infrastructure logic is genuinely complex enough to benefit from a full programming language.

How do I handle sensitive values (passwords, API keys) in Terraform? Never put them in .tf files or .tfvars files committed to Git. Options: mark the variable as sensitive = true (redacts from plan output), pass via environment variables (TF_VAR_db_password=secret), use AWS Secrets Manager or HashiCorp Vault data sources to fetch secrets at apply time, or use SOPS to encrypt .tfvars files committed to Git.

📄

Get The Print Version

Download a PDF of this article for offline reading.

About the Publisher

SV

SkillVeris Team

Cloud & Security Team

Our cloud and security experts break down complex infrastructure topics into practical, beginner-friendly guides.

View all posts

Never miss an update

Get the latest tutorials and guides delivered to your inbox.

No spam. Unsubscribe anytime.

Frequently Asked Questions

21 categories · pick one to explore

Does SkillVeris have a tech blog, and what does it cover?
Yes, the SkillVeris blog has over 500 articles covering AI and machine learning, programming, web development, DevOps, cloud, security, databases and career guidance. Articles are practical and answer-first, and many use the Learn Through Hobbies approach, teaching technical concepts through cricket, music, gaming or cooking analogies. Everything is free to read.
What is the SkillVeris tech glossary and how big is it?
The SkillVeris glossary is a free reference of roughly 2,000-plus technology terms, each with a clear plain-language definition. It spans AI, programming, web, DevOps, cloud, security and database vocabulary, so whenever a lesson, article or job description uses jargon you do not recognise, the glossary gives you a fast, reliable answer.
Are the developer cheat sheets on SkillVeris free to download?
The cheat sheets are completely free to use, like everything else on SkillVeris. Each sheet condenses a language or tool into its essential syntax, commands and patterns for quick reference while coding. They are designed for rapid lookup during real work, complementing the deeper explanations found in study notes and courses.
Which programming references and cheat sheets are available?
Cheat sheets cover the platform's main domains, including programming languages, AI and ML tooling, web development, DevOps, cloud, security and databases, matching the topics of the 37 live courses. Each sheet lists related reading links and hashtags, so you can jump from a quick reference into fuller study notes or blog articles.
How do I find the meaning of a technical term quickly?
Search the SkillVeris glossary, which holds around 2,000-plus terms with concise, plain-language definitions. Each entry gets to the point in its first sentence, then links to related reading like blog posts or study notes for deeper context. It is faster and more consistent than sifting through scattered search results.
Is the SkillVeris blog good for beginners learning to code?
Yes, many blog articles are written specifically for beginners, and the Learn Through Hobbies style makes them unusually approachable: you might learn Python concepts through cricket or understand APIs through cooking. With 500-plus articles across skill levels, beginners can start with fundamentals and keep reading as they advance, entirely free.
Can cheat sheets replace full courses for learning a language?
No, cheat sheets are references, not teaching tools; they assume you already understand the concepts and just need syntax or commands fast. To actually learn a language, take a structured SkillVeris course with its 24–40 lessons and assessments, then keep the cheat sheet beside you while practising in Code Lab.
How often are new blog articles published on SkillVeris?
The blog grows regularly and already exceeds 500 articles, with new posts added as courses launch and technologies evolve. Topics track the platform's catalogue across AI, programming, web development, DevOps, cloud and security, so checking the Blog section periodically surfaces fresh tutorials, explainers and career-focused pieces, all free to read.
Does the glossary cover AI and machine learning terms?
Yes, AI and machine learning vocabulary is a major part of the roughly 2,000-plus term glossary, covering everything from foundational terms to modern concepts around LLMs, RAG and MLOps. Definitions are plain-language and answer-first, which helps when dense AI papers or course lessons throw unfamiliar jargon at you.
Are there cheat sheets for interview preparation?
Cheat sheets work well as interview-day refreshers because they compress syntax, commands and key concepts into scannable references. For dedicated preparation, combine them with the SkillVeris interview questions feature, which includes readiness scoring, plus study notes for depth. Reviewing a relevant cheat sheet just before an interview steadies recall under pressure.
Can I read the tech blog without signing up?
Yes, the blog is freely readable, and SkillVeris never charges for content. All 500-plus articles are open, covering tutorials, concept explainers and career advice. Creating a free account adds value elsewhere on the platform, like course progress tracking and certificates, but reading the blog requires no commitment at all.
How is the SkillVeris glossary different from Wikipedia?
The glossary is purpose-built for learners: definitions are short, plain-language and answer-first, sized for a quick lookup mid-lesson rather than a deep encyclopedic read. Entries also cross-link to related SkillVeris study notes, blog posts and courses, so a definition becomes a doorway into structured learning instead of a dead end.
Do blog articles use the Learn Through Hobbies method?
Many blog articles teach technical topics through hobby analogies, a hallmark of the SkillVeris blog, so you will find articles explaining programming through cricket, machine learning through music, or system design through cooking. The analogy is the teaching device; the article still delivers the real technical concept underneath.
Where can I find quick programming references while coding?
Open the SkillVeris cheat sheets, which are built exactly for that moment: compact, scannable references for syntax, commands and common patterns across languages and tools. Keep the relevant sheet in a browser tab while you work in Code Lab or your own editor, and dip into the glossary for terminology.
Is there a glossary entry for terms I meet in job descriptions?
Very likely yes, with roughly 2,000-plus terms across AI, programming, web, DevOps, cloud, security and databases, the glossary covers most jargon that appears in tech job descriptions. Decoding a listing this way helps you judge role fit honestly and prepares you to discuss those terms in interviews.
Are the blog articles written for the Indian tech audience?
The blog serves Indian learners plus a worldwide audience. Content stays globally relevant while acknowledging realities that matter in India, such as free access being essential for students and freshers, and career guidance that connects naturally to the SkillVeris jobs portal, which aggregates roles across India, UK, USA, Germany and Remote.
Can I suggest a topic for the blog or glossary?
SkillVeris content grows in response to what learners need, so feedback is welcome through the platform's support channels. If a term is missing from the glossary or a topic deserves an article, telling the team helps prioritise it. Meanwhile, the AI Mentor can answer the question immediately, 24/7, at any depth.
Do cheat sheets and glossary entries link to deeper learning?
Yes, every cheat sheet and glossary entry carries related reading links into study notes, blog articles and courses, plus concept hashtags for discovering similar content. This cross-linking means a thirty-second lookup can smoothly become a structured learning session whenever you decide you want more than a quick answer.
What makes SkillVeris programming references trustworthy?
The references are written to strict internal quality standards, kept consistent with the platform's 37 live courses, and never padded with invented statistics or hype. Definitions and cheat sheets are reviewed against the same content contracts that govern courses, and the answer-first style makes any inaccuracy easy to spot and correct.
How do the blog, glossary and cheat sheets fit into my learning routine?
Use them as satellites around your main course: read blog articles for context and motivation, hit the glossary the instant jargon appears, and keep cheat sheets open while coding. Together with study notes, Code Lab and the 24/7 AI Mentor, they turn passive reading into a complete, free learning system.

What Learners Say

Real journeys from the SkillVeris community — swipe for more.

SkillVeris taught me Python through Cricket. Now I’m building real projects and feeling confident!
Arjun S. · B.Tech Student
The best platform for hobby-based learning. Concepts finally stick.
Priya R. · Data Analyst
I went from zero coding to a portfolio of projects — all by learning through my love for gaming. Landed my first internship!
Kabir M. · CS Undergraduate
Trending Topics50 popular tags — tap to explore
Trending CoursesAll 37 free courses — tap to browse