Terraform 0.13+ locks provider versions per module. After upgrades you see 'no available releases match the given constraints' or behavior drift — resolve the lockfile deliberately, never by deleting state.
version = "~> 3.0" plus a lockfile pinned to 2.x (or vice versa) can't resolve. The lockfile exists so every machine/env uses identical provider builds — commit it, update it explicitly.
aws provider v4→v5 changed attribute semantics (e.g. some deprecated fields removed): plan output diffs everywhere. The upgrade guide per provider is required reading, not optional.
terraform version ; grep -A3 required_providers *.tf ; grep -A5 'provider' .terraform.lock.hcl | head -15
terraform init -upgrade # bumps within constraints and rewrites .terraform.lock.hcl
# version = "~> 5.0" ; terraform init -upgrade ; terraform plan -out=tfplan # read every diff before apply
git add .terraform.lock.hcl ; # CI should run terraform init (no -upgrade) — identical provider builds everywhere
terraform init -upgrade is safe (code/state untouched); terraform apply is where caution lives. Pin major versions in required_providers and let lockfiles handle exact builds: floaty constraints are how teammates end up on different provider behavior.
You can, but you lose reproducibility — every run picks whatever satisfies constraints that day, and provider behavior drift breaks plans. Update the lock (init -upgrade) and commit it instead.
Provider majors often change attribute semantics or defaults. That's the documented upgrade path (guides per major): read them, adjust config, review the plan diff-by-diff before applying.
An opinionated VPC module: per-AZ NAT, explicit dependencies, EKS-ready outputs.
Terraform AWS Foundation — $37 →One-time. Yours to modify. Instant download from the NinjaOps template store.