Day-7-terraform
Mastering Secrets Management with Terraform and HashiCorp Vault
TLDR: This blog post provides a comprehensive guide on integrating Terraform with HashiCorp Vault for effective secrets management, covering installation, configuration, and practical examples.
In the world of DevOps, managing sensitive information such as passwords, API tokens, and certificates is crucial. This blog post is based on Day 7 of the Terraform Zero to Hero series, where we dive deep into the concept of secrets management using Terraform and HashiCorp Vault. Understanding how to implement secrets management is essential for any DevOps engineer, as it helps in securely handling sensitive data.
create EC2 instance |
Search ->ec2 -> select instance (lots of cards → resource) -> launch instance |
Name : vault |
Os : ubuntu |
AMI : V22.04 (free tire -> available for 750 hr/ year) |
Instance type: t2.micro (free tire) |
Key-pair : drop down (create a new key pair) -> name : aws_login -> type: RSA -> format : .pem - - - > create key pair (file downloaded-> aws_login.pem) |
Configure storage : 8gb |
----> launch instance |
login to created ec2 and install package and vault |
ssh -i aws_login.pem ubuntu@<created-instance-public-ip-add> |
update package and install gpg: sudo apt update && sudo apt install gpg |
Download the signing key to a new keyring : wget -O- https://apt.releases.hashicorp.com/gpg |
Verify the key's fingerprint : gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint |
Add the HashiCorp repo : echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" |
sudo apt update |
Finally, Install Vault : sudo apt install vault |
start vault : vault server -dev -dev-listen-address="0.0.0.0:8200" |
→env variable : export VAULT_ADDR=’http://0.0.0.0:8200’ |
→unseal key: — |
→Root token: — |
open a new tab and login to created instance |
ssh -i aws_login.pem ubuntu@<created-instance-public-ip-add> |
export VAULT_ADDR=’http://0.0.0.0:8200’ |
unable to open issue → http://<public ip address>:8200 |
Created instance -> security (tab) -> security group - > inbound rules - > edit inbound rules |
Add rule ->type: custom tcp -> port: 8200-> source : any where - > save rule |
refresh page → http://<public ip address>:8200 → now u can see vault UI |
signin vault → create secret and enable AppRole method for Auth |
signin vault → [Method: Token ,Token: paste root token] → root user |
imp topic : secrets engines, Access, Policies |
secrets engines (side bar)→ generic → KV -→ path: kv → enable engine |
create secrete → path : test-secret → secret data [key: username , value: gokul ] → save |
Access → enable new method → AppRole (~IAM role in AWS) →next —> enable method |
now i want to autheticate Terraform using AppRole Mechanism |
cant create any roles using UI , so we have to do it through terminal |
→ create roles —>create policy → attach that policy → approle |
run in terminal below command : |
// create policy -> policy name: terraform , granting certain action to folder/path/mount points in secrets engines
vault policy write terraform - <<EOF
path "*" {
capabilities = ["list", "read"]
}
path "secrets/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "kv/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "auth/token/create" {
capabilities = ["create", "read", "update", "list"]
}
EOF
// create AppRole -> token_policies=policy name(from above)
vault write auth/approle/role/terraform \
secret_id_ttl=10m \
token_num_uses=10 \
token_ttl=20m \
token_max_ttl=30m \
secret_id_num_uses=40 \
token_policies=terraform
~ aws access and secret access key → generate Role ID and Secret ID with policy name -> terraform |
Generate Role ID: vault read auth/approle/role/terraform/role-id |
Generate Secret ID: vault write -f auth/approle/role/terraform/secret-id |
// main.tf
provider "aws" {
region = "us-east-1"
}
provider "vault" {
address = "http://<instance-public-ip>:8200"
skip_child_token = true
auth_login {
path = "auth/approle/login"
parameters = {
role_id = "<>" // generated above step
secret_id = "<>" // generated above step
}
}
}
// to read data from vault --> kv/test-secret
data "vault_kv_secret_v2" "example" {
mount = "kv" // change it according to your mount
name = "test-secret" // change it according to your secret
}
resource "aws_instance" "my_instance" {
ami = "ami-053b0d53c279acc90"
instance_type = "t2.micro"
tags = {
Secret = data.vault_kv_secret_v2.example.data["username"] // to get value(gokul) from key -> username
}
}
terraform init |
terraform plan |
terraform apply |
What is Secrets Management?
Secrets management refers to the processes and tools used to store, manage, and access sensitive information securely. Whether you are using Terraform, Ansible, CI/CD pipelines, or Kubernetes, implementing a robust secrets management strategy is vital. HashiCorp Vault is one of the most popular tools for this purpose, allowing integration with various platforms including Terraform.
Overview of HashiCorp Vault
HashiCorp Vault is a tool designed for securely accessing secrets. It supports various integrations and can be used with Terraform, Ansible, CI/CD tools, and Kubernetes. In this tutorial, we will focus on integrating Terraform with HashiCorp Vault to manage secrets effectively.
Setting Up the Environment
Creating a Linux Instance
To get started, we will create a Linux instance on AWS. For this demonstration, we will use Ubuntu 20.04. Here are the steps:
Log in to your AWS console.
Launch a new EC2 instance and select Ubuntu 20.04 as the operating system.
Once the instance is running, note down the public IP address.
Installing HashiCorp Vault
After setting up the instance, we need to install HashiCorp Vault. Follow these steps:
SSH into your EC2 instance using the command:
ssh -i your-key.pem ubuntu@your-instance-ip
Update the package manager and install GPG:
sudo apt update sudo apt install -y gnupg software-properties-common
Add the HashiCorp repository:
wget -qO - https://apt.releases.hashicorp.com/gpg | sudo apt-key add - echo "deb [arch=amd64] https://apt.releases.hashicorp.com focal main" | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt update sudo apt install vault
Verify the installation by running:
vault
Starting the Vault Server
HashiCorp Vault can run in two modes: development and production. For demonstration purposes, we will start the development server:
vault server -dev
This command will start the Vault server in development mode, which is suitable for testing and learning.
Configuring HashiCorp Vault
Enabling the Key-Value (KV) Secret Engine
Access the Vault UI by navigating to
http://your-instance-ip:8200
in your web browser.Use the root token provided in the terminal to log in.
Enable the KV secret engine by executing the following command in the Vault CLI:
vault secrets enable -path=kv kv
Create a secret in the KV store:
vault kv put kv/test-secret username=your-username password=your-password
Creating Access Policies and Roles
To allow Terraform to access the secrets, we need to create a policy and a role:
Create a policy that grants access to the KV secrets:
path "kv/*" { capabilities = ["read", "create", "update"] }
Enable AppRole authentication:
vault auth enable approle
Create a role for Terraform:
vault write auth/approle/role/terraform policies=terraform
Retrieve the Role ID and Secret ID:
vault read auth/approle/role/terraform
Integrating Terraform with HashiCorp Vault
Writing the Terraform Configuration
Create a new directory for your Terraform project and navigate into it:
mkdir terraform-vault-integration cd terraform-vault-integration
Create a
main.tf
file and add the following configuration:provider "aws" { region = "us-east-1" } provider "vault" { address = "http://your-instance-ip:8200" } data "vault_kv_secret_v2" "example" { name = "test-secret" mount = "kv" } resource "aws_instance" "example" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" tags = { Name = "MyInstance" Secret = data.vault_kv_secret_v2.example.data["password"] } }
Initialize Terraform:
terraform init
Apply the configuration:
terraform apply
Conclusion
In this blog post, we explored the integration of Terraform with HashiCorp Vault for effective secrets management. We covered the installation of Vault, configuration of the KV secret engine, and how to set up Terraform to retrieve secrets securely. This integration is crucial for managing sensitive information in a secure and efficient manner.
Feel free to experiment with different configurations and let us know your thoughts in the comments. Happy coding!