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.
Cloud Computing
Master Terraform version constraints for Terraform core and providers. Covers operators, lock files, required_version, required_providers, and upgrade...
Pin Terraform core with required_version and providers with required_providers version constraints. Use ~> (pessimistic) for most cases — it allows patch/minor updates while blocking breaking changes. Always commit .terraform.lock.hcl.
terraform {
required_version = ">= 1.5.0, < 2.0.0"
}This ensures anyone running this config has Terraform 1.5+ but not 2.x. If someone runs an incompatible version:
Error: Unsupported Terraform Core version
This configuration does not support Terraform version 1.3.9.terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40" # >= 5.40.0, < 6.0.0
}
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.80, < 4.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.20.0" # >= 5.20.0, < 5.21.0 (patch only)
}
}
}| Operator | Meaning | Example | Allows |
|---|---|---|---|
= 5.40.0 | Exact version | Only 5.40.0 | 5.40.0 |
!= 5.40.0 | Exclude version | Any except 5.40.0 | All but 5.40.0 |
> 5.40 | Greater than | 5.41+ | 5.41.0, 6.0.0, etc. |
>= 5.40 | Greater than or equal | 5.40+ | 5.40.0, 5.41.0, etc. |
< 6.0 | Less than | Below 6.0 | 5.99.99, etc. |
<= 5.40 | Less than or equal | 5.40 and below | 5.40.0, 5.39.0, etc. |
~> 5.40 | Pessimistic (recommended) | >= 5.40.0, < 6.0.0 | 5.40.x, 5.41.x, 5.99.x |
~> 5.40.0 | Pessimistic (patch) | >= 5.40.0, < 5.41.0 | 5.40.0, 5.40.1, 5.40.99 |
# Created by terraform init
# Records EXACT versions + hashes used
terraform init # Creates lock file
terraform init -upgrade # Upgrades within constraints# .terraform.lock.hcl (auto-generated — don't edit manually)
provider "registry.terraform.io/hashicorp/aws" {
version = "5.40.0"
constraints = "~> 5.40"
hashes = [
"h1:abc123...",
]
}Always commit .terraform.lock.hcl to git — it ensures everyone uses the exact same provider version.
# Root module — pin tightly
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40" # Narrow range
}
}
}
# Child module — use loose minimum
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0" # Wide range — let root module decide
}
}
}terraform version
terraform providers# Bump the constraint
aws = {
source = "hashicorp/aws"
version = "~> 5.50" # Was ~> 5.40
}terraform init -upgrade
terraform plan # Review changes — new provider versions may change behaviorterraform plan # Check for unexpected changes
terraform apply # Apply in non-production first| Problem | Solution |
|---|---|
| "No matching version" | Broaden constraints or check registry |
| "Inconsistent dependency lock file" | Run terraform init -upgrade |
| Provider version conflict between modules | Use compatible ranges |
| Wrong Terraform core version | Install correct version with tfenv |
~> for most constraints — allows safe updates, blocks breaking changesVersion constraints protect your infrastructure from unexpected breaking changes. Use ~> for providers, >= for modules, and always commit the lock file. Upgrade deliberately — one provider at a time, in non-production first.
Learn how to use Terraform data sources to query existing resources, look up AMIs, reference remote state, and build dynamic configurations. Complete.
Learn how to use Terraform count and for_each to create multiple resources. Side-by-side comparison, practical examples, conditional creation
Complete guide to Terraform lifecycle rules. Learn prevent_destroy, create_before_destroy, ignore_changes
Master multi-account AWS management with Terraform. Learn provider aliases, cross-account IAM roles, AWS Organizations integration, and production-ready.