neohoddr
neohoddr

Reputation: 33

Ansible chocolatey - Just want to update packages if present

I have an ansible playbook developed using Chocolatey to upgrade a set of packages. However, I want the playbook to only upgrade a package if it is installed and skip if the package is not present. However, what the playbook is doing is upgrading present packages but installing the packages that are not present. I know from the playbook that it is doing exactly what it is supposed to do because of the state being set to latest. What I want to know is how to modify the playbook to only upgrade present packages (possibly using a when: statement) but I cannot seem to find anything out there to help with this. Thanks in advance.

Below is the ansible playbook. And yes, I know I could include the packages in a loop rather than running them one at a time but I found that is not as verbose as I would like.

---
- hosts: all
  tasks:
    - name: Update putty on Windows machines
      win_chocolatey:
        name: putty
        state: latest

    - name: Update WinSCP on Windows machines
      win_chocolatey:
        name: winscp
        state: latest

    - name: Update Notepad++ on Windows machines
      win_chocolatey:
        name: notepadplusplus
        state: latest

    - name: Update SQL Server Management Studio on Windows machines
      win_chocolatey:
        name: sql-server-management-studio
        state: latest

    - name: Update Firefox on Windows machines
      win_chocolatey:
        name: firefox
        state: latest

    - name: Update Google Chrome on Windows machines
      win_chocolatey:
        name: googlechrome
        state: latest

    - name: Update Brave Browser on Windows machines
      win_chocolatey:
        name: brave
        state: latest

    - name: Update 7zip on Windows machines
      win_chocolatey:
        name: 7zip
        state: latest

    - name: Update TreeSize Free on Windows machines
      win_chocolatey:
        name: treesizefree
        state: latest

    - name: Update Wireshark on Windows machines
      win_chocolatey:
        name: wireshark
        state: latest

    - name: Update PowerBI data gateway on Windows machines
      win_chocolatey:
        name: powerbigateway
        state: latest

    - name: Update RVTools on Windows machines
      win_chocolatey:
        name: rvtools
        state: latest

Upvotes: 3

Views: 1320

Answers (3)

ansible313
ansible313

Reputation: 1

This will search for outdated packages and upgrade them without an exact name or number:

  tasks:
  - name: gathering choco facts
    win_chocolatey_facts:
      filter:
      - 'outdated'
      - 'packages'
    register: choco_name
  - name: count outdated packages
    debug:
        msg:  "{{ ansible_chocolatey.outdated|length }}"
  - name: filter outdated packagename
    debug:
        msg: 
          - "{{ choco_name.ansible_facts.ansible_chocolatey.outdated[item].package }}"
    loop: "{{ range(1, ansible_chocolatey.outdated|length +1, 1) }}"
    loop_control:
      index_var: item
  - name: update outdated Packages
    win_chocolatey:
      name: 
      - "{{ choco_name.ansible_facts.ansible_chocolatey.outdated[item].package }}"
      state: upgrade
    loop: "{{ range(1, ansible_chocolatey.outdated|length +1, 1) }}"
    loop_control:
      index_var: item

Upvotes: 0

Gary Ewan Park
Gary Ewan Park

Reputation: 19021

In addition to the answer provided by @Windos, you may want to look at the skipPackageUpgradesWhenNotInstalled configuration option. From the docs page:

skipPackageUpgradesWhenNotInstalled - Skip Packages Not Installed During Upgrade - if a package is not installed, do not install it during the upgrade process.

This feature is disabled by default, but you should be able to enable it as part of your playbook. From the documentation for the collection:

- name: Enable Chocolatey Feature to skip not installed packages
  win_chocolatey_feature:
    name: skipPackageUpgradesWhenNotInstalled
    state: enabled

Off the top of my head, I am not sure whether the exit code from Chocolatey changes if it actually skips a package since it wasn't installed, so this might be something that you want to test to ensure it doesn't impact on anything else that you are trying to do with the playbook.

Upvotes: 2

Windos
Windos

Reputation: 1956

What you need to do is first check what packages are installed, you can do this with the win_chocolatey_facts module.

If you just want to update all installed packages, then you can loop through what that module returns and do the update:

---
- hosts: all
  tasks:
    - name: Gather facts from Chocolatey CLI
      win_chocolatey_facts:

    - name: Upgrade installed packages
      win_chocolatey:
        name: '{{ item.package }}'
        state: latest
      failed_when: false # Setting this means if one package fails, the loop will continue. You can remove it if you don't want that behaviour.
      loop: '{{ ansible_chocolatey.packages }}' # This variable comes from the facts task above automatically.
...

If you do only want to care about the intersection of packages between your list and what's on the machine, then I'd suggest storing that list of packages in a variable and checking against it in your loop.

---
- hosts: all
  vars:
    chocolatey_packages_to_upgrade:
      - putty
      - winscp
      - notepadplusplus
      - sql-server-management-studio
      - firefox
      - googlechrome
      - brave
      - 7zip
      - treesizefree
      - wireshark
      - powerbigateway

  tasks:
    - name: Gather facts from Chocolatey CLI
      win_chocolatey_facts:

    - name: Upgrade installed packages
      win_chocolatey:
        name: '{{ item.package }}'
        state: latest
      when: item.package in chocolatey_packages_to_upgrade # Only process this package if the package is in the predefined list
      failed_when: false # Setting this means if one package fails, the loop will continue. You can remove it if you don't want that behaviour.
      loop: '{{ ansible_chocolatey.packages }}' # This variable comes from the facts task above automatically.
...

You can always reverse this loop, that is you can loop on your desired packages and only upgrade if they were found in the automatic variable from the facts module.

Also, if you'd prefer not to use a loop at all, you can still do your individual tasks like this:

    - name: Update putty on Windows machines
      win_chocolatey:
        name: putty
        state: latest
      when: '"putty" in ansible_chocolatey.packages'

Upvotes: 3

Related Questions