Install Hashicorp Vault to store Secrets and use it in Terraform.
Tags: beginners, tutorial, devops, hashicorpvault
Published: 2024-02-11 03:06:35

## 1. Installation 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
```
- Update packages
```
sudo apt update
```
- Install Vault
```
sudo apt install vault
```
## 2. Start Vault Server
- Start Vault Server
```
vault server -dev -dev-listen-address="0.0.0.0:8200"
```
## 3. Configure Terraform to read the secret from Vault.
1. Enable AppRole Authentication:
> To enable the AppRole authentication method in Vault, you need to use the Vault CLI or the Vault HTTP API.
- Run the following command to enable the AppRole authentication method:
```
vault auth enable approle
```
2. Create an AppRole:
- 2.a) Create Policy
```
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
```
2.b) Create the AppRole:
```
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
```
3. Generate Role ID and Secret ID:
> After creating the AppRole, you need to generate a Role ID and Secret ID pair. The Role ID is a static identifier, while the Secret ID is a dynamic credential.
- 3.a) Generate Role ID:
```
vault read auth/approle/role/my-approle/role-id
```
- 3.b) Generate Secret ID:
```
vault write -f auth/approle/role/my-approle/secret-id
```
This command generates a Secret ID and provides it in the response. Save the Secret ID securely, as it will be used for Terraform authentication.
## 4. Provider.tf file
```
provider "vault" {
  address = "<>:8200"
  skip_child_token = true

  auth_login {
    path = "auth/approle/login"

    parameters = {
      role_id = "<>"
      secret_id = "<>"
    }
  }
}
```
## 5. Main.tf
- 5.a) Create vault server
```
# Create vault server - 1 
resource "aws_instance" "vault-server-1" {
  ami                    = "ami-053b0d53c279acc90"
  instance_type          = "t2.micro"
  key_name               = "efronlogin"
  subnet_id              = aws_subnet.sd-snet1.id
  vpc_security_group_ids = [aws_security_group.sd-sg-1.id]
  user_data              = base64encode(file("vault_userdata.sh"))

   tags = {
    name="vault-Master"
    Environment="dev"
  }

}
```
- 5.b) Connect to Hashicorp Vault via "data" resource
```
 data "vault_kv_secret_v2" "example" {
   mount = "secret" // change it according to your mount
   name  = "dev-s3" // change it according to your secret
 }
```
- 5.c) Use it to retrieve in Terraform

- create EC2 instance with Tag names and Secret Name
```
resource "aws_instance" "my_instance" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"

  tags = {
    Name = "test"
    Secret = data.vault_kv_secret_v2.example.data["secret_name"]
  }
}
```

**Credits:-**
Thanks to [Abhishek Veeramalla](https://www.youtube.com/@AbhishekVeeramalla)