Orchestrating SSH-less LXC containers using Ansible
The catch with LXC containers and Ansible
When you execute an Ansible playbook, modules you use in the tasks you define are compiled to a Python script, copied to the remote system via SSH, and then executed via SSH.
Ansible does this using its built in ssh connection plugin, which does the dirty work of copying and executing the files, running commands in sudo, etc. When you’re dealing with bare-metal hosts or VMs, the hosts you’re managing probably already have SSH running, so that’s a great way to manage a wide variety of infrastructure without having to add yet another agent.
However, when managing LXC containers, perhaps you do not wish to have SSH running inside each and every container, connect each container to your management network, and deal with the security implications of managing all of these SSH installations.
Either one of these plugins will allow us to execute tasks in Ansible targeting the container without accessing the container over SSH. Instead, the host that the container lives on will receive the SSH connection, and the Ansible module will be transparently executed using lxc-attach.
How do I set up lxc_ssh?
Take for example a host named “vm” which has a container named “container” running on it. The container does not have ‘sshd’ running, however I do have root SSH access to “vm” from the remote host I am executing my Ansible playbooks on and I just wrote some plays I want to run on “container”.
First, I need to download the lxc_ssh connection plugin:
And now my project looks like this:
Alongside playbook.yml, create a file called ansible.cfg and configure it with the path to our lxc_ssh connection plugin and test inventory.
Create your inventory (replace the ansible_host setting with the IP/hostname of “vm”):
Now create inventory/group_vars/containers.yml. This maps “container” to “vm” and enables the lxc_ssh connection plugin for the container host entries:
And last, an example playbook for playbook.yml:
This playbook will run inside the container, as confirmed by the output of hostname.
So the final layout of our test project will look like: