Can Terraform mask variables in the console output?

Viewed 5380

I wanted to post this as a feature request but I wanted to see if anyone else has found some clever way of doing this before I post. Or maybe someone from Hashicorp can tell me this will be a feature in the coming

I have looked high and low for some way to mask variables from the console when running terraform apply/show. Preferably trying to mask variables using a local-exec provisioner when passing variables to a script.

A tool called Terrahelp is the only thing I can find that will do this but it will only apply to variables in a tfvars file which doesn't allow interpolations. This doesn't help since we are trying to use Vault to keep secrets out of the terraform files.

Current Versions
Terraform v0.11.7
provider.null v1.0.0
provider.template v1.0.0
provider.vault v1.3.1
provider.vsphere v1.8.1

Use Case

provisioner "local-exec" {
    command = "&'${path.module}\\scripts\\script.ps1' -name ${var.node_name} -pass '${var.pass}' -user ${var.user} -server ${var.server}"
    interpreter = ["Powershell", "-Command"]
  }  

Attempted Solutions I'm using Vault to keep secrets out of the Terraform files, so I am using the vault provider and calling data from it. I have tried to create a module and output the secrets with the sensitive = true value and then calling that module to use the secrets however that still shows in the console.

Proposal

Allow some kind of sensitive value much like output to variables within Terraform. So if scripts like the above are called in the console they won't show sensitive variable information.

References https://github.com/hashicorp/terraform/issues/16114 https://github.com/hashicorp/terraform/issues/16643

6 Answers

Thanks for the feedback, the passwords cannot be set for a one time use as some of these are service accounts in AD that do other things which those applications cannot handle constant password changes.

We did find a solution through another product which is Azure/Azure DevOps. We are storing credentials in key vaults in Azure which Azure DevOps has access to and using Azure DevOps pipelines to send terraform code to our Build Server. Azure DevOps seems to act as a shell which hides any secrets from the console and it works pretty well. I would recommend it to anyone who is also looking to hide secrets from terraform files/command line.

Here is how I do it for a few on-premise services:

1 - var.password doesn't actually stores a password. Rather, it stores the name of an environment variable.

2 - My scripts get passwords from those environment variables.

3 - I have a small program that loads secrets to environment and clears them for terraform apply.

So in the end I just bypass Terraform for secrets used by scripts. Not ideal, but I also couldn't find a better solution.

I think https://github.com/cloudposse/tfmask might be what you're looking for:

Command line utility to mask sensitive output from a transform plan or terraform apply.

You first set an environment variable to filter the masked keys (admittedly there's some manual work involved here):

export TFMASK_VALUES_REGEX="(?i)^.*(secret|password|oauth|token|key).*$"

And then pipe terraform commands through tfmask, resulting in masked output:

terraform plan | tfmask

This is self-advertising, but I create a tool called terramask that works with Terraform 0.12.

Issues are welcome

I can't quite tell if this is your use case or not, but one strategy that we've used with sensitive variables is to make use of the default Terraform behavior to use environment variables to set TF variables, e.g.,

variable "sensitive_variable" {
  type = "string"
}
sensitive_var=$(curl url/with/remote/value)
export TF_VAR_sensitive_variable=$sensitive_var
terraform apply
Related