changed_when and ansible.builtin.dnf linting help

I’m trying to configure an IPv6 token in my “deploy_basevm.yaml” playbook, as well as update packages from a default install to the latest versions. The intent is that I’ll deploy a new VM, system packages are updated, and I have the IP which I expect to have. Just using “CHANGEME” as some placeholder value for now.

Originally, I had this for setting the IPv6 token since I couldn’t find a module which manages it. There is no output from running this nmcli command from the CLI.

    - name: Set IPv6 IID token
      ansible.builtin.command:
        nmcli con mod enX0 ipv6.token ::"CHANGEME"
      become: true

Ansible-lint complains that I should only run something if it needs to be changed, and suggested using change_me for it, but I’m unsure what it thinks is conflicting. The below receives a linting complaint, " conflicting action statements: ansible.builtin.command, change_whenansible-lintsyntax-check[specific]"

    - name: Set IPv6 IID token
      ansible.builtin.command:
        nmcli con mod enX0 ipv6.token ::"CHANGEME"
      change_when: 'nmcli -g ipv6.token con show enX0 != \:\:"CHANGEME"'
      become: true

What is the conflict here?

For the ansible.builtin.dnf, the linter complains that I shouldn’t blindly update everything, which is 100% fair but given the context for this playbook it’s what I would like to do. I want to handle any specific versioning in playbooks that are meant for deploying the specific service. Eg, some sort of VM is going to be a monitoring service, so I’d run the above deplpy_basevm.yaml, then another playbook that deploys the monitoring thing along with any versioning I need to be careful of like a library version.

    - name: Update all packages
      ansible.builtin.dnf:
        name: '*'
        state: latest
      become: true

Python is version 3.14, Ansible is 2.18 if that matters.

There are a few issues with this:

First I think the command can only be on a separate line from ansible.builtin.command if it is followed with a | or > (or |- or >-, see this Stackoverflow comment for more details), eg:

    - name: Set IPv6 IID token
      ansible.builtin.command: >
        nmcli con mod enX0 ipv6.token ::"CHANGEME"

Or:

    - name: Set IPv6 IID token
      ansible.builtin.command: |
        nmcli con mod enX0 ipv6.token ::"CHANGEME"

However you are best using cmd, like this:

    - name: Set IPv6 IID token
      ansible.builtin.command:
        cmd: nmcli con mod enX0 ipv6.token ::"CHANGEME"

The “conflicting action statements” is because of change_when, this should be changed_when (see the documentation) and it should either be a boolean, or evaluate to a boolean:

    - name: Set IPv6 IID token
      ansible.builtin.command:
        cmd: nmcli con mod enX0 ipv6.token ::"CHANGEME"
      changed_when: true
      become: true

If you don’t want the task to run each time and if there is a way to get the existing value then you could update the task to only run when the token needs changing? Or if it should only run once:

    - name: Set IPv6 IID token
      ansible.builtin.command:
        cmd: nmcli con mod enX0 ipv6.token ::"CHANGEME"
      run_once: true
      become: true

It sounds like you need to simply ensure that ansible-lint ignores the state being set to latest since that is what you want?

    - name: Update all packages  # noqa: package-latest
      ansible.builtin.dnf:
        name: '*'
        state: latest
      become: true