authenticationansiblecreateusercreate-guid

Create user & group if it does not exist using Ansible


I have a customized requirement.

  1. Check if user tomuser belongs to group tomuser & exists no matter what the uid, gid is; then simply do nothing i.e. we are good.

  2. if group tomuser does not exist create group tomuser with gid 1900.

  3. if user tomuser does not exist create user tomuser with gid 1900 and assign in the the group tomuser.

  4. Finally if uid, gid 1900 is already in use while creating user and group then prefer uid,gid as 2020 and if that too is in use then any random unique number is fine for both.

Below, is something I could think off which I understand is not the ideal solution; but i also end-up with issues

playbook below:


- name: Check tomuser user in passwd file
  tags: always
  ignore_errors: yes
  block:

    - group:
        name: tomuser
        gid: "{{ item }}"
      loop:
        - "1900"
        - "2020"
      register: groupcreated            
      when: "tomuser" in groups

    - debug:
        msg: "GROUP tomuser does not exists or is empty"
      when: 'tomuser' not in groups and not groups['tomuser']

    - debug:
        msg: "GROUP tomuser does not exists"
      when: 'tomuser' not in groups

    - debug:
        msg: "GROUP tomuser is empty"
      when: not groups['tomuser']


    - raw: "cat /etc/passwd |grep -i tomuser"
      register: tomusercheck

Output:

TASK [Check tomcat USER on server] *************************************************************************************************************************************
task path: /app/patch/patch.yml:81
fatal: [10.9.9.44]: FAILED! => {
    "reason": "Syntax Error while loading YAML.\n  did not find expected key\n\nThe error appears to be in '/app/patch/checktomuser.yml': line 11, column 30, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n            gid: '1900'\n          when: \"tomuser\" in groups\n                             ^ here\nThis one looks easy to fix. It seems that there is a value started\nwith a quote, and the YAML parser is expecting to see the line ended\nwith the same kind of quote. For instance:\n\n    when: \"ok\" in result.stdout\n\nCould be written as:\n\n   when: '\"ok\" in result.stdout'\n\nOr equivalently:\n\n   when: \"'ok' in result.stdout\"\n"

Kindly suggest.


Solution

  • Got it. Should be idempotent as well.

    ---
    - hosts: my_host
      become: true
      tasks:
        - name: determine available groups
          getent:
            database: group
    
        - name: determine available users
          getent:
            database: passwd
    
        - name: set group with gid 1900 when not available
          group:
            name: tomuser
            gid: 1900
          when:
            - "'tomuser' not in ansible_facts.getent_group"
            - "'1900' not in item.value"
          loop: "{{ ansible_facts.getent_group | dict2items }}"
    
        - name: set group with gid 2020 when not available
          group:
            name: tomuser
            gid: 2020
          when:
            - "'tomuser' not in ansible_facts.getent_group"
            - "'2020' not in item.value"
          loop: "{{ ansible_facts.getent_group | dict2items }}"
    
        - name: create random number
          set_fact:
            random_num: "{{ range(1500, 2000) | random(seed=item) }}"
          run_once: yes
          with_items:
            - string
    
        - name: set group with random gid when 2020 already in use
          group:
            name: tomuser
            gid: "{{ random_num }}"
          when:
            - "'tomuser' not in ansible_facts.getent_group"
            - "'2020' in item.value"
          loop: "{{ ansible_facts.getent_group | dict2items }}"
    
        - name: set fact when tomuser exists
          set_fact:
            user_exists: true
          when: '"tomuser" in item.key'
          loop: "{{ ansible_facts.getent_passwd | dict2items }}"
    
        - name: set fact when tomuser does not exists
          set_fact:
            user_exists: false
          when: '"tomuser" not in item.key'
          loop: "{{ ansible_facts.getent_passwd | dict2items }}"
    
        - name: set user with uid 1900, and group tomuser when not available
          user:
            name: tomuser
            uid: 1900
            group: tomuser
          when:
            - not user_exists
            - "'1900' not in item.value[1]"
          loop: "{{ ansible_facts.getent_passwd | dict2items }}"
    
        - name: set user with uid 2020, and group tomuser when not available
          user:
            name: tomuser
            uid: 2020
            group: tomuser
          when:
            - not user_exists
            - "'2020' not in item.value[1]"
          loop: "{{ ansible_facts.getent_passwd | dict2items }}"
    
        - name: set user with random uid, and group tomuser when not available
          user:
            name: tomuser
            uid: "{{ random_num }}"
            group: tomuser
          when:
            - not user_exists
            - "'2020' in item.value[1]"
          loop: "{{ ansible_facts.getent_passwd | dict2items }}"