linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/kb/Terraform basics/tf-init

kb/core ── Terraform basics ── beginner

terraform init: the first command in any project

terraform init downloads the provider plugins (AWS, GCP, and so on), creates a lockfile that pins their versions, and prepares the working directory. Without it, neither plan nor apply will run.

view as markdown

What terraform init does

When you write provider "aws" { ... } in a file, Terraform cannot talk to AWS on its own. It needs a provider plugin, a separate program that knows how to speak to the AWS API.

terraform init does three things:

  1. Reads the required_providers block in your code and checks which plugins are needed.
  2. Downloads them from the Terraform Registry into a .terraform/ folder next to your code.
  3. Creates a .terraform.lock.hcl file that pins the exact versions of the downloaded plugins along with their hashes. See tf-lockfile.

After init the directory is ready, and you can run plan and apply.

When to run it

You need to run init the first time after git clone of someone else's repository, or after creating a new project. Run it again if:

  • required_providers changed in the code (a different provider or a different version).
  • A backend block was added or changed (where state is stored, see tf-init-backends).
  • A new module "..." block appeared.

If none of these changed, you do not need to run init again.

What shows up in the directory

After the first init:

your-project/
├── main.tf                      # your code
├── .terraform/                  # appeared after init
│   └── providers/
│       └── registry.terraform.io/
│           └── hashicorp/
│               └── aws/
│                   └── 5.60.0/
│                       └── linux_amd64/
│                           └── terraform-provider-aws_v5.60.0_x5
└── .terraform.lock.hcl          # also appeared

Important:

  • .terraform/ is a cache. Add it to .gitignore and do not commit it.
  • .terraform.lock.hcl is the opposite: always commit it. It guarantees that your teammates download the same provider versions.

Useful flags

  • terraform init -upgrade updates providers to the latest versions within the version constraint. If the code says version = "~> 5.0", then -upgrade moves you from 5.50 to 5.60, but not to 6.x.
  • terraform init -reconfigure reinitializes from scratch. You need it when you have changed the backend settings and Terraform asks whether to migrate state.
  • terraform init -input=false skips interactive questions. This is the mode for CI/CD.

Pitfalls

  • init does not work offline. Plugins are downloaded from registry.terraform.io. Corporate networks sometimes set up a mirror through terraform { provider_installation { ... } } in ~/.terraformrc, see tf-cli-config.
  • Corporate proxy. If your backend is in the office and the internet is reachable only through a proxy, you need to set the HTTPS_PROXY and HTTP_PROXY variables before running.
  • The lockfile blocks the upgrade. If init complains "requested version is not the locked version", it means the lockfile holds one version while you want another. The fix is either init -upgrade or an explicit change to the constraint.
  • The cache in .terraform/ depends on the OS. If a teammate works on macOS and you work on Linux, you cannot just copy .terraform/ over; each person runs init locally.

What is inside .terraform.lock.hcl

A small file that looks roughly like this:

hcl
provider "registry.terraform.io/hashicorp/aws" {
  version     = "5.60.0"
  constraints = "~> 5.60"
  hashes = [
    "h1:abc123...",
    "h1:def456...",
  ]
}

This is what makes runs reproducible: the next init installs exactly version 5.60.0 with exactly these hashes. If the hashes do not match, init fails. This protects you against tampered packages.

§ команды

bash
terraform init

Basic initialization: download providers, create the lockfile.

bash
terraform init -upgrade

Update providers within the version constraint.

bash
terraform init -reconfigure

Reinitialize after changing the backend, without migrating state.

bash
TF_LOG=DEBUG terraform init

When init hangs or complains: read the detailed log to see what is being pulled and from where.

§ см. также

  • hcl-syntaxHCL: the language you write Terraform inHCL (HashiCorp Configuration Language) is the language you use to describe the desired state of your infrastructure. It looks like JSON, but it is easier to read: you can write comments, variables, and loops.
  • tf-planterraform plan: see what Terraform is about to doplan is a dry run: Terraform reads your HCL, reads the state, and shows the diff between them. It changes nothing in the cloud. This is your main tool for not breaking prod by mistake.
  • tf-lockfile.terraform.lock.hcl: pinning provider versionsThe lockfile pins the exact provider versions and their hashes, so you and CI always run the same build. It is created on terraform init and updated through init -upgrade. Commit it to git.
  • tf-version-constraintsVersion constraints in Terraform: required_version and providersrequired_version pins which versions of terraform may run this code. required_providers.version does the same for providers. The pessimistic operator ~> 5.60 is the standard: it allows minor updates and blocks major ones.
  • tf-init-backendsBackends in Terraform: where state livesA backend is where the state file is stored. The default is local, next to your HCL. Remote backends (S3, GCS, Terraform Cloud, http) give you shared access and locking. This course uses only local; remote is covered as an overview.
  • aws-providerAWS provider: configuration and where Terraform finds your keysThe AWS provider looks for credentials in several places in order: env variables, ~/.aws/credentials, the instance IAM role. Usually `aws configure` locally or a role on EC2 is enough, and you configure nothing else.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies