Initialize Terraform Configuration
The core Terraform workflow consists of three main steps after you have written your Terraform configuration:
- Initialize prepares the working directory so Terraform can run the configuration.
- Plan enables you to preview any changes before you apply them.
- Apply makes the changes defined by your Terraform configuration to create, update, or destroy resources.
When Terraform initializes your working directory, it configures the backend, installs all providers and modules referred to in the Terraform project, and creates a lock file if it doesn't already exist. In addition, you can use the init
command to upgrade the providers and modules for your project. These steps ensure Terraform uses the correct state, modules, and providers to create, update, or destroy your resources.
In this tutorial, you will initialize a Terraform configuration that uses both local and remote modules, explore the .terraform
directory, and update your provider and module versions. In the process, you will learn more about the init
command's integral role in the Terraform workflow.
Prerequisites
This tutorial assumes that you are familiar with Terraform. If you are new to Terraform itself, refer first to the Get Started tutorials. For this tutorial, you will need:
- the Terraform 0.14+ CLI installed locally.
- Docker.
Clone the example repository
In your terminal, clone the learn-terraform-init
repository.
Navigate to the cloned repository.
Review configuration
This directory contains configuration that uses multiple providers, a local module, and a remote module. You will use these resources to review how Terraform initializes the working directory.
Here, you will find the following files:
the
versions.tf
file defines theterraform
block. In it, therequired_providers
block specifies the provider and provider version required by the configuration.the
main.tf
file defines two NGINX containers: one using thedocker_container
resource, and the other through a local module calledngnix
. The configuration also includes thehello
module, a public module that returns a random pet name.the
nginx
directory contains a Terraform module that defines an NGINX container. It accepts thecontainer_name
andnginx_port
inputs, which configure the container's name and external port number respectively.
Initialize your configuration
Initialize the Terraform configuration.
The output describes the steps Terraform executes when you initialize your configuration.
Terraform downloads the modules referenced in the configuration. It determines that the
hello
module is a remote module, so it downloads it from the public Terraform Registry. It also recognizes that themodule "nginx-pet"
block uses the localnginx
module.Note
When you change a module's source or version, you must re-initialize your Terraform configuration or run
terraform get
to download the new version or from a different source.Terraform initializes the backend. Since the
terraform
block does not include acloud
orbackend
block, Terraform defaults to the local backend.If the
cloud
block is present when you initialize the working directory, Terraform will integrate with Terraform Cloud and create a Terraform Cloud workspace with the name specified in the block if it does not yet exist.Note
When you change a configuration's backend, you must re-initialize your Terraform configuration.
Terraform downloads the providers referenced in the configuration. Since the configuration does not yet have a lock file, Terraform downloads the
docker
andrandom
providers as specified inversions.tf
.By default, Terraform will attempt to download the provider version specified by the lock file (
.terraform.lock.hcl
). If the lock file does not exist, Terraform will use therequired_providers
block to determine the provider version. If neither exists, Terraform will download the latest provider version.Terraform creates a lock file, which records the versions and hashes of the providers used in this run. This ensures consistent Terraform runs in different environments, since Terraform will download the versions recorded in the lock file for future runs by default.
You only need to initialize configuration the first time you use it or if you modify any provider version, module version, or backend. You will do this in the Reinitialize configuration section.
Now that you have installed the providers and modules used by the configuration, Terraform can verify whether your configuration syntax is valid and internally consistent. This includes checking if your resources are missing required fields or have mismatched argument types. You must initialize in order to validate your configuration.
Validate your configuration.
Review initialization artifacts
When Terraform initializes a new Terraform directory, it creates a lock file named .terraform.lock.hcl
and the .terraform
directory.
Explore lock file
The lock file ensures that Terraform uses the same provider versions across your team and in ephemeral remote execution environments. During initialization, Terraform will download the provider versions specified by this file rather than the latest versions.
Open .terraform.lock.hcl
to review its structure and contents.
If the versions defined in the lock file provider
block conflict with the versions defined in the versions.tf
file's required_providers
block, Terraform will prompt you to re-initialize your configuration using the -upgrade
flag. You will do this in the Update provider and module versions section.
Explore the .terraform
directory
Terraform uses the .terraform
directory to store the project's providers and modules. Terraform will refer to these components when you run validate
, plan
, and apply
,
Note
Terraform automatically manages .terraform
. Do not directly modify this directory's contents. Exploring the .terraform
directory is meant to deepen your understanding of how Terraform works, but the contents and structure of this directory are subject to change between Terraform versions.
View the .terraform
directory structure.
Notice that the .terraform
directory contains two sub-directories: modules
and providers
.
The
.terraform/modules
directory contains amodules.json
file and local copies of remote modules.Open
modules.json
. This file shows that the configuration uses three modules: the root module, the remotehello
module, and the localnginx-pet
module.modules.jsonSince the
hello
module is remote, Terraform downloaded the module from its source and saved a local copy in the.terraform/modules/hello
directory during initialization. Open the files in.terraform/modules/hello
to view the module's configuration. These files are intended to be read-only. Like the other contents in.terraform
, do not modify them. Terraform will only update a remote module when you runterraform init -upgrade
.Since the
nginx-pet
module refers to a local module, Terraform refers directly to the module configuration. This means that if you make changes to a local module, Terraform will recognize them immediately.The
.terraform/providers
directory stores cached versions of all of the configuration's providers.View the
.terraform/providers
directory. When you ranterraform init
earlier, Terraform downloaded the providers defined in your configuration from the provider's source (defined by therequired_providers
block) and saved them in their respective directories, defined as[hostname]/[namespace]/[name]/[version]/[os_arch]
.
Update provider and module versions
In versions.tf
, update the random
provider's version to 3.0.1
.
In main.tf
, update the hello
module's version to 3.1.0
.
Reinitialize configuration
Since you updated the provider and module versions, you must re-initialize the configuration for Terraform to install the updated versions.
If you attempt to validate, plan, or apply your configuration before doing so, Terraform will prompt you to re-initialize.
Re-initialize your configuration.
Notice that Terraform downloaded the updated module version and saved it in .terraform/modules/hello
. However, Terraform was unable to update the provider version since the new provider version conflicts with the version found in the lock file.
Re-initialize your configuration with the -upgrade
flag. This tells Terraform to download the new version of the provider, and update the version and signature in the lock file.
View the .terraform/providers
directory structure. Notice that Terraform installed the updated random
provider version.
Open the lock file. Notice that the random
provider now uses version 3.0.1
. Even though there are two versions of the random
provider in .terraform/providers
, Terraform will always use the version recorded in the lock file.
Reconcile configuration
Since you have updated your provider and module version, check whether your configuration is still valid.
The new version of the hello
module expects a new required argument. Add the second_hello
required argument to the hello
module.
Re-validate your configuration.
Now your Terraform project is initialized and ready to be applied.
Next steps
Over the course of this tutorial, you initialized a Terraform configuration with both local and remote modules, explored the .terraform
directory, and updated your provider and module versions. These steps were integral to understanding the mechanisms underlying terraform init
.
For more information on topics covered in this tutorial, check out the following resources.
- Complete the Lock and Upgrade Provider Versions tutorial.
- Complete the Migrate State to Terraform Cloud tutorial.
- Read more about
init
in the documentation.