Terraform 1.4 — Things to notice

Terraform 1.4 is released last month and brought some nice improvements. While I am playing around with this new version, I thought to describe them here and group them into categories.

Security

  • Sensitive values are now hidden in console input
// creating non sensitive variable
variable "checking_sensitive" {
type = string
}

// running terraform plan without supplying the default value
// value is visible on the console as variable is not marked as sensitive.
Amits-MacBook-Pro:terraform amitdube$ terraform plan -target terraform_data.test_data
var.checking_sensitive
Enter a value: sdfdfsdf

// Marking the variable as sensitive
variable "checking_sensitive" {
type = string
sensitive = true
}

// As I am typing, the value is not visible on the console as the variable is sensitive.
Amits-MacBook-Pro:terraform amitdube$ terraform plan -target terraform_data.test_data
var.checking_sensitive
Enter a value:
  • Support of customer-managed GCP KMS keys to GCS backend to encrypt/decrypt the state file.

This adds additional layer of security if terraform state is sensitive which is the case in almost all the cases.

To use customer-managed encryption keys, you need to create a key and give your project’s GCS service agent permission to use it with the Cloud KMS CryptoKey Encrypter/Decrypter predefined role.

More details here.

terraform {
backend "gcs" {
bucket = "tf-state-prod"
prefix = "terraform/state"
kms_encryption_key {
location = "us-east1" # optional, defaults to 'global'
key_ring = "terraform-keyring"
key = "terraform-key"
}
}
}
  • A different service account can be used to access state bucket then the one used by terraform to deploy infra as per configuration files. This helps in implementing the concept of “least privilege implementation”.
GOOGLE_BACKEND_IMPERSONATE_SERVICE_ACCOUNT="<name of service account that will be used to connect to terraform state>"
GOOGLE_IMPERSONATE_SERVICE_ACCOUNT="<name of the service account that will be used to deploy infrastructure>"

Automation

  • Create terraform workspace if not already exist by setting a flag.
// Currently I have only one workspace
Amits-MacBook-Pro:terraform amitdube$ terraform workspace list
* default

// If I try to switch to a namespace that doesnt exist. I will get an error.
Amits-MacBook-Pro:terraform amitdube$ terraform workspace select test

Workspace "test" doesnt exist.

You can create this workspace with the "new" subcommand
or include the "-or-create" flag with the "select" subcommand.

// I can use the -or-create flag to create the workspace if doesn't exist.
Amits-MacBook-Pro:terraform amitdube$ terraform workspace select -or-create test
Created and switched to workspace "test"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.

Replacement / New Resource

  • There is an in built replacement of null_resource available now. It’s called terraform_data resource.
  • It can be used to trigger provisioners based on change in variables.
  • Additionally it can also store/calculate temporary values in input and output attributes.
variable "checking_sensitive" {
type = string
sensitive = true
}

resource "terraform_data" "test_data" {
triggers_replace = var.checking_sensitive
input = var.checking_sensitive
provisioner "local-exec" {
command = "echo ${self.input} >> private_ips.txt"
}
}

Documentation https://developer.hashicorp.com/terraform/language/resources/terraform-data

New Command

A new command is introduced to export terraform functions signature in machine-readable format.

  • This command returns list of all the terraform functions along with their description, return type & the list of parameters.
terraform metadata functions -json 

--

--

Amit Kumar Dube (अमित दुबे)

@AmitDubeDev | Professional GCP Architect | Terraform ACE | Lead Infra Consultant | Hindi Speaker