Terraform Operations

From NovaOrdis Knowledge Base
Jump to: navigation, search



terraform version


terraform --help
terraform <command> --help

Verbose Output and Debugging


Set TF_LOG environment variable to one of:

  • INFO
  • WARN

This will send debug output to stderr.

To write to file, set TF_LOG_PATH. Note that even when TF_LOG_PATH is set, TF_LOG must be set in order for any logging to be enabled.




The initialization operation initializes various local settings that will be used by subsequent commands. Without additional arguments, it uses the current directory as root module and creates a .terraform directory, which contains a "plugins" sub-directory. The command also downloads provider binaries and, if any modules are used, the module source. The command needs to be re-run if new modules are set or changed, or backend configuration changes.

terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.49.0...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.aws: version = "~> 2.49"

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.


The -upgrade option will additionally check for any newer versions of existing modules and providers that may be available.


-from-module is a useful option when we want to avoid creating transient metadata, such as the .terraform directory, inside a module directory. A common use case is when we run provisioning off modules maintained in a Git repository. While using it, be aware of the following idiosyncrasy: the --from-module= argument must not include ~.

mkdir ~/tmp/pseudo-root-module
cd ~/tmp/pseudo-root-module
terraform init --from-module=../../playground/hashicorp/terraform/simplest-module

The command makes a physical copy of the configuration in the current directory. terraform apply can then be executed in that directory.

Configuration File Formatting

terraform fmt

Formats all .tf in the current directory. It aligns equals, etc. Formatting enables standardization.


terraform validate


Pull dependencies of the module the command is run against from their repositories and store a copy locally in the .terraform directory.

terraform get


The plan is created based on the state maintained locally or remotely by Terraform. By default, before each plan operation, Terraform sync all resources in its state.


terraform apply

When the first apply operation is executed, state file terraform.tfstate is created. By default, before each apply operation, Terraform sync all resources in its state.

The output shows the execution plan, in a format similar to diff.

-/+ means the resource will be destroyed and recreated rather than update it in-place. ~ means update in-place.

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.terraform-test-01 will be created
  + resource "aws_instance" "terraform-test-01" {
      + ami                          = "ami-a6faba49dddaecfb7"
      + arn                          = (known after apply)
      + associate_public_ip_address  = (known after apply)
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
      + host_id                      = (known after apply)
      + id                           = (known after apply)
      + instance_state               = (known after apply)
      + instance_type                = "m5.4xlarge"
      + ipv6_address_count           = (known after apply)
      + ipv6_addresses               = (known after apply)
      + key_name                     = (known after apply)
      + network_interface_id         = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      + primary_network_interface_id = (known after apply)
      + private_dns                  = (known after apply)
      + private_ip                   = (known after apply)
      + public_dns                   = (known after apply)
      + public_ip                    = (known after apply)
      + security_groups              = (known after apply)
      + source_dest_check            = true
      + subnet_id                    = (known after apply)
      + tenancy                      = (known after apply)
      + volume_tags                  = (known after apply)
      + vpc_security_group_ids       = (known after apply)

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)

      + root_block_device {
          + delete_on_termination = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.terraform-test-01: Creating...
aws_instance.terraform-test-01: Still creating... [10s elapsed]
aws_instance.terraform-test-01: Still creating... [20s elapsed]
aws_instance.terraform-test-01: Creation complete after 24s [id=i-afbbc2c4a789ab871]

Apply Options


Skip interactive approval of plan before applying.


terraform show

Shows the state. It contain interesting information obtained after installation, such as IP addresses, etc.

It also shows content of terraform.tfstate state file.


Used to extract the value of an output variable from the state file.

All variables are extracted with:

terraform output

A specific variable is extracted with:

terraform output <output-var-name>





Instances can be imported using their ID:

terraform import aws_instance.web i-00000000000


terraform destroy



The state exposes a set of sub-commands that allow basic state management.

terraform state


terraform state list


cd <root-module-dir>
terraform refresh

The command reconcile the state Terraform knows about via its terraform.tfstate file with the real-world infrastructure. The command can be used to detect any drift from the last-known state, and to update the state file. The command does not modify infrastructure, but does modify the state file. If the state is changed, this may cause changes to occur during the next plan or apply.

Force Unlock

terraform force-unlock

Command to force-unlock state.

Use force-unlock with caution. If state is unlocked when someone else is holding the lock, multiple writers can write it and the state can be corrupted. Force unlock should only be used to unlock your own lock in the situation where automatic unlocking failed.

More on state locking available here:

State Locking

Provider-Specific Operations

AWS Operations

Terraform AWS Operations