"Enhancing Security using Hashicorp vault and integrating with terraform : A Step-by-Step Guide to Avoid Hardcoded Secrets"

"Enhancing Security using Hashicorp vault and integrating with terraform : A Step-by-Step Guide to Avoid Hardcoded Secrets"

ยท

4 min read

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.

https://youtu.be/sIkRK33AY50?si=jv7a9rumvkQazmf5

ย