DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Terraform Tutorial

Introduction to Terraform
Installing Terraform
The Terraform Core Workflow
Terraform Variables and Outputs
Terraform State and Backends
Terraform Modules
Terraform Data Sources
Terraform Count and for_each
Terraform Expressions and Functions
Terraform Dynamic Blocks
Terraform Workspaces
Terraform with AWS
Terraform Provisioners
Terraform CI/CD Pipeline
Terraform Security

terraform init

PreviousPrev
Next

Learn exactly what terraform init does, downloading providers, setting up backends, creating the lock file, and how to use init flags like -upgrade and -reconfigure.

What Is terraform init?

terraform init is the very first command you run in any Terraform project. It prepares your working directory so that every other Terraform command (plan, apply, destroy) can work correctly.

Think of it like npm install or pip install, it sets up the dependencies your project needs before you can do anything else.

terraform init

What terraform init Does Internally

When you run terraform init, Terraform does three things:

1. Downloads Provider Plugins

Terraform reads the required_providers block in your configuration and downloads the declared providers from the Terraform Registry (or a private registry):

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "3.6.0"
    }
  }
}

Running init on this configuration downloads both the AWS and Random providers into .terraform/providers/. This directory can be hundreds of megabytes, always add it to .gitignore.

Sample output:

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Finding hashicorp/random versions matching "3.6.0"...
- Installing hashicorp/aws v5.54.1...
- Installing hashicorp/random v3.6.0...

Terraform has been successfully initialized!

2. Sets Up the Backend

If you have a backend block configured, init connects to it and migrates state if needed:

terraform {
  backend "s3" {
    bucket = "my-tfstate-bucket"
    key    = "production/terraform.tfstate"
    region = "us-east-1"
  }
}

When switching from local state to a remote backend, init asks:

Do you want to copy existing state to the new backend?
  yes/no:

3. Creates the Lock File

terraform init writes .terraform.lock.hcl, a file that pins the exact provider versions downloaded:

# .terraform.lock.hcl (auto-generated)
provider "registry.terraform.io/hashicorp/aws" {
  version     = "5.54.1"
  constraints = "~> 5.0"
  hashes = [
    "h1:abc123...",
  ]
}

Always commit .terraform.lock.hcl to Git. It ensures every team member and every CI/CD pipeline uses exactly the same provider versions, preventing "works on my machine" failures caused by version drift.

The .terraform Directory

After init, your project will have:

my-project/
├── main.tf
├── variables.tf
├── .terraform/                    # ← created by init, add to .gitignore
│   ├── providers/
│   │   └── registry.terraform.io/
│   │       └── hashicorp/
│   │           └── aws/5.54.1/    # downloaded provider binary
│   └── terraform.tfstate          # backend config cache
└── .terraform.lock.hcl            # ← commit this to Git

Common init Flags

-upgrade

Re-download all providers, selecting the newest version that satisfies your constraints:

terraform init -upgrade

Use this when you want to update providers to the latest allowed version. Without -upgrade, init uses the versions already in the lock file.

Warning: Always run terraform plan after -upgrade to check for breaking changes in the new provider version.

-reconfigure

Force init to reconfigure the backend without migrating state:

terraform init -reconfigure

Useful when you have changed your backend configuration and want to switch without copying existing state.

-backend=false

Skip backend initialisation entirely:

terraform init -backend=false

Useful in CI pipelines where you only want to validate the configuration without connecting to a remote backend.

-backend-config

Pass backend configuration values at init time instead of hardcoding them in the backend block, great for keeping bucket names or credentials out of source code:

terraform init \
  -backend-config="bucket=my-tfstate-bucket" \
  -backend-config="key=production/terraform.tfstate" \
  -backend-config="region=us-east-1"

When to Re-run init

You must re-run terraform init whenever you:

ChangeWhy
Add or remove a required_providers entryNew provider needs to be downloaded
Change provider version constraintsDifferent version needs to be installed
Change the backend blockBackend connection must be re-established
Clone a repo for the first timeProviders are not committed to Git
Add or update a module sourceModule code needs to be downloaded

It is always safe to re-run init, it never modifies your infrastructure.

init in CI/CD Pipelines

In a CI/CD pipeline, always run init before plan or apply. Use the -input=false flag to prevent interactive prompts:

# GitLab CI example
terraform-plan:
  script:
    - terraform init -input=false
    - terraform plan -out=tfplan

Knowledge Check

Exercise

Question 1: Lock File Purpose

After running terraform init, you see a .terraform.lock.hcl file. A teammate asks if they should commit it. What do you tell them?

Exercise

Question 2: When to Re-run init

You add a new provider to required_providers in your main.tf. You run terraform plan immediately. What happens?

Exercise

Question 3: terraform init -upgrade

Your lock file pins AWS provider at v5.0.0. A new version v5.54.1 is available. You want to update. What command do you run?

PreviousPrev
Next

Continue Learning

Introduction to Terraform

Learn what Terraform is, how Infrastructure as Code works, why it beats clicking through cloud consoles, and how Terraform compares to Ansible, CloudFormation and Pulumi.

12 min read·Easy

Installing Terraform

Step-by-step guide to installing Terraform on macOS, Linux and Windows using the official HashiCorp package managers. Verify the install and run your first real Terraform configuration.

10 min read·Easy

The Terraform Core Workflow

The four commands that power every Terraform project, init, plan, apply, and destroy. Learn the complete workflow loop used by every DevOps engineer managing infrastructure as code.

5 min read·Easy

Explore Related Topics

AW

AWS Tutorials

Provision AWS infrastructure with Terraform

CI

CI/CD Tutorials

Run terraform plan/apply in CI pipelines

Try the Tool

YAML Validator

Validate Terraform and Kubernetes YAML configs before applying.

On This Page

What Is terraform init?What terraform init Does Internally1. Downloads Provider Plugins2. Sets Up the Backend3. Creates the Lock FileThe .terraform DirectoryCommon init Flags-upgrade-reconfigure-backend=false-backend-configWhen to Re-run initinit in CI/CD PipelinesKnowledge Check