What are we doing here?

This blog includes a series of videos and references to help new users or enthusiasts better understand how to use open source and free technology tools. The quick links includes more information for accessing many of the tools covered along with other references to learn more for taking advantage of these tools.

Click HERE to see the full list of topics covered!

More Advanced Scripting with Ansible

Working more and more in a sysadmin capacity recently has forced me to double down on learning more with Ansible, and thought I'd share some learnings. 

As previously written in other posts - one can filter those using the Ansible label on the right-hand side - Ansible is a great tool for helping to automate tasks to a fleet of hosts. Ansible is agentless, meaning the managed nodes do not need to install any particular software other than Python which is normally available on most Linux hosts. The scripts, called playbooks, are written in a .yaml format to make them easily readable with little study. Hosts can be dynamically added to the Ansible host node by adding them in the host file, or if accessible to the Ansible management node via DNS. What I have recently learned and found eye-opening is the ability to prompt and to add conditionals to create more dynamic and reusable playbooks (Ansible scripts) and enhance the usability of Ansible. 

Making a prompt

Ansible can prompt for user input before running and making changes to a selection of hosts. This is quite powerful because it allows a script to be written, and reused by other sysadmins or managers without having to even really understand the script syntax (never a good thing, but a thing). 

---
- name: User onboarding
  hosts: localhost

  vars_prompt:
    - name: uid
      prompt: Enter the users UID
      private: false
    - name: userpasswd
      prompt: Enter the general password
      private: false

  tasks:
    - name: Add user account
      become: true
      ansible.builtin.user:
        name: "{{ uid }}"
        password: "{{ userpasswd | password_hash('sha512') }}"
      delegate_to: targetservername
...

The above will prompt the admin to enter in the User account ID and provide a password for the user. The prompt structure has a name which identifies the variable for which the prompt result (entered by the admin/user running the playbook). An example of the output for the admin would be as follows:

[root@6e5abc86b9fb scripts]# ansible-playbook sample.yml 
Enter the users UID: Bob
Enter the general password: bob1234


Clicking enter after entering the values will then go off and perform the assigned task, which in the above example will create a user on the target system.

If we wanted to double check the entered values before running the tasks, it is possible to also use the same prompt method to verify values. 

---
- name: User onboarding
  hosts: localhost

  vars_prompt:
    - name: uid
      prompt: Enter the users UID
      private: false
    - name: userpasswd
      prompt: Enter the general password
      private: false

  tasks:
    - name: Confirm values
      pause:
        prompt: |
          Please confirm the below information is correct!
          Press return to continue. Press Ctrl+c and then "a" to abort.
          User UID: {{ uid }}
          User password: {{ userpasswd }}

    - name: Add user account
      become: true
      ansible.builtin.user:
        name: "{{ uid }}"
        password: "{{ userpasswd | password_hash('sha512') }}"
      delegate_to: targetservername
...


The task references to the prompt to display the values for the user to double check. The pause value in the above script will stop the tasks from proceeding one after the other and await the user to confirm by hitting 'Enter'. Sample output:

[root@6e5abc86b9fb scripts]# ansible-playbook sample.yml
Enter the users UID: bob 
Enter the general password: bob1234

PLAY [User onboarding] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************
ok: [localhost]

TASK [Confirm values] ************************************************************************************************************************************************
[Confirm values]
Please confirm the below information is correct!
Press return to continue. Press Ctrl+c and then "a" to abort.
User UID: bob
User password: bob1234
 

Using conditionals

Ansible handles conditionals - i.e. if statements - using the term when. In the task adding a when: allows for conditionals to then be added with options such as a few below:

- if equal - ==

- if not equal - !=

- Is defined - is defined

- Is not defined - is not defined

- great than - >

- less than - < 

More information can be found here:

https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_conditionals.html 

Example of changing the user password hash level based on high or low security prompt. 

---
- name: User onboarding
  hosts: localhost

  vars_prompt:
    - name: uid
      prompt: Enter the users UID
      private: false
    - name: userpasswd
      prompt: Enter the general password
      private: false
    - name: securitylevel
      prompt: Does the user require a higher security for his/her password (Yes/No)?
      private: false

  tasks:
    - name: Confirm values
      pause:
        prompt: |
          Please confirm the below information is corect!
          Press return to continue. Press Ctrl+c and then "a" to abort.
          User UID: {{ uid }}
          User password: {{ userpasswd }}
          High security: {{ securitylevel }}

    - name: Add user account
      become: true
      ansible.builtin.user:
        name: "{{ uid }}"
        password: "{{ userpasswd | password_hash('sha256') }}"
      when: securitylevel == "No"
      delegate_to: localhost

    - name: Add user account
      become: true
      ansible.builtin.user:
        name: "{{ uid }}"
        password: "{{ userpasswd | password_hash('sha512') }}"
      when: securitylevel == "Yes"
      delegate_to: localhost

...

 

And a sample of the full output:

[root@6e5abc86b9fb scripts]# ansible-playbook sample.yml
Enter the users UID: katherine
Enter the general password: kat1234
Does the user require a higher security for his/her password (Yes/No)?: No

PLAY [User onboarding] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************
ok: [localhost]

TASK [Confirm values] ************************************************************************************************************************************************
[Confirm values]
Please confirm the below information is correct!
Press return to continue. Press Ctrl+c and then "a" to abort.
User UID: katherine
User password: kat1234
High security: No
:
ok: [localhost]

TASK [Add user account] **********************************************************************************************************************************************
changed: [localhost]

TASK [Add user account] **********************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP ***********************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
 

In the above the task flagged as skipping is passed over because the conditional - set security level to high - is false hence the task is skipped and the playbook continues. 

Hope it helps for users to get more out of the great tool that is Ansible! 

No comments:

Post a Comment