Skip to content
This repository has been archived by the owner. It is now read-only.

What would be the way to load vaulted variables for Ansible roles #605

Open
Lowess opened this issue Jun 14, 2017 · 11 comments

Comments

Projects
None yet
6 participants
@Lowess
Copy link
Contributor

commented Jun 14, 2017

ISSUE TYPE
  • Feature Idea / Question ?

Hey guys,

I am trying to organize our Ansible-Container repository so that we can share common ansible roles across different teams (in order to keep things DRY). A couple of our roles rely on Ansible-Vault to encrypt secrets. My question is about how do I make use of Ansible Vault within Ansible-Container ?

In a classic Ansible world, we leverage the group_vars/all folder to store both a vars.yml and vault.yml files into it. This gives a structure like this:

inventory-name/
└── group_vars
    └── all
        ├── rolename-A
        │   ├── vars.yml
        │   └── vault.yml
        └── rolename-B
            ├── vars.yml
            └── vault.yml

Thanks to this convention we know where we can find vaulted vars for a specific role and rekey the secret as needed.

Back to Ansible-container. Our project layout looks like this:

├── ansible                   > Global ansible space where roles can be reused across projects
│   └── roles                 > Common roles shared across different teams in different AC projects
----------------------------------------------------------------------
├── image-science           > Image science team AC workspace
│   ├── objectclassifier    > One AC project...
│   │    └── roles/...      > Specific roles used for this AC project only
│   ├── opencv-no-cuda      > An other AC project...
│   │    └── roles/...
│   └── sceneclassifier     > One more AC project...
│         └── roles/...
----------------------------------------------------------------------
├── ops-team      > Ops team AC workspace
│   └── ...       > AC project
----------------------------------------------------------------------
└── web-engineering       >  Web Eng team AC workspace
     └── ...

Let's take for example a role which installs a log collector (Like sumologic or splunk). I will most likely need to store an API key and a secret (in a vault file) for the sumologic role in order to make it able to contact the log platform.

The sumologic role will be located under ansible/roles/sumologic as most of the teams will need to ship their logs out of the cluster. Let's say each team will use their own API key, which means they each have an ansible-vault key per team.

Does ansible-container offer a way to do such a thing ? Can ansible-container make use of group_vars when the ansible command is executed ?

I have been able to load variables using a command like this, but as you can see If I need to add a --extra-vars statement for each variable file it will quickly become unmanageable:

ansible-container build --roles-path /home/florian/workspace/gumref/ansible/  -- -e @vars/test/vars.yml  -e @vars/test/vault.yml

I am interested in your thoughts on this ?
Thanks,
Florian

@chouseknecht

This comment has been minimized.

Copy link
Member

commented Jun 15, 2017

@Lowess

Thanks for using Ansible Container, and for taking the time to post such a detailed question.

As far as decrypting the vault files, you would need use a password file. You can pass in --vault-password-file to ansible-playbook using the -- option, the same way you're passing the -e option.

You can also set an environment variable in the conductor containerANSIBLE_VAULT_PASSWORD_FILE. Set the variable using --with-variables on the CLI. Or, set it in container.yml.

Of course, you will also need to mount the password file to the conductor container, which you can do using --with-volumes. Or, again, set in container.yml.

Setting volumes and variables for the conductor in container.yml would look like the following:

version: '2'

settings:
    conductor:
        base: 'centos:7'
        environment:
            ANSIBLE_VAULT_PASSWORD_FILE: /Users/user1/.vault_password
        volumes:
            /Users/user1/.vault_password:/Users/user1/.vault_password:ro

services:
...

We're going to add Ansible Vault support. In fact, it's on my short list of things to get done in the next day or three. You'll be able to pass in a password, a password file, environment variable, or even be prompted for a password. The decryption will take place in the conductor, and the unencrypted variables will be available for use in container.yml and any roles. I'll integrate it with settings as well.

As far as making it easier to access all your variable files, I'm wondering if you could simply mount them to the conductor container using settings.volumes, and then reference them within the role using include_vars. You might even be able to use an environment variable to add a degree of abstraction.

The other option is to maybe add some additional attributes to settings. Open to suggestions there.

@j00bar

This comment has been minimized.

Copy link
Collaborator

commented Jun 21, 2017

Spot on, @chouseknecht. 👍

@awiddersheim

This comment has been minimized.

Copy link

commented Jun 21, 2017

@chouseknecht I just started evaluating the ansible-container project and it looks promising. That said, I quickly ran up against a lot of the same issues as @Lowess.

Having the vault support you described would be awesome.

I'm not sure I agree with having to use include_vars in roles. This would mean the end user has control over the roles they are using which isn't really the case when it comes to consuming community roles from galaxy. Most of those from what I have found rely on the default variables being overridden from things like host_vars or group_vars.

It almost seems like we need an include_vars in container.yml much like there is a roles which can also support decrypting vaulted vars files.

Also, looks like a lot of the variable and roles documentation is out of date. Doesn't seem like main.yml is a thing anymore.

I'm also not found of declaring my vars twice. Once for the conductor and again for the playbooks. Seems repetitive especially since most of my vars can be stored in the same files.

@chouseknecht

This comment has been minimized.

Copy link
Member

commented Jun 21, 2017

@awiddersheim See #614. It's a proposal for implementing vault and secrets. Please add feedback.

@awiddersheim

This comment has been minimized.

Copy link

commented Jun 21, 2017

@chouseknecht just saw that. That should help. I also saw #609 which if I understand correctly should help with having to specify variable files twice.

I do wish though that there was --var-dir that mimics include_vars dir option.

@Lowess

This comment has been minimized.

Copy link
Contributor Author

commented Jun 21, 2017

Hi guys, couldn't we consider deploying a group_vars folder next to the playbook generated from the template on the conductor. I am talking about the files that are generated into the /tmp/ folder.

I think right now there is no way to provide a custom ansible.cfg file or override this ansible-playbook command so that we can add an inventory using -i.

@awiddersheim

This comment has been minimized.

Copy link

commented Jun 21, 2017

I think really in the end you would want to be able to uplift your entire ansible playbook directory structure that might include libraries, plugins, etc. Just having access to roles is too little.

@geerlingguy

This comment has been minimized.

Copy link
Contributor

commented Jun 21, 2017

To @awiddersheim's point, it is a bit less convenient to not have at least a glue playbook—almost every project I work on, there are a bunch of roles, but there are always at least two or three other tasks that I need to run before the roles (or to clean up or kick something off after), and it's annoying to have to build a new role for one or two of these maintenance-y tasks.

@awiddersheim

This comment has been minimized.

Copy link

commented Jun 21, 2017

@Lowess from what I can tell everything in your current ansible-container directory does get mounted on the conductor as a volume under /src. So, if you have a group_vars in your folder it should be accessible to the conductor.

If you run ansible-container build --save-conductor-container you can run docker inspect on it and you can see the volumes it's mounted for you.

This also means that any ansible.cfg file you have in your directory will also get seen and used by ansible-playbook.

There are a couple of problems though. The first is the playbook that ansible-conductor generates has no groups associated with it so nothing will likely happen unless you have an all.yml in your group_vars.

You can see the hosts file generation happening here.

The second problem is when ansible-playbook is run in the conductor it specifies the generated playbook and hosts file on the command line.

ansible-playbook -vvvv  -i /tmp/tmpVeGFVI/hosts -c docker  /tmp/tmpVeGFVI/playbook.yml

This means even if you did inventory = foo in your ansible.cfg the command line arguments would override that. Also, since the generated playbook and hosts are put into a temp directory any group_vars or host_vars in your ansible-container directory wont' get used.

You can access them by doing ansible-container build --var-file group_vars/foo.yml or ansible-container build -- -e@/src/group_vars/foo.yml but that doesn't really work right. Same thing goes for include_vars or var_files in your role.

I really like Ansible's inventory directory ability. Been pretty successful with the following pattern and was hoping to continue applying it here:

development/
├── group_vars
│   └── all
│       ├── secrets.yml
│       └── vars.yml
└── hosts
staging/
├── group_vars
│   └── all
│       ├── secrets.yml
│       └── vars.yml
└── hosts
production/
├── group_vars
│   └── all
│       ├── secrets.yml
│       └── vars.yml
└── hosts

This doesn't really seem possible now. Closest thing would be doing include_vars in my roles but that falls over once galaxy roles are introduced.

Almost seems like having main.yml back in the mix would provide a lot more power in these types of cases.

@awiddersheim

This comment has been minimized.

Copy link

commented Jun 21, 2017

Similar request to discussion above here.

@TaiSHiNet

This comment has been minimized.

Copy link

commented May 5, 2018

@awiddersheim did you ever manage to get it working? I have quite a few roles from my non-container setup and would love to reuse them

erijpkema added a commit to rug-cit-hpc/league-of-robots that referenced this issue Dec 21, 2018

We needed to remove the secrets from the roles..
now that we want to deploy multiple clusters.
Unfortunately, group vars cannot be directories (like proposed here:
ansible/ansible-container#605 :-( )
Therefore each virtual cluster needs a separate master playbook.
talos_cluster.yml has been included here as a start.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.