Terraform Workflow (write->plan->apply)
Tags: terraform, aws, devops, cloud
Published: 2022-06-19 22:36:40

Now that we are familiar with Terraform's building blocks we can start exploring *how* Terraform expects people to use it.

It may sound silly, but learning workflow can prevent common pitfalls and unexpected problems. I am sure all of us ended up in a situation when we were using something incorrectly. It happens to me very often because I want to use something as soon as possible hoping that I will figure things out as I go. 

Since this blog doubles as my study notes, I believe I should not slack off and included this section because it is something that will be tested on the exam.

&nbsp;

This photo illustrates basic workflow that Terraform wants its users to follow:
![Terraform workflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1ormw9rdlb77vosclve.jpeg)

We touched on it during the practice and we followed this workflow without it being formally introduced. So here it is.

First we write our configuration and initialize our project.

Then we format and validate the code to tidy it up and check for syntax error.

After that we do a dry-run (`terraform plan`) to see what exactly Terraform will attempt to deploy and verify it.

Last step is an actual deploy with `terraform apply`.

One command that is used often is `terraform destroy` which destroys deployed resource from current configuration.

&nbsp;

## Terraform `init` command

This is a command that we used a lot and it is used to initialize terraform projects and update providers. This is the first command we would run after writing our configuration or after cloning existing configuration.
```bash
$ terraform init
```
That's also a command that needs to be run after we add/import new modules and checks if all versions are correct.

This command downloads Terraform backend and sets up things like lock file and other important internal files.

Rule of thumb is that we need to run `init` whenever we add new modules, change versions, add/remove providers, or change Terraform backend in some way. Luckily, Terraform will inform us if we forgot to initialize our configuration.

&nbsp;

## Terraform `validate` command

Validate command does exactly what its name suggests. It checks the code for syntax errors and ensures that it is internally consistent. It only looks at the configuration files (`*.tf`) in the current working directory
```bash
$ terraform validate
```

If you want `validate` to check files inside folders (eg you have `modules/` directory), you need to set `-recursive` flag:
```bash
$ terraform validate -recursive
```

&nbsp;

## Terraform `plan` command

This command is often called a `dry-run` so make sure you remember it. When you hear the words "execution plan" that would be it as well.

It is used to determine the changes to apply to the existing (if any) resources. You will get a report of what is going to be created, modified, or destroyed. Terraform also allows for saving this plan in a file.

You can save the plan and execute that saved plan at a later time or use it for analysis and record keeping.

Execution plan is not a requirement for deployment, but it is always a good idea to see what will happen.

That's how you run it:
```bash
$ terraform plan
```


&nbsp;

## Terraform `apply` command

This is how you actually deploy your resources or applying changes to your infrastructure. As with `plan` command, you will also get a report identifying which resources are to be created, modified, or destroyed. 

After running this command Terraform will also create a `state` file. This is a living record of all deployed resources. State warrants a whole articles on its own given how important it is. 

One thing to note, this command only applies to the resources specified in your current configuration. It will not touch any existing resources that are not part of the configuration you are deploying.


That's how you deploy resource with Terraform:
```bash
$ terraform apply
```

Or if you don't want to type `yes` every time, you can set an auto-approve tag:
```bash
$ terraform apply -auto-approve
```

&nbsp;

## Terraform `destroy` command

Destroying resources is an integral part of Terraform. Deploying consistent and reproducible infrastructure implies that you will be creating and destroying resources when needed.

We used this command extensive in the practice section of this series because we do not want to leave any technical debt behind. It also ensures that we do not incur any unnecessary charges from AWS.

Just like with plan and apply commands, Terraform will show you what exactly it will attempt to destroy.

This is how you use it:
```bash
$ terraform destroy
```
It also supports `auto-approve` flag:
```bash
$ terraform destroy -auto-approve
```

&nbsp;

Thank you for reading! At this point you are becoming somewhat knowledgeable about Terraform and its capabilities. We still have one big topic to cover. This topic is *State*.

See you in the next article!