Allowing Ansible playbooks to work with new user groups on first run

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 use when 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?).

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`

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.

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! :)