ansible 事实 循环 条件

一、管理事实

Ansible事实是Ansible在受管主机上自动检测到的变量。事实中包含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用。

为受管主机收集的一些事实可能包括:

主机名称
内核版本
网络接口
IP地址
操作系统版本
各种环境变量
CPU数量
提供的或可用的内存
可用磁盘空间

实例

查看主机信息

[root@server playbook]# cat fact.yml 
---
- hosts: lamp
  tasks: 
    - name: 
      debug: 
        var: ansible_facts

执行

[root@server playbook]# ansible-playbook fact.yml 

PLAY [lamp] *****************************************************************************

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

TASK [debug] ****************************************************************************
ok: [192.168.58.20] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.58.20"
        ],
        "all_ipv6_addresses": [
            "fe80::4f83:a388:3cd:89bc"
...........

将事实替换为动态的值

[root@server playbook]# cat fact.yml 
---
- hosts: lamp
  tasks: 
    - name: print ip
      debug: 
        msg: >
          The IP of {{ ansible_facts['default_ipv4']['address']  }}


执行

[root@server playbook]# ansible-playbook fact.yml 

PLAY [lamp] *****************************************************************************

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

TASK [print ip] *************************************************************************
ok: [192.168.58.20] => {
    "msg": "The IP of 192.168.58.20\n"
}

可以使用setup模块显示所有事实

[root@server playbook]# ansible lamp -m setup
192.168.58.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.58.20"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::4f83:a388:3cd:89bc"
        ],
        "ansible_apparmor": {
            "status": "disabled"
...............

关闭事实可以提高运行速度(gather_facts: no)

[root@server playbook]# cat fact.yml 
---
- hosts: lamp
  gather_facts: no
  tasks: 
    - name: no
      setup: 
    - name: print ip
      debug: 
        var: 
          ansible_facts
[root@server playbook]# 

执行

[root@server playbook]# ansible-playbook  fact.yml 

PLAY [lamp] *****************************************************************************

TASK [setup] ****************************************************************************
ok: [192.168.58.20]

TASK [print ip] *************************************************************************
ok: [192.168.58.20] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.58.20"
        ],
        "all_ipv6_addresses": [
            "fe80::4f83:a388:3cd:89bc"
        ],
        "ansible_local": {},
        "apparmor": {
            "status": "disabled"
............

自定义事实
通常在/etc/ansible/facts.d目录下编写以.fact为扩展名的自定义事实文件

[root@server ansible]# cat  lo.fact
[lp]
package = httpd
service = httpd
state = started 
enabled = yes


---
- hosts: 192.168.200.145
  vars:
    dir: /etc/ansible/facts.d
    file: zzz.fact
  tasks:
    - name: create dir
      file:
        state: directory
        recurse: yes
        path: "{{ dir }}"
    - name: create file
      copy:
        src: "{{ file }}"
        dest: "{{ dir }}"

//运行
[root@lserver  playbook]# ansible-playbook fact.yml 

PLAY [192.168.58.20 ] *********************************************************

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

TASK [create dir] **************************************************************
ok: [192.168.58.20 ]

TASK [create file] *************************************************************
changed: [192.168.58.20 ]

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

查看

//查看http是否运行
[root@server ansible]# ansible 192.168.58.20 -m command -a 'systemctl status httpd'
192.168.58.20 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2021-07-25 21:22:16 EDT; 35s ago
     Docs: man:httpd.service(8)
 Main PID: 84981 (httpd)
   Status: "Running, listening on: port 80"
    Tasks: 213 (limit: 11300)
   Memory: 25.4M
.........

魔法变量:

魔法变量说明
hostvars包含受管主机的变量,可以用于获取另一台受管主机的变量的值。 如果还没有为受管主机收集事实,则它不会包含该主机的事实。
group_names列出当前受管主机所属的所有组
groups列出清单中的所有组和主机
inventory_hostname包含清单中配置的当前受管主机的主机名称。 因为各种原因有可能与事实报告的主机名称不同

二、循环

通过利用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。

Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。

实例

创建用户

[root@server playbook]# cat for.yml 
---
- hosts: lamp
  tasks: 
    - name: 
      user: 
        name: "{{ item  }}"
        state: present
      loop: 
        - xu
        - meng

执行

[root@server playbook]# ansible-playbook  for.yml 

PLAY [lamp] *****************************************************************************

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

TASK [user] *****************************************************************************
changed: [192.168.58.20] => (item=xu)
changed: [192.168.58.20] => (item=meng)

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


运用变量

[root@server playbook]# cat for.yml 
---
- hosts: lamp
  vars: 
    package: 
      - httpd
      - vsftpd
  tasks: 
    - name: 
      yum : 
        name: "{{ item  }}"
        state: installed
      loop: "{{ package  }}"

执行

[root@server playbook]# ansible-playbook  for.yml 

PLAY [lamp] *****************************************************************************

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

TASK [yum] ******************************************************************************
ok: [192.168.58.20] => (item=httpd)
changed: [192.168.58.20] => (item=vsftpd)

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


循环散列

[root@server playbook]# cat for.yml 
---
- hosts: lamp
  tasks: 
    - name: 
      user: 
        name: "{{ item.name  }}"
        groups: "{{ item.groups  }}"
        state: present
      loop: 
        - name: lbw
          groups: nb
        - name: qtql
          groups: suzhigc

执行

[root@server playbook]# ansible-playbook  for.yml 
PLAY [lamp] *****************************************************************************

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

TASK [user] *****************************************************************************
changed: [192.168.58.20] => (item={'name': 'lbw', 'groups': 'nb'})
changed: [192.168.58.20] => (item={'name': 'qtql', 'groups': 'suzhigc'})

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

三、 条件判断

Ansible可使用conditionals在符合特定条件时执行任务或play。例如,可以利用一个条件在Ansible安装或配置服务前确定受管主机上的可用内存。

我们可以利用条件来区分不同的受管主机,并根据它们所符合的条件来分配功能角色。Playbook变量、注册的变量和Ansible事实都可通过条件来进行测试。可以使用比较字符串、数字数据和布尔值的运算符。

以下场景说明了在Ansible中使用条件的情况:

可以在变量中定义硬限制(如min_memory)并将它与受管主机上的可用内存进行比较。
Ansible可以捕获并评估命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将路过批处理。
可以利用Ansible事实来确定受管主机网络配置,并决定要发送的模板文件(如,网络绑定或中继)。
可以评估CPU的数量,来确定如何正确调节某一Web服务器。
将注册的变量与预定义的变量进行比较,以确定服务是否已更改。例如,测试服务配置文件的MD5检验以和查看服务是否已更改。

1. 条件判断语句

when语句用于有条件地运行任务。它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足,则跳过任务。
值为true才运行

[root@server playbook]# cat for.yml 
---
- hosts: lamp
  vars: 
    qtql: true
  tasks: 
    - name: 
      user: 
        name: "{{ item.name  }}"
        groups: "{{ item.groups  }}"
        state: present
      loop: 
        - name: lbw
          groups: nb
        - name: qtql
          groups: suzhigc
          

值为false跳过

[root@server playbook]# cat for.yml 
---
- hosts: lamp
  vars: 
    qtql: false
  tasks: 
    - name: 
      user: 
        name: "{{ item.name  }}"
        groups: "{{ item.groups  }}"
        state: present
      loop: 
        - name: lbw
          groups: nb
        - name: qtql
          groups: suzhigc

1.1示例条件

操作示例
等于(值为字符串)ansible_machine == “x86_64”
等于(值为数字)max_memory == 512
小于min_memory < 128
大于min_memory > 256
小于等于min_memory <= 256
大于等于min_memory >= 512
不等于min_memory != 512
变量存在min_memory is defined
变量不存在min_memory is not defined
布尔变量是True1、True或yes的求值为Truememory_available
布尔变量是False。0、False或no的求值为Falsenot memory_available
第一个变量的值存在,作为第二个变量的列表中的值ansible_distribution in supported_distros

1.2测试多个条件

一个when语句可用于评估多个条件。使用and和or关键字组合条件,并使用括号分组条件。

如果任一条件为真时满足条件语句,则应当使用or语句。例如,如果计算机上运行的是红帽企业linux或Fedora,则下述条件得到满足:

	when: ansible_distribution == "runtime" or ansible_distribution == "Fedora"

使用and运算时,两个条件都必须为真,才能满足整个条件语句。例如,如果远程主机是红帽企业Linux7.5主机,并且安装的内核是指定版本,则将满足以下条件:

 when: ansible_distribution_version == "7.5" and ansible_kernel == "3.10.0-327.el7.x86_64"

when关键字还支持使用列表来描述条件列表。向when关键字提供列表时,将使用and运算组合所有条件。下面的示例演示了使用and运算符组合多个条件语句的另一方式:

    when:
  - ansible_distribution_version == "7.5"
  - ansible_kernel == "3.10.0-327.el7.x86_64"

这种格式提高了可读性,而可读性是良好编写Ansible Playbook的关键目标。

通过使用括号分组条件,可以表达更复杂的条件语句。例如,如果计算机上运行的是红帽企业Linux7或Fedora28,则下述条件语句得到满足。此示例使用大于字符,这样长条件就可以在playbook中分成多行,以便于阅读。

when: >
  ( ansible_distribution == "Redhat" and
    ansible_distribution_major_version == "7" )
  or
  ( ansible_distribution == "Fedora" and
    ansible_distribution_major_version == "28" )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值