Loops,Conditions,file,copy in Ansible
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 tagtag1or the tagtag2--skip-tags [tag3, tag4]- run all tasks except those with either the tagtag3or the tagtag4--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