【自动化运维系列教程】Ansible Playbook剧本

一、playbook剧本介绍

  • 优势
    • 便于功能的重用
  • 本质上就是.yml结尾的文件
  • 遵循YAML语法编写

1.YAML语法

  • 一个键对应一个值时,冒号后面必须要有空格

name: nginx
一个键对应多个值时,分行写
键:
- 值
- 值
- 值
同级别代码要有相同缩进,建议是4个空格

2.Playbook基本结构

- hosts: 主机或主机组 
  user: 用户名
  tasks:
      - name: 任务名称
	    模块名称: 参数  参数  参数 
      - name: 任务名称
	    模块名称: 参数  参数  参数 
      - name: 任务名称
	    模块名称: 参数  参数  参数

3.执行Playbook剧本

#  ansible-playbook  剧本存放路径

二、Playbook的简单应用

1.基本应用

创建名为king的用户,指定用户shell为/bin/bash

[root@zabbix_server ansible]# vim /root/ansible/work/createking.yaml
- hosts: appserver
  user: root
  tasks:
       - name: create king user
         user: name=king shell=/bin/bash state=present

执行剧本

[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createking.yaml

PLAY [webserver] *********************************************************************************************

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

TASK [create king user] **************************************************************************************
changed: [node1]
changed: [node2]

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

2.剧本在执行用户自定义的任务前,会自动执行一个名称为Gathering Facts的任务,即调用setup模块搜集被管理机的状态数据,可添加如下参数取消该行为

- hosts: appserver
  user: root
  gather_facts: false		#添加此段内容
  tasks:
      - name: create hadoop user
        user: name=hadoop shell=/sbin/nologin state=present

三、Playbook中变量的使用

1.剧本中如何调用变量

{{ 变量名称 }}

2.在Playbook中直接定义变量

[root@zabbix_server ansible]# vim /root/ansible/work/createmartin.yaml
- hosts: webserver
  user: root
  gather_facts: false
  vars:
    - user_name: "martin"
    - shell_name: "/sbin/nologin"
  tasks:
    - name: create user martin
      user: name={{ user_name }} shell={{ shell_name }} state=present

执行

[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createmartin.yaml

PLAY [webserver] *********************************************************************************************

TASK [create user martin] ************************************************************************************
changed: [node1]
changed: [node2]

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

检查结果

[root@zabbix_server ansible]# ansible webserver -m shell -a 'id martin'
node1 | CHANGED | rc=0 >>
uid=1003(martin) gid=1003(martin) 组=1003(martin)
node2 | CHANGED | rc=0 >>
uid=1003(martin) gid=1003(martin) 组=1003(martin)

3.在主机清单中定义变量

A.为主机组定义变量

[root@zabbix_server ansible]# vim /root/ansible/hosts
#在文件底部新增内容
[webserver:vars]
user_name="jerry"
shell_name="/bin/bash"
编写脚本文件
[root@zabbix_server ansible]# vim /root/ansible/work/createjerry.yaml
- hosts: webserver
  user: root
  gather_facts: false
  tasks:
   - name: create user jerry
     user: name={{ user_name }} shell={{ shell_name }} state=present
执行剧本
[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createjerry.yaml

PLAY [webserver] *********************************************************************************************

TASK [create user jerry] *************************************************************************************
changed: [node1]
changed: [node2]

PLAY RECAP ***************************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
查询结果
[root@zabbix_server ansible]# ansible webserver -m shell -a 'id jerry'
node2 | CHANGED | rc=0 >>
uid=1004(jerry) gid=1004(jerry) 组=1004(jerry)
node1 | CHANGED | rc=0 >>
uid=1004(jerry) gid=1004(jerry) 组=1004(jerry)

B.为单个主机定义变量

修改主机清单文件
[webserver]
node1 user_name="test01"
node2 user_name="test02"

[webserver:vars]
shell_name="/bin/bash"
编写Playbook剧本
[root@zabbix_server ansible]# vim /root/ansible/work/createtest.yaml
- hosts: webserver
  user: root
  gather_facts: false
  tasks:
    - name: create user test
      user: name={{ user_name }} shell={{ shell_name }} state=present
测试剧本
[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createtest.yaml

PLAY [webserver] *********************************************************************************************

TASK [create user test] **************************************************************************************
changed: [node2]
changed: [node1]

PLAY RECAP ***************************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
查询结果
[root@zabbix_server ansible]# ansible webserver -m shell -a 'tail -n 1 /etc/passwd'
node2 | CHANGED | rc=0 >>
test02:x:1005:1005::/home/test02:/bin/bash
node1 | CHANGED | rc=0 >>
test01:x:1005:1005::/home/test01:/bin/bash

4.在外部文件定义变量

先删除之前在hosts清单文件中定义的变量

A.编写变量文件

[root@zabbix_server ansible]# vim /root/ansible/work/userinfo
user_name: "test03"
shell_name: "/bin/false"

B.编写Playbook剧本文件

[root@zabbix_server ansible]# vim /root/ansible/work/createtest03.yaml
- hosts: webserver
  user: root
  gather_facts: false
  vars_files:
    - /root/ansible/work/userinfo
  tasks:
    - name: create user test03
      user: name={{ user_name }} shell={{ shell_name }} state=present
执行剧本
[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createtest03.yaml

PLAY [webserver] *********************************************************************************************

TASK [create user test03] ************************************************************************************
changed: [node2]
changed: [node1]

PLAY RECAP ***************************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
查询结果
[root@zabbix_server ansible]# ansible webserver -m shell -a 'id test03'
node2 | CHANGED | rc=0 >>
uid=1006(test03) gid=1006(test03) 组=1006(test03)
node1 | CHANGED | rc=0 >>
uid=1006(test03) gid=1006(test03) 组=1006(test03)

C.加密外部变量文件

修改变量文件中的内容
[root@zabbix_server ansible]# vim /root/ansible/work/userinfo
user_name: "test04"
shell_name: "/bin/false"
加密文件
[root@zabbix_server ansible]# ansible-vault encrypt /root/ansible/work/userinfo 
New Vault password: 
Confirm New Vault password: 
Encryption successful

[root@zabbix_server ansible]# cat /root/ansible/work/userinfo 	#已经是加密状态了
$ANSIBLE_VAULT;1.1;AES256
32333166663865303139613165316666376132303933353738636138313830383639333662316533
3463636432613632313263363534326435393766616336360a623266636666653832336265616334
31636362396463613962643533316530626536346634306237333463613832306264666265616565
3130353133623966390a663130373761636537386637613136656564326663623666346339376232
62383966396539393730623762356239626335353065623130636439643839353135353636323030
3034393030326432396236366665366537636639623166316137
执行剧本

执行加密文件的时候,需要携带--ask-vault参数

[root@zabbix_server ansible]# vim /root/ansible/work/createtest04.yaml
- hosts: webserver
  user: root
  gather_facts: false
  vars_files:
    - /root/ansible/work/userinfo
  tasks:
    - name: create user test04
      user: name={{ user_name }} shell={{ shell_name }} state=present
[root@zabbix_server ansible]# ansible-playbook --ask-vault /root/ansible/work/createtest04.yaml 
Vault password: 

PLAY [webserver] ********************************************************************************************

TASK [create user test04] ***********************************************************************************
changed: [node2]
changed: [node1]

PLAY RECAP **************************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
验证结果
[root@zabbix_server ansible]# ansible webserver -m shell -a 'id test04'
node1 | CHANGED | rc=0 >>
uid=1007(test04) gid=1007(test04) 组=1007(test04)
node2 | CHANGED | rc=0 >>
uid=1007(test04) gid=1007(test04) 组=1007(test04)

四、案例:批量部署MariaDB

分别在node1node2上部署MriaDB,并且设置好ServerID和开启二进制日志

1.为不用主机定义变量

[root@zabbix_server ansible]# vim /root/ansible/hosts
[webserver]
node1 id=11
node2 id=12

[dbserver]
node3

[webserver:vars]
slave="master"

[all:vars]
ansible_password=centos

2.自定义My.cnf配置文件

[root@zabbix_server ansible]# vim /root/ansible/work/my.cnf

[mysqld]
server_id={{ id }}	#填写我们的自定义变量
log_bin={{ slave }}	#填写我们的自定义变量
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

3.编写剧本

[root@zabbix_server ansible]# vim /root/ansible/work/mysql.yaml
- hosts: webserver
  user: root
  tasks:
    - name: install mariadb
      yum: name=mariadb-server state=present

    - name: push mysql config
      template: src=/root/ansible/work/my.cnf dest=/etc/my.cnf	#这里的模块用template因为支持自定义变量

    - name: Start mariaDB service
      service: name=mariadb state=started enabled=yes

执行剧本

[root@zabbix_server ansible]# ansible-playbook  /root/ansible/work/mysql.yaml 

PLAY [webserver] *********************************************************************************************

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

TASK [install mariadb] ***************************************************************************************
changed: [node2]
changed: [node1]

TASK [push mysql config] *************************************************************************************
changed: [node1]
changed: [node2]

TASK [Start mariaDB service] *********************************************************************************
changed: [node1]
changed: [node2]

PLAY RECAP ***************************************************************************************************
node1                      : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

检查数据库服务状态

[root@zabbix_server ansible]# ansible webserver -m shell -a'netstat -tunlp | grep 3306'
node2 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      2111/mysqld         
node1 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      2098/mysqld

查看ServerID

[root@zabbix_server ansible]# ansible webserver -m shell -a 'grep -i "server_id" /etc/my.cnf'
node1 | CHANGED | rc=0 >>
server_id=11
node2 | CHANGED | rc=0 >>
server_id=12

查看二进制日志状态

[root@zabbix_server ansible]# ansible webserver -m shell -a 'mysql -uroot -e "show master status"'
node1 | CHANGED | rc=0 >>
File	Position	Binlog_Do_DB	Binlog_Ignore_DB
master.000003	245		
node2 | CHANGED | rc=0 >>
File	Position	Binlog_Do_DB	Binlog_Ignore_DB
master.000003	245

五、条件判断

when: 条件

[root@zabbix_server ansible]# vim /root/ansible/work/createuserABC.yaml
- hosts: webserver
  user: root
  tasks:
    - name: create userE
      user: name=userE shell=/bin/bash state=present
      when: ansible_default_ipv4["address"] == "192.168.140.11"

    - name: create userF
      user: name=userF shell=/bin/bash state=present
      when: ansible_default_ipv4["address"] == "192.168.140.12"
[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/createuserABC.yaml

PLAY [webserver] ********************************************************************************************

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

TASK [create userE] *****************************************************************************************
skipping: [node2]
changed: [node1]

TASK [create userF] *****************************************************************************************
skipping: [node1]
changed: [node2]

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

1.关于内置变量

可以使用setup查看

[root@zabbix_server ansible]# ansible webserver -m setup

2.关于变量取值

"address": "192.168.140.12",

遇到这种,直接填写前面的变量即可去到后面的值address

3.关于列表取值

"ansible_all_ipv4_addresses": [
            "192.168.140.12"
        ],

当我想取到IP地址的时候,可以在剧本文件中填写ansible_all_ipv4_addresses[0]
列表默认从0开始,当有多条数据的时候,从0开始一次向后排序
以下是Python中样例

>>> ansible_all_ipv4_addresses = [ "192.168.140.11","192.168.140.12","192.168.140.13"]
>>> ansible_all_ipv4_addresses
['192.168.140.11', '192.168.140.12', '192.168.140.13']
>>> ansible_all_ipv4_addresses [1]	#使用下角标调用数据
'192.168.140.12'
>>> ansible_all_ipv4_addresses [2]
'192.168.140.13'
>>> ansible_all_ipv4_addresses [0]
'192.168.140.11'

4.关于字典取值

"ansible_default_ipv4": {
            "address": "192.168.140.12", 
            "alias": "ens33", 
            "broadcast": "192.168.140.255", 
            "gateway": "192.168.140.2", 
            "interface": "ens33", 
            "macaddress": "00:0c:29:0f:55:d2", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "192.168.140.0", 
            "type": "ether"
        },

当我想取字典里的值,只需要填写字典名["键值"]即可
比如我想拿到MAC地址,那么剧本里填写ansible_default_ipv4["macaddress"]
以下是Python中的样例

>>> ansible_default_ipv4 = {"address":"192.168.140.10","netmask":"255.255.255.0"}
>>> ansible_default_ipv4 ["netmask"]
'255.255.255.0'
>>> ansible_default_ipv4 ["address"]
'192.168.140.10'

5.列表+字典取值

"ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.140.11"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:fe37:97c7"
        ]

当我想取值IPV4地址的时候,可以在剧本中填写ansible_facts["ansible_all_ipv4_addresses"][0]
当字典中有多个值的时候,同样从数字0开始依次向后排

六、循环

loop关键字

- hosts: webserver
  user: root
  tasks: 
      - name: create userAA/BB/CC
        user: name={{ item }} state=present		#item是内置变量,用于传递后面循环的参数
        loop:
           - "userAA"
           - "userBB"
           - "userCC"

通过字典为item赋值

- hosts: webserver
  user: root
  gather_facts: false
  tasks:
      - name: create user11/22/33
        user: name={{ item["username"] }} shell={{ item["sh_name"] }} state=present
        loop:
            - { "username":"user11", "sh_name":"/sbin/nologin" }
            - { "username":"user22", "sh_name":"/bin/bash" }
            - { "username":"user33", "sh_name":"/bin/sync" }

案例:通过循环安装依赖

- hosts: webserver
  user: root
  gather_facts: false
  tasks:
    - name: install deps
      yum: name={{ item }} state=present
      loop:
         - gcc
         - openssl-devel
         - zlib-devel
         - pcre-devel

执行结果

[root@zabbix_server ansible]# ansible-playbook /root/ansible/work/nginx.yaml

PLAY [webserver] ********************************************************************************************

TASK [install deps] *****************************************************************************************
changed: [node1] => (item=gcc)
changed: [node1] => (item=openssl-devel)
ok: [node1] => (item=zlib-devel)
ok: [node1] => (item=pcre-devel)
changed: [node2] => (item=gcc)
changed: [node2] => (item=openssl-devel)
ok: [node2] => (item=zlib-devel)
ok: [node2] => (item=pcre-devel)

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

七、Jinjia模板

  • 支持在配置文件中调用变量{{ 变量名称 }}
  • 增加配置文件灵活性
  • 建议配置文件以.j2结尾
  • Jinja模板要使用template模块推送,触发变量替换

1.关于Jinjia模板的写法

其实刚刚第四步,我们已经用到了Jinjia模板

[root@zabbix_server ansible]# vim /root/ansible/work/my.cnf.j2	#建议以.j2结尾文件

[mysqld]
server_id={{ id }}	#上面第四步用到的自定义变量
log_bin={{ slave }}	#上面第四步用到的自定义变量
bind-address={{ ansible_default_ipv4["address"] }}	#摘自setup模块中的变量
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

2.handlers组件

  • tasks同级别组件, 默认情况 ,handers下定义的任务是不会自动执行的,只有在满足了一定的条件,由特定的条件触发其执行
  • 应用场景
    • 检测配置文件,自动重启服务加载配置

我们来简单改一下第四步示例的Playbook剧本

[root@zabbix_server ansible]# vim /root/ansible/work/mysql.yaml

- hosts: webserver
  user: root
  tasks:
    - name: install mariadb
      yum: name=mariadb-server state=present

    - name: push mysql config
      template: src=/root/ansible/work/my.cnf.j2 dest=/etc/my.cnf
      notify: Restart mriaDB	#触发条件,写handlers里名字即可

    - name: Start mariaDB service
      service: name=mariadb state=started enabled=yes
  handlers:	#与tasks同级
    - name: Restart mriaDB
      service: name=mariadb state=restarted	#当检测到配置文件改动以后,就会触发自动重启服务

八、role角色

1.role角色介绍

  • 本质上就是个目录
    • 默认存放路径/etc/ansible/roles/
  • 一个需求对应一个角色

2.修改配置文件

[root@zabbix_server ansible]# vim /root/ansible/ansible.cfg
roles_path    = /root/ansible/roles	#修改默认地址

[root@zabbix_server ansible]# mkdir /root/ansible/roles

3.创建角色

[root@zabbix_server ansible]# cd /root/ansible/roles
[root@zabbix_server roles]# pwd
/root/ansible/roles
[root@zabbix_server roles]# ansible-galaxy init lnmp
- Role lnmp was created successfully

4.目录结构

如果没有tree命令,请安装yum install -y tree

  • defaults默认参数
  • files普通文件、软件安装包
  • handlers触发的操作
  • meta元数据
  • tasks常规任务、操作
  • templates
    • jinja模块
  • tests剧本相关的测试代码
  • vars定义变量
  • 同一个角色中,相互引用数据时,不需要添加任何目录,直接调用即可
[root@zabbix_server roles]# tree /root/ansible/roles/lnmp
/root/ansible/roles/lnmp
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

8 directories, 8 files

5.案例:批量自动化部署Zabbix Agent

关于Zabbix Server4.x版本部署教程:https://www.wsjj.top/archives/109
关于Zabbix Server5.x版本部署教程:https://www.wsjj.top/archives/18
关于Zabbix Agent4.x版本部署教程:https://www.wsjj.top/archives/110
关于Zabbix Agent5.x版本部署教程:https://www.wsjj.top/archives/19

A.回到Serverweb界面配置自动注册

关于Zabbix自动发现和自动注册教程:https://www.wsjj.top/archives/113

ansible01

B.创建角色

[root@zabbix_server roles]# cd /root/ansible/roles/
[root@zabbix_server roles]# ansible-galaxy init agent
- Role agent was created successfully
[root@zabbix_server roles]# ls
agent

C.准备Zabbix Agent用到的Jinjia模板

因为我本机已经配置过了Zabbix ServerAgent,所以我就直接复制过来了

[root@zabbix_server roles]# cp /etc/zabbix/zabbix_agentd.conf /root/ansible/roles/agent/templates/zabbix_agentd.conf.j2
修改Jinjia模板
[root@zabbix_server roles]# vim /root/ansible/roles/agent/templates/zabbix_agentd.conf.j2
#配置文件并不完整,仅展示修改的地方
Server=192.168.140.10	#指定Zabbix Server地址
ServerActive=192.168.140.10	#指定Zabbix Server地址
Hostname={{ ansible_fqdn }}	#这里调用setup模块中的变量,是对应的主机名
UnsafeUserParameters=1	#开启自定义键值

D.编写剧本

[root@zabbix_server roles]# vim /root/ansible/roles/agent/tasks/main.yml
---
# tasks file for agent

- name: Zabbix yum.repo	#配置yum源
  yum_repository:
      name: zabbix4
      file: zabbix4
      description: zabbix4 YUM repo
      baseurl: https://mirrors.aliyun.com/zabbix/zabbix/4.4/rhel/7/x86_64/
      gpgcheck: no
      enabled: yes

- name: Install Zabbix-Agent	#安装Zabbix-Agent
  yum: name=zabbix-agent state=present

- name: Copy Zabbix-Agent Config	#拷贝配置文件
  template: src=zabbix_agentd.conf.j2 dest=/etc/zabbix/zabbix_agentd.conf	#这里和之前不同的是,源文件不用写路径
  notify: Restart Zabbix-Agent daemon	#指定触发条件,我们将稍后写进handlers

- name: Start Zabbix-Agent daemon	#启动Zabbix-Agent服务,并且设置开机自启动
  service: name=zabbix-agent state=started enabled=yes
编写handlers
[root@zabbix_server roles]# vim /root/ansible/roles/agent/handlers/main.yml
---
# handlers file for agent

- name: Restart Zabbix-Agent daemon	#这里的名字一定要和上面的触发条件名字一致
  service: name=zabbix-agent state=restarted

E.编写角色剧本(重要)

[root@zabbix_server roles]# vim /root/ansible/work/zabbix_agent.yaml
- hosts: webserver	#指定主机组
  user: root
  roles:
    - agent	#这里写角色名

F.执行剧本

[root@zabbix_server roles]# cd /root/ansible/
[root@zabbix_server ansible]# ls
ansible.cfg  createuser.yaml  hosts  roles  work
[root@zabbix_server ansible]# ansible --version
ansible 2.9.27
  config file = /root/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
[root@zabbix_server roles]# ansible-playbook /root/ansible/work/zabbix_agent.yaml

PLAY [webserver] ********************************************************************************************

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

TASK [agent : Zabbix yum.repo] ******************************************************************************
changed: [node1]
changed: [node2]

TASK [agent : Install Zabbix-Agent] *************************************************************************
changed: [node2]
changed: [node1]

TASK [agent : Copy Zabbix-Agent Config] *********************************************************************
changed: [node1]
changed: [node2]

TASK [agent : Start Zabbix-Agent daemon] ********************************************************************
changed: [node2]
changed: [node1]

RUNNING HANDLER [agent : Restart Zabbix-Agent daemon] *******************************************************
changed: [node1]
changed: [node2]

PLAY RECAP **************************************************************************************************
node1                      : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

G.检查服务是否启动

[root@zabbix_server ansible]# ansible webserver -m shell -a 'netstat -tunlp | grep zabbix'
node1 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      4664/zabbix_agentd  
tcp6       0      0 :::10050                :::*                    LISTEN      4664/zabbix_agentd  
node2 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:10050           0.0.0.0:*               LISTEN      4374/zabbix_agentd  
tcp6       0      0 :::10050                :::*                    LISTEN      4374/zabbix_agentd

H.回到Serverweb界面,查看是否自动添加主机

ansible02