Apply Terraform configuration
The core Terraform workflow consists of three main steps once you have written your Terraform configuration:
- Initialize prepares the working directory so Terraform can run the configuration.
- Plan lets you preview any changes before you apply them.
- Apply executes the changes defined by your Terraform configuration to create, update, or destroy resources.
When it makes changes to your infrastructure, Terraform uses the providers and modules installed during initialization to execute the steps stored in the execution plan. These steps create, update, and delete infrastructure to match your resource configuration.
In this tutorial, you will apply configuration to provision Docker containers on
your local machine, and review the steps that Terraform takes to apply your
configuration. You will also learn how Terraform recovers from errors during
apply, and some common ways to use the apply
command.
Prerequisites
The 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.
- jq.
Clone the example repository
In your terminal, clone the learn-terraform-apply
repository.
Navigate to the cloned repository.
Review configuration
Open the main.tf
file. This file defines configuration for four Docker
containers running the latest nginx
image.
In this example configuration, the docker_container.nginx
resources depend on
the random_pet.nginx
and docker_image.nginx
resources. When you apply this
configuration, Terraform will create the image and random_pet
resources first,
followed by the containers.
Initialize configuration
Initialize your configuration to install the providers it references.
Apply configuration
When you apply this configuration, Terraform will:
- Lock your project's state, so that no other instances of Terraform will
attempt to modify your state or apply changes to your resources. If Terraform
detects an existing lock file (
.terraform.tfstate.lock.info
), it will report an error and exit. - Create a plan, and wait for you to approve it. Alternatively, you can provide a saved
speculative plan created with the
terraform plan
command, in which case Terraform will not prompt for approval. - Execute the steps defined in the plan using the providers you installed when you initialized your configuration. Terraform executes steps in parallel when possible, and sequentially when one resource depends on another.
- Update your project's state file with a snapshot of the current state of your resources.
- Unlock the state file.
- Print out a report of the changes it made, as well as any output values defined in your configuration.
Apply the configuration.
Since you did not provide a saved speculative plan, Terraform created a plan and asked you to approve it before making any changes to your resources.
Respond to the confirmation prompt with a yes
to apply the proposed execution
plan.
When you applied the example configuration, Terraform created the random pet name and image resources first, and then created the four containers which depend on them in parallel. When Terraform creates a plan, it analyzes the dependencies between your resources so that it makes changes to your resources in the correct order, and in parallel when possible.
Now that Terraform has provisioned your containers, use curl
to send an HTTP
request to one of them.
The container will respond with the NGINX welcome page.
Errors during apply
When Terraform encounters an error during an apply step, it:
- Logs the error and reports it to the console.
- Updates the state file with any changes to your resources.
- Unlocks the state file.
- Exits.
Terraform does not support rolling back a partially-completed apply. Because of this, your infrastructure may be in an invalid state after a Terraform apply step errors out. After you resolve the error, you must apply your configuration again to update your infrastructure to the desired state.
To review how Terraform handles errors, introduce an intentional error during an apply.
Add the following configuration to main.tf
to create a new Docker container running the
latest Redis image.
The time_sleep.wait_after_image
resource will introduce a 60 second delay
between downloading the image and creating the container. During this time, you
will remove the image from your local Docker instance in order to artificially
introduce an error.
Tip
If you need more time, increase the value of the create_duration
argument to the time_sleep.wait_after_image
resource.
Apply the new configuration. Respond to the confirmation prompt with a yes
.
After Terraform creates the Redis image resource, within 60 seconds, open a new terminal window and remove the image from your local Docker host.
Return to the terminal where terraform apply
is running. Because you removed
the image from Docker after Terraform provisioned it, Terraform will error out
when it tries to create the docker_container.data
container.
Docker was unable to find the Redis image, so the Docker provider could not create the Redis container and reported the error to Terraform.
Common reasons for apply errors include:
- A change to a resource outside of Terraform's control.
- Networking or other transient errors.
- An expected error from the upstream API, such as a duplicate resource name or reaching a resource limit.
- An unexpected error from the upstream API, such as an internal server error.
- A bug in the Terraform provider code, or Terraform itself.
Depending on the cause of the error, you may need to resolve the underlying
issue by either modifying your configuration or diagnosing and resolving
the error from the cloud provider API. In this example, Terraform successfully
created the docker_image.redis
resource, but was unable to create the
containers because you made a change outside of Terraform's control by removing
the image from Docker. Your Terraform project is still tracking the image
resource because Terraform has not yet refreshed your resource's state.
Print out the state of your Terraform resources with terraform show
.
The terraform show
command prints out Terraform's current understanding of the
state of your resources. It does not refresh your state, so the information in
your state can be out of date. In this case, your project's state reports the
existence of the Redis image you manually removed earlier in this tutorial.
The next time you plan a change to this project, Terraform will update the
current state of your resources from the underlying APIs using the providers you
have installed. Terraform will notice that the image represented by the
docker_image.redis
resource no longer exists. When you apply your
configuration, Terraform will recreate the image resource before creating the
docker_container.data
container.
Apply your configuration. Respond to the confirmation prompt with a yes
to
provision the Redis image and container.
In this case, you were able to recover from the error by re-applying your configuration. Depending on the underlying cause of the error, you may need to resolve the error outside of Terraform or by changing your Terraform configuration. For example, if Terraform reports a resource limit error from your cloud provider, you may need to work with your cloud provider to increase that limit before applying your configuration.
Replace Resources
When using Terraform, you will usually apply an entire
configuration change at once. Terraform and its providers will determine the
changes to make and the order to make them in. However, there are some cases
where you may need to replace or modify individual resources. Terraform provides
two arguments to the apply
command that allow you to interact with specific resources: -replace
and
-target
.
Use the -replace
argument when a resource has become unhealthy or stops working
in ways that are outside of Terraform's control. For instance, a
misconfiguration in your Docker container's OS configuration could require that
the container be replaced. There is no corresponding change to your Terraform configuration, so you want to instruct Terraform to reprovision the resource using the same configuration.
The -replace
argument requires a resource address. List the resources in your
configuration with terraform state list
.
Replace the second Docker container. Respond to the confirmation prompt with a
yes
.
The second case where you may need to partially apply configuration is when
troubleshooting an error that prevents Terraform from applying your entire
configuration at once. This type of error may occur when a target API or Terraform provider error leaves your resources in an invalid state
that Terraform cannot resolve automatically. Use the -target
command line
argument when you apply to target individual resources. Refer to the Target resources
tutorial for more information.
Clean up infrastructure
Now that you have learned how Terraform applies changes to your infrastructure,
remove the resources you provisioned in this tutorial. Confirm the
operation with a yes
.
Next steps
In this tutorial, you learned how Terraform applies changes to your infrastructure by working with example configuration to deploy Docker containers. You also reviewed how Terraform handles errors by reproducing an error during the apply step. Check out the following resources to learn more about managing your Terraform projects:
- Learn how to Customize Terraform Configuration with Variables.
- Learn how to work on Terraform projects with your team with the Store Remote State tutorial and the Terraform Cloud get started tutorials.
- Learn about Running Terraform in Automation.