In this article, we’ll discuss some very useful Terraform CLI tips and cheatsheets. When you want to use a tool or improve your expertise in a particular technology, it’s good to read a lot of articles and, of course, official documentation. However, sometimes having a brief cheat sheet of it, can be very handy at times.
Terraform
Terraform, a Go-based program released by Hashicorp in 2014, is used to build, change, and version control your infrastructure(IaC). And this has an extremely strong and user-friendly Command Line Interface.
Prerequisites
- Basics of Terraform – IaC (Terraform CLI)
- Command Line basics
Terraform CLI Tips and Cheatsheets
Installation
Install through curl
$ curl -O <https://releases.hashicorp.com/terraform/1.3.5/terraform_1.3.5_linux_amd64.zip>
$ sudo unzip terraform_1.3.5_linux_amd64.zip -d /usr/local/bin/
$ rm terraform_1.3.5_linux_amd64.zip
Install using tfenv (Terraform Version Manager)
First of all, download the tfenv binary and put it in your PATH.
$ git clone <https://github.com/tfutils/tfenv.git> ~/.tfenv
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> $HOME/bashrc
Then, you can install the desired version of Terraform:
$ tfenv install 1.3.7
Usage
Version Check
$ terraform --version
Terraform v1.3.7
on linux_amd64
Terraform init
The following command is used to initialize the terraform project:
$ terraform init
It’s the first command you need to execute. Unless terraform plan
, apply
, destroy
and import
will not work. This command terraform init
will install the followings:
- Terraform modules
- Backend
- Provider(s) plugins
You can initialize the Terraform without any input prompt. To do this, run the following command:
$ terraform init -input=false
Also, if you want to change the backend configuration during the init command, run the following command:
$ terraform init -backend-config=proj/s3.dev.tf -reconfigure
Here, reconfigure
is used to tell Terraform to not copy the existing state to the new remote state location.
Terraform Get
This command is very useful when you have defined some modules. And if you edit modules, you need to get modules content again.
$ terraform get -update=true
When using modules, the first thing you’ll need to do is a terraform get
. This appends modules to the .terraform directory. Unless you do another terraform get -update=true
, you’ve effectively vendored those components.
Terraform Plan
The plan step validates the configuration for execution and creates a plan to be applied to the target infrastructure provider.
$ terraform plan -out plan.out
It’s a crucial Terraform tool that lets users know the actions Terraform will do before making any changes, providing confidence that a modification will have the desired effect once deployed.
When you execute terraform plan
, Terraform will scan all *.tf files in your directory and create the plan.
Terraform Apply
Now it’s time to execute the plan:
$ terraform apply plan.out
Terraform can guarantee that the execution plan will not change by generating it and applying it in the same command without the need to write it to disk. This decreases the possibility of potentially sensitive data being left behind or being incorrectly checked into version control.
$ terraform apply
- Apply and Auto Approve
$ terraform apply -auto-approve
- Apply and Define New Variables Value
$ terraform apply -auto-approve -var tags-repository_url=${GIT_URL}
- Apply Only One Module
$ terraform apply -target=module.s3
This -target
option works with Terraform plan too.
Terraform Destroy
$ terraform destroy
Delete all the resources!
A deletion plan can be created before:
$ terraform plan –destroy
target
option allows to destroy only one resource, for example, an S3 bucket :
$ terraform destroy -target aws_s3_bucket.my_bucket
Debugging in Terraform
In Terraform terraform console
command is useful for testing interpolations before using them in configurations. Terraform console will read configured state even if it is remote.
$ echo "aws_iam_user.sagar.arn" | terraform console
arn:aws:iam::123456789:user/sagar
Graph in Terraform
$ terraform graph | dot –Tpng > graph.png
Visual representation (graph) of Terraform resources.
Terraform Validate
The validate command is used to validate/check the syntax of the Terraform files. A syntax check is done on all the Terraform files in the directory and will display an error if any of the files don’t validate. The syntax check does not cover every syntax common issue.
$ terraform validate
Providers
You can use a lot of providers/plugins in your Terraform definition resources, so it can be useful to have a tree of providers used by modules in your project.
$ terraform providers
.
├── provider.aws ~> 4.49.0
├── module.my_module
│ ├── provider.aws (inherited)
│ ├── provider.null
│ └── provider.template
└── module.elastic
└── provider.aws (inherited)
State
Pull Remote State in A Local Copy
$ terraform state pull > terraform.tfstate
Push State in a Remote Backend storage
$ terraform state push
This command is useful if, for example, you originally use a local tf state and then you define backend storage, in S3 or Consul…
How to Tell to Terraform You Moved a Resource in A Module?
If you moved an existing resource in a module, you need to update the state:
$ terraform state mv aws_iam_role.role1 module.mymodule
How to Import Existing Resources in Terraform?
If you have an existing resource in your infrastructure provider, you can import it in your Terraform state:
$ terraform import aws_iam_policy.elastic_post
arn:aws:iam::123456789:policy/elastic_post
Workspaces
To manage multiple distinct sets of infrastructure resources/environments.
Instead of creating a directory for each environment to manage, we need to just create needed workspace and use them:
Create Workspace
This command creates a new workspace and then select it
$ terraform workspace new dev
Select a Workspace
$ terraform workspace select dev
List Workspaces
$ terraform workspace list
default
* dev
staging
Show Current Workspace
$ terraform workspace show
dev
Tools
1. jq
jq is a command-line JSON processor. It’s very lightweight and it can be used with Terraform output to make terraform more powerful.
Installation
For Linux:
$ sudo apt-get install jq
or
$ yum install jq
For OS X:
$ brew install jq
Usage
For example, we defined outputs in a module and when we execute terraform apply outputs are displayed:
$ terraform apply
...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
elastic_endpoint = vpc-toto-12fgfd4d5f4ds5fngetwe4.ap-south-1.es.amazonaws.com
We can extract the value that we want in order to use it in a script for example. With jq it’s easy:
$ terraform output -json
{
"elastic_endpoint": {
"sensitive": false,
"type": "string",
"value": "vpc-toto-12fgfd4d5f4ds5fngetwe4.ap-south-1.es.amazonaws.com"
}
}
$ terraform output -json | jq '.elastic_endpoint.value'
"vpc-toto-12fgfd4d5f4ds5fngetwe4.ap-south-1.es.amazonaws.com"
2. Terraforming
If you have an existing AWS account for example with existing components like S3 buckets, SNS, VPC … You can use the Terraforming tool, a tool written in Ruby, which extracts existing AWS resources and converts them to Terraform files!
Installation
$ sudo apt install ruby
# OR
$ sudo yum install ruby
and
$ gem install terraforming
Usage
Pre-requisites:
As in Terraform, you need to set AWS credentials:
$ export AWS_ACCESS_KEY_ID="an_aws_access_key"
$ export AWS_SECRET_ACCESS_KEY="a_aws_secret_key"
$ export AWS_DEFAULT_REGION="eu-central-1"
You can also specify the credential profile in ~/.aws/credentials and with –profile option.
$ cat ~/.aws/credentials
[sagar]
aws_access_key_id = xxx
aws_secret_access_key = xxx
aws_default_region = eu-central-1
$ terraforming s3 --profile sagar
Example
$ terraforming --help
Commands:
terraforming alb # ALB
...
terraforming vgw # VPN Gateway
terraforming vpc # VPC
$ terraforming s3 > aws_s3.tf
Note: Terraform can’t extract API gateway resources for the moment so you need to write it manually.
Conclusion
In this article, I talked about some of the important Terraform CLI tips and cheatsheets. There is still a lot more than this, but you can go and explore them yourself. Thank you!