Using Terraform Data Sources Effectively
Learn how to use Terraform data sources to query existing resources, look up AMIs, reference remote state, and build dynamic configurations. Complete.
DevOps
Complete guide to Terraform providers — what they are, how to configure them, version constraints, multiple provider instances, and the official registry. With real examples for AWS, Azure, and GCP.
A Terraform provider is a plugin that lets Terraform interact with a specific API — cloud platforms, SaaS services, databases, DNS, or any system with an API. Providers translate your HCL configuration into API calls.
# This block tells Terraform: "I need to talk to AWS"
provider "aws" {
region = "us-east-1"
}Without providers, Terraform can't do anything. They're the bridge between your .tf files and the real world.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your .tf │────▶│ Terraform │────▶│ Provider │────▶ API
│ files │ │ Core │ │ Plugin │
└──────────────┘ └──────────────┘ └──────────────┘resource "aws_instance" "web" {...}Since Terraform 0.13+, declare providers in the required_providers block:
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
google = {
source = "hashicorp/google"
version = "~> 6.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}<NAMESPACE>/<TYPE>hashicorp/aws — HashiCorp's official AWS providerintegrations/github — GitHub's official providerdigitalocean/digitalocean — DigitalOcean's providerFull address: registry.terraform.io/hashicorp/aws
| Constraint | Meaning | Example |
|---|---|---|
= 5.50.0 | Exact version only | Pin to specific release |
>= 5.0 | Minimum version | At least 5.0 |
~> 5.0 | Pessimistic (>=5.0, <6.0) | Recommended — allows minor/patch updates |
~> 5.50.0 | Pessimistic patch only (>=5.50.0, <5.51.0) | Very conservative |
>= 5.0, < 6.0 | Range | Explicit bounds |
Use ~> (pessimistic constraint) for stability:
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # Allows 5.x.x but not 6.0
}provider "aws" {
region = "eu-west-1"
profile = "production" # Uses ~/.aws/credentials profile
# Optional: assume a role
assume_role {
role_arn = "arn:aws:iam::123456789012:role/TerraformRole"
session_name = "terraform-deploy"
}
}provider "azurerm" {
features {}
subscription_id = var.subscription_id
tenant_id = var.tenant_id
}provider "google" {
project = "my-project-id"
region = "europe-west4"
}Deploy to multiple regions or accounts using provider aliases:
# Default provider (us-east-1)
provider "aws" {
region = "us-east-1"
}
# Second provider for EU region
provider "aws" {
alias = "eu"
region = "eu-west-1"
}
# Use the alias in resources
resource "aws_instance" "us_server" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
# Uses default provider (us-east-1)
}
resource "aws_instance" "eu_server" {
provider = aws.eu # Uses the EU alias
ami = "ami-0europe1234567890"
instance_type = "t3.micro"
}provider "aws" {
alias = "production"
region = "us-east-1"
profile = "prod-account"
}
provider "aws" {
alias = "staging"
region = "us-east-1"
profile = "staging-account"
}The Terraform Registry hosts 4,000+ providers. Key categories:
| Provider | Use Case |
|---|---|
hashicorp/aws | Amazon Web Services |
hashicorp/azurerm | Microsoft Azure |
hashicorp/google | Google Cloud |
hashicorp/kubernetes | Kubernetes clusters |
hashicorp/helm | Helm chart deployments |
hashicorp/vault | HashiCorp Vault secrets |
hashicorp/consul | Consul service mesh |
| Provider | Use Case |
|---|---|
digitalocean/digitalocean | DigitalOcean cloud |
integrations/github | GitHub repos/teams |
cloudflare/cloudflare | Cloudflare DNS/CDN |
datadog/datadog | Datadog monitoring |
PagerDuty/pagerduty | PagerDuty alerts |
| Provider | Use Case |
|---|---|
bpg/proxmox | Proxmox VE VMs |
kreuzwerker/docker | Local Docker containers |
phillbaker/elasticsearch | Elasticsearch clusters |
After terraform init, Terraform creates .terraform.lock.hcl:
provider "registry.terraform.io/hashicorp/aws" {
version = "5.82.2"
constraints = "~> 5.0"
hashes = [
"h1:abcdef123456...",
"zh:1234567890ab...",
]
}Always commit this file to version control. It ensures your team uses identical provider versions.
# Update all providers to latest allowed version
terraform init -upgrade
# Update specific provider
terraform init -upgrade -target=hashicorp/awsError: Failed to query available provider packages
Could not retrieve the list of available versions for provider hashicorp/awsFix: Check internet connectivity or configure a provider mirror:
provider_installation {
network_mirror {
url = "https://terraform-mirror.example.com/"
}
}Error: Inconsistent dependency lock fileFix: Run terraform init -upgrade to update the lock file, then commit it.
Usually a provider bug. Workarounds:
terraform apply again (often self-heals)# Clear cached plugins and re-download
rm -rf .terraform
terraform initNever hardcode credentials in .tf files:
# ❌ BAD — credentials in code
provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
# ✅ GOOD — use environment variables
# export AWS_ACCESS_KEY_ID="..."
# export AWS_SECRET_ACCESS_KEY="..."
provider "aws" {
region = "us-east-1"
}For CI/CD pipelines, use:
# Show providers required by current config
terraform providers
# Show provider versions in lock file
terraform versionProviders are what make Terraform powerful — they connect your HCL code to 4,000+ services. Use version constraints (~>) for stability, commit your .terraform.lock.hcl file, never hardcode credentials, and use provider aliases when deploying across regions or accounts.
Learn how to use Terraform data sources to query existing resources, look up AMIs, reference remote state, and build dynamic configurations. Complete.
Compare Terraform and OpenTofu side by side. Understand licensing, features, compatibility, and which IaC tool is right for your organization.
Master Terraform version constraints for Terraform core and providers. Covers operators, lock files, required_version, required_providers, and upgrade...
Learn how to use Terraform count and for_each to create multiple resources. Side-by-side comparison, practical examples, conditional creation