Protect sensitive input variables
Often you need to configure your infrastructure using sensitive or secret information such as usernames, passwords, API tokens, or Personally Identifiable Information (PII). When you do so, you need to ensure that you do not accidentally expose this data in CLI output, log output, or source control. Terraform provides several features to help avoid accidentally exposing sensitive data.
In this tutorial, you will use Terraform to deploy a web application on AWS,
including a VPC, load balancer, EC2 instances, and a database. You will replace
the database's hard-coded credentials with variables configured with the
sensitive
flag. Terraform will then redact these values in the output of Terraform commands or log messages. Next, you will set values
for these variables using environment variables and with a .tfvars
file.
Finally, you will identify the sensitive values in state, and learn about ways
to protect your state file.
Prerequisites
You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.
Select the HCP Terraform tab to complete this tutorial using HCP Terraform.
This tutorial assumes that you are familiar with the Terraform workflow. If you are new to Terraform, complete the Get Started tutorials first.
In order to complete this tutorial, you will need the following:
- Terraform v1.2+ installed locally.
- An AWS account with local credentials configured for use with Terraform.
- The git CLI.
Note
Some of the infrastructure in this tutorial may not qualify for the AWS free tier. Destroy the infrastructure at the end of the tutorial to avoid unnecessary charges. We are not responsible for any charges that you incur.
Create infrastructure
Clone the Learn Terraform Sensitive Variables GitHub repository for this tutorial.
Change to the repository directory.
This configuration defines a web application, including a VPC, load balancer, EC2 instances, and a database.
Initialize this configuration.
Now apply the configuration to create the example infrastructure.
Respond to the confirmation prompt with a yes
.
Tip
This tutorial shows the output for Terraform commands run with Terraform Community Edition. If you are following the HCP Terraform workflow, the output may differ slightly but the results will be the same.
If you use HCP Terraform to provision your resources, your workspace now displays the list of all of the resources it manages.
Refactor database credentials
Open main.tf
in your text editor. Near the bottom of the file, find the
aws_db_instance.database
block that defines your database. The database
username and password are hard-coded. Refactor this configuration to remove
these values.
First, declare input variables for the database administrator username and
password in variables.tf
.
Notice that you've declared the variables as sensitive
. Now update main.tf
to reference these variables.
If you were to run terraform apply
now, Terraform would prompt you for values
for these new variables since you haven't assigned defaults to them. However,
entering values manually is time consuming and error prone. Next, you will use
two different methods to set the sensitive variable values, and learn about
security considerations of each method.
Set values with a .tfvars
file
Terraform supports setting variable values with variable definition (.tfvars
)
files. You can use multiple variable definition files, and many practitioners
use a separate file to set sensitive or secret values.
Create a new file called secret.tfvars
to assign values to the new variables.
Apply these changes using the -var-file
parameter. Respond to the confirmation
prompt with yes
.
Because you flagged the new variables as sensitive
, Terraform redacts their
values from its output when you run a plan, apply, or destroy command. Notice
that the password is marked sensitive value
, while the username is marked
sensitive
. The AWS provider considers the password argument for any database
instance as sensitive, whether or not you declare the variable as sensitive, and
will redact it as a sensitive value
. You should still declare this variable as
sensitive to make sure it's redacted if you reference it in other locations than
the specific password argument.
Setting values with a .tfvars
file allows you to separate sensitive values
from the rest of your variable values, and makes it clear to people working with
your configuration which values are sensitive. However, it requires that you
maintain and share the secret.tfvars
file with only the appropriate people.
You must also be careful not to check .tfvars
files with sensitive values into
version control. For this reason, GitHub's recommended .gitignore file for
Terraform
configuration
is configured to ignore files matching the pattern *.tfvars
.
Set values with variables
Set the database administrator username and password using environment variables for Terraform Community Edition or Terraform variables for HCP Terraform.
When Terraform runs, it looks in your environment for variables that match the
pattern TF_VAR_<VARIABLE_NAME>
, and assigns those values to the corresponding
Terraform variables in your configuration.
Now, run terraform apply
, and Terraform will assign these values to your new variables.
Respond to the confirmation prompt with yes
.
Note
When using environment variables to set sensitive values, keep in mind that those values will be in your environment and command-line history.
Reference sensitive variables
When you use sensitive variables in your Terraform configuration, you can use them as you would any other variable. Terraform will redact these values in command output and log files, and raise an error when it detects that they will be exposed in other ways.
Add the following output values to outputs.tf
.
Now apply this change. Terraform will raise an error, since the output is derived from sensitive variables.
Flag the database connection string output as sensitive
, causing Terraform to hide it.
Apply this change to see that Terraform will now redact the database connection
string output. Respond to the confirmation prompt with yes
to apply these
changes.
Sensitive values in state
When you run Terraform commands with a local state file, Terraform stores the
state as plain text, including variable values, even if you have flagged them as
sensitive
. Terraform needs to store these values in your state so that it can
tell if you have changed them since the last time you applied your
configuration.
Tip
If you are using an operating system without the grep
command,
open the terraform.tfstate
file in your text editor and search for password
to see the relevant lines.
Marking variables as sensitive is not sufficient to secure them. You must also keep them secure while passing them into Terraform configuration, and protect them in your state file. HCP Terraform and Terraform Enterprise manage and share sensitive values, and encrypt all variable values before storing them. HashiCorp Vault secures, stores, and tightly controls access to tokens, passwords, and other sensitive values.
Clean up your infrastructure
Before moving on, destroy the infrastructure you created in this tutorial.
Be sure to respond to the confirmation prompt with yes
.
If you used HCP Terraform for this tutorial, after destroying your resources, delete the learn-terraform-sensitive-variables
workspace from your HCP Terraform organization.
Next steps
In this tutorial you used Terraform variables to set sensitive information about
your infrastructure. In addition to setting the sensitive
flag for sensitive
inputs, you must also ensure that sensitive values are not accidentally exposed
when you pass them into your Terraform configuration. Also, you must keep your
Terraform state file secure to avoid accidentally exposing sensitive data.
Now that you know how to use sensitive input variables, check out the following resources for more information.
- Inject secrets into Terraform using the Vault provider by following another tutorial.
- Automatically encrypt state at rest by storing it in HCP Terraform. Get Started with Terraform Cloud.
- Read the documentation about how to manage sensitive data in state.