One place for hosting & domains

      How To Use Conditionals in Ansible Playbooks



      Part of the Series:
      How To Write Ansible Playbooks

      Ansible is a modern configuration management tool that doesn’t require the use of an agent software on remote nodes, using only SSH and Python to communicate and execute commands on managed servers. This series will walk you through the main Ansible features that you can use to write playbooks for server automation. At the end, we’ll see a practical example of how to create a playbook to automate setting up a remote Nginx web server and deploy a static HTML website to it.

      In Ansible, you can define conditions that will be evaluated before a task is executed. When a condition is not met, the task is then skipped. This is done with the when keyword, which accepts expressions that are typically based on a variable or a fact.

      The following example defines two variables: create_user_file and user. When the create_user_file is evaluated to true, a new file will be created in the home directory of the user defined by the user variable:

      Create a new file called playbook-04.yml in your ansible-practice directory:

      • nano ~/ansible-practice/playbook-04.yml

      Then add the following lines to the new playbook file:

      ~/ansible-practice/playbook-04.yml

      ---
      - hosts: all
        vars:
          - create_user_file: yes
          - user: sammy  
        tasks:
          - name: create file for user
            file:
              path: /home/{{ user }}/myfile
              state: touch
            when: create_user_file
      

      Save and close the file when you’re done editing its contents.

      To execute this playbook on servers from your inventory file, run ansible-playbook with the same connection arguments you’ve used before when running other playbooks in this series. Again, we’ll be using an inventory file named inventory and the sammy user to connect to the remote servers:

      • ansible-playbook -i inventory playbook-04.yml -u sammy

      When the condition is met, you’ll see a changed status in the play output:

      Output

      ... TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] ...

      If you change the value of create_user_file to no, the condition will be evaluated to false. In this case, you’ll see a skipping status in the play output, indicating that the task was not executed:

      Output

      ... TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] ...

      A common use for conditionals in the context of Ansible playbooks is to combine them with register, a keyword that creates a new variable and assigns it with the output obtained from a command. This way, you can use any external command to evaluate the execution of a task.

      One important thing to notice is that, by default, Ansible will interrupt a play if the command you’re using to evaluate a condition fails. For that reason, you’ll need to include an ignore_errors directive set to yes in said task, and this will make Ansible move on to the next task and continue the play.

      The following example will only create a new file in the user home directory in case that file doesn’t exist yet, which we’ll test with an ls command. If the file exists, however, we’ll show a message using the debug module.

      Create a new file called playbook-05.yml in your ansible-practice directory:

      • nano ~/ansible-practice/playbook-05.yml

      Then add the following content to the new playbook file:

      ~/ansible-practice/playbook-05.yml

      ---
      - hosts: all
        vars:
          - user: sammy
        tasks:
          - name: Check if file already exists
            command: ls /home/{{ user }}/myfile
            register: file_exists
            ignore_errors: yes
      
          - name: create file for user
            file:
              path: /home/{{ user }}/myfile
              state: touch
            when: file_exists is failed
      
          - name: show message if file exists
            debug:
              msg: The user file already exists.
            when: file_exists is succeeded
      

      Save and close the file when you’re done.

      Then, run ansible-playbook with the same connection arguments from the previous examples. Here, we’re using an inventory file named inventory and a user named sammy, but you should change these values accordingly:

      • ansible-playbook -i inventory playbook-05.yml -u sammy

      The first time you run this playbook, the command will fail because the file doesn’t exist in that path. The task that creates the file will then be executed, while the last task will be skipped:

      Output

      ... TASK [Check if file already exists] ********************************************************************* fatal: [203.0.113.10]: FAILED! => {"changed": true, "cmd": ["ls", "/home/sammy/myfile"], "delta": "0:00:00.004258", "end": "2020-10-22 13:10:12.680074", "msg": "non-zero return code", "rc": 2, "start": "2020-10-22 13:10:12.675816", "stderr": "ls: cannot access '/home/sammy/myfile': No such file or directory", "stderr_lines": ["ls: cannot access '/home/sammy/myfile': No such file or directory"], "stdout": "", "stdout_lines": []} ...ignoring TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] TASK [show message if file exists] ********************************************************************** skipping: [203.0.113.10] ...

      From the output, you can see that the create file for user task caused a change in the server, which means the file was created. Now, run the playbook again and you’ll get a different result:

      • ansible-playbook -i inventory playbook-05.yml -u sammy

      Output

      ... TASK [Check if file already exists] ********************************************************************* changed: [203.0.113.10] TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] TASK [show message if file exists] ********************************************************************** ok: [203.0.113.10] => { "msg": "The user file already exists." } ...

      If you’d like to learn more about using conditionals in Ansible playbooks, please refer to the official documentation.



      Source link

      How To Use Loops in Ansible Playbooks



      Part of the Series:
      How To Write Ansible Playbooks

      Ansible is a modern configuration management tool that doesn’t require the use of an agent software on remote nodes, using only SSH and Python to communicate and execute commands on managed servers. This series will walk you through the main Ansible features that you can use to write playbooks for server automation. At the end, we’ll see a practical example of how to create a playbook to automate setting up a remote Nginx web server and deploy a static HTML website to it.

      When automating server setup, sometimes you’ll need to repeat the execution of the same task using different values. For instance, you may need to change permissions of multiple files, or create multiple users. To avoid repeating the task several times in your playbook file, it’s better to use loops instead.

      In programming, a loop allows you to repeat instructions, typically until a certain condition is met. Ansible offers different looping methods, with the loop keyword being the most recommended option for longer term compatibility.

      The following example creates three different files on the /tmp location. It uses the file module within a task that implements a loop using three different values.

      Create a new file called playbook-06.yml in your ansible-practice directory:

      • nano ~/ansible-practice/playbook-06.yml

      Then add the following lines to the new playbook file:

      ~/ansible-practice/playbook-06.yml

      ---
      - hosts: all
        tasks:
          - name: creates users files
            file:
              path: /tmp/ansible-{{ item }}
              state: touch
            loop:
              - sammy
              - erika
              - brian
      

      Save and close the file when you’re done.

      Then, run ansible-playbook with the same connection arguments from the previous examples. Again, we’re using an inventory file named inventory and a user named sammy, but you should change these values accordingly:

      • ansible-playbook -i inventory playbook-06.yml -u sammy

      You’ll get output like this, showing each individual item value that was used within the loop:

      Output

      ... TASK [creates users files] ****************************************************************************** changed: [203.0.113.10] => (item=sammy) changed: [203.0.113.10] => (item=erika) changed: [203.0.113.10] => (item=brian) ...

      For more detailed information on how to use loops when writing Ansible playbooks, please refer to the official documentation.



      Source link

      How To Install and Manage System Packages in Ansible Playbooks



      Part of the Series:
      How To Write Ansible Playbooks

      Ansible is a modern configuration management tool that doesn’t require the use of an agent software on remote nodes, using only SSH and Python to communicate and execute commands on managed servers. This series will walk you through the main Ansible features that you can use to write playbooks for server automation. At the end, we’ll see a practical example of how to create a playbook to automate setting up a remote Nginx web server and deploy a static HTML website to it.

      Automating the installation of required system packages is a common operational task in Ansible playbooks, since a typical application stack requires software from different sources.

      The apt module manages system packages on Debian-based operating systems such as Ubuntu, the distribution we’re using on remote nodes throughout this guide. The following playbook will update the apt cache and then make sure Vim is installed on remote nodes.

      Create a new file called playbook-09.yml in your ansible-practice directory:

      • nano ~/ansible-practice/playbook-09.yml

      Then add the following lines to the new playbook file:

      ~/ansible-practice/playbook-09.yml

      ---
      - hosts: all
        become: yes
        tasks:
          - name: Update apt cache and make sure Vim is installed
            apt:
              name: vim
              update_cache: yes
      

      Save and close the file when you’re done.

      Notice that we’ve included the become directive in the beginning of the play. This is required since installing packages requires administrative system permissions.

      Removing a package is done in a similar way, the only change is that you have to define the package state to absent. The state directive has a default value of present, which will make sure that the package is installed on the system, regardless of the version. The package will be installed if not present. To assure you have the latest version of a package, you can use latest instead. This will cause apt to update the requested package if that is not on their latest version.

      Remember to provide the -K option when running this playbook, since it requires sudo permissions:

      • ansible-playbook -i inventory playbook-09.yml -u sammy -K

      Output

      BECOME password: PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.10] TASK [Update apt cache and make sure Vim is installed] ************************************************** ok: [203.0.113.10] PLAY RECAP ********************************************************************************************** 203.0.113.10 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

      When installing multiple packages, you can use a loop and provide an array containing the names of the packages you want to install. The following playbook will make sure the packages vim, unzip, and curl are installed and in their latest version.

      Create a new file called playbook-10.yml in your ansible-practice directory, on your Ansible control node:

      • nano ~/ansible-practice/playbook-10.yml

      Add the following content to the new playbook file:

      ~/ansible-practice/playbook-10.yml

      ---
      - hosts: all
        become: yes
        tasks:
          - name: Update apt cache and make sure Vim, Curl and Unzip are installed
            apt:
              name: "{{ item }}"
              update_cache: yes
            loop:
              - vim
              - curl
              - unzip
      

      Save and close the file when you have finished.

      Then, run ansible-playbook with the same connection arguments from the previous examples, and don’t forget to include the -K option since this playbook requires administrative privileges:

      • ansible-playbook -i inventory playbook-09.yml -u sammy -K

      You’ll see output like this, indicating that the same task run through three iterations using the different values we have provided: vim, curl, and unzip:

      Output

      BECOME password: PLAY [all] *************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************** ok: [203.0.113.10] TASK [Update apt cache and make sure Vim, Curl and Unzip are installed] ************************************************************************** ok: [203.0.113.10] => (item=vim) ok: [203.0.113.10] => (item=curl) changed: [203.0.113.10] => (item=unzip) PLAY RECAP *************************************************************************************************************************************** 203.0.113.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

      For more details on how to manage system packages, including how to remove packages and how to use advanced apt options, you can refer to the official documentation.



      Source link