What this command does in detail
- Downloads the provider. Reads versions.tf's required_providers block, and downloads the matching azurerm provider plugin into a local .terraform/ folder.
- Locks the provider version. Writes (or checks, if it already exists) .terraform.lock.hcl, recording the exact provider version and checksums downloaded, so every future run uses the identical version.
- Configures the backend. Reads backend.tf and connects to the configured remote state location, so later commands know where to read and write state.
Init does not read or evaluate any resource blocks, and it does not contact Azure's resource APIs at all — it only needs to reach the Terraform provider registry and, if a backend is configured, the state storage account.
Where to run it from working directory
Run it from inside the folder containing the .tf files you want to work with. This project has two separate root modules, and each needs its own independent init:
terraform -chdir=terraform init terraform -chdir=terraform/bootstrap init
-chdir=<path> tells Terraform to run as if you'd cd'd into that folder first, without actually changing your shell's working directory — useful from a repository root, and the pattern this project's README and GitHub Actions workflow use throughout.
Precondition what must already be true
- Terraform CLI is installed, at a version satisfying versions.tf's required_version (1.7 or later, below 2.0).
- Network access to registry.terraform.io (or an internal mirror) to download the provider.
- If initializing with a real backend: the state storage account and container already exist — created once by bootstrap/main.tf — and you're authenticated (az login) as an identity with the Storage Blob Data Contributor role on that container.
- For offline / structural checks only, that last requirement can be skipped entirely with -backend=false.
Postcondition what becomes true after it succeeds
- A local .terraform/ folder exists, containing the downloaded provider plugin.
- .terraform.lock.hcl is present and up to date — commit this file to Git so everyone uses the same provider version.
- If a backend was configured, Terraform is connected to it: later commands (plan, apply, output) will read and write state there instead of a local file.
- No Azure resources have been created, changed, or inspected yet.
How this project uses it real examples
terraform -chdir=terraform init -backend-config backend.hcl
Uses the partial-configuration file described on the backend.tf page to supply the storage account, container, and state file name.
terraform -chdir=terraform init -input=false -lockfile=readonly \ -backend-config="storage_account_name=$TF_STATE_STORAGE_ACCOUNT" \ -backend-config="container_name=tfstate" \ -backend-config="key=metals.tfstate"
-input=false stops Terraform from pausing for interactive prompts in a non-interactive CI job. -lockfile=readonly uses the committed .terraform.lock.hcl exactly as-is, without letting the workflow silently upgrade provider versions on its own.
terraform -chdir=terraform init -backend=false -input=false -lockfile=readonly
Downloads the provider so terraform validate and terraform test can run, without ever touching the real state backend — used by this project's CI checks on every push and pull request.
terraform -chdir=terraform init -migrate-state -backend-config backend.hcl
Used only when someone previously ran Terraform locally (with local state) and needs to copy that state into the new shared backend, instead of starting from an empty remote state against already-existing resources.
Common errors and how to fix them
| What you see | Likely cause | How to fix it |
|---|---|---|
| “Backend configuration changed” | The backend settings on disk (in .terraform/) don't match what you just supplied. | Re-run with -reconfigure to discard the old settings, or -migrate-state if you actually want to move existing state. |
| Authorization / 403 error reaching the storage account | Your Azure identity doesn't have the Storage Blob Data Contributor role on the tfstate container. | Run az login with the correct account, and confirm the role assignment from bootstrap/main.tf was actually applied. |
| Storage account or container not found | Bootstrap hasn't been run yet, or the storage account name in backend.hcl / -backend-config is wrong. | Run bootstrap/main.tf first, then copy its TF_STATE_STORAGE_ACCOUNT output exactly. |
| “Failed to install provider” | No network access to the provider registry, or a corporate proxy/firewall is blocking it. | Check your internet connection; if behind a proxy, configure Terraform's provider installation settings accordingly. |
| “Unsupported Terraform Core version” | The installed terraform CLI doesn't satisfy versions.tf's required_version. | Install a Terraform CLI version between 1.7 and 2.0 (this project's workflows use 1.16.0). |