Docker and add_host: I'm doing it wrong.

220 views
Skip to first unread message

William George

unread,
Jun 24, 2016, 10:06:26 AM6/24/16
to Ansible Project
So I've got to manage a relatively dynamic fleet of machines in the wild.  

Wanting to keep the running environment of these things as bare-bones as possible, so decision was made to have all the complex bits inside of docker containers, what-for relative immutability and the like.  

Clearly we want to use ansible to make sure the containers are doing what they ought to do when they're supposed to be doing it.

Likewise, getting the hardware setup is a bit of a pain, so we use Ansible for this as well.  

My first attempt goes something like this:

- name:  apply docker role
  hosts
:  docker-hosts
  roles
:
   
- role:  docker_host  # role that make sure docker is up to date,  running, deploys the right images, starts containers


- name: apply worker role
  hosts
:  workers  # group that contains all the containers started on the docker-hosts
  roles
:
   
- role:  worker


And of course the final tasks in the docker_host role is:


- name:  add container as host
  add_host
:
    name
:  "{{ inventory_hostname }}-container"
    ansible_host
:  "{{ ansible_eth0.ipv4.address }}"
    ansible_port
:  "{{ ssh_port }}"
    groups
:  workers

Of course, this doesn't work because add_host bypasses the host loop and only runs once.  

Now I can't imagine I'm the first person that's wanted to spin up containers on multiple hosts, so there's got to be a sane way to go about this.

I *could* just statically create both the host and the container in `ansible_hosts`, but that feels like exactly the sort of error-prone kludge we're trying to avoid in the first place.  

What am I missing?  Is there a more sensible way to go about this? 

William George

unread,
Jun 24, 2016, 9:49:39 PM6/24/16
to Ansible Project

You know what, I tried to be civil and do this the right way, but you've simply pushed me too far.

So, until I have some kind of answer about why add_host bypasses the host loop and what the idiomatic way to accomplish this is, I'm just going to say 'to hell with it' and unbypass that shizz.

That's right, I LIVE DANGEROUS. Deal with it.

ansible/plugins/action/add_host.py, line 40:
    BYPASS_HOST_LOOP = False  # biatch!

which yields:

TASK [docker_host : run deployable image] ************************
ok: [h2]
ok: [h1]

TASK [docker_host : add container as host] ******************************
changed: [h1]
changed: [h2]

I'm still certain there's some perfectly valid reason they have this disabled, but what we've got here is failure to communicate. Some developers you just can't reach. So you get what we have here, which is the way they wants it. Well, they gets it. I don't like it any more than you.

Matt Martz

unread,
Jun 25, 2016, 9:25:00 AM6/25/16
to ansible...@googlegroups.com
With add_host, generally speaking you want to use a `with_items` loop.  You could do something like:

- name:  add containers as hosts
  add_host:
    name:  "{{ item }}-container"
    ansible_host:  "{{ hostvars[item].ansible_eth0.ipv4.address }}"
    ansible_port:  "{{ hostvars[item].ssh_port }}"
    groups:  workers
  with_items: "{{ groups['docker-hosts'] }}"

That should do what you need.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/b88113ac-5125-42f1-8853-623d77a48d49%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Matt Martz
@sivel
sivel.net

William George

unread,
Jun 25, 2016, 12:00:51 PM6/25/16
to Ansible Project
That looks sensible.  I guess the reason I didn't go this route to begin with is I was hoping to have something that was more tied to the state of the earlier steps, but in the end I suppose it doesn't matter.

Would it be sane to include this in a role?  Or should this be outside of the role?

Also, if the ssh_port were dynamic/randomly assigned and I registered it in earlier steps, would the above still work?

William George

unread,
Jun 25, 2016, 3:06:09 PM6/25/16
to Ansible Project
Reading into it more, 'post_tasks' in `site.yml` seems like the right place for this, and is working fine.

I'd *prefer* to have the role be able to dictate the value of `ssh_port`, but I can't seem to figure out a way to use that variable from `post_tasks` in `site.yml`.  Not the end of the world I guess.  

Thanks for the help though!
Reply all
Reply to author
Forward
0 new messages