L3 Task Execution management
1. Defining task execution with host groups
task2-1.yaml
---
- hosts: all
tasks:
- name: create tmp folder on all servers
file:
dest: $HOME/tmp/
state: directory
- hosts: all
tasks:
- name: create a file on a remote machine
file:
dest: $HOME/tmp/file
state: '{{file_state}}'
- hosts: web
tasks:
- name: create file on web machines
file:
dest: $HOME/tmp/web-file
state: '{{file_state}}'
- hosts: all:!db
tasks:
- name: create file on web machines
file:
dest: $HOME/tmp/web-not-db-file
state: '{{file_state}}'
- hosts: all:&backup:!web
tasks:
- name: create file on web machines
file:
dest: $HOME/tmp/backup-file
state: '{{file_state}}'
# operators '& and' and '! not'
# Set "file_state" as variable passed in '{{file_state}}'
- operators '& and' and '! not'
- Set
"file_state"
as variable passed in'{{file_state}}'
1-1 file.state: directory
If directory, all intermediate subdirectories will be created if they do not exist. Since Ansible 1.7 they will be created with the supplied permissions.
1-2 file.state: '{{file_state}}'
-
File module: https://docs.ansible.com/ansible/latest/modules/file_module.html#file-module
-
once with the state of touch, create this file if it doesn't exist
- Seoncd time, we'll run it with the state of absent
1-3 hosts: all:!db
and all:&backup:!web
- operators
'& and'
and'! not'
- Set "file_state" as variable passed in
'{{file_state}}'
1-4 Touch file
#!/bin/bash
ansible-playbook -i ../inventory.ini task2-1.yaml -e file_state=touch
-
-e
EXTRA_VARS, set additional variables askey=value
orYAML/JSON
, if filename prepend with@
-
If
touch
(new in 1.4), an empty file will be created if thepath
does not exist, while an existing file or directory will receive updated file access and modification times, (similar to the waytouch
works from the command line).
1-5 Delete file
#!/bin/bash
ansible-playbook -i ../inventory.ini task2-1.yaml -e file_state=absent
-
If
absent
, directories will be recursively deleted, and files or symlinks will be unlinked. -
Note that
absent
will not causefile
to fail if the path does not exist as the state did not change.
2. Using tags to limit play execution
task2-2-tag.yaml
---
- hosts: all
tasks:
- name: create a file
file:
dest: $HOME/tmp/file
state: touch
tags:
- create-file
- hosts: all:k8s_servers:!db
tags:
- delete-file
tasks:
- name: delete a file
file:
dest: $HOME/tmp/file
state: absent
- hosts: web:githost
tasks:
- name: delete a file
file:
dest: /tmp/file
state: absent
tags:
- delete-file
- hosts: all
tags:
- list-file
tasks:
- name: Recursively find /tmp files
find:
paths: $HOME/tmp/
recurse: yes
register: all_files
- debug:
msg: "{{ all_files.files[0].path }}"
2-1 Add tags
- name: delete a file
file:
dest: $HOME/tmp/file
state: absent
tags:
- create-file
- hosts: all:k8s_servers:!db
tags:
- delete-file
2-2 Take advantage tags
$ ansible-playbook -i ../inventory.ini task2-2-tag.yaml --skip-tags create-file --tags delete-file
$ ansible-playbook -i ../inventory.ini task2-2-tag.yaml --tags create-file
PLAY RECAP *********************************************************************************************************************************************
githost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Tags
When you execute a playbook, you can filter tasks based on tags in two ways:
On the command line, with the --tags
or --skip-tags
options
ansible-playbook -i ../inventory.ini task2-2-tag.yaml --skip-tags create-file --tags delete-file
--tags
or--skip-tags
can be used both or just one
2-3 List files in directory
- hosts: all
tags:
- list-file
tasks:
- name: Recursively find /tmp files
find:
paths: $HOME/tmp/
recurse: yes
register: all_files
- debug:
msg: "{{ all_files.files[0].path }}"
Show output
- debug:
msg: "{{ all_files.files[0].path }}"
TASK [debug] *******************************************************************************************************************************************
ok: [githost] => {
"msg": "/home/vagrant/tmp/file"
}
ok: [k8s-jx] => {
"msg": "/home/vagrant/tmp/file"
}
ok: [k8s-jx1] => {
"msg": "/home/vagrant/tmp/file"
}
ok: [k8s-jx2] => {
"msg": "/home/vagrant/tmp/file"
}
PLAY RECAP *********************************************************************************************************************************************
githost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx1 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
k8s-jx2 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3. Executing tasks on localhost
3-1 You dont have to create host for localhost
ininventory.ini
---
- hosts: localhost
tasks:
- name: Create a file via ssh connection
file:
dest: $HOME/Devops_sap/ansible/code/task2/2-3ssh-created
state: touch
- hosts: localhost
connection: local
tasks:
- name: Create a file via sdirect local connection
file:
dest: $HOME/Devops_sap/ansible/code/task2/2-3direct-created
state: touch
4. Limiting plays from the command line
---
- hosts: all
tasks:
- name: the first task
file:
dest: $HOME/tmp/first-task
state: '{{file_state}}'
- name: the second task
file:
dest: $HOME/tmp/second-task
state: '{{file_state}}'
- name: the last task
file:
dest: $HOME/tmp/last-task
state: '{{file_state}}'
4-1 execute from Start
and Step
by name
$ ansible-playbook -i ../inventory.ini task2-4-limit.yaml -e file_state=touch --start-at-task='the second task'
$ ansible-playbook -i ../inventory.ini task2-4-limit.yaml -e file_state=touch --start-at-task='the second task'
--start-at-task='the second task'
5. Specifying variables via inventory
When we start an Ansible run, one of the very first things that we see is that Ansible wants to gather facts from a host. This is effectively a set of variables that we can consume in our playbooks to make certain actions happen on a host-by-host basis.
A very powerful tool. We also find though that sometimes we want to pass specific variables on a host-by-host or group-by-group basis, sort of extending the function of what the inventory provides.
5-1 2-5-invetory.ini
...
[backup]
k8s-jx2 backup_file=$HOME/tmp/backup_file
[all:vars]
all_file=$HOME/tmp/all_file
[web:vars]
web_file=$HOME/tmp/web_file
[all:vars]
[web:vars]
5-2 task2-5-var.yaml
---
- hosts: web
tasks:
- name: create a web file
file:
dest: '{{web_file}}'
state: '{{file_state}}'
- hosts: backup
tasks:
- file:
dest: '{{backup_file}}'
state: '{{file_state}}'
- hosts: db
tasks:
- file:
dest: '{{db_file}}'
state: '{{file_state}}'
when: db_file is defined
- hosts: all
tasks:
- file:
dest: '{{all_file}}'
state: '{{file_state}}'
5-3 when
when: db_file is defined
- Sometimes you will want to skip a particular step on a particular host.
This could be something as simple as not installing a certain package if the operating system is a particular version, or it could be something like performing some cleanup steps if a filesystem is getting full.
- check db_file is defined: https://medium.com/opsops/is-defined-in-ansible-d490945611ae
**5-4 Run the command **
$ ansible-playbook -i ../2-5-inventory.ini task2-5-var.yaml -e file_state=touch
$ ansible-playbook -i ../2-5-inventory.ini task2-5-var.yaml -e file_state=absent
Becasue the db_file
is not defined
TASK [file] *************************************************************************
skipping: [k8s-jx1]
skipping: [k8s-jx2]
...
k8s-jx1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
k8s-jx2 : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0