"Enhancing Security using Hashicorp vault and integrating with terraform : A Step-by-Step Guide to Avoid Hardcoded Secrets"
Create AWS EC2 instance on Ubuntu:
To create an AWS EC2 instance with Ubuntu, you can use the AWS Management Console or the AWS CLI. Here are the steps involved in creating an EC2 instance using the AWS Management Console:
Go to the AWS Management Console and navigate to the EC2 service.
Click on the Launch Instance button.
Select the Ubuntu Server xx.xx LTS AMI.
Select the instance type that you want to use.
Configure the instance settings.
Click on the Launch button.
Install vault on the EC2 instance
To install Vault on the EC2 instance, you can use the following steps:
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 | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.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 tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
Install Vault
sudo apt install vault
To verify vault installation, use below
Use the following command, to start vault
For practise purpose we are using dev environment, in realtime we use production environments.
vault server -dev -dev-listen-address="0.0.0.0:8200"
To set the VAULT_ADDR environment variable in your current shell session, you can use the following command:
export VAULT_ADDR='http://0.0.0.0:8200'
After setting the VAULT_ADDR, you can use Vault CLI commands, and they will communicate with the Vault server running at the specified address:
Now you would be able to access your vault user interface page at http://<publicip>:8200
choose method as token and token value , you will get when running below command for the first time, make a note of it to use it later.
vault server -dev -dev-listen-address="0.0.0.0:8200"
In this scenario, We are using Vault to configure a basic KV (Key-Value) store, which is used to store usernames and passwords.
First step is to provide the mount path which hashicorp uses to store the cred details
Provide path name as per your choice, here i gave kv and click on Enable engine
Now create a secret, provide secretname and secretdata tab, provide username and password
Once this is saved, only you, as an admin, will have access to it. To grant access to Terraform or any other integrations, you need to define roles as follows
currently via user interface , creation of roles is not supported , so we have to use CLI and run commands to create a role.
Enable AppRole Authentication:
This command tells Vault to enable the AppRole authentication method.
vault auth enable approle
Create an AppRole:
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
This command defines a Vault policy named terraform
that grants various permissions for different paths, including listing, reading, creating, updating, and deleting secrets, as well as managing tokens. This policy is used to control access for Terraform and other integrations.
Now you'll need to create an AppRole with appropriate policies and configure its authentication settings. Here are the steps to create an AppRole:
create the app role
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
Generate Role ID and Secret ID:
You can retrieve the Role ID using the Vault CLI:
vault read auth/approle/role/terraform/role-id
Generate Secret ID:
vault write -f auth/approle/role/terraform/secret-id
Save the Secret ID and Role ID securely, as it will be used for Terraform authentication.
Example code to integrate hashicorp vault with terraform
provider "aws" {
region = "us-east-1"
}
provider "vault" {
address = "http://54.210.31.17:8200"
skip_child_token = true
auth_login {
path = "auth/approle/login"
parameters = {
role_id = "9c747bec-641e-73ed-9986-8740092ed09c"
secret_id = "23de76c8-5e98-27b2-2943-093cd6882b32"
}
}
}
data "vault_kv_secret_v2" "example" {
mount = "kv"
name = "secret_demo"
}
# Security Group for Splunk
resource "aws_security_group" "splunk_sg" {
name = "splunk_sg_new2"
description = "Allow SSH and HTTP traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 8000
to_port = 8000
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EC2 Instance for Splunk
resource "aws_instance" "splunk_instance" {
ami = "ami-04a81a99f5ec58529" # Ensure this AMI is valid in us-east-1
instance_type = "t2.micro"
security_groups = [aws_security_group.splunk_sg.name]
user_data = <<-EOF
#!/bin/bash
set -e
# Update packages and install Docker
sudo apt-get update -y
sudo apt-get install -y docker.io
# Start Docker and add ubuntu user to the docker group
sudo systemctl start docker
sudo usermod -aG docker ubuntu
# Wait for Docker to start
sleep 5
# Run the Splunk container
sudo docker run -d -p 8000:8000 \
-e SPLUNK_START_ARGS="--accept-license" \
-e SPLUNK_PASSWORD="${data.vault_kv_secret_v2.example.data["username"]}" \
--name splunk splunk/splunk:latest
EOF
tags = {
Name = "SplunkInstance"
Secret = data.vault_kv_secret_v2.example.data["username"]
}
}
Thanks to Abhishek Veeramalla for the amazing explanation. Check out the video tutorial by Abhishek Veeramalla for more details.