Skip to content

Releases: suzuki-shunsuke/tfcmt

v4.10.0

02 Jun 03:26
Immutable release. Only release title and notes can be modified.
v4.10.0
7a487f0

Choose a tag to compare

Pull Requests | Issues | v4.9.1...v4.10.0

Features

#1294 plan: Support disabling labels by a command line option and environment variable

Added a command line option -disable-label and an environment variable TFCMT_DISABLE_LABEL. If they are set, tfcmt plan doesn't set labels.

tfcmt plan -disable-label -- terraform plan
export TFCMT_DISABLE_LABEL=true
tfcmt plan -- terraform plan

Fixes

#1295 validate if command is specified

tfcmt plan and tfcmt apply require command to be executed.

tfcmt plan -- terraform plan
tfcmt apply -- terraform apply

So this pull request adds a validation if command is specified.
If no command is specified, tfcmt plan and apply return an error immediately.

$ tfcmt plan
ERRO[0000] tfcmt failed                                  error="no command specified"

Others

#1292 #1293 Improve the help message

v4.9.1

09 May 22:31
Immutable release. Only release title and notes can be modified.
v4.9.1
7a2e3a2

Choose a tag to compare

Pull Requests | Issues | v4.9.0...v4.9.1

Fix

#1187 #1257 #1258 Exit commands with non zero exit code if any error such as API rate limit happens

This update changes the exit code of tfcmt when an error happens.
The exit code was same with the exit code of terraform plan and terraform apply.
This means tfcmt might have exited with zero even if tfcmt failed to post a comment due to some reason such as API rate limit.
This was not a bug but a expected behavior.
But this behaviour was dangerous because people might have missed unexpected changes.

So this update changes the behaviour as tfcmt exits with non zero if any error such as API rate limit happens.

v4.9.0

01 Feb 07:30
Immutable release. Only release title and notes can be modified.
v4.9.0
74ffe99

Choose a tag to compare

Pull Requests | Issues | v4.8.0...v4.9.0

Features

#1083 #1115 Support masking sensitive data

You can mask sensitive data in outputs of terraform.
This feature prevents the leak of sensitive data.

The following outputs are masked.

Caution

Even if you maske secrets using this feature, secrets are still stored in Terraform States.
Please see also Sensitive Data in State.

You can use environment variables TFCMT_MASKS and TFCMT_MASKS_SEPARATOR.

  • TFCMT_MASKS: A list of masks. Masks are joined by TFCMT_MASKS_SEPARATOR
  • TFCMT_MASKS_SEPARATOR: A separator of masks. The default value is ,

The format of each mask is ${type}:${value}.
${type} must be either env or regexp.
If ${type} is env, ${value} is a masked environment variable name.
If ${type} is regexp, ${value} is a masked regular expression.

e.g. Mask GitHub access tokens and the environment variable DATADOG_API_KEY.

export TFCMT_MASKS='env:GITHUB_TOKEN,env:DATADOG_API_KEY,regexp:ghp_[^ ]+'
tfcmt plan -- terraform plan

e.g. Change the separator to /.

export TFCMT_MASKS_SEPARATOR=/
export TFCMT_MASKS='env:GITHUB_TOKEN/env:DATADOG_API_KEY/regexp:ghp_[^ ]+'

All matching strings are replaced with ***.
Replacements are done in order of TFCMT_MASKS, so the result depends on the order of TFCMT_MASKS.
For example, if TFCMT_MASKS is regexp:foo,regexp:foo.*, regexp:foo.* has no meaning because all foo are replaced with *** before replacing foo.* with *** so foo.* doesn't match with anything.

Example

This example creates a resource google_cloudbuild_trigger.
This resource has a GitHub Access token as a field substitutions._GH_TOKEN.

main.tf

resource "google_cloudbuild_trigger" "filename_trigger" {
  location = "us-central1"
  trigger_template {
    branch_name = "main"
    repo_name   = "my-repo"
  }
  substitutions = {
    _GH_TOKEN = var.gh_token # Secret
  }
  filename = "cloudbuild.yaml"
}
variable "gh_token" {
  type        = string
  description = "GitHub Access token"
}
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.13.0"
    }
  }
}

If you run terraform plan without masking, the secret would be leaked.
To prevent the leak, let's mask the secret.

export TFCMT_MASKS=env:TF_VAR_gh_token # Mask the environment variable TF_VAR_gh_token

Please see _GH_TOKEN in the output of tfcmt plan and the pull request comment.
You can confirm _GH_TOKEN is masked as *** properly.

$ tfcmt plan -- terraform plan
tfcmt plan -- terraform plan

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_cloudbuild_trigger.filename_trigger will be created
  + resource "google_cloudbuild_trigger" "filename_trigger" {
      + create_time   = (known after apply)
      + filename      = "cloudbuild.yaml"
      + id            = (known after apply)
      + location      = "us-central1"
      + name          = (known after apply)
      + project       = "hello"
      + substitutions = {
          + "_GH_TOKEN" = "***"
        }
      + trigger_id    = (known after apply)

      + trigger_template {
          + branch_name = "main"
          + project_id  = (known after apply)
          + repo_name   = "my-repo"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

image

Terraform sensitive input variables and outputs and sensitive function

Terraform itself has features to prevent sensitive data from being leaked.

So first you should use these features.
But even if these features are available, it still makes sense for tfcmt to mask sensitive data.
Please imagine the situation that platform engineers manage Terraform workflows and product teams manage Terraform codes in a Monorepo.
Then platform engineers need to prevent sensitive data from being leaked, but if product teams forget to protect them with sensitive flags, sensitive data would be leaked.
By protecting sensitive data using tfcmt, platform engineers can prevent sensitive data from being leaked while delegating the management of Terraform codes to product teams.
tfcmt's masking feature works as a guardrail.

v4.9.0-2

26 Jan 13:51
Immutable release. Only release title and notes can be modified.
v4.9.0-2
56dfca4

Choose a tag to compare

v4.9.0-2 Pre-release
Pre-release

v4.8.0...v4.9.0-2

Changes from v4.9.0-1

56dfca4 fix(mask): Change the default separator from ; to ,

Features

#1083 #1115 support masking secrets

You can mask secrets in outputs of terraform.
This feature prevents the leak of secrets.

The following outputs are masked.

Caution

Even if you maske secrets using this feature, secrets are still stored in Terraform States.
Please see also Sensitive Data in State.

You can use environment variables TFCMT_MASKS and TFCMT_MASKS_SEPARATOR.

  • TFCMT_MASKS: A list of masks. Masks are joined by TFCMT_MASKS_SEPARATOR
  • TFCMT_MASKS_SEPARATOR: A separator of masks. The default value is ,

The format of each mask is ${type}:${value}.
${type} must be either env or regexp.
If ${type} is env, ${value} is a masked environment variable name.
If ${type} is regexp, ${value} is a masked regular expression.

e.g. Mask GitHub access tokens and the environment variable DATADOG_API_KEY.

export TFCMT_MASKS="env:GITHUB_TOKEN,env:DATADOG_API_KEY,regexp:ghp_[^ ]+"
tfcmt plan -- terraform plan

e.g. Change the separator to /.

export TFCMT_MASKS_SEPARATOR=/
export TFCMT_MASKS="env:GITHUB_TOKEN/env:DATADOG_API_KEY/regexp:ghp_[^ ]+"

All matching strings are replaced with ***.
Replacements are done in order of TFCMT_MASKS, so the result depends on the order of TFCMT_MASKS.
For example, if TFCMT_MASKS is regexp:foo,regexp:foo.*, regexp:foo.* has no meaning because all foo are replaced with *** before replacing foo.* with *** so foo.* doesn't match with anything.

Example

This example creates a resource google_cloudbuild_trigger.
This resource has a GitHub Access token as a field substitutions._GH_TOKEN.

main.tf

resource "google_cloudbuild_trigger" "filename_trigger" {
  location = "us-central1"

  trigger_template {
    branch_name = "main"
    repo_name   = "my-repo"
  }

  substitutions = {
    _GH_TOKEN = var.gh_token # Secret
  }

  filename = "cloudbuild.yaml"
}

variable "gh_token" {
  type        = string
  description = "GitHub Access token"
}

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.13.0"
    }
  }
}

If you run terraform plan without masking, the secret would be leaked.
To prevent the leak, let's mask the secret.

export TFCMT_MASKS=env:TF_VAR_gh_token # Mask the environment variable TF_VAR_gh_token

Please see _GH_TOKEN in the output of tfcmt plan and the pull request comment.
You can confirm _GH_TOKEN is masked as *** properly.

$ tfcmt plan -- terraform plan
tfcmt plan -- terraform plan

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_cloudbuild_trigger.filename_trigger will be created
  + resource "google_cloudbuild_trigger" "filename_trigger" {
      + create_time   = (known after apply)
      + filename      = "cloudbuild.yaml"
      + id            = (known after apply)
      + location      = "us-central1"
      + name          = (known after apply)
      + project       = "hello"
      + substitutions = {
          + "_GH_TOKEN" = "***"
        }
      + trigger_id    = (known after apply)

      + trigger_template {
          + branch_name = "main"
          + project_id  = (known after apply)
          + repo_name   = "my-repo"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

image

v4.9.0-1

26 Jan 08:33
Immutable release. Only release title and notes can be modified.
v4.9.0-1
dcbce63

Choose a tag to compare

v4.9.0-1 Pre-release
Pre-release

v4.8.0...v4.9.0-1

Features

#1083 #1115 support masking secrets

You can mask secrets in outputs of terraform.
This feature prevents the leak of secrets.

The following outputs are masked.

Caution

Even if you maske secrets using this feature, secrets are still stored in Terraform States.
Please see also Sensitive Data in State.

You can use environment variables TFCMT_MASKS and TFCMT_MASKS_SEPARATOR.

  • TFCMT_MASKS: A list of masks. Masks are joined by TFCMT_MASKS_SEPARATOR
  • TFCMT_MASKS_SEPARATOR: A separator of masks. The default value is ;

The format of each mask is ${type}:${value}.
${type} must be either env or regexp.
If ${type} is env, ${value} is a masked environment variable name.
If ${type} is regexp, ${value} is a masked regular expression.

e.g. Mask GitHub access tokens and the environment variable DATADOG_API_KEY.

export TFCMT_MASKS="env:GITHUB_TOKEN;env:DATADOG_API_KEY;regexp:ghp_[^ ]+"
tfcmt plan -- terraform plan

e.g. Change the separator to /.

export TFCMT_MASKS_SEPARATOR=/
export TFCMT_MASKS="env:GITHUB_TOKEN/env:DATADOG_API_KEY/regexp:ghp_[^ ]+"

All matching strings are replaced with ***.
Replacements are done in order of TFCMT_MASKS, so the result depends on the order of TFCMT_MASKS.
For example, if TFCMT_MASKS is regexp:foo;regexp:foo.*, regexp:foo.* has no meaning because all foo are replaced with *** before replacing foo.* with *** so foo.* doesn't match with anything.

Example

This example creates a resource google_cloudbuild_trigger.
This resource has a GitHub Access token as a field substitutions._GH_TOKEN.

main.tf

resource "google_cloudbuild_trigger" "filename_trigger" {
  location = "us-central1"

  trigger_template {
    branch_name = "main"
    repo_name   = "my-repo"
  }

  substitutions = {
    _GH_TOKEN = var.gh_token # Secret
  }

  filename = "cloudbuild.yaml"
}

variable "gh_token" {
  type        = string
  description = "GitHub Access token"
}

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.13.0"
    }
  }
}

If you run terraform plan without masking, the secret would be leaked.
To prevent the leak, let's mask the secret.

export TFCMT_MASKS=env:TF_VAR_gh_token # Mask the environment variable TF_VAR_gh_token

Please see _GH_TOKEN in the output of tfcmt plan and the pull request comment.
You can confirm _GH_TOKEN is masked as *** properly.

$ tfcmt plan -- terraform plan
tfcmt plan -- terraform plan

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_cloudbuild_trigger.filename_trigger will be created
  + resource "google_cloudbuild_trigger" "filename_trigger" {
      + create_time   = (known after apply)
      + filename      = "cloudbuild.yaml"
      + id            = (known after apply)
      + location      = "us-central1"
      + name          = (known after apply)
      + project       = "hello"
      + substitutions = {
          + "_GH_TOKEN" = "***"
        }
      + trigger_id    = (known after apply)

      + trigger_template {
          + branch_name = "main"
          + project_id  = (known after apply)
          + repo_name   = "my-repo"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

image

v4.8.0

27 Dec 12:18
Immutable release. Only release title and notes can be modified.
v4.8.0
063d756

Choose a tag to compare

Pull Requests | Issues | v4.7.3...v4.8.0

Features

#1090 #1091 Support passing GitHub Access token via the environment variable TFCMT_GITHUB_TOKEN

In addition to the environment variable GITHUB_TOKEN, tfcmt supports the environment variable TFCMT_GITHUB_TOKEN too.

v4.8.0-1

27 Dec 11:28
Immutable release. Only release title and notes can be modified.
v4.8.0-1
7083f1f

Choose a tag to compare

v4.8.0-1 Pre-release
Pre-release

v4.7.3...v4.8.0-1

Features

#1090 #1091 Support passing GitHub Access token via the environment variable TFCMT_GITHUB_TOKEN

In addition to the environment variable GITHUB_TOKEN, tfcmt supports the environment variable TFCMT_GITHUB_TOKEN too.

v4.7.3

18 Dec 11:29
Immutable release. Only release title and notes can be modified.
v4.7.3
5474748

Choose a tag to compare

Pull Requests | Issues | v4.7.2...v4.7.3

Bug Fixes

#1073 Fix a bug code blocks are broken if "```" are used in the command output @jemiam

When triple backticks are in results for terraform command, wrapCode method uses HTML tags(pre + code) to escape it.
But currently these tags are also escaped so it doesn't work as intended.

New Contributor 🎉

Thank you for your contirbution!

@jemiam #1073

v4.7.2

08 Dec 00:07
Immutable release. Only release title and notes can be modified.
v4.7.2

Choose a tag to compare

Pull Requests | Issues | v4.7.1...v4.7.2

Fixes

#1061 #1062 Change the default template to fix the issue that emojis aren't rendered

Recently, some emojis in tfcmt's comments aren't rendered properly.

image

We guess this is a bug of GitHub itself.

We found the bug doesn't occur if we remove emojis from the end of lines.

Before

### :warning: Resource Deletion will happen :warning:

After

### :warning: Resource Deletion will happen

Until the bug will be fixed, we'll remove emojis from the end of lines.

Others

Update dependencies

#1058 chore(deps): update dependency golang/go to v1.21.5

v4.7.1

11 Oct 03:17
Immutable release. Only release title and notes can be modified.
v4.7.1

Choose a tag to compare

Pull Requests | Issues | v4.7.0...v4.7.1

Others

#959 chore(deps): update dependency golang/go to v1.21.3
#960 fix(deps): update module github.com/google/go-cmp to v0.6.0