Using Ansible Vault to Encrypt a String

Ansible DevOps Security

There are a number of ways to protect secrets you wish to use in your Playbooks. I’ll show a simple example here of how you can encrypt a string, copy it into your Playbook for use and then run the Playbook, where the string is de-crypted in-line and used without exposing it in plain text within any of the Ansible YAML files. If you are using version control to store your Ansible Playbooks (you are right? 😀 ), then you’ll not want to be storing the plain text passwords direct into the YAML.

Create the Encrypted String

First we need to create an encrypted string, in this example we’re using Ansible Vault for this, we’ll run the following command which will take the string we wish to be encrypted for later use in our Playbook.

ansible-vault encrypt_string --vault-id @prompt WellSecretString!

You’ll be prompted for the vault password, you’ll need to enter this to encrypt the string, and you’ll also need to provide it when you run the Playbook, or the string will not be able to be de-crypted and used. When run you’ll see an output something like this:

Add to the Playbook

Within your Playbook you then need to include the encrypted text (ciphertext) in say a variable, where you can then call upon the variable within a task to use it for something. Here is a very simple example playbook that consists of three files, you add the encrypted text into a variable called “secretstring” in the vault-play.yml file. Note the name of the server is because i’m using it to build a Kubernetes cluster, so just using it for this example.



  - hosts: localhost
    become: false
      - name: Check Ansible Version
            - ansible_version.major == 2
            - ( ansible_version.minor == 7 or ansible_version.minor == 9)
          msg: "Sanger Ansible requires Ansible 2.7 or 2.9"

  - import_playbook: vault-play.yml



  - name: "Reachability Checks"
    hosts: k8sservers

      secretstring: !vault |

    - name: "Test Reachability"
    - name: "Print Secret String"
        msg: "{{ secretstring }}"



Okay, great we’re ready to run the Playbook.

Run the Playbook

Now, you can’t just run the Playbook as you normally would otherwise when Ansible reaches the encrypted string it will barf because it is unable to decrypt the string. So to get round this all we need to do is supply the vault password when we run the Playbook as follows:

ansible-playbook vault.yml -i hosts --ask-vault-pass

And there you go, as you can see Ansible first asks you for your vault password then runs the Playbook and decrypts the string in-line, okay this isn’t very helpful, we’re just printing the secret to the string, but think of what else you could do, such as feeding this secret into a command to perform some privileged operation such as become/sudo etc.

$ ansible-playbook vault.yml -i hosts --ask-vault-pass
Vault password:

PLAY [localhost] **********************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************
ok: [localhost]

TASK [Check Ansible Version] **********************************************************************************************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"

PLAY [Reachability Checks] ************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************
ok: []

TASK [Test Reachability] **************************************************************************************************************************************
ok: []

TASK [Print Secret String] ************************************************************************************************************************************
ok: [] => {
    "msg": "WellSecretString!"

PLAY RECAP ****************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


Although simple, it is powerful. As mentioned there are other methods to protect secrets in your Playbooks, a downside of this method is that the Vault password is a shared password, i.e. anyone who needs to run the Playbook needs to know it, but if you are a small team or its just you, it can be an excellent way to protect your secrets without too much hassle.

Leave a Reply

Your email address will not be published. Required fields are marked *