Every configuration starts with init, and unpinned providers are a classic source of surprise breakage.
A provider is a plugin that knows one API. You declare which ones you need in a terraform block:
sourceis the registry address, likehashicorp/aws(short forregistry.terraform.io/hashicorp/aws).versionis a constraint:~> 6.0means at least 6.0 and below 7.0;~> 6.2.1means at least 6.2.1 and below 6.3.0;>= 1.2, < 2.0is explicit.required_versionconstrains the Terraform CLI itself.
terraform init prepares the directory: it downloads providers into .terraform/, downloads modules, configures the backend, and writes `.terraform.lock.hcl`, which records the exact provider versions and their checksums. Commit the lock file so everyone and CI use identical providers; run terraform init -upgrade to move to newer versions within the constraints deliberately.
A provider block configures it: region, credentials (better from the environment, such as AWS_PROFILE or OIDC in CI, than in code), default tags. Several configurations of one provider use alias, for example two AWS regions, and resources select one with provider = aws.us.
Rerun init whenever you add a provider, a module or change the backend; plan will tell you if you forgot.
Example
terraform {
required_version = ">= 1.10"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 6.0" }
random = { source = "hashicorp/random", version = "~> 3.7" }
}
}
provider "aws" {
region = "eu-west-1"
default_tags { tags = { team = "platform", managed_by = "terraform" } }
}
provider "aws" {
alias = "us"
region = "us-east-1" # e.g. for CloudFront certificates
}
# terraform init
# - Installing hashicorp/aws v6.x.y...
# Terraform has created a lock file .terraform.lock.hclRemember
- required_providers + version constraints; ~> allows the last component to grow
- init downloads providers and writes .terraform.lock.hcl: commit it
- Use alias for multiple configurations of one provider
Watch out for
- Not committing .terraform.lock.hcl, so CI silently picks a newer provider than you tested.