HashiCorp Vault Integration with Terraform - Day 10

·

3 min read

HashiCorp Vault is a tool designed to securely store and access secrets. It provides a centralized place to manage sensitive data such as API keys, passwords, certificates, and encryption keys. Vault offers features such as encryption, access control, dynamic secrets, and audit logging to help organizations manage and secure their secrets effectively.

Steps to Install Vault on Ubuntu machine

https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-install

Security Group configuration

Configure the inbound rules of the EC2 instance to allow traffic on port 8200

Start the Vault development server

vault server -dev -dev-listen-address="0.0.0.0:8200"

Configure environment variables

Add the environment variables for both Vault address and token.

export VAULT_ADDR='ENTER YOUR VAULT ADDRESS'

export VAULT_TOKEN='ENTER YOUR VAULT TOKEN'

Check the Vault status

vault status

Sign in to Vault development server

<PUBLIC IP OF EC2 INSTANCE>:8200

Select the method as 'Token' and provide the Vault token to sign in to Vault.

Select 'Secrets Engines' from the left panel and click 'Enable new engine'.

To store a key-value pair, select 'KV' from the generic list and click 'Next'.

Enter a name for the path and click 'Enable Engine'.

After creating the path, click 'Create secret' on the next page.

Enter the path for the secret, store your key-value pair, and click 'Save'.

Once your key pair is stored, you will see it listed under 'Secrets Engine' as shown below.

To use these credentials from other resources like Terraform, you need to grant access to the external resource.

To create an 'AppRole', navigate to 'Authentication Methods' in the left panel and select 'AppRole' from the generic list.

Enable the AppRole authentication method.

Create vault policies via CLI. Policies in Vault control what a user can access.

Enable an AppRole role named "terraform", to configure some basic token options and to attach the previously defined "terraform" policy to all tokens that it creates when applications authenticate with the role.

Generate Role ID and Secret ID

vault read auth/approle/role/my-approle/role-id

vault write -f auth/approle/role/my-approle/secret-id

Reference: https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-policies

Use Vault in Terraform Configuration

Terraform configuration to provision an AWS EC2 instance and dynamically retrieve a secret from HashiCorp Vault to tag the instance during creation.

Function of the Terraform configuration:

  • The script configures the AWS provider (provider "aws") to use the us-east-2 region and the Vault provider (provider "vault") to connect to the Vault server running on an EC2 instance with a public IP address (http://<PUBLIC IP OF EC2 INSTANCE>:8200).

  • It also sets skip_child_token = true, which skips creating child tokens for authentication.

  • The auth_login block specifies the authentication method (approle) and provides the role_id and secret_id required for authentication.

  • The data "vault_kv_secret_v2" "example" block retrieves a secret (kaizen-creds) from the Vault server under the creds mount point.

  • This secret can be accessed later in the configuration using data.vault_kv_secret_v2.example.data["kaizen"].

  • The resource "aws_instance" "dev_instance" block provisions an EC2 instance with the specified AMI (ami-0c20d88b0021158c6) and instance type (t2.micro).

  • It also assigns tags to the instance, a tag called secret, which gets its value from the Vault secret retrieved earlier (data.vault_kv_secret_v2.example.data["kaizen"]).

provider "aws" {
  region = "us-east-2"
}

provider "vault" {
  address = "http://<PUBLIC IP OF EC2 INSTANCE>:8200"
  skip_child_token = true

  auth_login {
    path = "auth/approle/login"

    parameters = {
      role_id = "<ENTER YOUR ROLE ID>"
      secret_id = "<ENTER YOUR SECRET ID>"
    }
  }
}

data "vault_kv_secret_v2" "example" {
  mount = "creds"
  name  = "kaizen-creds"
}

resource "aws_instance" "dev_instance" {
    ami = "ami-0c20d88b0021158c6"
    instance_type = "t2.micro"

    tags = {
      secret = data.vault_kv_secret_v2.example.data["kaizen"]
    }  
}