Terraform Init Command
Tags: terraform, azure
Published: 2022-08-16 20:44:00

This is Part-03 of **Developer's Guide to Terraform** in this section we are going to discuss about the Terraform Commands.

As we know that terraform is command line tool like git, Kubernetes, this means that terraform also gets operated with its command line like we operate git or Kubernetes with command line.

Terraform also offers various commands which you can use... to know the list of command name you can use terraform help command

```terraform 
🦄  terraform -h
Usage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure

All other commands:
  console       Try Terraform expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote Terraform modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a Terraform resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Experimental support for module integration testing
  untaint       Remove the 'tainted' state from a resource instance
  version       Show the current Terraform version
  workspace     Workspace management

Global options (use these before the subcommand, if any):
  -chdir=DIR    Switch to a different working directory before executing the
                given subcommand.
  -help         Show this help output, or the help for a specified subcommand.
  -version      An alias for the "version" subcommand.
```

With above result you can see that terraform has various commands which you can use to manage your infrastructure but to begin with terraform to automate your infrastructure you may not need to know all of these, in this blog we will discuss what all commands you need to know to provision Infrastructure with terraform.

## Terraform Init
The terraform init command is used to initialize a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. It is safe to run this command multiple times.

_**Usage**_

`terraform init [options]`

```terraform 
🦄  terraform init -h
Options:

  -backend=false          Disable backend or Terraform Cloud initialization for
                          this configuration and use what what was previously
                          initialized instead.

                          aliases: -cloud=false

  -backend-config=path    Configuration to be merged with what is in the
                          configuration file's 'backend' block. This can be
                          either a path to an HCL file with key/value
                          assignments (same format as terraform.tfvars) or a
                          'key=value' format, and can be specified multiple
                          times. The backend type must be in the configuration
                          itself.

  -force-copy             Suppress prompts about copying state data when
                          initializating a new state backend. This is
                          equivalent to providing a "yes" to all confirmation
                          prompts.

  -from-module=SOURCE     Copy the contents of the given module into the target
                          directory before initialization.

  -get=false              Disable downloading modules for this configuration.

  -input=false            Disable interactive prompts. Note that some actions may
                          require interactive prompts and will error if input is
                          disabled.

  -lock=false             Don't hold a state lock during backend migration.
                          This is dangerous if others might concurrently run
                          commands against the same workspace.

  -lock-timeout=0s        Duration to retry a state lock.

  -no-color               If specified, output won't contain any color.

  -plugin-dir             Directory containing plugin binaries. This overrides all
                          default search paths for plugins, and prevents the
                          automatic installation of plugins. This flag can be used
                          multiple times.

  -reconfigure            Reconfigure a backend, ignoring any saved
                          configuration.

  -migrate-state          Reconfigure a backend, and attempt to migrate any
                          existing state.

  -upgrade                Install the latest module and provider versions
                          allowed within configured constraints, overriding the
                          default behavior of selecting exactly the version
                          recorded in the dependency lockfile.

  -lockfile=MODE          Set a dependency lockfile mode.
                          Currently only "readonly" is valid.

  -ignore-remote-version  A rare option used for Terraform Cloud and the remote backend
                          only. Set this to ignore checking that the local and remote
                          Terraform versions use compatible state representations, making
                          an operation proceed even when there is a potential mismatch.
                          See the documentation on configuring Terraform with
                          Terraform Cloud for more information.
```

Let's look at various parameter option with terraform init command

## 1. Terraform init with backend
If you have terraform provider block with empty backend blocked specified like this

```terraform 
terraform {
  required_providers {
    azurerm = {
      version = "~> 2.88.1"
      source = "hashicorp/azurerm"
    }
  }
  backend "azurerm" {
  }
}
```
Then you need to specify the backend at the time of initialization of terraform from terraform init command, to do that you can run terraform init with backend-config option

```terraform 
terraform init -backend-config=storage_account_name=tfstatefile01 -backend-config=container_name=tfstate -backend-config=key=dev-network.terraform.tstate -backend-config=resource_group_name=DefaultResourceGroup-EUS -backend-config=subscription_id=2a04288a-8136-4880-b526-c6070e59f004 -backend-config=tenant_id=37d20c78-05e3-416d-83ab-cdbc21fed22a -backend-config=client_id=*** -backend-config=client_secret=***
```
As you can see terraform backend-config parameter multiple times.

Here with terraform init we are specifying following terraform backend configuration

- azure backend storage account name
- azure backend storage account resource group name
- azure backend storage account container name
- azure subscription Id
- azure tenant id
- azure service principal client Id
- azure service principal client secret

It is also possible that partial configuration you specify in terraform code block and partial with terraform init backend-config parameters.

| NOTE         |
| -------------|
| If your terraform backend block is defined empty as given above then backend configuration must requires to specify at terraform init command otherwise it will throw an error | 

```terraform 
🦄  terraform init
Initializing modules...

Initializing the backend...
container_name
  The container name.

  Enter a value:

key
  The blob key.

  Enter a value:

storage_account_name
  The name of the storage account.

  Enter a value:

╷
│ Error: obtaining Authorization Token from the Azure CLI: parsing json result from the Azure CLI: waiting for the Azure CLI: exit status 1: ERROR: AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The grant was issued on '2022-07-28T06:34:30.5567960Z' and the TokensValidFrom date (before which tokens are not valid) for this user is '2022-08-16T19:33:00.0000000Z'.
```

---

## 2. Terraform Init without backend

Now let's say we have terraform provider defined with empty backend and we still would like to run terraform init command without terraform backend then you can do that with `backend=false` option.

Here is the command 

``` terraform
terraform {
  required_providers {
    azurerm = {
      version = "~> 2.88.1"
      source = "hashicorp/azurerm"
    }
  }
  backend "azurerm" {
  }
}

🦄  terraform init -backend=false
Initializing modules...

Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Reusing previous version of aztfmod/azurecaf from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.88.1
- Using previously-installed aztfmod/azurecaf v1.2.18

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

## 3. Disable Input action with Terraform Init

By default if you run terraform init it will ask for the backend configuration as prompt, if you want you can disable the prompt option using input=false option 

| NOTE | 
| ------------- |
| Disabling interactive prompts give some error if input is disabled |

That's it for now, there are some other options also available with terraform init command which we can take at look at later in some other section.

Next we will look at terraform plan command.