'Delete users that aren't in a dictionary

I have a task in ansible that return a dictionary with a list of users and I use it to add these users by another task in my server.

- name: Get users
  uri:
    url: http://users.com/users
    method: GET
    return_content: yes
  register: json_users

-name: Add users
 user:
   name: "{{ item }}"
 with_items:
   - {{ json_users[content] }}

Now, I would like to delete the users which are not in this list, but I don't know how to propose this task.

My list is something like that:

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "[email protected]",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "[email protected]",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },

Now, imagine that I have in a server more users apart from the user list. Would be possible create another task in ansible to delete that? I'm open to used any method.

Thanks



Solution 1:[1]

ansible provides a very great argument called state: in modules. this argument can be used to control the behavior of the module on the target nodes i.e absent/present i.e delete/add in the case of user.

Before calling the user: module with delete as an argument you need to create a list of all the users on the target node and then compare it with the users in the above json and then call the user: module with delete: argument.

- name: Get users
  uri:
    url: http://users.com/users
    method: GET
    return_content: yes
  register: json_users

- name: Add users
 user:
   name: "{{ item }}"
 with_items:
   - "{{ json_users[content] }}"

- name: create a list of users not present in the above json
  <module>:

- name: Add users
 user:
   name: "{{ item }}"
 state: absent
 remove: yes
 with_items:
   - "{{ to_delete_list }}"

Hope so this helps. Let me know in case you need help in creating a list of users not present in the json. Also the {{ json_users[content] }} will get all the keywords as an iteration in with_items you need only the name attribute to be used with user module.

In addition to the above we can get the list of users using a module getent: this will set a fact called getent_passwd: we can parse this code to get the username.

Created a list of the expected users using username: as keyword.

---
- name: to delete the users not needed as per the json
  hosts: localhost
  gather_facts: no
  tasks:
    - include_vars: 
        file: vars.yml
        name: expected

    - getent:
        database: passwd
      register: list_of_users

    - set_fact:
        expected_users: "{{ expected_users | default([]) | map(attribute='item') | list }}"
      loop:
        - "{{ expected | json_query('expected[*].username')  }}"

    - debug:
        msg: "{{ item.key }}"
      when: "item.key not in expected_users"
      with_dict:
        - "{{ getent_passwd }}"

You can update the debug: to use the user: module with state: absent

Note: You have to be careful when deleting users

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1