Skip to content

Security

Handling sensitive values

Hashicorp Vault

You can use HashiCorp Vault to store and manage sensitive information such as secrets, tokens, and passwords for use in Terraform. The Vault provider can be installed and configured in your Terraform configuration using the following code:

provider "vault" {
  address = "<https://vault.example.com>"
  token   = "VAULT_TOKEN"
}

A vault_generic_secret data source can then be used to read secrets from Vault and use them in your Terraform configuration. Here is an example of how to do this:

data "vault_generic_secret" "example" {
  path = "secret/mysecret"
}

resource "aws_db_instance" "example" {
  password = data.vault_generic_secret.example.data["password"]
}

Using vault_generic_secret allows you to read secrets from the secret/mysecret path in Vault and use the password field from the secret to set the password for an aws_db_instance resource. This is just one way to use HashiCorp Vault with Terraform. Other Vault data sources and resources can also be used to manage and use secrets in your Terraform configuration.

Environment variables

To keep sensitive information such as passwords, API keys, and tokens out of your Terraform configuration files, you can use environment variables. Marking a variable as sensitive will redact its value from Terraform commands or log messages. Here's an example:

variable "db_password" {
  type = string
  sensitive = true
}

resource "aws_db_instance" "example" {
  # ...

  password = var.db_password
}

To set the value of the db_password variable using an environment variable, use the TF_VAR_ prefix followed by the variable name. For example, set the value of the db_password variable by setting the TF_VAR_db_password environment variable:

export TF_VAR_db_password="mysecretpassword"

When using environment variables to set sensitive values, keep in mind that those values will be in your environment and command-line history. Secure your environment and command-line history to prevent accidental exposure of sensitive information.

TFMASK

tfmask is an open-source program written in Go that dynamically censors values in the Terraform execution log output. You can use tfmask to hide sensitive data in outputs during execution. To use tfmask, you will need to install it on your system and then configure it to censor the values you want to hide. You can do this by setting the TFMASK_VALUES_REGEX and TFMASK_CHAR environment variables to supply the regex expression and the character replacing the actual values.

Here’s an example of how to use tfmask with Terraform:

# Install tfmask
go get github.com/cloudposse/tfmask

# Set the TFMASK_VALUES_REGEX environment variable to specify the regex expression for values to censor
export TFMASK_VALUES_REGEX='(?i)^.*(secret|password|private_key|access_key).*$'

# Set the TFMASK_CHAR environment variable to specify the character replacing the actual values
export TFMASK_CHAR='*'

# Run Terraform commands and pipe the output through tfmask
terraform plan | tfmask

In this example, we’re installing tfmask using go get, and then setting the TFMASK_VALUES_REGEX and TFMASK_CHAR environment variables to specify the regex expression for values to censor and the character replacing the actual values. Finally, we’re running a terraform plan command and piping the output through tfmask to censor any sensitive values in the output.

Connecting to AWS using assume role

  • Use assume_role block within the AWS provider configuration to assume an IAM role when connecting to AWS in Terraform.
  • This allows you to use temporary security credentials to access AWS resources.
  • It is useful when working with multiple AWS accounts or when granting access to AWS resources to users or applications without AWS credentials.
  • Define an assume_role block within the aws provider configuration.
  • The role_arn argument specifies the Amazon Resource Name (ARN) of the IAM role to assume.
  • The session_name argument specifies a name for the session.
  • The external_id argument is an optional value that you can use to further secure the role assumption process.
  • Terraform will use the assume_role block to assume the specified IAM role and obtain temporary security credentials.
  • These credentials will be used to access AWS resources defined in your Terraform configuration.
  • Example:
provider "aws" {
  region = "us-east-1"

  assume_role {
    role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
    session_name = "SESSION_NAME"
    external_id  = "EXTERNAL_ID"
  }
}

It's better than using an access key and secret because it allows granting temporary access to resources without sharing long-term credentials. The assume_role block in AWS provider configuration is used to assume an IAM role and obtain temporary credentials. Example code:

S3 backend encrypt

The encrypt option for the S3 backend in Terraform allows you to enable server-side encryption for the state file stored in the S3 bucket1]. Here is an example of how to use the encrypt option:

terraform {
  backend "s3" {
    bucket = "mybucket"
    key    = "path/to/my/key"
    region = "us-east-1"
    encrypt = true
  }
}

In this example, we specify the encrypt option and set it to true to enable server-side encryption for the state file. This means that the state file will be encrypted at rest using Amazon S3-managed keys (SSE-S3).