Skip to main content

Command Palette

Search for a command to run...

Loops,Conditions,file,copy in Ansible

Updated
5 min read

Loops in Playbook:

We use loops when we need to perform a task repeatedly

Syntax:

with_items ---> is the loop

To use items within a loop, enclose them in double curly braces like this: '{{item}}'.

with_items:
    - item-1
    - item-2
    - item-n

Example:

one.yml

---
- hosts: dev
  connection: ssh

  tasks:
    - name: creating user
      user:
        name: '{{item}}'
        state: present
      with_items:
        - vishal
        - sandeep
        - kapil
...

ansible-playbook one.yml

PLAY [dev] *****************************************************************************************************************************************************************
ok: [slave-1] => (item=vishal)
ok: [slave-1] => (item=sandeep)
ok: [slave-1] => (item=kapil)

To Create a user we have to use user.

To Create a group we have to use group.

Installing multiple packages and restarting service using handlers:

Problem statement: Install Git, Java, Maven, and HTTPD. Start the HTTPD server after completing the installation.

---
- hosts: ops
  connection: ssh

  tasks:
    - name: installing multiple dependecies
      yum:
        name: [httpd,git,java-1.8.0-openjdk,maven]
        state: present
      notify: start httpd
  handlers:
    - name: start httpd
      service: name=httpd state=restarted
...

In the above playbook, we used the yum module to install software packages, and then notified handlers using notify after the completion of installation. When a notification is received by a handler, it checks the notification message and name of the handler, and if both match, the handler is executed.

Condition in playbook

Conditions can be used in tasks to specify that the task should only be performed when a certain condition is met.

Syntax: when

Problem Statement: install httpd server if OS is RedHat and apache2 if OS is Debian.

- hosts: all
  connection: ssh

  vars:
    packName: httpd

  tasks:
    - name: install httpd in RedHat OS
      yum:
        name: httpd
        state: present
      when: ansible_os_family == 'RedHat'
      notify: start httpd

    - name: install apache2 in Debian OS
      yum:
        name: apache2
        state: present
      when: ansible_os_family == 'Debian'

  handlers:
    - name: start httpd
      service: name=httpd state=restarted
...

output:


TASK [install httpd in RedHat OS] ******************************************************************************************************************************************
changed: [slave-2]
changed: [slave-1]

TASK [install apache2 in Debian OS] ****************************************************************************************************************************************
skipping: [slave-1]
skipping: [slave-2]

RUNNING HANDLER [start httpd] **********************************************************************************************************************************************
changed: [slave-2]
changed: [slave-1]

PLAY RECAP *****************************************************************************************************************************************************************
slave-1                    : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
slave-2                    : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

You can see that the installation on Debian was skipped because we are not using the Debian OS.

Tags

If we have a large playbook and want to execute or skip a specific part of the playbook, we can use tags.

  • --tags all - run all tasks, ignore tags (default behavior)

  • --tags [tag1, tag2] - run only tasks with either the tag tag1 or the tag tag2

  • --skip-tags [tag3, tag4] - run all tasks except those with either the tag tag3 or the tag tag4

  • --tags tagged - run only tasks with at least one tag

  • --tags untagged - run only tasks with no tags

below playbook is used to install httpd and start the service

Four.yaml
---
- hosts: all
  connection: ssh

  tasks:
    - name: installing httpd
      yum: name=httpd state=present
      tags: abc

    - name: running https service
      service: name=httpd state=restarted

For the first time when I run the above playbook, HTTPD gets installed and the service starts.

But when I want to run it again, HTTPD doesn't need to be reinstalled, so I just want to skip that step using tags at runtime.

cmd:

ansible-playbook Four.yaml --skip-tags "abc"

ok: [slave-2]

TASK [running https service] ***********************************************************************************************************************************************
changed: [slave-1]
changed: [slave-2]

PLAY RECAP *****************************************************************************************************************************************************************
slave-1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
slave-2                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

You can see that the playbook is only running the service task, as we used the appropriate tag to skip the task where HTTPD installation is specified.

To download a file in remove servers:

    - name: downloading maven tar
      get_url:
        url: https://dlcdn.apache.org/maven/maven-3/3.9.1/binaries/apache-maven-3.9.1-bin.tar.gz
        dest: /root
      tags: abc

To create a file in remote servers:

- name: creating maven.sh file
      file:
        path: /etc/profile.d/maven.sh
        state: touch
      tags: abc

To create a folder in remote servers:

- name: creating maven.sh file
      file:
        path: /etc/folder1
        state: directory
      tags: abc

To add content into a file in remote servers:

If file is not found it'll create one for us in remote servers

- name: writing script to change maven java version
      copy:
        dest: /etc/profile.d/maven.sh
        content: |
          export JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto
          export M2_HOME=/opt/maven
          export MAVEN_HOME=/opt/maven
          export PATH=${M2_HOME}/bin:${PATH}
      tags: abc

To copy a file from local to remote servers:

---
- hosts: all
  connection: ssh

  tasks:
    - name: copying file from local to remote
      copy:
        src: copying.pdf
        dest: /root
        owner: vishal
        group: raju
        mode: 777
...

To create file and changing user,group,permissions in remote servers:

---
- hosts: all
  connection: ssh

  tasks:
    - name: creating users
      user:
        name: '{{item}}'
        state: present
      with_items:
        - vishal
        - raju

    - name: creating file and changing permissions and users
      file:
        path: /root/vi.pdf
        state: touch
        owner: vishal
        group: raju
        mode: 777
      tags: abc

Maven 3.9.1 installation with external url and changing its java version:

---
- hosts: all
  connection: ssh

  tasks:
    - name: installing java 17
      yum:
        name: java-17-amazon-corretto.x86_64 
        state: present
      tags: abc

    - name: downloading maven tar
      get_url:
        url: https://dlcdn.apache.org/maven/maven-3/3.9.1/binaries/apache-maven-3.9.1-bin.tar.gz
        dest: /root
      tags: abc

    - name: unzip and moving
      command: tar xvf apache-maven-3.9.1-bin.tar.gz -C /opt
      tags: abc

    - name: linking
      command: sudo ln -s /opt/apache-maven-3.9.1/ /opt/maven  
      tags: abc

    - name: writing script to change maven java version
      copy:
        dest: /etc/profile.d/maven.sh
        content: |
          export JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto
          export M2_HOME=/opt/maven
          export MAVEN_HOME=/opt/maven
          export PATH=${M2_HOME}/bin:${PATH}
      tags: abc

    - name: changing file permissions
      command: sudo chmod +x /etc/profile.d/maven.sh
      tags: abc

    - name: executing file
      shell: source /etc/profile.d/maven.sh 
 ...

Check if git exists and install if doesn't exists:

- hosts: all
  connection: ssh

  tasks:
    - name: file checker
      stat:
        path: /usr/bin/git
      register: info

    - name: if exists
      debug:
        msg: git already installed
      when: info.stat.exists

    - name: install_git
      yum:
        name: git
        state: present
      when: not info.stat.exists