When configuring infrastructure, you often need to use sensitive data such as usernames, passwords, API tokens, or Personally Identifiable Information (PII). It’s crucial to prevent accidental exposure of this information in CLI output, logs, or version control. Terraform offers built-in features to help safeguard sensitive data.
Overview
In this tutorial, you’ll learn how to use Terraform to deploy a web application on AWS step by step. You’ll set up key infrastructure components like a VPC, a load balancer, EC2 instances, and a database. Instead of hardcoding database credentials, you’ll use sensitive variables to keep them secure, Terraform will automatically redact these values in command outputs and logs.
You’ll also discover how to manage sensitive variables using environment variables and .tfvars
files. To wrap things up, we’ll talk about how sensitive data appears in Terraform state and go over best practices to keep your state files secure.
Prerequisites
Before you get started, make sure you have:
- Terraform installed.
- AWS account with admin rights.
- Git CLI installed.
Cheat sheet 1: You can follow along with this tutorial using either Terraform Community Edition or HCP Terraform. If you go with HCP Terraform, you’ll get extra features like remote state management, structured plan outputs, and resource summaries.
Cheat sheet 2: Some of the resources you’ll create might go beyond AWS Free Tier limits. To avoid unexpected charges, remember to clean up and destroy your infrastructure when you’re done.
Step 1: Deploy Infrastructure
- Clone the repository: learn-terraform-sensitive-variables
git clone https://github.com/djcloudking/terraform-challenges/tree/main/20_Learn-terraform-sensitive-variables

- cd learn-terraform-sensitive-variables
This setup builds the foundation for your web application, covering everything from networking and load balancing to compute instances and a database.
- Initialize Terraform: terraform init


This sets up your working directory and pulls in the necessary providers to get started.
- Apply the configuration: terraform apply
- Terraform will generate an execution plan and prompt for confirmation. Enter
yes
to proceed.
Cheat Sheet: If using HCP Terraform, output formatting may differ slightly, but the process remains the same.

Step 2: Modify Database Credentials
By default, the database configuration in main.tf
contains hardcoded credentials. You’ll refactor this to use input variables instead.
- Declare sensitive variables in
variables.tf
:

- You’ve marked the variables as sensitive, great! Now, update
main.tf
to use these variables.

If you were to run terraform apply
right now, Terraform would ask you to enter values for these new variables since you haven’t set defaults for them. But typing them in manually can be slow and lead to mistakes. Next, you’ll explore two different ways to set these sensitive variables and learn about the security pros and cons of each method.
Step 3: Define Values Using a .tfvars
File
- Create a
secret.tfvars
file to assign values to the new variables:

Apply these changes by using the -var-file
parameter, and when prompted for confirmation, type “yes” to proceed.
- Run terraform apply -var-file=”secret.tfvars”

Since you marked the new variables as sensitive, Terraform will hide their values in the output whenever you run commands like plan, apply, or destroy.
You’ll notice that the password is flagged as a sensitive value, and so is the username. The AWS provider automatically considers the password for any database instance as sensitive, even if you don’t explicitly mark the variable as sensitive, so it will be redacted.
It’s still a good practice to declare this variable as sensitive to ensure it’s hidden in other places where it might be referenced.
Using a .tfvars
file to set values lets you keep sensitive data separate from other variables, making it easier to spot which values are sensitive.
However, this approach means you’ll need to securely manage and share the secret.tfvars
file only with the right people. It’s also important not to accidentally commit .tfvars
files with sensitive information into version control.
Cheat Sheet: That’s why Terraform’s recommended .gitignore
file is set up to ignore files that match the *.tfvars
pattern.
Step 4: Set values with variables
- Set the database administrator username and password using environment variables for
Cheat Sheet: the following commands will vary if you are using Terraform Community Edition or Terraform variables for HCP Terraform, Mac or Linux, Windows Powershell, or Windows Command Prompt.
- When Terraform runs, it checks your environment for any variables that follow the pattern
TF_VAR_<VARIABLE_NAME>
and automatically assigns those values to the matching Terraform variables in your configuration. - Run : export TF_VAR_db_username=admin TF_VAR_db_password=adifferentpassword

- Now, run
terraform apply
, and Terraform will assign these values to your new variables. - Respond to the confirmation prompt with
yes
.
Cheat Sheet: When you use environment variables to set sensitive values, remember that these values will be stored in your environment and could appear in your command-line history.
Step 5: Reference sensitive variables
When you use sensitive variables in your Terraform configuration, they behave like any other variable. However, Terraform will automatically hide these values in command output and log files, and it will throw an error if it detects they might be exposed in any other way.
- Now, go ahead and add the following output values to
outputs.tf
.

- Now apply this change: terraform init, then terraform apply. Terraform will raise an error, since the output is derived from sensitive variables.

- Mark the database connection string output as sensitive, so Terraform will automatically hide it.

- Apply this change (terraform apply), and you’ll see that Terraform now hides the database connection string output.
- When prompted for confirmation, type “yes” to apply the changes.

Step 6: Handle Sensitive values in state
When you run Terraform commands with a local state file, Terraform saves the state as plain text, including variable values, even those marked as sensitive.
It needs to store these values in the state file to track if they’ve changed since the last time you applied your configuration.
- Run grep “password” terraform.tfstate

Cheat Sheet: If you’re using an operating system that doesn’t have the grep
command, you can open the terraform.tfstate
file in your text editor and search for “password” to find the relevant lines.
- Just marking variables as sensitive isn’t enough to keep them secure. You also need to ensure they are protected when passing them into your Terraform configuration and secure them in your state file.
- HCP Terraform and Terraform Enterprise handle sensitive values by encrypting all variable values before storing them. For even tighter control, HashiCorp Vault securely stores and manages access to sensitive data like tokens and passwords.
Step 7: Clean up your infrastructure
- Before you move forward, make sure to destroy the infrastructure you set up in this tutorial to avoid any unnecessary costs or bills.
- Run:
terraform destroy
- When prompted for confirmation, type “yes” to proceed.
Bravo! You’ve deployed a secure web application on AWS using Terraform, while ensuring that sensitive data such as database credentials, API tokens, and access keys were not exposed in logs, CLI outputs, or version control.
Key security measures included marking variables as sensitive, using environment variables for secret injection, and securing Terraform state files.
What you did:
- Terraform Infrastructure: Deployed a VPC, ALB, EC2 instances, and an RDS database using Infrastructure as Code (IaC).
- Sensitive Variable Management: Used Terraform’s sensitive attribute to prevent secret exposure.
- Environment-Based Secrets: Implemented .tfvars files and environment variables for secure credential handling.
- Remote State Storage: Configured AWS S3 with encryption to protect Terraform state.
- Access Control & IAM: Restricted access to state files and sensitive outputs using IAM policies.
Key Technologies & Tools Used:
- Terraform: Infrastructure as Code for AWS resource provisioning.
- AWS IAM & Security Groups: Role-based access and network security enforcement.
- AWS S3 (Remote State Storage): Secure Terraform state with encryption and restricted access.
- AWS Secrets Manager & HashiCorp Vault: Best practices for managing secrets.
- Git & .gitignore: Prevented sensitive data from being committed to version control.
What you’ll learn:
- How to protect sensitive data in Terraform using built-in security features.
- The importance of securing Terraform state files with remote storage and access restrictions.
- How to inject sensitive values into Terraform configurations without exposing them in logs.
- Best practices for infrastructure automation and security in AWS environments.
Find all configuration files on Github: https://github.com/djcloudking/terraform-challenges/tree/main/20_Learn-terraform-sensitive-variables.

Leave a Reply