Fact, cycle and condition judgment

Fact, cycle and condition judgment

1. Describe Ansible facts

Ansible is actually a variable that ansible automatically detects on the managed host. The fact contains host related information that can be used like regular variables, conditions, loops in play, or any other statement that depends on the values collected from the managed host.

Some of the facts collected for managed hosts may include:

  • Host name
  • Kernel version
  • network interface
  • IP address
  • Operating system version
  • Various environmental variables
  • Number of CPU s
  • Memory provided or available
  • disk space available

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 based on the value of the fact

Usually, each play will automatically run the setup module to collect facts before performing the first task.

One way to view the facts collected for the managed host is to run a collection of facts and use the debug module to display ansible_ Short playbook of facts variable value.

We use the module to get the opposite facts.

[root@node1 ansible]# ansible 192.168.100.147 -m setup
192.168.100.147 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.100.147"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::79b2:48d0:db63:ff3e"
        ],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "07/22/2020",
        "ansible_bios_version": "6.00",
        "ansible_cmdline": {
            "BOOT_IMAGE": "(hd0,msdos1)/vmlinuz-4.18.0-257.el8.x86_64",
Omit......

We can directly get all the content on the opposite side. There may be a lot of content. At this time, we can only view the previous content

[root@node1 ansible]# ansible 192.168.100.147 -m setup|less

We use playbook to get the opposite facts

[root@node1 ansible]# cat test.yml / / if you need to get the fact that the opposite side is full, enter the playbook
---
- hosts: 192.168.100.147
  tasks: 
    - name: ansible_facts
      debug: 
        var: ansible_facts

[root@node1 ansible]# 

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

PLAY [192.168.100.147] *********************************************************************************************

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

TASK [print all facts] *********************************************************************************************
ok: [192.168.100.147] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.100.147"
        ],
        "all_ipv6_addresses": [
            "fe80::79b2:48d0:db63:ff3e"
        ],
        "ansible_local": {},
Omitted here......

We can also get the specified fact content, for example, we can get the opposite IP address

[root@node1 ansible]# cat test1/test. YML / / playbook content writing method
---
- hosts: '192.168.100.147'
  tasks: 
    - name: print all facts
      debug: 
        var: ansible_facts['default_ipv4']['address']

[root@node1 ansible]# 



[root@node1 ansible]# ansible-playbook test1/test.yml / / obtain the opposite IP address through the announcement

PLAY [192.168.100.147] *********************************************************************************************

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

TASK [print all facts] *********************************************************************************************
ok: [192.168.100.147] => {
    "ansible_facts['default_ipv4']['address']": "192.168.100.147"
}

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

[root@node1 ansible]# 

Get the specified content, as well as a simple way to write

[root@node1 ansible]# cat test1/test.yml   
---
- hosts: '192.168.100.147'
  tasks: 
    - name: print all facts
      debug: 
        var: ansible_facts.default_ipv4.address  //Here we use points to represent,

[root@node1 ansible]# 

Playbook displays ansible in JSON format_ The contents of the facts variable.

The following table shows some facts that may be collected from managed nodes and can be used in playbook:

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 / / although this method is simple, it is not recommended because it may conflict with some functions in python.

Note: msg can add something to the previous variable

When using facts in playbook, Ansible dynamically replaces the variable name of facts with the corresponding value:

[root@node1 ansible]# cat test1/test.yml 
---
- hosts: '192.168.100.147'
  tasks: 
    - name: test
      debug: 
        msg: >   //It means to print the content of one line. For beauty, we can write on a new line
          The host named  {{ ansible_facts['fqdn'] }} of ip is
          {{ ansible_facts['default_ipv4']['address'] }}

[root@node1 ansible]# 



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

PLAY [192.168.100.147] *********************************************************************************************

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

TASK [test] ********************************************************************************************************
ok: [192.168.100.147] => {
    "msg": "The host named  node2 of ip is 192.168.100.147\n"     //The ip has come out
}

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

2. Inject ansible facts as variables

In ansible2 Before 5, the fact was that it was prefixed with the string ansible_ Single variable injection, not as ansible_ Part of the facts variable is injected. For example, ansible_facts ['distribution '] facts will be called ansible_distribution.

Many older playbook s still use the fact that variables are injected instead of ansible_ Create a new syntax for the namespace under the facts variable. We can use temporary commands to run the setup module to display the values of all facts in this form. The following example uses a temporary command to run the setup module on the managed host 192.168.100.147:

ansible 172.16.103.129 -m setup   //This is our first command to get the opposite facts above

ansible fact name comparison

ansible_facts formOld fact variable form
ansible_facts['hostname']ansible_hostname
ansible_facts['fqdn']ansible_fqdn
ansible_facts['default_ipv4']['address']ansible_default_ipv4['address']
ansible_facts['interfaces']ansible_interfaces
ansible_facts['devices']['vda']['partitions']['vda1']['size']ansible_devices['vda']['partitions']['vda1']['size']
ansible_facts['dns']['nameservers']ansible_dns['nameservers']
ansible_facts['kernel']ansible_kernel

At present, Ansible recognizes both the new fact naming system (using ansible_facts) and the old "fact injected as a separate variable" naming system before 2.5.

Insert in the * * [default] section of the Ansible configuration file_ facts_ as_ Set the vars parameter to False * * to turn off the old naming system. The default setting is currently True.

[root@node1 ansible]# vim ansible.cfg / / enter the configuration file


# inject_facts_as_vars = True / / change to false to execute the old command. Remember to uncomment

‚Äč inject_ facts_ as_ The default value of vars may be changed to False in future versions of Ansible. If set to False, only the new * * Ansible can be used_ facts.*** The naming system references Ansible facts. Therefore, it is suggested that we should adapt to this way from the beginning.

3. Close fact collection

Sometimes we don't want to collect facts for play. The reasons for this may be:

  • 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 prerequisite software before collecting facts

For the above reasons, we may want to turn off the fact collection function permanently or temporarily. To disable the fact collection function for play, you can turn gather_ Set the facts keyword to no:

[root@node1 ansible]# cat test1/test.yml 
---
- hosts: '192.168.100.147'
  gather_facts: no     //If we don't want to get the opposite facts, we have to close it.
  tasks: 
    - name: test
      debug: 
        msg: >
          The host named  {{ ansible_facts['fqdn'] }} of ip is
          {{ ansible_facts['default_ipv4']['address'] }}

[root@node1 ansible]# 

Even if gather is set for play_ Facts: No, you can also manually collect facts at any time by running the task using the setup module:

[root@node1 ansible]# cat test1/test.yml 
---
- hosts: '192.168.100.147'
  gather_facts: no 
  tasks: 
    - name: test
      setup: 
    - name: debug
      debug: 
        var: ansible_facts


[root@node1 ansible]# 

4. Create custom facts

In addition to using the facts captured by the system, we can also customize the facts and store them locally on each managed host. These facts are consolidated into a standard list of facts collected when the setup module runs on the managed host. They enable the managed host to provide arbitrary variables to Ansible to adjust the behavior of play.

Custom facts can be defined in static files. The format can be INI files or JSON. They can also be executable scripts that generate JSON output, just like dynamic manifest scripts.

With custom facts, we can define specific values for the managed host for play to populate the configuration file or run tasks conditionally. Dynamic custom facts allow you to programmatically determine the values of these facts at play runtime, and even determine which facts to provide.

By default, the setup module starts from * * / etc / ansible / facts Load custom facts in the files and scripts in the D directory. The name of each file or script must be in The end of fact * * can only be used. The dynamic custom fact script must output the fact in JSON format and must be an executable file.

The following is a static custom fact file written in INI format. The custom fact file in INI format contains the top-level value defined by a part, followed by the key value pair for the fact to be defined:

[packages]     //This configuration file is to be written on the managed host
web_package = httpd
db_package = mariadb-server

[users]
user1 = joe
user2 = jane

The same fact may be provided in JSON format. The following JSON facts are equivalent to the facts specified in the INI format in the above example. JSON data can be stored in static text files or output to standard output through executable scripts:

{
  "packages": {
    "web_package": "httpd",
    "db_package": "mariadb-server"
  },
  "users": {
    "user1": "joe",
    "user2": "jane"
  }
}

be careful:

Custom fact files cannot be in YAML format like playbook. JSON format is the closest equivalent format.

Custom facts are stored in ansible by the setup module_ facts. ansible_ Local variable.

Facts are sorted by the name of the file that defines them. For example, suppose that the previous custom facts are saved on the managed host as * * / etc / ansible / facts d/custom. File generation of fact * *. under these circumstances,

ansible_ facts. ansible_ The value of local ['custom'] ['users'] [' user1 '] is joe.

You can use temporary commands to run the setup module on the managed host to check the structure of custom facts.

[root@node1 ansible]# ansible 192.168.100.147 -m setup|less / / after execution, we search for local and packages below. We find these two things, which are just written by the managed host.

        "ansible_local": {
            "custom": {
                "packages": {
                    "db_package": "mariadb-server",
                    "web_package": "httpd"


                "packages": {
                    "db_package": "mariadb-server",
                    "web_package": "httpd"

Note: Custom facts are used in the same way as the default facts in playbook:

---
- hosts: all
  tasks:
  - name: Prints various Ansible facts
    debug:
      msg: >
        The package to install on {{ ansible_facts['fqdn'] }}
        is {{ ansible_facts['ansible_local']['cutstom']['packages']['web_package'] }}

5. Magic variables

Some variables are not facts or configured through the setup module, but are also automatically set by Ansible. These magic variables can also be used to obtain information related to a specific managed host.

There are four most commonly used:

Magic variableexplain
hostvarsA variable that contains a managed host and can be used to get the value of a variable of another managed host. If facts have not been collected for the managed host, it will not contain the facts for that host.
group_namesLists all groups to which the currently managed host belongs
groupsLists all groups and hosts in the list
inventory_hostnameContains the host name of the currently managed host configured in the manifest. For various reasons, it may be different from the host name reported in the fact

There are many other "magic variables". For more information, see the following link:

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable.

One way to gain insight into their values is to use the debug module to report the contents of the hostvars variable for a specific host:

ansible 172.16.103.129 -m debug -a 'var=hostvars["localhost"]'

6. Iterative tasks using loops

By using loops, the task of using the first mock exam is not necessary. For example, instead of writing five tasks to ensure that there are five users, they just need to write one task to iterate over a list of five users to ensure that they all exist.

Ansible supports iterative tasks on a set of projects using the loop keyword. Loops can be configured to repeat tasks using items in the list, the contents of files in the list, a generated sequence of numbers, or a more complex structure.

A simple loop iterates over a set of projects. Add the loop keyword to the task and take the list of items that should be iterated by it as the value. The loop variable item holds the values used during each iteration.

Consider the following code snippet, which uses the service module twice to ensure that two network services are running:

- name: Postfix is running
  service:
    name: postfix
    state: started
    
- name: Devecot is running
  service:
    name: dovecot
    state: started        //It is unnecessary to use twice to ensure that the service is started. We can use a more concise method

These two tasks can be rewritten to use a simple loop, so that only one task is needed to ensure that both services are running:

- name: service
  service:
    name: "{{ item }}"
    state: started
  loop:
    - postfix
    - dovecot

example:

If we want to create multiple users, such as ten or hundreds, we can use the loop to create them. The code is as follows:

[root@node1 ansible]# cat test1/test.yml / / here, for example, we create five users shen
---
- hosts: 192.168.100.147
  tasks: 
    - name: create user
      user: 
        name: '{{item}}'
        state: present
      loop: 
        - shen1
        - shen2
        - shen3
        - shen4
        - shen5
[root@node1 ansible]# 

 
[root@node1 ansible]# ansible-playbook test1/test.yml / / we can see that the managed host is created successfully. At this time, the managed host should be created by five of us

PLAY [192.168.100.147] *******************************************************************************************

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

TASK [create user] ***********************************************************************************************
changed: [192.168.100.147] => (item=shen1)
changed: [192.168.100.147] => (item=shen2)
changed: [192.168.100.147] => (item=shen3)
changed: [192.168.100.147] => (item=shen4)
changed: [192.168.100.147] => (item=shen5)

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

[root@node1 ansible]# 

[root@node2 ~]# id shen1 / / the managed host has these five users
uid=1002(shen1) gid=1002(shen1) group=1002(shen1)
[root@node2 ~]# id shen2
uid=1003(shen2) gid=1003(shen2) group=1003(shen2)
[root@node2 ~]# id shen3
uid=1004(shen3) gid=1004(shen3) group=1004(shen3)
[root@node2 ~]# id shen4
uid=1005(shen4) gid=1005(shen4) group=1005(shen4)
[root@node2 ~]# id shen5
uid=1006(shen5) gid=1006(shen5) group=1006(shen5)
[root@node2 ~]# 

You can provide the list used by loop through a variable. In the following example, the variable mail_services contains a list of services that need to be running.

Do it with variables

[root@node1 node]# cat llll.yml / / create a file and write these contents
users: 
  - shen6
  - shen7
  - shen8
  - shen9
  - shen10
[root@node1 node]# 


[root@node1 ansible]# cat test.yml / / if we use variables, let's write it like this
---
- hosts: 192.168.100.147
  vars_files: 
    node/llll.yml
  tasks: 
    - name: create user
      user: 
        name: '{{item}}'
        state: present
      loop: '{{users}}'
[root@node1 ansible]#


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

PLAY [192.168.100.147] *********************************************************************************************

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

TASK [create user] *************************************************************************************************
changed: [192.168.100.147] => (item=shen6)
changed: [192.168.100.147] => (item=shen7)
changed: [192.168.100.147] => (item=shen8)
changed: [192.168.100.147] => (item=shen9)
changed: [192.168.100.147] => (item=shen10)

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

7. Circular hash or dictionary list

The loop list does not need to be a simple list of values. In the following example, each item in the list is actually a hash or dictionary. Each hash or dictionary in the example has two keys, name and groups. The value of each key in the current item loop variable can be passed through item Name and item Groups variable.

[root@node1 node]# vim llll.yml / / now let's write it another way
[root@node1 node]# cat llll.yml 
users: 
  - name: shen1
    uid: 2000
  - name: shen2
    uid: 3000
  - name: shen3
    uid: 4000
  - name: shen4
    uid: 5000
[root@node1 node]# 


[root@node1 ansible]# cat test.yml / / pay attention to the writing method of the execution file
---
- hosts: 192.168.100.147
  vars_files: 
    node/llll.yml
  tasks: 
    - name: create user
      user: 
        name: '{{item.name}}'   //
        uid: '{{item.uid}}'
        state: present
      loop: '{{users}}'
[root@node1 ansible]# 


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

PLAY [192.168.100.147] *********************************************************************************************

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

TASK [create user] *************************************************************************************************
changed: [192.168.100.147] => (item={'name': 'shen1', 'uid': 2000})
changed: [192.168.100.147] => (item={'name': 'shen2', 'uid': 3000})
changed: [192.168.100.147] => (item={'name': 'shen3', 'uid': 4000})
changed: [192.168.100.147] => (item={'name': 'shen4', 'uid': 5000})

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

[root@node1 ansible]# 


[root@node2 ~]# id shen1 / / you can see that his uid has changed
uid=2000(shen1) gid=1002(shen1) group=1002(shen1)
[root@node2 ~]# id shen2
uid=3000(shen2) gid=1003(shen2) group=1003(shen2)
[root@node2 ~]# id shen3
uid=4000(shen3) gid=1004(shen3) group=1004(shen3)
[root@node2 ~]# id shen4
uid=5000(shen4) gid=1005(shen4) group=1005(shen4)
[root@node2 ~]# 

8. Circular keywords of earlier styles

In Ansible2 Before 5, most playbooks used different loop syntax. Multiple cyclic keywords are provided with the prefix whth_, Followed by the name of the Ansible lookup plug-in. This circular syntax is common in existing playbooks, but may be deprecated at some point in the future.

Ansible loop of earlier style

Circular keyworddescribe
with_itemsThe behavior is the same as the loop keyword of a simple list, such as a string list or a hash / dictionary list. But different from loop, if it is with_items provides a list of lists, which will be flattened into a single-level list. The loop variable item holds the list items used during each iteration.
with_fileThis keyword requires a list of control node file names. The loop variable item saves the contents of the corresponding file in the file list during each iteration.
with_sequenceThis keyword does not require a list, but requires parameters to generate a list of values from a sequence of numbers. The loop variable item saves the value of a generated item in the generated sequence during each iteration.

With in playbook_ An example of items is as follows:

vars:
  data:
    - user0
    - user1
    - user2
tasks:
  - name: "with_items"
    debug:
      msg: "{{ item }}"
    with_items: "{{ data }}"

From ansible2 Starting with 5, it is recommended to write a loop using the loop keyword.

9. Use the register variable with loop

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 ansible]# cat test.yml 
---
- hosts: 192.168.100.147
  tasks: 
    - name: test
      command: "echo shunzi {{item}},ni xi huan chi shi"  
      loop:
        - shen1
        - shen2
        - shen3
      register: result
    - debug: 
        var: result

[root@node1 ansible]# 



[root@node1 ansible]# ansible-playbook test.yml / / the execution succeeds. We can find the content of greeting the specified user

PLAY [192.168.100.147] *******************************************************************************************

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

TASK [test] ******************************************************************************************************
changed: [192.168.100.147] => (item=shen1)
changed: [192.168.100.147] => (item=shen2)
changed: [192.168.100.147] => (item=shen3)

TASK [debug] *****************************************************************************************************
ok: [192.168.100.147] => {
    "result": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "shunzi",
                    "shen1,ni",
                    "xi",
                    "huan",
                    "chi",
                    "shi"
                ],
                "delta": "0:00:00.006161",
                "end": "2021-07-25 07:09:28.296358",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo shunzi shen1,ni xi huan chi shi",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "shen1",
                "rc": 0,
                "start": "2021-07-25 07:09:28.290197",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "shunzi shen1,ni xi huan chi shi",
                "stdout_lines": [
                    "shunzi shen1,ni xi huan chi shi"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "shunzi",
                    "shen2,ni",
                    "xi",
                    "huan",
                    "chi",
                    "shi"
                ],
                "delta": "0:00:00.002744",
                "end": "2021-07-25 07:09:28.647163",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo shunzi shen2,ni xi huan chi shi",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "shen2",
                "rc": 0,
                "start": "2021-07-25 07:09:28.644419",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "shunzi shen2,ni xi huan chi shi",
                "stdout_lines": [
                    "shunzi shen2,ni xi huan chi shi"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": [
                    "echo",
                    "shunzi",
                    "shen3,ni",
                    "xi",
                    "huan",
                    "chi",
                    "shi"
                ],
                "delta": "0:00:00.003040",
                "end": "2021-07-25 07:09:28.977042",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo shunzi shen3,ni xi huan chi shi",
                        "_uses_shell": false,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "shen3",
                "rc": 0,
                "start": "2021-07-25 07:09:28.974002",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "shunzi shen3,ni xi huan chi shi",
                "stdout_lines": [
                    "shunzi shen3,ni xi huan chi shi"
                ]
            }
        ]
    }
}

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

[root@node1 ansible]# 

In the above example, the results key contains a list. Below, the playbook is modified so that the second task iterates over this list:

[root@node1 ansible]# cat test.yml 
---
- hosts: 192.168.100.147
  tasks: 
    - name: test
      command: "echo shunzi {{item}},ni xi huan chi shi"  
      loop:
        - shen1
        - shen2
        - shen3
      register: result
    - debug: 
        msg: "STDOUT from previous task: {{ item.stdout }}"
      loop: "{{ echo_results['results'] }}"

[root@node1 ansible]# 

10. Run tasks in a regulated manner

Ansible can use conditions to perform tasks or play when specific conditions are met. For example, a condition can be used to determine the available memory on the managed host before ansible installs or configures the service.

We can use conditions to distinguish different managed hosts and assign functional roles according to their conditions. Playbook variables, registered variables, and Ansible facts can all be tested by conditions. You can use operators that compare strings, numeric data, and Boolean values.

==
<
>
<=
>=

The following scenario illustrates the use of conditions in Ansible

  • You can define a hard limit (such as min_memory) in the variable and compare it with the available memory on the managed host.
  • Ansible can capture and evaluate the output of a command to determine whether a task has been completed before performing further operations. For example, if a program fails, it will pass through batch processing.
  • The Ansible fact can be used to determine the managed host network configuration and determine the template file to send (such as network binding or relay).
  • You can evaluate the number of CPU s to determine how to properly tune a Web server.
  • Compare the registered variables with predefined variables to determine whether the service has changed. For example, test MD5 of the service configuration file to verify and see if the service has changed.

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, run the task. If the conditions are not met, the task is skipped.

One of the simplest conditions that can be tested is whether a boolean variable is True or False. The when statement in the following example causes the task to run only_ my_ Run when task is True:

[root@node1 ansible]# cat test.yml 
---
- name: test
  hosts: 192.168.100.147
  vars_files:
    node/llll.yml
  vars: 
    power: true        //Give a judgment   
  tasks: 
    - name: create user
      user:
        name: "{{ item.name}}"
        uid: "{{item.uid}}"
        state: absent
      loop: "{{users}}"
      when: power
[root@node1 ansible]# 

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

PLAY [test] ******************************************************************************************************

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

TASK [create user] ***********************************************************************************************
changed: [192.168.100.147] => (item={'name': 'shen1', 'uid': 2000})
changed: [192.168.100.147] => (item={'name': 'shen2', 'uid': 3000})
changed: [192.168.100.147] => (item={'name': 'shen3', 'uid': 4000})
changed: [192.168.100.147] => (item={'name': 'shen4', 'uid': 5000})

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

The following example tests my_ Whether the service variable has a value. If there is a value, it will be my_ The value of service is used as the name of the package to install. If my is not defined_ Service variable, the task is skipped and no error is displayed.

[root@node1 ansible]# cat test.yml 
---
- name: test
  hosts: 192.168.100.147
  vars_files:
    node/llll.yml      
  tasks: 
    - name: create user
      user:
        name: "{{ item.name}}"
        uid: "{{item.uid}}"
        state: present
      loop: "{{users}}"
      when: '"{{ item.name }}" == "{{ shen3}}"'
[root@node1 ansible]# 

The following table shows some operations that can be used when processing conditions:

operationExample
Equal to (value is string)ansible_machine == "x86_64"
Equal to (value is numeric)max_memory == 512
less thanmin_memory < 128
greater thanmin_memory > 256
Less than or equal tomin_memory <= 256
Greater than or equal tomin_memory >= 512
Not equal tomin_memory != 512
Variable existsmin_memory is defined
Variable does not existmin_memory is not defined
The boolean variable is true. 1. True or yes evaluates to truememory_available
The boolean variable is False. 0, False, or no evaluate to Falsenot memory_available
The value of the first variable exists as the value in the list of the second variableansible_distribution in supported_distros

The last entry in the table above looks confusing at first. The following example demonstrates its working principle.

Keywords: Linux

Added by Smudly on Fri, 14 Jan 2022 08:38:12 +0200