terraform initPrepare a Terraform working directory
terraform init gets a directory of .tf files ready to run: it connects the state backend, downloads modules and provider plugins, and records exact provider versions in .terraform.lock.hcl. Run it first, and again whenever providers, modules or the backend change. It never touches your infrastructure.
terraform init [-upgrade] [-reconfigure | -migrate-state] [-backend-config=FILE|KEY=VALUE] [-input=false]You've cloned the infra repo and want to run a plan for the dev environment. Nothing works until the directory is initialised.
terraformThe Terraform CLI, a single Go binary. Providers are separate plugin binaries it downloads.
init reads every .tf file in the current directory (the root module) and looks at the terraform block. Backend: it configures where state lives (local file, or S3 with locking, Terraform Cloud...) and saves that choice in .terraform/terraform.tfstate; if the backend changed it asks to migrate state. Modules: for every module block it fetches the source (registry, Git, S3, or just records a local path) into .terraform/modules. Providers: for each required_providers entry it asks the registry (registry.terraform.io) which versions exist, picks the newest that satisfies the constraint, or the one already in .terraform.lock.hcl, downloads the zip for your OS and CPU, verifies its checksum and signature, and unpacks it under .terraform/providers/. It then writes the chosen versions and their hashes to the lock file. Nothing is planned or changed in the cloud, so init is always safe to re-run.
-upgradeRe-resolve providers and modules to the newest allowed versions-reconfigureUse the new backend config and ignore the old (no migration)-migrate-stateCopy existing state into a changed backend-backend-config=…Backend settings from a file or KEY=VALUE (partial config)-backend=falseSkip backend setup (e.g. for validate in CI)-input=falseDon't prompt; fail if input is needed-lockfile=readonlyFail instead of changing .terraform.lock.hcl-plugin-dir=PATHUse providers from a local directory (air-gapped)Committing the .terraform/ directoryIt holds hundreds of MB of platform-specific plugin binaries and backend details.
Commit .terraform.lock.hcl; add .terraform/ to .gitignoreNot committing .terraform.lock.hclEach machine resolves its own provider versions; a new minor release can change plans in CI but not on your laptop.
Commit the lock file; change versions deliberately with terraform init -upgradeAnswering 'no' to the state migration promptThe new backend starts empty, so the next apply tries to create resources that already exist (or you lose track of them).
Answer yes, then verify with terraform state listHard-coding the prod bucket and key in the backend block shared by all environmentsBackend blocks can't use variables; one typo and dev writes prod's state.
Partial config: terraform init -backend-config=env/prod.s3.tfbackendTry these on a Linux machine of your own. Each task has a hint and a solution.
In ~/infra, initialise the way a CI job would: no prompts, with the S3 backend settings from env/staging.s3.tfbackend. (Rename backend.tf.example to backend.tf first, so there is an s3 backend to configure.)
Write the .gitignore lines a Terraform repo needs, and save them in ~/app/.gitignore.
Read this output line and explain it: '- Using previously-installed hashicorp/aws v6.71.0'
terraform initPrepare a Terraform working directory
terraform init gets a directory of .tf files ready to run: it connects the state backend, downloads modules and provider plugins, and records exact provider versions in .terraform.lock.hcl. Run it first, and again whenever providers, modules or the backend change. It never touches your infrastructure.
terraform init [-upgrade] [-reconfigure | -migrate-state] [-backend-config=FILE|KEY=VALUE] [-input=false]You've cloned the infra repo and want to run a plan for the dev environment. Nothing works until the directory is initialised.
terraformThe Terraform CLI, a single Go binary. Providers are separate plugin binaries it downloads.
init reads every .tf file in the current directory (the root module) and looks at the terraform block. Backend: it configures where state lives (local file, or S3 with locking, Terraform Cloud...) and saves that choice in .terraform/terraform.tfstate; if the backend changed it asks to migrate state. Modules: for every module block it fetches the source (registry, Git, S3, or just records a local path) into .terraform/modules. Providers: for each required_providers entry it asks the registry (registry.terraform.io) which versions exist, picks the newest that satisfies the constraint, or the one already in .terraform.lock.hcl, downloads the zip for your OS and CPU, verifies its checksum and signature, and unpacks it under .terraform/providers/. It then writes the chosen versions and their hashes to the lock file. Nothing is planned or changed in the cloud, so init is always safe to re-run.
-upgradeRe-resolve providers and modules to the newest allowed versions-reconfigureUse the new backend config and ignore the old (no migration)-migrate-stateCopy existing state into a changed backend-backend-config=…Backend settings from a file or KEY=VALUE (partial config)-backend=falseSkip backend setup (e.g. for validate in CI)-input=falseDon't prompt; fail if input is needed-lockfile=readonlyFail instead of changing .terraform.lock.hcl-plugin-dir=PATHUse providers from a local directory (air-gapped)Committing the .terraform/ directoryIt holds hundreds of MB of platform-specific plugin binaries and backend details.
Commit .terraform.lock.hcl; add .terraform/ to .gitignoreNot committing .terraform.lock.hclEach machine resolves its own provider versions; a new minor release can change plans in CI but not on your laptop.
Commit the lock file; change versions deliberately with terraform init -upgradeAnswering 'no' to the state migration promptThe new backend starts empty, so the next apply tries to create resources that already exist (or you lose track of them).
Answer yes, then verify with terraform state listHard-coding the prod bucket and key in the backend block shared by all environmentsBackend blocks can't use variables; one typo and dev writes prod's state.
Partial config: terraform init -backend-config=env/prod.s3.tfbackendTry these on a Linux machine of your own. Each task has a hint and a solution.
In ~/infra, initialise the way a CI job would: no prompts, with the S3 backend settings from env/staging.s3.tfbackend. (Rename backend.tf.example to backend.tf first, so there is an s3 backend to configure.)
Write the .gitignore lines a Terraform repo needs, and save them in ~/app/.gitignore.
Read this output line and explain it: '- Using previously-installed hashicorp/aws v6.71.0'