# terraform / providers / resources

The Bridge and the Blueprint: Providers & Resources

A provider is the plugin that lets Terraform speak to a platform's API. A resource is the object you actually want built. One is the bridge, the other is what crosses it — and understanding the difference is the key to reading any Terraform configuration.

$ terraform plan
provider "aws"Connects to AWS API
resource "aws_instance"Object to create
init
Downloads Provider
apply
Creates Resource
# architecture

How a Request Travels

Terraform
Provider (AWS)
AWS API
Creates Infrastructure
provider

The Bridge

Without a provider, Terraform has no idea how to create an AWS EC2 instance, an Azure VM, a Docker container, or a GitHub repository. It's a plugin, downloaded during terraform init, that translates your configuration into real API calls.

resource

The Blueprint

The resource block is what you actually want built — the EC2 instance, the S3 bucket, the VPC. Terraform reads it, compares it to current state, and creates, updates, or deletes accordingly.

# plugins

Terraform Providers

Popular Providers

aws
Amazon Web Services
azurerm
Microsoft Azure
google
Google Cloud Platform
docker
Docker Containers
kubernetes
Kubernetes Clusters
github
GitHub Repositories
cloudflare
DNS & CDN
vmware
VMware Infrastructure
digitalocean
DigitalOcean Servers
main.tfAWS PROVIDER
1 2 3
provider "aws" {
  region = "ap-south-1"
}
reads as

Region: Mumbai

This tells Terraform to use the AWS provider and create every AWS resource in this configuration inside the ap-south-1 region.

main.tfAZURE
1 2 3
provider "azurerm" {
  features {}
}
main.tfGOOGLE CLOUD
1 2 3 4
provider "google" {
  project = "my-project"
  region  = "asia-south1"
}

Multiple Providers, One Project

main.tfCOMBINED
1 2 3 4 5
provider "aws" {
  region = "ap-south-1"
}

provider "cloudflare" {}
  • In one run, Terraform can create an AWS EC2 instance, a Cloudflare DNS record, a CloudFront distribution, and a Route53 zone — all coordinated from a single configuration.

main.tfPINNING A VERSION
1 2 3 4 5 6 7
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}
source

hashicorp/aws

Reads as Company / Provider — HashiCorp's own build of the AWS provider plugin.

version constraint

~> 6.0

Means >= 6.0 and < 7.0 — accepts any patch or minor update within the 6.x line, never a breaking major version.

terminalAUTHENTICATION
$ export AWS_ACCESS_KEY_ID=xxxxxxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxxx
# or
$ aws configure

Provider Lifecycle

terraform init
↓ downloads provider
terraform plan
↓ uses provider
terraform apply
↓ calls cloud APIs

Terraform never stores credentials itself — it reads them from environment variables or your provider's own CLI configuration.

# objects

Terraform Resources

A resource is an infrastructure object Terraform creates and manages — an EC2 instance, an S3 bucket, a VPC, an RDS database, an IAM user, a security group, a Docker container. Everything you create in Terraform is, ultimately, a resource.

syntax

resource "<TYPE>" "<NAME>" { }

The type tells Terraform what kind of object to create; the name is a local label used only inside your configuration to reference it later.

main.tfBASIC EC2
1 2 3 4
resource "aws_instance" "web" {
  ami           = "ami-0123456789"
  instance_type = "t2.micro"
}
arguments

What You Set

Arguments tell Terraform what to create — inputs like instance_type, ami, or availability_zone. You write these directly into the resource block.

attributes

What You Get Back

After creation, Terraform knows values it couldn't have known beforehand — public IP, private IP, ARN, ID, DNS name. Reference them as aws_instance.web.public_ip.

main.tfTAGS
1 2 3 4 5 6 7
resource "aws_instance" "web" {
  ami           = "ami-123456"
  instance_type = "t2.micro"

  tags = {
    Name = "WebServer"
  }
}
main.tfRESOURCE REFERENCE
1 2 3 4 5
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_security_group" "web" {
  vpc_id = aws_vpc.main.id
}
DEPENDENCY GRAPH

When one resource references another — like aws_security_group.web pointing at aws_vpc.main.id — Terraform automatically understands it must create the VPC first, then the security group.

RESOURCE ADDRESS

Every resource has a unique address, such as aws_instance.web or aws_s3_bucket.logs. It's used in references, the state file, imports, and targeted commands.

main.tfMULTIPLE RESOURCES
1 2 3
resource "aws_vpc" "main" {}
resource "aws_subnet" "public" {}
resource "aws_instance" "web" {}

Resource Lifecycle

terraform apply
Reads Configuration
Compares State
Creates / Updates / Deletes
# distinction

Provider vs Resource

ProviderResource
Connects Terraform to a platform or serviceDefines an infrastructure object to create
Downloads as a plugin during terraform initCreated during terraform apply
Example: aws, azurerm, google, dockerExample: aws_instance, aws_s3_bucket, azurerm_virtual_machine
Configures authentication and regionConfigures the properties of the infrastructure
# end to end

Provider + Resource Together

main.tfFULL EXAMPLE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = "ap-south-1"
}

resource "aws_instance" "web" {
  ami           = "ami-0123456789abcdef0"
  instance_type = "t3.micro"

  tags = {
    Name = "Terraform-Web-Server"
  }
}

How Terraform Processes This

terraform init
↓ downloads AWS provider
terraform plan
↓ reads aws_instance, calculates changes
terraform apply
↓ AWS provider calls AWS API
EC2 Instance Created