Skip to main content

Command Palette

Search for a command to run...

L2. Terraform Providers, Variables, and Project Structuring - A Practical Beginner’s Guide

Updated
4 min read

Learning Terraform opens the door to managing cloud infrastructure using Infrastructure as Code (IaC). In this guide, we’ll dive into providers, variables, multi-cloud setups, and how to structure a professional Terraform project.

This blog is especially for students, new learners, and junior DevOps engineers who want to build a solid foundation in Terraform - without getting overwhelmed.


🔌 What Is a Provider in Terraform?

A provider in Terraform is a plugin that connects Terraform to your cloud platform (like AWS, Azure, GCP, etc.).

Think of it as the bridge between your Terraform code and the cloud infrastructure you're trying to automate.

🔧 Example: AWS Provider

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

This block tells Terraform:

  • Use the AWS provider

  • Target the us-east-1 region

Terraform will then use this configuration to authenticate and create resources in AWS.

🧠 Tip:

Without a provider block, Terraform won’t know:

  • Which cloud to talk to

  • How to authenticate

  • Where to create infrastructure


☁️ Official, Partner & Community Providers

Terraform supports hundreds of providers, categorized as:

  1. Official Providers – Maintained by HashiCorp
    e.g., AWS, Azure, GCP, Kubernetes

  2. Partner Providers – Maintained by vendors (e.g., Oracle, Alibaba)

  3. Community Providers – Maintained by the community (less reliable)

✅ Always check provider activity and documentation at: registry.terraform.io


🌐 Multi-Region and Multi-Cloud Configuration

🔁 Multi-Region Setup (Single Cloud, Multiple Regions)

To deploy resources in multiple AWS regions:

provider "aws" {
  alias  = "use1"
  region = "us-east-1"
}

provider "aws" {
  alias  = "usw2"
  region = "us-west-2"
}

resource "aws_instance" "east" {
  provider      = aws.use1
  ami           = "ami-east"
  instance_type = "t2.micro"
}

resource "aws_instance" "west" {
  provider      = aws.usw2
  ami           = "ami-west"
  instance_type = "t2.micro"
}

🌐 Multi-Cloud Setup (e.g., AWS + Azure)

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

provider "azurerm" {
  features = {}
  subscription_id = "your-subscription-id"
  client_id       = "your-client-id"
  client_secret   = "your-secret"
  tenant_id       = "your-tenant-id"
}

⚠️ Each provider has a unique name and authentication mechanism. Use the official docs to get syntax and examples.


🧱 Terraform Resources

A resource represents a piece of infrastructure - like an EC2 instance, an S3 bucket, or a virtual machine.

🧩 Example (AWS EC2 Instance):

resource "aws_instance" "example" {
  ami           = var.ami_id
  instance_type = var.instance_type
}

Use documentation to find the correct syntax and resource names (e.g., aws_instance, azurerm_virtual_machine).


💡 Variables in Terraform

Hardcoding values (like AMI IDs, instance types) is bad practice. Use variables to make your Terraform configuration reusable.

🔽 Input Variables (Defined in variables.tf)

variable "ami_id" {
  description = "AMI for EC2"
  type        = string
  default     = "ami-0abcd1234"
}

variable "instance_type" {
  description = "Instance type"
  type        = string
  default     = "t2.micro"
}

🔼 Output Variables (Defined in outputs.tf)

output "instance_ip" {
  description = "Public IP of the instance"
  value       = aws_instance.example.public_ip
}

🧾 TFVARS: Dynamic Value Management

To dynamically pass values instead of hardcoding them in .tf files, use a terraform.tfvars file:

ami_id        = "ami-07a5b1a7"
instance_type = "t2.medium"

Terraform will automatically load this file during terraform apply. For custom files:

terraform apply -var-file="prod.tfvars"

🧠 Conditional Expressions in Terraform

Use conditionals when you want to assign values based on a variable (like environment type):

🔐 Example: Conditional CIDR Block

cidr_blocks = var.environment == "prod" ? ["10.0.1.0/24"] : ["10.0.2.0/24"]

This logic:

  • Assigns one subnet range in production

  • Assigns another for development

✅ Use it for:

  • Public access controls

  • Instance types

  • Resource counts

  • Tags and naming conventions


🔧 Built-in Functions in Terraform

Terraform provides useful built-in functions to manipulate data:

FunctionDescriptionExample
length()Get the length of a listlength(var.subnet_ids)
upper()Convert to uppercaseupper(var.env)
map()Create a map from key/value pairsmap("env", "dev", "tier", "web")

More at Terraform Function Docs


To keep things clean and scalable, organize files like this:

terraform-project/
├── main.tf            # Core logic
├── variables.tf       # Input variables
├── outputs.tf         # Output variables
├── provider.tf        # Provider blocks
├── terraform.tfvars   # Variable values

This modular structure:

  • Improves readability

  • Makes collaboration easier

  • Encourages reuse across environments🧪 Key Takeaways

✅ Providers connect Terraform to your cloud
✅ Use aliases for multi-region or multi-cloud setups
✅ Resources define what to deploy
✅ Variables and TFVARS make code reusable
✅ Conditionals and functions make configurations smarter
✅ Project structure matters for maintainability


🎯 Start writing small modules using providers and variables.
🔍 Read official provider docs.
🛠 Practice customizing configurations for different environments.

3 views

More from this blog

Iresh's Blog

20 posts