ansible implementation handler, processing task failure, file management

Posted by fireant on Sun, 07 Nov 2021 22:09:39 +0100

##Run tasks conditionally
####-Syntax of conditional tasks
######The when statement is used to run a task conditionally. It takes the condition to be tested as the value. If the conditions are met. Then run the task. If the conditions are not met, skip the task.

######Example:

When when The value of is false Task execution will be skipped when the value is true Execute as soon as possible.
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node2] *******************************************************************

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

TASK [vsftpd] ******************************************************************
skipping: [node2]

PLAY RECAP *********************************************************************
node2                      : ok=1    changed=0    unreachable=0    failed=0   
[root@node1 ansible]# cat test.yml 
---
- hosts: node2
  tasks: 
    - name: vsftpd
      yum:
        name: vsftpd
        state: present
      when: false

####Example 2:

You can also set a variable to act as true and false
[root@node1 ansible]# cat test.yml 
---
- hosts: node2
  vars:
    install: true
  tasks: 
    - name: install httpd
      yum:
        name: httpd
        state: present
      when: install

[root@node2 ~]# rpm -qa | grep httpd
[root@node2 ~]# 

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node2] *******************************************************************

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

TASK [install httpd] ***********************************************************
changed: [node2]

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

[root@node2 ~]# rpm -qa | grep httpd
httpd-filesystem-2.4.37-21.module+el8.2.0+5008+cca404a3.noarch
httpd-2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
httpd-tools-2.4.37-21.module+el8.2.0+5008+cca404a3.x86_64
redhat-logos-httpd-81.1-1.el8.noarch

####Example 3:

When a variable does not define a variable, use when This statement is used to judge that a non-existent variable is null. At this time, it will be skipped and no error will be reported
[root@node1 ansible]# cat test.yml 
---
- hosts: node2
  vars: 
  tasks: 
    - name: install httpd
      yum:
        name: "{{ install }}"
        state: present
      when: install is defined

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node2] *******************************************************************

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

TASK [install httpd] ***********************************************************
skipping: [node2]

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

The following condition judges may be used

JudgeExample
Equal to (value is string)A = "B"
Equal to (value is numeric)A = B
less than<
greater than>
Less than or equal to<=
Greater than or equal to>=
Not equal to!=
Variable existsxxx is defined
Variable does not existxxx is not defined
The Boolean value is true1,true yes
Boolean value is false0,false no
The value of the first variable exists and is in the list of the second variableA in B

Multiple conditions can be used

orOne of the two conditions is true
andYou need both to be true

####Example 4:

This is performed by the operating system
 If ansible_facts['distribution']The value of is version If it is in the list, execute this task. If it is not in the list, skip it.
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  vars:
    version:
      - redHat
      - CentOS
  tasks: 
    - name: install httpd
      yum:
        name: httpd
        state: present
        when: ansible_facts['distribution'] in version

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [install httpd] ***********************************************************
skipping: [node3]

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

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  vars:
    version:
      - RedHat
      - CentOS
  tasks: 
    - name: install httpd
      yum:
        name: httpd
        state: present
      when: ansible_facts['distribution'] in version

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [install httpd] ***********************************************************
skipping: [node3]

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

###Multi condition test

Condition means when the system is Redhat The task is executed when the version is 8; As long as one of the preceding conditions is not true, it will be implemented or The following conditions.
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: install httpd
      yum:
        name: httpd
        state: present
      when: >
        (ansible_distribution == "RedHat" and
         ansible_distribution_major_version == "8")
        or
        (ansible_distribution == "CentOS" and
         ansible_distribution_major_version == "7")

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [install httpd] ***********************************************************
skipping: [node3]

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

[root@node1 ansible]# cat /etc/redhat-release 
Red Hat Enterprise Linux release 8.2 (Ootpa)
Because when I was here Redhat8.2 Version, so execute the task.

##Combining loops and conditional tasks

Determine whether the mounted file system has more than 5000 free space, ansible_mounts Fact, which represents the relevant fact of a mounted file system, as long as/You can perform tasks when the attached files meet 5000 available space
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [install httpd] ***********************************************************
ok: [node3] => (item={'mount': '/', 'device': '/dev/mapper/rhel-root', 'fstype': 'xfs', 'options': 'rw,relatime,attr2,inode64,noquota', 'size_total': 18238930944, 'size_available': 15579222016, 'block_size': 4096, 'block_total': 4452864, 'block_available': 3803521, 'block_used': 649343, 'inode_total': 8910848, 'inode_available': 8848991, 'inode_used': 61857, 'uuid': 'b9c7a6c6-5708-4cb2-a9f5-b2d13417b480'})
skipping: [node3] => (item={'mount': '/mnt/cdrom', 'device': '/dev/sr0', 'fstype': 'iso9660', 'options': 'ro,relatime,nojoliet,check=s,map=n,blocksize=2048', 'size_total': 8436285440, 'size_available': 0, 'block_size': 2048, 'block_total': 4119280, 'block_available': 0, 'block_used': 4119280, 'inode_total': 0, 'inode_available': 0, 'inode_used': 0, 'uuid': '2020-04-04-08-21-15-00'}) 
skipping: [node3] => (item={'mount': '/boot', 'device': '/dev/sda1', 'fstype': 'xfs', 'options': 'rw,relatime,attr2,inode64,noquota', 'size_total': 1063256064, 'size_available': 876179456, 'block_size': 4096, 'block_total': 259584, 'block_available': 213911, 'block_used': 45673, 'inode_total': 524288, 'inode_available': 523987, 'inode_used': 301, 'uuid': '94b52148-4654-4714-b7f4-4b3aedec9dde'}) 
- hosts: node3
  tasks:
    - name: install httpd
      command: /usr/bin/systemctl is-active vsftpd //Determine whether vsftpd is running
      ignore_errors: yes  //If the task fails, ignore the error and continue to execute
      register: result  //Save the result information of the module in a variable named result
    - name:
      service:
        name: httpd
        state: restarted
      when: result['rc'] == 0  //Evaluate the output of the vsftpd task. If the exit code of the systemctl command is 0, vsftpd is activated and the task restarts httpd

##Implementation handler
####-Only when notify notification is used and the configuration file is modified can the tasks in handlers be executed. Even if a task is notified multiple times, the tasks in handlers will only be executed once. Notify must be used in combination with handlers

Only when you modify the service configuration file will it be executed handlers What's inside
---
- hosts: node3
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: present
      notify:
        - started httpd
  handlers:
    - name: start httpd
      service:
        name: httpd
        state: started

##Processing task failed

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: install httpd
      yum:
        name: httpdd
        state: present
      ignore_errors: yes  //Ignore errors, skip when errors occur, and perform subsequent tasks.
      notify:
        - started httpd
  handlers:

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [install httpd] ***********************************************************
fatal: [node3]: FAILED! => {"changed": false, "failures": ["No package httpdd available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}

###Enforce handler after task failure

ahead yum If a non-existent service is installed, an error will be reported to exit according to the normal processing mechanism, but it is added force_handlers It will also call the notification to execute handlers The task inside.
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  force_handlers: yes
  tasks: 
    - name: test
      command: /bin/true
      notify: restart the database
  
    - name: test2
      yum:
        name: notapkg
        state: latest

  handlers:
    - name: start httpd
      service:
        name: mariadb
        state: restarted

###Specify task failure conditions

As long as there is world,The mission was considered a failure.
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node2] *******************************************************************

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

TASK [test] ********************************************************************
changed: [node2]

TASK [fail] ********************************************************************
fatal: [node2]: FAILED! => {"changed": false, "msg": "fail"}

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

##Specifies when the changed results are reported

It is output regardless of whether the task executed has been modified on the managed host changed,If changed_when: false No matter whether it is repaired or not, it will not be output changed Only show ok.
---
- hosts: node3
  force_handlers: yes
  tasks:
    - name: test
      yum:
        name: httpd
        state: present
      changed_when: true
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
changed: [node3]

PLAY RECAP *********************************************************************
node3                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
ok: [node3]

PLAY RECAP *********************************************************************
node3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
When modified to false Only the ok

changed in combination with notify

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      shell: /usr/local/bin/upgrade-database
      register: command_result
      changed_when: "'Success' in command_result.stdout"
      notify:
        - restarted mariadb
     
  handlers:
    - name:
      service:
        name: mariadb
        state: restarted

Ansible blocks and error handling

block There can be multiple tasks. Multiple tasks form a task block. When one task fails, the task will be executed if the whole task block fails rescue The task inside, if block If the task inside is executed successfully, it will not be executed rescue The task inside. always That is, whether other tasks fail or not, always All the tasks inside will be performed.
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      block:
        - name: one
          yum:
            name: httpd
            state: present
      rescue:
        - name: two
          service:
            name: httpd
            state: started
      always:
        - name: therr
          shell: echo 'hello' > /mnt/hgfs/test
modulareffect
blockDefine main tasks
rescueDefine the task to run when the task defined in the block clause fails
alwaysDefine tasks that always run independently, regardless of whether the tasks defined in the block and rescue clauses succeed or fail

##Document management

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      blockinfile:
        path: /mnt/hgfs/test
        block: linux
 take test Replace all the contents in the file

copy module

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
changed: [node3]

PLAY RECAP *********************************************************************
node3                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      copy:
        src: /etc/ansible/passwd
        dest: /mnt/hgfs

[root@node3 hgfs]# ls
m.sh  passwd  test

###Use of fetch module

Connect the on the remote host m.sh This file copy To the file tree organized by the host name of the execution location file on the control node
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      fetch:
        src: /mnt/hgfs/m.sh
        dest: /etc/ansible/

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
changed: [node3]

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

####Use of stat module
View the status information of the specified file

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      stat: 
        path: /etc/ansible/m.sh
If you want to see the output result, you need to register the result as a variable and use debug The module outputs it.
[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      stat: 
        path: /etc/ansible/m.sh
      register: result
    - debug:
        var: result
[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
ok: [node3]

TASK [debug] *******************************************************************
ok: [node3] => {
    "result": {
        "changed": false,
        "failed": false,
        "stat": {
            "exists": false

####Use of synchronize module
###Synchronize is used to synchronize the directory. It can synchronize the directory of the main control end to the controlled end.

[root@node1 ansible]# ansible-playbook test.yml 

PLAY [node3] *******************************************************************

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

TASK [test] ********************************************************************
ok: [node3]

TASK [Synchronize directory] ********************************************************************
changed: [node3]

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

[root@node1 ansible]# cat test.yml 
---
- hosts: node3
  tasks: 
    - name: test
      yum:
        name: rsync
        state: present
    - name: Synchronize directory
      synchronize:
        src: roles
        dest: /opt
[root@node3 opt]# ls
[root@node3 opt]# 

[root@node3 opt]# ls
roles

Topics: Linux Operation & Maintenance ansible CentOS