For a long time, I've had some Ansible playbooks—most notably ones that would install Docker then start some Docker containers—where I had to split them in two parts, or at least run them twice, because they relied on the control user having a new group assigned for some later tasks.
The problem is, Ansible would connect over SSH to a server, and use that connection for subsequent tasks. If you add a group to the user (e.g. docker
), then keep running more tasks, that new group assignment won't be picked up until the SSH connection is reset (similar to how if you're logged in, you'd have to log out and log back in to see your new groups
).
The easy fix for this? Add a reset_connection
meta task in your play to force Ansible to drop its persistent SSH connection and reconnect to the server:
- name: Ensure pi user is added to the docker group.
ansible.builtin.user:
name: pi
groups: docker
append: true
# reset_connection doesn't support conditionals.
- name: Reset connection so docker group is picked up.
meta: reset_connection
That example was taken from my Raspberry Pi Internet monitoring playbook, and was added as part of the issue Use 'meta: reset_connection` if Docker pi user group changes. See commit.
Unfortunately, you can't add when
conditionals to the reset_connection
meta task... so it will always reset the connection on every playbook run. But it's a small price to pay to have a playbook that always works on the first run!
Comments
I wonder if it would work as a handler. That way it wouldn't run every time.
To make it work mid-playbook, you'd still need to call
meta: flush_handlers
then (is that allowed to usewhen
conditionals?), and it gets a little annoying to juggle.I also tried putting the task inside a block with the conditional, but that didn't work either (it still ran every time, I guess the block's conditional is just applied to tasks within the block?).
aha, good point, it wouldn't work well handler-wise. nice tricky problem :)
@RedOpsJames mentioned on Twitter that it may be possible to work around this limitation by putting the task in a separate file and using a conditional
include_tasks
.> is that allowed to use when conditionals?
No, it does not. There has been an open issue for a while, but the devs don't seem interesting making a way to limit handler flushing to a subset of hosts.
- https://github.com/ansible/ansible/issues/41313
Awesome! thanks for the info!
Could you put in another playbook file and call it with a conditional on main playbook?
I have not tried it but it should be possible to wrap reset_connection in a block which supports `when`
I tried this and it didn't work (see my reply to @tedder above).
Well, it didn't work with me the first time that I did the Raspberry Pi internet monitoring playbook this week. And I know for sure that I still got the warning or failure message for this specific reset connection thing.
This was on a fresh Raspberry Pi OS installation, that's because I crashed my OS after removing python, I thought I could remove it and do a reinstall but when python was gone and I clicked to open the menu everything was gone or broken... LOL
So I learned the hard way that you can't do that on a Raspberry Pi.
Back to the ansible installation, I got the exact issue as you mention in the readme of internet-pi so after a reboot and running the playbook again I finally have it running alright.
Pretty cool...
Now I am watching all your ansible 101 videos and just found out that this is very powerful and that I can do a ton of different things with it which is way above my skills at the moment, I'm trying to figure out now how I can set the Pi-Hole as DNS server and that it also checks what I'm doing on my main computer, it doesn't do that yet.
However I'm happy that I managed to get it installed the right way and that Pi-Hole is running and I can login with the internet explorer on my main computer, that's quite an accomplishment for me at the moment.
A good first step! for Pi-Hole, you may also need to make another modification or two before DNS works correctly; see this issue on GitHub: resolvconf.conf needs modification so local Docker containers get DNS. Though it should just work if you set your computer's DNS server entry to the IP address of the Pi-hole.
I was facing this problem with while executing playbooks locally (setting up a local machine). I could not use reset_connection as there was no SSH connection (locally). Therefore I found another workaround without having to break the playbook execution by doing a relogin. Using the command module and executing:
'sg docker -c the_actual_docker_command' fixed the problem for me. 'docker' represents the newly created group ID in this case.
Best regards! :)
Are you genius :)
You save my day. Thanks a million times.
Whaou ! that's so great. Thank you, I had the same problem... the power of collective intelligence.