# Securing AWS Instances with HashiCorp Vault and Terraform

In this blog, we will deep dive into the Terraform Vault. Terraform Vault is a Hashicorp tool that can store and manage different secrets such as tokens, passwords, API tokens, certificates, and so on. By smoothly integrating the terraform with the Hashicorp vault, can ensure the integrity of our sensitive data and mitigate the risk of unauthorized access or data leaks. This integration empowers us to leverage secrets stored in the HashiCorp Vault directly within our Terraform workflows, enhancing security measures and safeguarding critical information.

Firstly, we will initiate the creation of an EC2 instance either manually from AWS ui or using Terraform. Subsequently, within the instance, our focus will shift to the installation of Hashicorp Vault. This installation lays the groundwork for subsequent integration with Terraform, establishing a smooth connection between the two tools. Through this orchestrated process, we aim to set up an environment where HashiCorp Vault becomes an integral part of our Terraform workflows, enhancing security and management of sensitive information.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706098409262/42934130-6902-44cf-9b15-62272045bc97.png align="center")

Our instance is created and ready.

In the ec2 instance, we will install the Vault.

**Install gpg**

```plaintext
sudo apt update && sudo apt install gpg
```

**Download the signing key to a new keyring**

```plaintext
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
```

**Verify the key's fingerprint**

```plaintext
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
```

**Add the HashiCorp repo**

```plaintext
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
```

```plaintext
sudo apt update
```

**Finally, Install Vault**

```plaintext
sudo apt install vault
```

To start the Vault

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099057523/01740d52-1077-4230-b755-b183a182bb0e.png align="center")

After executing all the commands above, our vault is running successfully.

Open another terminal and log into the instance and run the following command that is displayed.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099227200/c1d805f6-2c0a-4cf4-90ff-ffb4b61ed011.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099320837/b6b2d5d1-4716-4e00-9834-6f7715dedaa5.png align="center")

To access the vault we need to give the access to instance to access port 8200.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099482468/b2d38167-38c9-4d2d-932f-c2d8e4028b91.png align="center")

Lets access the Vault in http://[3.88.160.206:8200](http://3.88.160.206:8200)/

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099575549/815a95c0-9370-438b-a3a0-b237cf295cc3.png align="center")

Now to log into the Vault, the token is available in the terminal. Copy the code and paste it.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099691856/7cdb2fe0-98e6-407e-9a8d-516ed09a28b5.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099779714/94b679a3-1d5f-40d0-a108-393f15867176.png align="center")

We have successfully logged into the Vault.

At the sidebar, we can see the Secret ENgines, Access, Policies. Let's know about these.

**Secret Engine**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706099975253/9d6fa0b6-b1e5-4640-b90e-7730856304e5.png align="center")

The Secret Engine in HashiCorp Vault is responsible for managing and dispensing secrets, which are sensitive pieces of information such as API keys, passwords, or certificates. They are nothing but the different types of secrets that we can create in Hashicorp Vault.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706100334986/b8f0bf7b-5636-4c28-8938-ecf5d88c8826.png align="center")

We create a simple engine and the engine is enabled. IT will be used to create the key-value pairs.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706100479834/d706b47c-1c9f-4ca8-98c9-e34bdb3f7b68.png align="center")

A secret is created inside the Hashicorp Vault. only the root user has access to it. If anyone wants to access the secret through Terraform or Ansible, they need the grant. The grant is only possible from the **Access** feature of Vault. Here in the Hashicorp vault, Access can be considered as an IAM role and Policy can be considered as IAM policy.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706100929788/dfaa8761-6e50-45b2-8812-40603e96f3e9.png align="center")

In the Access section, there are different authentication methods, we chose the AppRole. But we cannot create the role using UI, we need do it from the terminal.

Enable the authentication method

```plaintext
vault auth enable approle
```

Let's create the policy

```plaintext
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
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706104344710/ed64452c-8f9a-49a1-8e76-1f71a4ad696b.png align="center")

**Create the Role**

```plaintext
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
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706104383333/94530e28-1e1b-4f92-981e-69285637e1ac.png align="center")

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.

**Generate Role ID**:

```plaintext
vault read auth/approle/role/terraform/role-id
```

**Generate Secret ID**:

```plaintext
vault write -f auth/approle/role/terraform/secret-id
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706104427374/5d6ba2e0-610d-4944-bf68-5af9a6bb298b.png align="center")

We will create the instance and will use the secret created in the vault.

**main.tf**

```plaintext
provider "aws" {
  region = "us-east-1"
}

provider "vault" {
  address = "3.88.160.206:8200"
  skip_child_token = true

  auth_login {
    path = "auth/approle/login"

    parameters = {
      role_id = "ed169c1c-c96b-613a-479a-c1b82de9a720"
      secret_id = "5a65c56e-3132-2410-b83a-bd52658dfcf2"
    }
  }
}

data "vault_kv_secret_v2" "example" {
  mount = "kv" 
  name  = "test-secret" 
}

resource "aws_instance" "my_instance" {
  ami           = "ami-053b0d53c279acc90"
  instance_type = "t2.micro"

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

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706102836322/56c72695-be80-497a-b14f-9454f08b299b.png align="center")

```plaintext
terraform plan
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706105013828/4fbe2911-a11f-42e9-95b3-43a20ac0b073.png align="center")

It shows the 1 to add and in the tag section name=" test" and secret="subash" will be imported from the hashicorp vault.

```plaintext
terraform apply
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706105738634/864cd6b5-7590-4023-9bf2-fe4ecbe1419f.png align="center")

The Terraform apply is successful and the resource is added.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706105809298/eaef1121-8f3d-4618-b009-5ba014880c6d.png align="center")

Our resource is created successfully.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1706105858826/b1927572-43f8-457e-a34b-938eaf37d9c2.png align="center")

We can see in the tag section the secret named "subash" is also imported from the Hashicorp vault that we had created earlier.

Destroy the resources

```plaintext
terraform destroy
```

This integration enhances the security of your infrastructure by centralizing and managing secrets in the HashiCorp Vault, allowing Terraform to securely access and use these secrets during infrastructure provisioning. It's a great practice for ensuring the integrity of sensitive data and minimizing the risk of unauthorized access or data leaks.

I hope you liked this blog. If any mistake, do comment down below 🚀.

Do like and share this blog♥️
