9

I have a deployment project that I share with other teams. I have encrypted my secrets with vault. I would like to encrypt the production file with a password and a staging file with an other password to avoid other teams having access to production secrets.

Is it possible to do that ?

I have done something like that. My secrets :

cat /group_vars/all/vault_production.yml (encrypt with password A)
production_password: 'test1'

cat/group_vars/all/vault_staging.yml (encrypt with password B)
staging_password: 'test2'

My environments :

cat hosts-production
[all:vars]
env_type=production

cat hosts-staging
[all:vars]
env_type=staging

My script :

- copy:
  content: |
    env PASS={{hostvars[inventory_hostname][env_type + '_password']}}
  ...

And I launch the playbook like that.

# for production
ansible-playbook  -i hosts-staging test.yml --vault-password-file .password_a
# for staging
ansible-playbook  -i hosts-staging test.yml --vault-password-file .password_b

But that doesn't work because there is 2 differents passwords (ERROR! Decryption failed). Do you know how to do that ?

Thanks.

BR,

Eric

elhostis
  • 1,067
  • 14
  • 32
  • My initial feeling is to move the vault files out into someplace they aren't automatically included and explicitly include only the one you need at a time, but I haven't vetted this to see if it works. – Xiong Chiamiov Aug 26 '16 at 16:59

2 Answers2

8

Multiple vault passwords are supported since Ansible 2.4:

ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml

If multiple vault passwords are provided, by default Ansible will attempt to decrypt vault content by trying each vault secret in the order they were provided on the command line.

In the above case, the ‘dev’ password will be tried first, then the ‘prod’ password for cases where Ansible doesn’t know which vault id is used to encrypt something.

Tamlyn
  • 22,122
  • 12
  • 111
  • 127
4

Sorry, only one vault password allowed per run today. Best way to work around this in the case where you really only need one or the other is to dynamically load a vaulted file based on a var; eg:

- hosts: localhost
  vars_files:
  - secretstuff-{{ env_type }}.yml
  tasks:
  ...

or

- hosts: localhost
  tasks:
  - include_vars: secretstuff-{{ env_type }}.yml
  ...

depending on if you need the vars to survive for one play or the entire run (the latter will bring them in as facts instead of play vars).

nitzmahone
  • 13,720
  • 2
  • 36
  • 39
  • Thanks Matt. But there is still a problem. With this include, I can't get dynamically the variable : For example : shell: echo {{ hostvars[inventory_hostname][env_type + '_sql_password] }} # is not working shell: echo {{staging_sql_password}} # is working – elhostis Aug 29 '16 at 08:45
  • Hrm, that works fine for me on current versions of ansible: `hostvars[inventory_hostname][env_type + '_sql_password']` when using include_vars. Question is: if you're only loading one or the other, why not just call it "sql_password" and be done with it? – nitzmahone Aug 29 '16 at 21:25
  • Whoo, you totally are right @Matt David. It works good like that. Thank you very much. Eric – elhostis Sep 02 '16 at 16:25