Learn how to secure sensitive information In Terraform using Terrahelp
By: Joshua Yohannan
Tags: Encryption, Terrafrom

Rupeek is India’s largest asset-backed lending platform.

This means that while we have the pleasure to serve the credit needs of millions of Indians, it is our top-most priority to secure their personal information. We are big on security, and we do not compromise on it — ever. We always ensure to keep sensitive information encrypted. Meaning, we convert the original information, known as plain text, into an alternative form known as ciphertext.

Even within Rupeek, keeping confidential information in plain text is not endorsed. Because anyone with access to the version control system can access the secret information and there is no way to inspect or revoke who has had access. Better safe than sorry!

At Rupeek, we use Terraform to manage infrastructure as code. This blog discusses how we ensure the security of sensitive information such as passwords and usernames.

Let’s take the below example as our problem statement.

In the above example, you can see that we need to pass the username and password as plain text for the database creation. There are a number of ways to overcome such problem statements and there are certain things you need to be extra careful when you are writing a terraform code. Let’s take a look into it.

1) Secrets should not be held in plain text.

2) Maintain the safety of your Terraform state file.

Secrets should not be held in plain text

Normally we don’t endorse keeping confidential information in plain text. Here are some reasons why -

1) The secret is accessible to anyone who has access to the version control system.

2) There’s no way to inspect or revoke the secret’s access.

To overcome this we use Encryption. It converts the original representation of the information, known as plain text, into an alternative form known as ciphertext.

Encryption Using Terrahelp

Terrahelp is a command line utility written in Go, which provides encryption for Terraform variables and state files.

Currently, Terrahelp offers -

Encryption & decryption functionality — This functionality provides the ability to encrypt and decrypt files such as terraform.tfstate files, as well as piped in output from commands such as terraform apply etc.

Masking functionality — If you don’t want to encrypt sensitive data but rather mask it out with something like *****, you can use the mask command instead.

You can find the steps to install Terrahelp here (https://github.com/opencredo/terrahelp).

Now, we’ll see how Terraform variables can be encrypted using Terrahelp.

Suppose the terraform code looks like this:

database.tfvars

example.tfvars

The sensitive piece of information here is “samplepassword”.

How to encrypt the sensitive values using Terrahelp?

First, create a file and paste the sensitive value in the file.

Next, we need to figure out a key for the encryption. Let’s use ‘057EFE8CF0F15DE86876F9E313E3D0D6’ as the encryption key.

Now, let’s encrypt the file!

The encrypted value from terrahelp-example-help.txt file will look like below:

Next, copy and paste this encrypted value in place of the sensitive plain text in the code.

The example.tfvars variable will look like this:

Now, we can safely upload this to any version control system.

How to run Terraform Plan/Apply with encrypted variables?

First, clone the code from the version control system. Then, we need to decrypt the example.tfvars file before running the terraform plan.

When we pass the option ‘-mode=inline’, Terrahelp will check each line. It takes only the variable that is encrypted by Terrahelp.

After decryption, the example.tfvars file will revert to its original state. However, we need to keep in mind to use the same key for decryption that was used for encryption.

Now we can plan/apply in Terraform. But where do we store this simple key value (encryption-key)?

We either set the encryption key as Environment Variables or use Jenkins Global credentials.

Setting the encryption key as Environment Variables

We do the following to set the encryption key as Environment variables:

Use Jenkins Global credentials

When running Terraform using Jenkins, we save the information as ‘simple-key’ Global credentials and add this decryption as a separate step before the Terraform plan or apply.

For example:

Jenkins Global credentials ensure that no sensitive information is in plain text. However, those using the code must take extra steps to either manually set this encryption/decryption of variables or run a wrapper script before running a terraform plan or apply.

Maintain the safety of your Terraform state file

Whenever you deploy your infrastructure with Terraform it will generate a state file that contains all the data about the infrastructure including all the parameters you passed in. This state file will be created in the folder where you ran terraform apply as plain text. To protect the state files I suggest keeping the Terraform state file in storage that support encryption like AWS s3, GCS, etc.

Conclusion

Sensitive information should not be kept in plain text for security issues. You can maintain the safety of your Terraform state file using encrypted storage. There are several other use cases that we can do with Terrahelp. We shall discuss those in the upcoming blogs. So stay tuned!