Integrating HashiCorp Vault with Terraform for Securing RDS Credentials | Technical EJ - Latest Technology News

Thursday, 22 May 2025

Integrating HashiCorp Vault with Terraform for Securing RDS Credentials

  Ekansh Jain       Thursday, 22 May 2025

I have successfully integrated HashiCorp Vault with Terraform to store the password of the RDS instance for the master username.





Steps to follow:

1. Deploy a Vault server in an EC2 instance. You can create a new EC2 instance or can use the existing one, if you have any.

In my case, I created a new EC2 instance of the Ubuntu flavour and used the following commands to deploy and run the Vault server in development mode.

wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt update && sudo apt install vault

You can verify if the vault server has been deployed or not using the following command.

vault




2. Start the vault server using the following command. This will be exposed on port 8200 and will be accessible through every IP address.
vault server -dev -dev-listen-address="0.0.0.0:8200"





3. You can access vault dashboard using http://ec2_instance_public_ip:8200




4. To log in through the Vault dashboard, you can use the token as visible from the below screenshot.




5. Now, let's create a secret. Click on KV under the secrets engines tab.




So here we are going to create a key-value (KV) pair, and we will use the value as a password for the RDS master user for our RDS instance.

6. After providing the path name (I am using dbpassword), you can click on Enable engine.




7. Click on create secret.




8. Here, you can provide the path of your secret along with a key-value pair. (I am using myrdspostgrespassword as a path for this secret)



Here, I have named my name as "password", and in value, I have stored the actual password, which we are going to use as a master user password for our RDS instance.

9. Now, in order to read this secret from Terraform, we need to create an ACL policy and role. That being said, click on Enable new method under authentication method.




10. Here we will use AppRole method for authentication to this vault server.




11. Then, click on enable method after entering Path (I am using 
approle)



12. Now, we have enabled the authentication method, i.e., AppRole; now we need to create a policy and role as mentioned in the step: 9, using which terraform can access the vault and can read the secret "password: mypassword"

In order to do so, open a new terminal where you have access to the EC2 instance and run the following commands to create the ACL policy and role.

$export VAULT_ADDR='http://0.0.0.0:8200'


-- writing policy


$vault policy write terraform - <<EOF

path "dbpassword/*" { # <-- Use your chosen secret mount name here
capabilities = ["create", "read", "update", "delete", "list"] } path "auth/token/create" { capabilities = ["create", "read", "update", "list"] } EOF


EOF

Success! Uploaded policy: terraform


-- Creating role and attaching above created policy with parameter token_policies


$ vault write auth/approle/role/terraform \

    secret_id_ttl=20m \

    token_num_uses=10 \

    token_ttl=20m \

    token_max_ttl=30m \

    secret_id_num_uses=40 \

    token_policies=terraform


Success! Data written to: auth/approle/role/terraform


13. Now, run the following commands to fetch the role ID and secret ID (similar to AWS Access Key and Secret Key).


$ vault read auth/approle/role/terraform/role-id

Key        Value

---        -----

role_id    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


$ vault write -f auth/approle/role/terraform/secret-id

Key                   Value

---                   -----

secret_id             xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

secret_id_accessor    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

secret_id_num_uses    40

secret_id_ttl         20m


14. Now, use the following Terraform code:

provider "aws" {
region = "ap-south-1"
}

provider "vault" {
address = "http://13.233.227.159:8200"
skip_child_token = true

auth_login {
path = "auth/approle/login"

parameters = {
role_id = "xxxxxxx"
secret_id = "xxxxxxx"
}
}
}

data "vault_kv_secret_v2" "my_vault_secret" {
mount = "dbpassword"
name = "myrdspostgrespassword"
}

resource "aws_db_instance" "rds_postgres" {
identifier = "postgres-instance"
allocated_storage = 20
db_name = "postgres"
engine = "postgres"
engine_version = "16.6"
instance_class = "db.t3.micro"
username = "postgres"
password = data.vault_kv_secret_v2.my_vault_secret.data["password"] // here "password" is the key which we stored in secret.
skip_final_snapshot = true
}


15. Then check the RDS resource. You will see one RDS created through terraform code and this rds is using the master user password from the vault



Note: You can verify the same by logging in to this RDS using the password you provided while creating a secret in the vault server.

GitHub Repository (with main.tf and readme.md files):

https://github.com/EkanshJain98/terraform-project/tree/main

logoblog

Thanks for reading Integrating HashiCorp Vault with Terraform for Securing RDS Credentials

Newest
You are reading the newest post

No comments:

Post a Comment

If you have any doubts, Please Comment down