HashiCorp Vault is a powerful tool for managing secrets and protecting sensitive data. Deploying Vault in a consistent and automated manner is crucial for maintaining a secure infrastructure. In this article, we will explore how to deploy HashiCorp Vault using Ansible, a popular open-source automation tool. We will create an Ansible role to streamline the deployment process, ensuring that Vault is installed and configured correctly on your infrastructure.
Prerequisites
Before we begin, ensure you have the following:
-
Ansible: Installed on your local machine. You can install it using pip:
pip install ansible
-
SSH Access: Ensure you have SSH access to the target servers where Vault will be deployed.
-
Servers: At least one server to deploy Vault. For production, consider a highly available setup with multiple nodes.
-
Ansible Inventory: A basic inventory file listing your target servers.
Creating an Ansible Role for Vault
Ansible roles allow you to organize tasks, handlers, and variables in a structured way. Let’s create a role named vault
to handle the deployment.
Step 1: Create the Role Structure
Run the following command to create the role structure:
ansible-galaxy init vault
This command will create a directory named vault
with the following structure:
vault/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
Step 2: Define Variables
Edit vault/defaults/main.yml
to define default variables for Vault installation:
vault_version: "1.13.0"
vault_download_url: "https://releases.hashicorp.com/vault/{{ vault_version }}/vault_{{ vault_version }}_linux_amd64.zip"
vault_install_dir: "/usr/local/bin"
vault_user: "vault"
vault_group: "vault"
vault_config_dir: "/etc/vault.d"
vault_data_dir: "/opt/vault"
Step 3: Create Tasks
Edit vault/tasks/main.yml
to define the tasks for installing and configuring Vault:
---
- name: Ensure Vault group exists
group:
name: "{{ vault_group }}"
state: present
- name: Ensure Vault user exists
user:
name: "{{ vault_user }}"
group: "{{ vault_group }}"
create_home: no
shell: /bin/false
- name: Download Vault
get_url:
url: "{{ vault_download_url }}"
dest: "/tmp/vault_{{ vault_version }}.zip"
mode: '0644'
- name: Unzip Vault binary
unarchive:
src: "/tmp/vault_{{ vault_version }}.zip"
dest: "{{ vault_install_dir }}"
remote_src: yes
mode: '0755'
notify: Restart Vault
- name: Create Vault configuration directory
file:
path: "{{ vault_config_dir }}"
state: directory
owner: "{{ vault_user }}"
group: "{{ vault_group }}"
mode: '0750'
- name: Create Vault data directory
file:
path: "{{ vault_data_dir }}"
state: directory
owner: "{{ vault_user }}"
group: "{{ vault_group }}"
mode: '0750'
- name: Copy Vault configuration
template:
src: vault.hcl.j2
dest: "{{ vault_config_dir }}/vault.hcl"
owner: "{{ vault_user }}"
group: "{{ vault_group }}"
mode: '0640'
notify: Restart Vault
- name: Create systemd service for Vault
template:
src: vault.service.j2
dest: /etc/systemd/system/vault.service
notify: Restart Vault
- name: Enable and start Vault service
systemd:
name: vault
enabled: yes
state: started
Step 4: Create Templates
Create a Vault configuration template vault/templates/vault.hcl.j2
:
storage "file" {
path = "{{ vault_data_dir }}"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
}
ui = true
Create a systemd service template vault/templates/vault.service.j2
:
[Unit]
Description=Vault service
After=network.target
[Service]
User={{ vault_user }}
Group={{ vault_group }}
ExecStart={{ vault_install_dir }}/vault server -config={{ vault_config_dir }}/vault.hcl
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=65536
Restart=on-failure
[Install]
WantedBy=multi-user.target
Step 5: Define Handlers
Edit vault/handlers/main.yml
to define a handler for restarting Vault:
---
- name: Restart Vault
systemd:
name: vault
state: restarted
Step 6: Use the Role in a Playbook
Create a playbook deploy_vault.yml
to use the vault
role:
---
- hosts: all
become: yes
roles:
- vault
Step 7: Run the Playbook
Execute the playbook to deploy Vault:
ansible-playbook -i inventory deploy_vault.yml
Conclusion
By following these steps, you have successfully created an Ansible role to automate the deployment of HashiCorp Vault. This approach ensures a consistent and repeatable deployment process, enhancing the security and reliability of your infrastructure. You can further customize the role to suit your specific requirements, such as integrating with a backend storage solution or enabling TLS.
For more information on Ansible and HashiCorp Vault, consider the following resources:
By leveraging the power of Ansible, you can efficiently manage your infrastructure and ensure that your secrets management solution is deployed securely and reliably.