Terraform 1.5 — Things to notice

Amit Kumar Dube (अमित दुबे)
AWS Tip
Published in
3 min readJun 16, 2023

--

Terraform 1.5 is released this week with some interesting new features. As I am exploring these new features, I thought to put them in this blog post.

New Features in Terraform 1.5.0

Upgrade Terraform to latest 1.5.0

If you are on Mac, use brew package manager to upgrade terraform to latest version 1.5.0 .

Amits-MacBook-Pro:frontend amitdube$ brew upgrade terraform

Amits-MacBook-Pro:frontend amitdube$ terraform version
Terraform v1.5.0

New Features

Check Block

A new check block is introduced. The check block can validate your infrastructure outside the usual resource lifecycle. Check blocks address a gap between post-apply and functional validation of infrastructure.

  • Check block can access any data source from any provider in your terraform code.
  • Check block can also have it’s own scoped data source which is only accessible to the check block.
  • Check block is executed at the end of plan and apply and doesn’t block the terraform code execution. If check block fails then terraform will display warning with message specified as error_message in the assert block.

Successful execution

check "status_code" {
data "http" "google" {
url = "https://www.google.com"
}

assert {
condition = data.http.google.status_code == 200
error_message = "${data.http.google.url} returned an unhealthy status code"
}
}

Amits-MacBook-Pro:frontend amitdube$ terraform apply
data.http.google: Reading...
data.http.google: Read complete after 1s [id=https://www.google.com]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Failed Execution (only warning)

check "status_code" {
data "http" "google_not_exist" {
url = "https://google.com/notexist"
}

assert {
condition = data.http.google_not_exist.status_code == 200
error_message = "${data.http.google_not_exist.url} returned an unhealthy status code"
}
}

Amits-MacBook-Pro:frontend amitdube$ terraform apply
data.http.google_not_exist: Reading...
data.http.google_not_exist: Read complete after 0s [id=https://google.com/notexist]

│ Warning: Check block assertion failed

│ on main.tf line 7, in check "status_code":
│ 7: condition = data.http.google_not_exist.status_code == 200
│ ├────────────────
│ │ data.http.google_not_exist.status_code is 404

│ https://google.com/notexist returned an unhealthy status code


Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Import Block

Like to moved block, terraform has now introduced the import block. Import block can replace the importing of resources via CLI. The import block can now be added to the code and executed using CI/CD workflows.

  • Define the resource that was created outside terraform in your terraform configuration file.
  • Add the import block with ID of created source as the provider end and ID of resource in terraform code.
  • Run Terraform apply . This will import all the other resource attribute to terraform code and going forward this resource can be managed by terraform.

resource "google_service_account" "cloudrun_sa" {
}

import {
id = "projects/<project_id>/serviceAccounts/<email>"
to = google_service_account.cloudrun_sa
}

Generate configuration for imported resources

Here is a good news around further simplification of import process in terraform. A new flag -generate-config-out=PATH is now added to terraform plan command.

  • With import block added and missing corresponding terraform, terraform can create the configuration by running terraform plan with above mentioned flag.
  • Once configuration is created, it can be reviewed and merged with your main configuration.
  • This feature requires manual interruption in order to review the generated configuration, review it, adjust it and merge it.
import {
id = "projects/<project_id>/serviceAccounts/<email>"
to = google_service_account.cloudrun_sa
}

Amits-MacBook-Pro:frontend amitdube$ terraform plan -generate-config-out=generated.tf

Amits-MacBook-Pro:TWRO-Infra-bot amitdube$ cat generated.tf
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "projects/twro-infra-bot-9e79/serviceAccounts/cloudrun-backend@twro-infra-bot-9e79.iam.gserviceaccount.com"
resource "google_service_account" "cloudrun_sa" {
account_id = "cloudrun-backend"
description = null
disabled = false
display_name = "Service Account to be used with cloudrun Application"
project = "<project_id>"
timeouts {
create = null
}
}

New Function strcontains

  • Returns true or false based whether a string is contained in another string.
Amits-MacBook-Pro:TWRO-Infra-bot amitdube$ terraform console
> strcontains("hello world", "world")
true
> strcontains("hello world", "universe")
false

plantimestamp function

  • Returns timestamp with terraform plan .
check "terraform_io_certificate" {
data "tls_certificate" "terraform_io" {
url = "https://www.terraform.io/"
}

assert {
condition = timecmp(plantimestamp(), data.tls_certificate.terraform_io.certificates[0].not_after) < 0
error_message = "terraform.io certificate has expired"
}
}

--

--

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