# 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.
How a Request Travels
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.
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.
Terraform Providers
Popular Providers
provider "aws" { region = "ap-south-1" }
Region: Mumbai
This tells Terraform to use the AWS provider and create every AWS resource in this configuration inside the ap-south-1 region.
provider "azurerm" { features {} }
provider "google" { project = "my-project" region = "asia-south1" }
Multiple Providers, One Project
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.
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 6.0" } } }
hashicorp/aws
Reads as Company / Provider — HashiCorp's own build of the AWS provider plugin.
~> 6.0
Means >= 6.0 and < 7.0 — accepts any patch or minor update within the 6.x line, never a breaking major version.
Provider Lifecycle
Terraform never stores credentials itself — it reads them from environment variables or your provider's own CLI configuration.
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.
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.
resource "aws_instance" "web" { ami = "ami-0123456789" instance_type = "t2.micro" }
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.
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.
resource "aws_instance" "web" { ami = "ami-123456" instance_type = "t2.micro" tags = { Name = "WebServer" } }
resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" } resource "aws_security_group" "web" { vpc_id = aws_vpc.main.id }
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.
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.
resource "aws_vpc" "main" {} resource "aws_subnet" "public" {} resource "aws_instance" "web" {}
Resource Lifecycle
Provider vs Resource
| Provider | Resource |
|---|---|
| Connects Terraform to a platform or service | Defines an infrastructure object to create |
Downloads as a plugin during terraform init | Created during terraform apply |
Example: aws, azurerm, google, docker | Example: aws_instance, aws_s3_bucket, azurerm_virtual_machine |
| Configures authentication and region | Configures the properties of the infrastructure |
Provider + Resource Together
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" } }