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 this data is not accidentally exposed 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 whenever they are used
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.
Note: Marking variables as sensitive is not sufficient to secure them. You should use secrets management tools and secure your state in addition to marking variables as sensitive.
Setting the sensitive
flag helps avoid accidental exposure of sensitive or
secret values. You must also keep them secure while passing them into
Terraform configuration, and protect them in your state file. Terraform Cloud 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.
»Prerequisites
This tutorial assumes that you are familiar with Terraform, and input variables. If you're new to Terraform, follow the Getting Started tutorial. If you aren't comfortable using input variables, follow the Customize Terraform Configuration with Variables tutorial.
In order to follow this tutorial, you will need the following:
- The Terraform CLI, version 0.14 or later.
- AWS 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
.
»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 environment variables
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.
Assign values to the database administrator username and password using environment variables.
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.
Since Terraform state can contain sensitive values, you must keep your state file secure to avoid exposing this data. Refer to the Terraform documentation to learn more about securing your state file.
»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
.
»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 Terraform cloud. Get Started with Terraform Cloud.
- Read the documentation about how to manage sensitive data in state.