# How to Get Started with Ansible Vault

**Goal:** With this short blog, my aim is to give the reader all the information he needs to successfully implement Ansible Vault in his DevOps project.

**Assumption:** This blog assumes that you already have a working knowledge of ansible concepts, such as roles, variables, inventory, playbooks etc.

## What is Ansible Vault?

According the [official documentation](https://docs.ansible.com/ansible/latest/vault_guide/vault.html):

> Ansible Vault encrypts variables and files so you can protect sensitive content such as passwords or keys rather than leaving it visible as plaintext in playbooks or roles.

Let me expand on the 'encrypted variable and files' part. You can keep all your sensitive information inside a single encrypted file, or you can encrypt individual variables/strings, and use them right inside your `playbook` or `vars` files.

### Choosing between encrypted variables or encrypted files

#### Encrypted Files

**Pros:**

* Easy to manage/share a file
    
* Easy to exclude encrypted files using `.gitignore`
    
* Easy to change `rekey` / change password.
    

**Cons:**

* Every time you need to update the contents of your encrypted file, you have to decrypt it, make your changes, and the encrypt it again.
    
* Updating your encrypted files, creates unnecessary changes to your `git` repository.
    

#### Encrypted Variables

**Pros:**

* Easy to update. You don't have to update a file containing other variables, but just your intended variable.
    
* Doesn't create unnecessary changes to your `git` repository.
    

**Cons:**

* Difficult to `rekey` / change password. If you have 20 encrypted variables, then you have to re-encrypt all 20 variables to change your password.
    
* Impossible to exclude them out of your `git` repository. Encrypted variables are used within your playbook/vars files. Excluding these files means excluding your playbook/vars from the repository.
    

Personally, I prefer encrypted files as they are easy to manage and can be excluded from the repository, even though, they are a hassle to update.

### The `ansible-vault` command line tool

Here's an oversimplified syntax of the `ansible-vault` command line tool:

```bash
ansible-vault <password source> <command>
```

There are three ways to provide password to the `ansible-vault` tool:

* A password prompt using the `--ask-vault-pass` option.
    
* A password file provided by the `--vault-password-file path/to/password/file` option.
    
* Third party secrets manager
    

There are 7 commands for the tool, namely create, decrypt, edit, view, encrypt, encrypt\_string, and rekey. Lets look at them.

### Create an encrypted variable

Just execute one of the following commands to create an encrypted variable:

```bash
ansible-vault encrypt_string --ask-vault-pass 'mysupersecretpassword' --name 'password_vars'

Or 

ansible-vault encrypt_string --vault-password-file path/to/password/file 'mysupersecretpassword' --name 'password_vars'
```

You'll get an output similar to this:

```plaintext
password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          35633434356139363131363933356438316561666431313862383231393364633564343862636330
          6136366435313165626637326238326432316264383562620a356664393361373230326339323934
          32653462343235633738336332623437393434333137333634363437346234356635363734623030
          3761363238656131330a386536393665653034636337343733376437316536306666376638616432
          3761
```

You can use this encrypted string directly in your YAML files.

### Create an encrypted file

This command will create new file named `vault.yml` :

```bash
ansible-vault create vault.yml
```

This command will encrypt an existing file named `vault.yml` :

```bash
ansible-vault encrypt vault.yml
```

### View an encrypted file

```bash
ansible-vault --ask-vault-pass view vault.yml
```

### Edit an encrypted file

```bash
ansible-vault --ask-vault-pass edit vault.yml
```

Set environment variable $EDITOR to `nano` if you don't want to use `vi`.

### Decrypt a file

```bash
ansible-vault --ask-vault-pass decrypt vault.yml
```

### Change password for a file

```bash
ansible-vault rekey vault.yml
```

### Using ansible vault in an ansible playbook

Let's implement what we have learned so far using an example.

In this example we'll try to ping a server using an ansible playbook. But since the server's IP address and user name is sensitive information, we'll keep them encrypted. We'll keep the IP address in an encrypted file and the username as an encrypted variable.

Lets start by creating a password file:

```bash
echo 'my_vault_password' > .vault_pass
```

Make sure you don't upload the password in a `git` repository:

```bash
echo '.vault_pass' >> .gitignore
```

There are two ways to use this vault password file:

1. Passing it as an argument `--vault-password-file`
    
    ```bash
    ansible-vault view --vault-password-file .vault_pass vault.yml
    ```
    
2. Setting path to this file in environment variable
    
    ```bash
    export ANSIBLE_VAULT_PASSWORD_FILE=path/to/.vault_pass
    ```
    

To encrypt the username `ubuntu`:

```bash
ansible-vault encrypt_string --vault-password-file .vault_pass 'ubuntu' --name 'vault_ansible_user'
```

You'll get an output similar to the one below. Save it.

> ```bash
> vault_ansible_user: !vault |
>           $ANSIBLE_VAULT;1.1;AES256
>           64653062636463306663313065646238616638623039316562643765363635653065623031643463
>           3636386430323964626135366563313162623263656434650a386538343233333764383236626266
>           62313635383962383461663861313663613932643666333234333666393134303964626463346539
>           3237666531393736660a323031346264613339613037366232343263386530663365366139653333
>           6331
> ```

Now, let's create an encrypted file `vault.yml` to store our server's IP address.

```bash
ansible-vault create --vault-password-file .vault_pass vault.yml
```

Paste the following content inside the editor:

```plaintext
---
vault_ansible_host: 1.1.1.1
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719460846905/16f0af6e-1d66-41e7-9cc9-e03e3cf8b0ae.png align="center")

Next, we'll define the `inventory.yml` file.

```yaml
---
server:
  hosts:
    server01:
      ansible_host: "{{ vault_ansible_host }}"
      ansible_user: vault_ansible_user: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          35633434356139363131363933356438316561666431313862383231393364633564343862636330
          6136366435313165626637326238326432316264383562620a356664393361373230326339323934
          32653462343235633738336332623437393434333137333634363437346234356635363734623030
          3761363238656131330a386536393665653034636337343733376437316536306666376638616432
          3761
```

Finally, we'll write our `playbook.yml`.

```yaml
---
- name: Playbook
  hosts: server
  vars_files:
    - vault.yml
  tasks:
    - name: ping task
      ansible.builtin.ping:
```

Here's my directory structure:

```plaintext
.
├── .vault_pass
├── inventory.yml
├── playbook.yml
└── vault.yml
```

To run the playbook, execute the following command:

```bash
ansible-playbook --vault-password-file .vault_pass -i inventory/hosts.yml playbook.yml
```

This is how to use ansible vault. For more information, please refer the [official documentation](https://docs.ansible.com/ansible/latest/vault_guide/vault.html). Thank you!
