Search code examples
ansiblevagrantansible-vault

Ansible called by Vagrant does not prompt for vault password


Summary

I have a Vagrantfile provisioning a Virtualbox VM with Ansible. The Ansible playbook contains an Ansible Vault-encrypted variable. My problem is that Vagrant provisioning does not prompt for the password although I pass the option to do so.

Minimal, complete example

Vagrantfile:

Vagrant.configure(2) do |config|
    config.vm.provider "virtualbox" do |vb|
        # Build a master VM for this box and clone it for individual VMs
        vb.linked_clone = true
    end
    config.vm.box = "bento/ubuntu-16.04"
    config.vm.hostname = "test-vm"

    config.vm.provision :ansible do |ansible|
        ansible.verbose = true
        ansible.playbook = "playbook.yml"
        ansible.ask_vault_pass = true
#       ansible.raw_arguments = --ask-vault-pass
#       ansible.raw_arguments = ["--vault-id", "@prompt"]
#       ansible.raw_arguments = ["--vault-id", "dev@prompt"]
    end
end

playbook.yml:

---
- name: Test
  hosts: all
  vars:
    foo: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          65306264626234353434613262613835353463346435343735396138336362643535656233393466
          6331393337353837653239616331373463313665396431390a313338333735346237363435323066
          66323435333331616639366536376639626636373038663233623861653363326431353764623665
          3663636162366437650a383435666537626564393866643461393739393434346439346530336364
          3639

  tasks:
    - name: print foo's value
      debug:
        msg: "foo -> {{ foo }}"

The Ansible Vault password is abc.

When I call vagrant up on first execution of the Vagrantfile or later vagrant provision I do not get the expected prompt to enter the password. Instead the task print foo's value prints the (red) message:

fatal: [default]: FAILED! => {"msg": "Attempting to decrypt but no vault secrets found"}

I also tried the outcommented alternatives in the Vagrantfile to make Ansible prompt for the password. I can see all of them in the ansible-playbook call printed by Vagrant.

Additionally, I tried several options when encrypting foo with ansible-vault encrypt_string, which did not help either.

What can I do to make Ansible prompt for the password when called with Vagrant?

Versions

  • kubuntu 16.04
  • Vagrant 1.8.1 and Vagrant 2.0.0
  • Ansible 2.4.0.0

Update

This is the Ansible call as printed by Vagrant:

PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --connection=ssh --timeout=30 --ask-vault-pass --limit="default" --inventory-file=/opt/vagrantVM/.vagrant/provisioners/ansible/inventory -v playbook.yml

If I execute this directly without Vagrant the password prompt works as expected! So it must be Vagrant, which somehow suppresses the prompt.


Solution

  • In Ansible 2.4.0.0, the Vault password prompt (i.e. --ask-vault-pass) is skipped when no tty is present (there is no execution of getpass.getpass function).

    With the Ansible 2.4.0.0 prompt implementation, the Vagrant provisioner integration don't receive an interactive prompt.

    Note that --ask-pass and --ask-become-pass implementation haven't changed (i.e. there is no mechanism to skip the getpass function) and are still working fine with Vagrant.

    I plan to report the issue upstream to the Ansible project, but for the moment you can resolve the situation by downgrading to Ansible 2.3 (or by using vault_password_file provisioner option instead).

    References: