Fact and task control

Fact and task control

1, Ansible management facts

ansible fact description

  1. Ansible is actually a variable that ansible automatically detects on the managed host

  2. The fact contains host related information that can be used like regular variables, conditions, loops in play, or any other statement that depends on values collected from managed hosts

  3. Some facts collected for managed hosts may include: host name, kernel version, network interface, IP address, operating system version, various environment variables, number of CPU s, memory provided or available, available disk space, and so on

  4. With the help of facts, the state of the managed host can be easily retrieved and the operation to be performed can be determined according to the state
    For example:

    • You can restart the server by running the conditional task based on the fact that it contains the current kernel version of the managed host
    • MySQL configuration files can be customized based on available memory through fact reporting
    • You can set the IPV4 address used in the configuration file according to the value of the fact
  5. Before performing the first task, each play will automatically collect facts with the retrograde setup module

An example of an ansible fact

factvariable
Short host nameansible_facts['hostname']
Fully qualified domain nameansible_facts['fqdn']
IPv4 addressansible_facts['default_ipv4'] ['address']
Name list of all network interfacesansible_facts['interfaces']
/Size of dev/vda1 disk partitionansible_facts['devices'] ['vda'] ['partitions'] ['vda1'] ['size']
DNS server listansible_facts['dns'] ['nameservers']
Currently running kernel versionansible_facts['kernel']

If the value of a variable is of hash / dictionary type, two syntax can be used to get its value. For example:

  • ansible_facts ['default_ipv4'] ['address'] can also be written as ansible_facts.default_ipv4.address
  • ansible_facts ['DNS'] [' nameservers'] can also be written as ansible_facts.dns.nameservers

View the IP address of node2 host

//Write playbook
---
- hosts: all
  tasks:
    - name: print ip
      debug:
        msg:
          the IPv4 address of {{ ansible_facts.fqdn }} is {{ ansible_facts.all_ipv4_addresses }}
//Execute playbook
[root@node1 test]# ansible-playbook fact.yml 

PLAY [all] **************************************************************************************************************************

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

TASK [print ip] *********************************************************************************************************************
ok: [192.168.100.110] => {
    "msg": "the IPv4 address of node2 is ['192.168.100.110']"
}

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

Turn off fact collection

Usually we turn off fact collection to:

  • Not prepared to use any facts
  • Hope to speed up play
  • You want to reduce the load caused by play on the managed host
  • The managed host cannot run the setup module for some reason
  • You need to install some necessary software before you collect facts

2, Write loop and conditional tasks

1. Introduction to loop in ansible

When writing playbook, we inevitably have to perform some repetitive operations, such as installing software packages, creating users in batch, operating all files in a directory, etc. Because ansible is a simple automation language, it also has the basic elements of process control and loop statements

1.1 loop

Use the loop in the playbook and use the loop keyword directly

As follows:

[root@node1 test]# vim test1.yml
---
- hosts: 192.168.100.110
  gather_facts: no
  tasks:
    - name: start service
      service:
        name: "{{ item }}"
        state: started
      loop:
        - httpd
        - php-fpm

You can also assign the list of loop loops to a variable in advance, and then call it in the loop statement:

[root@node1 test]# vim test_service.yml
test_services:
  - postfix
  - httpd

[root@node1 test]# vim test1.yml
- name: start services
  hosts: test
  vars_files:
    - test_services.yml
  tasks:
    - name: start service
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ test_services }}"

The results are as follows:

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

PLAY [192.168.100.110] **************************************************************************************************************

TASK [stop service] *****************************************************************************************************************
ok: [192.168.100.110] => (item=httpd)
ok: [192.168.100.110] => (item=php-fpm)

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

1.2 register variables in loop statements

The register keyword can also capture the output of a circular task. The following code snippet shows the structure of the register variable in a circular task:

[root@node1 test]# vim loop_register.yml
---
- hosts: 192.168.100.110
  gather_facts: no
  tasks:
    - name: looping echo task
      shell: 'echo this is my item: {{ item }}'
      loop:
        - one
        - two
      register: echo_results
      
    - name: show echo_results variable
      debug:
        var: echo_results

After executing the statement, you can see that the returned result of the variable is a dictionary list

  [root@node1 test]# ansible-playbook loop_register.yml
 PLAY [192.168.100.110] **************************************************************************************************************

TASK [looping echo task] ************************************************************************************************************
changed: [192.168.100.110] => (item=one)
changed: [192.168.100.110] => (item=two)

TASK [show echo_results variable] ***************************************************************************************************
ok: [192.168.100.110] => {
    "echo_results": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "ansible_facts": {
                    "discovered_interpreter_python": "/usr/libexec/platform-python"
                },
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo this is my item: one",
                "delta": "0:00:00.003536",
                "end": "2021-07-25 05:07:34.249739",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo this is my item: one",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "one",
                "rc": 0,
                "start": "2021-07-25 05:07:34.246203",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "this is my item: one",
                "stdout_lines": [
                    "this is my item: one"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo this is my item: two",
                "delta": "0:00:00.003148",
                "end": "2021-07-25 05:07:34.550064",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo this is my item: two",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "two",
                "rc": 0,
                "start": "2021-07-25 05:07:34.546916",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "this is my item: two",
                "stdout_lines": [
                    "this is my item: two"
                ]
            }
        ]
    }
}

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

1.3 list of old cycles

In ansible2 Previously, playbook implemented different loops through different loop statements, which used with_ As a prefix. These grammars are still compatible, but will be phased out in a future version

Circular statement keyworddescribe
with_itemsSimple list loop
with_nestedNested loop
with_dictCircular dictionary
with_fileglobLoops through all files in the specified directory
with_linesLoop through all lines in a file
with_sequenceGenerate a sequence of self increasing integers. You can specify the start value, end value and step size. The parameter is specified in the form of key=value, and format specifies the output format. Numbers can be decimal, hexadecimal, octal
with_subelementTraversal of child elements
with_togetherTraversing parallel data sets

Before learning to use loops, if you want to create four files on the same host, you might write the following playbook

[root@server4 ~]# vim test2.yml
---
- hosts: 192.168.100.110
  gather_facts: no
  tasks:
  - file:
      path: "/opt/a"
      state: touch
  - file:
      path: "/opt/b"
      state: touch
  - file:
      path: "/opt/c"
      state: touch
  - file:
      path: "/opt/d"
      state: touch

We repeatedly wrote the file module four times. In fact, we only changed the value of the parameter path each time. If we use a loop, it can be rewritten as follows

[root@server4 ~]# vim test2.yml
---
- hosts: 192.168.100.110
  gather_facts: no
  tasks:
  - file:
      path: "{{ item }}"
      state: touch
    loop: 
      - a
     - b
     - c
     - d

Keywords: Linux

Added by SCRUBBIE1 on Fri, 14 Jan 2022 11:45:31 +0200