# Tips and tricks with Terraform Terraform is available as a single binary package, which can be downloaded from https://www.terraform.io/downloads.html for various operating systems. If desired, update PATH to include `terraform` by updating `~/.profile` or `~/.bashrc` or by moving it to a well-known location such as `/usr/local/bin`. Remember to initialize it with `terraform init` in the directory with *.tf. ## Getting started It is highly recommended to read through [Getting Started Guide](https://learn.hashicorp.com/terraform/getting-started/install.html) if you are new to the language. ## Benefit to use Terraform Terraform is a language to provide common syntax to interact with multiple cloud providers. Unlike Java, which can be written once and run everywhere, it does not mask the differences from the cloud providers supported: AWS, GCP, Azure or OSK. DevOps engineers still have to understand the details of each cloud provider and write scripts specific to it. In addition to one language for all major cloud providers, there are sizable collections of modules for them. DevOps engineers are reuse the modules for faster development and better code quality. ## Drawback to use Terraform Terraform is not an official language by any cloud providers. It is always lag behind any improvement by the cloud providers. DevOps engineers will still have to use native languages if latest features are required. Terraform support is heavily skewed towards AWS with GCP as distant second. The support to OSK is limited to very basic features. ## What, not how Terraform is a declarative language. DevOps engineer describes what the target environment would be instead of how to build it. The engine would manage to figure out how to create a deployment. It is important to keep tracking the state of each deployment. Terraform does not have build-in registry for this. DevOps engineers need to set up good convention for this. *.tf files for a deployment needs to be in the same directory. Different deployments can not be mixed in the same directory. ## Plan ahead It is always a good idea to plan ahead before actual deployment. This provides a quick way for try-and-error without actual deployment, for example: `terraform plan ~/IdeaProjects/cpa-kubernetes.github/ostack/terraform/` ## Custom modules and submodules A module must contain a main.tf. It is a good idea to place custom modules in a Git repository or to publish them to Terraform registry. Modules can be nested. Submodules are invisible outside a module. It is important to nest modules logically. This makes the code reuse much easier. ``` module "consul" { source = "hashicorp/consul/aws" version = "0.1.0" } ``` ``` module "consul" { source = "github.com/hashicorp/example" } ``` ## Provisioners It can be handy to call a provisioner for some simple configuration. Ansible can be used for more complex configurations. ``` provisioner "file" { source = "script.sh" destination = "/tmp/script.sh" } provisioner "remote-exec" { inline = [ "chmod +x /tmp/script.sh", "/tmp/script.sh args", ] } ``` ## Reference 1. [Terraform Recommended Practices](https://www.terraform.io/docs/enterprise/guides/recommended-practices/index.html)