Terraform Providers Connecting to Cloud Platforms
Terraform itself does not know how to create an AWS server or an Azure database. It relies on plugins called providers to do that work. This topic explains what providers are, how they work, where they come from, and how to configure them correctly.
What Is a Provider
A provider is a plugin that teaches Terraform how to communicate with a specific service or platform. Each provider contains the code needed to talk to a service's API.
Analogy: The Universal Remote Control
Imagine Terraform as a universal remote control. On its own, the remote does nothing. You insert a module (provider) for your TV, and now the remote controls your TV. Insert a different module for your air conditioner, and now it controls that too. Providers are those modules.
Diagram: Provider Role
Your .tf files
|
v
[ Terraform Core ]
|
|---> [ AWS Provider ] ---> AWS API ---> EC2, S3, RDS...
|---> [ Azure Provider ] --> Azure API --> VMs, Blobs...
|---> [ GitHub Provider ] -> GitHub API -> Repos, Teams...
|---> [ Cloudflare Provider ] -> Cloudflare API -> DNS, CDN...
Where Providers Come From
Providers are published on the Terraform Registry at registry.terraform.io. The registry has three tiers:
| Tier | Who Maintains It | Example |
|---|---|---|
| Official | HashiCorp | hashicorp/aws, hashicorp/azurerm |
| Partner | Technology partners (verified) | datadog/datadog, mongodb/mongodbatlas |
| Community | Individual contributors | Various open-source providers |
When you run terraform init, Terraform downloads the provider plugins you declared and stores them in the .terraform folder.
Declaring a Provider
You declare providers in a terraform block and configure them in a provider block.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
Understanding Version Constraints
The version argument controls which provider version Terraform downloads. Version constraints follow standard rules:
| Constraint | Meaning |
|---|---|
= 5.0.0 | Exactly version 5.0.0 only |
>= 5.0 | Version 5.0 or newer |
~> 5.0 | Any version from 5.0 up to but not including 6.0 (patch updates only) |
~> 5.31 | Any version from 5.31 up to but not including 5.32 |
The ~> (tilde-greater-than) operator is called the pessimistic constraint operator. Most teams use it because it allows bug fixes but prevents breaking changes from a major version upgrade.
Provider Authentication
Every provider needs credentials to talk to its service. Terraform never stores passwords directly in your .tf files — that would be a serious security risk. Instead, providers read credentials from safe locations.
AWS Authentication Options
- Environment variables: Set
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYbefore running Terraform - AWS credentials file: Stored at
~/.aws/credentialson your machine - IAM roles: Automatically used when running Terraform on an EC2 instance or in a CI/CD pipeline with an attached role
Example: Setting AWS Credentials via Environment Variables
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE" export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" export AWS_DEFAULT_REGION="us-east-1"
With these environment variables set, the AWS provider automatically picks them up — no credentials in your code.
Configuring Multiple Providers
A single Terraform project can use multiple providers at once. You might deploy servers on AWS while managing DNS on Cloudflare.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
Provider Aliases for Multiple Regions
Sometimes you need to create resources in two different regions using the same provider. Use the alias argument to create two instances of the same provider.
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "west"
region = "us-west-2"
}
resource "aws_instance" "east_server" {
# uses the default aws provider (us-east-1)
ami = "ami-0abc123"
instance_type = "t3.micro"
}
resource "aws_instance" "west_server" {
provider = aws.west # explicitly uses the west alias
ami = "ami-0xyz789"
instance_type = "t3.micro"
}
Key Points
- A provider is a plugin that enables Terraform to communicate with a specific service's API.
- Declare providers in the
required_providersblock with a source and version constraint. - Use
~>version constraints to allow safe patch-level updates without breaking changes. - Never hard-code credentials in
.tffiles — use environment variables, credentials files, or IAM roles. - Use provider aliases to manage resources across multiple regions or accounts with the same provider.
