How to avoid plain text credentials in terraform code? Terraform is an open-source infrastructure as a code tool that supports multi-cloud platforms. Many organizations have taken the multi-cloud strategy to manage the cost and eliminate the single vendor dependency. If you have multiple cloud environments, terraform becomes the default choice for provisioning. Communicating to multi-cloud in a single language is easier than using the respective cloud tools like cloud formation.
When it comes to credentials in terraform code, you have to rely on an external vault to encrypt it. Codes will be stored in a git repository and keeping plain text passwords in the code will lead to security breaches. This article will walk through how to source the encrypted credentials from AWS secret manager.
Sample Terraform code with plain text password:
1. The following sample terraform code consists plain text password. The secret will be written in a text file on the successful execution.
resource "null_resource" "test" { provisioner "local-exec" { when = create command = "echo GooDay@123 > secret.txt" } }
2. Let’s run the terraform apply.
lingesh@unixarena:~/test$ terraform apply --auto-approve Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # null_resource.test will be created + resource "null_resource" "test" { + id = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. null_resource.test: Creating... null_resource.test: Provisioning with 'local-exec'... null_resource.test (local-exec): Executing: ["/bin/sh" "-c" "echo GooDay@123 > secret.txt"] null_resource.test: Creation complete after 0s [id=3284626307449570859] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
3. Let’s look at the secret file which should be created.
lingesh@unixarena:~/test$ cat secret.txt GooDay@123 lingesh@unixarena:~/test$
Let’s now simulate the same using AWS secret manager by encrypting the credentials.
Store the credentials in AWS Secret Manager
1. Login to AWS console and navigate to secret manager.
2. Select the credentials type as “other type of secret” and select plain text. Enter the credentials in JSON format.
3. Enter the secret name to store the credentials.
We have successfully stored the new credentials in AWS secret manager. In the next section, we will see how to call the stored credentials using terraform.
Update the terraform code to use encrypted credentials
1. Update the terraform code like the following to call the newly stored secret using terraform data module.
data "aws_secretsmanager_secret_version" "creds" { # Fill in the name you gave to your secret secret_id = "prod/app/ec2" }
2. Source the data to terraform local to read the JSON code.
locals { ec2_creds = jsondecode(data.aws_secretsmanager_secret_version.creds.secret_string) }
3. Let’s write the credentials to the text file using the following block of code. Here we haven’t used any plain text passwords in the code.
resource "null_resource" "test_user" { provisioner "local-exec" { when = create command = "echo ${local.ec2_creds.user} >> secret.txt" } } resource "null_resource" "test_pass" { provisioner "local-exec" { when = create command = "echo ${local.ec2_creds.password} >> secret.txt" } }
4. You can also call the secret to any part of the terraform code like below. (Ex: local.ec2_creds.user & local.ec2_creds.password )
output "Username" { description = "ec2 username" value = local.ec2_creds.user sensitive = true } output "Password" { description = "ec2 password" value = local.ec2_creds.password sensitive = true }
Putting all the codes together. Store the following content on “main.tf” file.
data "aws_secretsmanager_secret_version" "creds" { # Fill in the name you gave to your secret secret_id = "prod/app/ec2" } locals { ec2_creds = jsondecode(data.aws_secretsmanager_secret_version.creds.secret_string) } resource "null_resource" "test_user" { provisioner "local-exec" { when = create command = "echo ${local.ec2_creds.user} >> secret.txt" } } resource "null_resource" "test_pass" { provisioner "local-exec" { when = create command = "echo ${local.ec2_creds.password} >> secret.txt" } } output "Username" { description = "ec2 username" value = local.ec2_creds.user sensitive = true } output "Password" { description = "ec2 password" value = local.ec2_creds.password sensitive = true }
5. Let’s execute the code and see the results.
lingesh@unixarena:~/test$ terraform apply --auto-approve Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # null_resource.test_pass will be created + resource "null_resource" "test_pass" { + id = (known after apply) } # null_resource.test_user will be created + resource "null_resource" "test_user" { + id = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. Changes to Outputs: + Password = (sensitive value) + Username = (sensitive value) null_resource.test_pass: Creating... null_resource.test_user: Creating... null_resource.test_user: Provisioning with 'local-exec'... null_resource.test_user (local-exec): (output suppressed due to sensitive value in config) null_resource.test_pass: Provisioning with 'local-exec'... null_resource.test_pass (local-exec): (output suppressed due to sensitive value in config) null_resource.test_user: Creation complete after 0s [id=5936974914414746230] null_resource.test_pass: Creation complete after 0s [id=8908060725121377732] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: Password = <sensitive> Username = <sensitive> lingesh@unixarena:~/test$
Here is the decrypted text file.
lingesh@unixarena:~/test$ cat secret.txt admin GooDay@123 lingesh@unixarena:~/test$
The following visual shows the mapping between the AWS secret manager key vs Terraform code.
Using the same method, you can encrypt the credentials in terraform code for any cloud resources deployment. Hope this article is informative to you.
Leave a Reply