ansible的playbook

旧城冷巷雨未停 提交于 2020-11-01 18:57:25

一:ansible-playbook的基本语法

#编写以下yaml文件
[root@supervisor yaml]# cat /etc/ansible/yaml/test.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: 安装ntpdate,wget,lrzsz
      yum: state=present name=ntpdate,wget,lrzsz
    - name: 创建web目录
      shell: mkdir -p /data/cache
    - name: 安装httpd
      yum: state=present name=httpd
      notify:
        - Start httpd
  handlers:
    - name: Start httpd
      service: state=restarted name=httpd enabled=yes 
 
- hosts: centos7
  remote_user: root
  tasks:
    - name: 安装net工具
      yum: state=present name=net-tools
#检查语法是否正确
[root@supervisor yaml]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/yaml/test.yml --syntax-check
 
playbook: /etc/ansible/yaml/test.yml  
#执行playbook
[root@supervisor yaml]# ansible-playbook test.yml 
 
PLAY [all] **********************************************************************************************************************************************************************************************************************************
 
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.1.182]
ok: [192.168.1.183]
ok: [192.168.1.184]
ok: [192.168.1.181]
ok: [192.168.1.185]
ok: [192.168.1.186]
 
TASK [安装ntpdate,wget,lrzsz] *****************************************************************************************************************************************************************************************************************
changed: [192.168.1.184]
changed: [192.168.1.182]
changed: [192.168.1.185]
changed: [192.168.1.181]
changed: [192.168.1.183]
changed: [192.168.1.186]
 
TASK [创建web目录] ******************************************************************************************************************************************************************************************************************************
 [WARNING]: Consider using the file module with state=directory rather than running mkdir.  If you need to use command because file is insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg   #这里提示对文件操作用file模块
to get rid of this message.
changed: [192.168.1.184]
changed: [192.168.1.183]
changed: [192.168.1.181]
changed: [192.168.1.182]
changed: [192.168.1.185]
changed: [192.168.1.186]
 
TASK [安装httpd] ******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.185]
changed: [192.168.1.183]
changed: [192.168.1.184]
changed: [192.168.1.181]
changed: [192.168.1.182]
changed: [192.168.1.186]
 
RUNNING HANDLER [Start httpd] ***************************************************************************************************************************************************************************************************************
changed: [192.168.1.183]
changed: [192.168.1.181]
changed: [192.168.1.185]
changed: [192.168.1.184]
changed: [192.168.1.182]
changed: [192.168.1.186]
 
PLAY [centos7] ******************************************************************************************************************************************************************************************************************************
 
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.1.182]
ok: [192.168.1.184]
ok: [192.168.1.186]
 
TASK [安装net工具] ******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.186]
changed: [192.168.1.182]
changed: [192.168.1.184]
 
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.1.181              : ok=5    changed=4    unreachable=0    failed=0   
192.168.1.182              : ok=7    changed=5    unreachable=0    failed=0   
192.168.1.183              : ok=5    changed=4    unreachable=0    failed=0   
192.168.1.184              : ok=7    changed=5    unreachable=0    failed=0   
192.168.1.185              : ok=5    changed=4    unreachable=0    failed=0   
192.168.1.186              : ok=7    changed=5    unreachable=0    failed=0   
#yml文件说明
第一行:---类似于解释器如同shell的/bin/bash
第二行:- hosts:all  指定对那些主机进行操作
第三行:remote_user   指定执行用户
第四行:tasks  任务
第五行至第十行:可以有多个任务,- name任务的描述下边是具体任务内容
第十一行:norify和handlers配合使用,指定连锁动作
可以有多个hosts,多个tasks多个notify和handlers
二:ansible-playbook定义变量





ansible-playbook设置变量有以下五种方式:
1:hosts主机清单定义
2:vars  设置
3:vars_file  设置变量文件
4:vars_prompt 手动输入
5:setup  获取变量
============================================hosts主机清单
[root@supervisor yaml]# cat /etc/ansible/hosts   #主机清单
[centos6]
192.168.1.181
192.168.1.183
192.168.1.185
 
[centos7]
192.168.1.182
192.168.1.184
192.168.1.186
 
[centos:children]
centos6
centos7
 
[centos:vars]   #定义变量
port=8080
#使用变量
[root@supervisor yaml]# cat test
{{port}}
[root@supervisor yaml]# cat debug.yml 
---
- hosts: centos
  gather_facts: no
  tasks:
    - name: print port
      template: src=test dest=/tmp/test_debug
#执行结果
[root@supervisor yaml]# ansible centos -m shell -a "cat /tmp/test_debug"
192.168.1.185 | SUCCESS | rc=0 >>
8080
192.168.1.182 | SUCCESS | rc=0 >>
8080
192.168.1.184 | SUCCESS | rc=0 >>
8080
192.168.1.183 | SUCCESS | rc=0 >>
8080
192.168.1.181 | SUCCESS | rc=0 >>
8080
192.168.1.186 | SUCCESS | rc=0 >>
8080
============================================vars
比如需要在远程主机创建目录和文件,可以用vars在playbook中定义变量
---
- hosts: centos6
  remote_user: root
  vars:
      directory: /root/test
      file: /root/test/haha
  tasks:
    - name: 创建目录
      shell: "mkdir {{directory}}"
    - name: 创建文件
      shell: "touch {{file}}"
============================================vars_file
同时如果变量比较多,我们可以写在文件中,然后调用该文件。用于往远程主机传递变量
[root@supervisor yaml]# cat variables_file  #定义变量的文件
name: lisi
passwd: 123456
[root@supervisor yaml]# cat test   #调用变量的文件
{{name}}
{{passwd}}
[root@supervisor yaml]# cat test2.yml 
---
- hosts: centos7
  remote_user: root
  vars_files:
    - variables_file
 
  tasks:
    - name: 复制文件  #传递变量(和copy模块类似)
      template: src=test dest=/root/test.file
#远程主机检查
[root@supervisor yaml]# ansible centos7 -a "cat /root/test.file" 
192.168.1.184 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.182 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.186 | SUCCESS | rc=0 >>
lisi
123456
============================================vars_prompt
这个是手动输入变量,比如我们创建一个用户的时候,手动输入密码
[root@supervisor yaml]# cat test3.yml 
---
 
- hosts: all
  remote_user: root
  vars_prompt:
    - name: users
      prompt: 输入用户名
    - name: passwd
      prompt: 输入密码
      private: no   #指定是否隐藏输入,默认为隐藏(yes)
  tasks:
    - name: 上传变量文件
      template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test  #变量文件
{{users}}
{{passwd}}
#执行状态
[root@supervisor yaml]# ansible-playbook test3.yml
输入用户名: 
输入密码: zhangsan
......
#执行结果
[root@supervisor yaml]# ansible all -a "cat /root/test.txt"
192.168.1.186 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.184 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.182 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.183 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.181 | SUCCESS | rc=0 >>
zhangsan
zhangsan
============================================setup方法
比如我们根据setup的信息,获取每个主机的IP地址和根分区的大小,如下
注意取值
[root@supervisor yaml]# cat test4.yml 
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: 上传变量文件
      template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test
{{ansible_virbr0.ipv4.address}}
{{ansible_mounts[0].size_total/1024/1024/1024}}
 
​​
ansible-playbook设置变量有以下四种方式:
1:vars  设置
2:vars_file  设置变量文件
3:vars_prompt 手动输入
4:setup  获取变量
============================================vars
比如需要在远程主机创建目录和文件,可以用vars在playbook中定义变量
---
- hosts: centos6
  remote_user: root
  vars:
      directory: /root/test
      file: /root/test/haha
  tasks:
    - name: 创建目录
      shell: "mkdir {{directory}}"
    - name: 创建文件
      shell: "touch {{file}}"
============================================vars_file
同时如果变量比较多,我们可以写在文件中,然后调用该文件。用于往远程主机传递变量
[root@supervisor yaml]# cat variables_file  #定义变量的文件
name: lisi
passwd: 123456
[root@supervisor yaml]# cat test   #调用变量的文件
{{name}}
{{passwd}}
[root@supervisor yaml]# cat test2.yml 
---
- hosts: centos7
  remote_user: root
  vars_files:
    - variables_file
 
  tasks:
    - name: 复制文件  #传递变量(和copy模块类似)
      template: src=test dest=/root/test.file
#远程主机检查
[root@supervisor yaml]# ansible centos7 -a "cat /root/test.file" 
192.168.1.184 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.182 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.186 | SUCCESS | rc=0 >>
lisi
123456
============================================vars_prompt
这个是手动输入变量,比如我们创建一个用户的时候,手动输入密码
[root@supervisor yaml]# cat test3.yml 
---
 
- hosts: all
  remote_user: root
  vars_prompt:
    - name: users
      prompt: 输入用户名
    - name: passwd
      prompt: 输入密码
      private: no   #指定是否隐藏输入,默认为隐藏(yes)
  tasks:
    - name: 上传变量文件
      template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test  #变量文件
{{users}}
{{passwd}}
#执行状态
[root@supervisor yaml]# ansible-playbook test3.yml
输入用户名: 
输入密码: zhangsan
......
#执行结果
[root@supervisor yaml]# ansible all -a "cat /root/test.txt"
192.168.1.186 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.184 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.182 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.183 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.181 | SUCCESS | rc=0 >>
zhangsan
zhangsan
============================================setup方法
比如我们根据setup的信息,获取每个主机的IP地址和根分区的大小,如下
注意取值
[root@supervisor yaml]# cat test4.yml 
---
- hosts: all
  remote_user: root
  gather_facts: True #(这一项表明是否执行setup模块,默认为执行,False为不执行)
  
  tasks:
    - name: 上传变量文件
      template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test
{{ansible_virbr0.ipv4.address}}
{{ansible_mounts[0].size_total/1024/1024/1024}}
 
​#执行结果
[root@centos6.9_1 ~]# cat test.txt 
192.168.122.1
8.28001785278
三:ansible-playbook的role(角色)

角色就是将一个playbook分开写,角色定义两种方式,如下
#方式1(安装httpd服务)
[root@supervisor ansible]# pwd
/etc/ansible
[root@supervisor ansible]# tree httpd
httpd
├── roles
│   └── httpd
│       └── tasks
│           └── main.yml
└── selt.yml
[root@supervisor ansible]# cat httpd/selt.yml   #主接口文件
---
- hosts: all
  gather_facts: no
  remote_user: root
  
  roles:
    - httpd
[root@supervisor ansible]# cat httpd/roles/httpd/tasks/main.yml  #任务文件
---
- name: 安装httpd
  yum: state=present name=httpd
- name: 配置开机启动项
  shell: echo "/usr/sbin/httpd" >> /etc/rc.local
- name: 启动httpd
  service: state=started name=httpd enabled=yes
#方式2(安装httpd服务,推荐使用此方式)
[root@supervisor httpd]# pwd
/etc/ansible/yaml/httpd
[root@supervisor httpd]# ls
handlers.yml  selt.yml  tasks.yml  varsfile.yml
[root@supervisor httpd]# cat selt.yml   #主接口文件
---
- hosts: all
  remote_user: root
  gather_facts: no
  vars_files:
    - varsfile.yml   #变量文件
 
  tasks:
    - include: tasks.yml  #任务文件
 
  handlers:
    - include: handlers.yml  #连锁动作文件
[root@supervisor httpd]# cat varsfile.yml  #变量文件
server_name: http
port: 80
[root@supervisor httpd]# cat tasks.yml    #任务文件
---
- name: 安装httpd
  yum: state=present name=httpd
- name: 准备启动配置
  shell: echo "/usr/sbin/httpd" >> /etc/rc.local
- name: 上传变量文件
  template: src=varsfile.yml dest=/root/varsfile
  notify: started httpd
[root@supervisor httpd]# cat handlers.yml   #连锁动作文件
---
- name: started httpd
  service: name=httpd state=started enabled=yes
四:playbook常用模块


======================================template模块
[root@supervisor yaml]# cat test_template.yml 
---
- hosts: all
  remote_user: root
  gather_facts: no
  vars_files:
    - variables_file
 
  tasks:
    - name: 上传变量文件   #template支持变量
      template: src=test_file dest=/root/test_file   
    - name: copy复制      #copy不支持变量
      copy: src=test_file  dest=/root/test_file1
#template执行
[root@supervisor yaml]# ansible all -m shell -a "cat /root/test_file"
192.168.1.181 | SUCCESS | rc=0 >>
lisi
123456
#copy执行结果
[root@supervisor yaml]# ansible all -m shell -a "cat /root/test_file1"
192.168.1.182 | SUCCESS | rc=0 >>
{{name}}
{{passwd}}
======================================set_fact模块
可以计算变量同时也可以设置新的变量(可以根据setup获取值)
[root@supervisor yaml]# ansible all -m setup |grep "ansible_memtotal_mb"
        "ansible_memtotal_mb": 490, 
        "ansible_memtotal_mb": 490, 
        "ansible_memtotal_mb": 488, 
        "ansible_memtotal_mb": 488, 
        "ansible_memtotal_mb": 488, 
        "ansible_memtotal_mb": 490, 
[root@supervisor yaml]# cat test_set_fact.yml 
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: 设置变量
      set_fact: port="{{ansible_memtotal_mb/2}}"
    - name: 复制文件
      template: src=test_set.conf dest=/root/
[root@supervisor yaml]# cat test_set.conf 
port={{port|default(1003)}}   #可以设置默认值
​======================================debug模块
打印信息
[root@supervisor yaml]# cat debug.yml 
---
- hosts: centos
  gather_facts: no
  vars:
     port: 9090
  tasks:
    - name: print port
      debug: msg="{{port}}"
[root@supervisor yaml]# ansible-playbook debug.yml 
 [WARNING]: Found variable using reserved name: port
 
PLAY [centos] *******************************************************************************************************************************************************************************************************************************
 
TASK [print port] ***************************************************************************************************************************************************************************************************************************
ok: [192.168.1.181] => {
    "msg": 9090
}
ok: [192.168.1.183] => {
    "msg": 9090
}
ok: [192.168.1.182] => {
    "msg": 9090
}
ok: [192.168.1.185] => {
    "msg": 9090
}
ok: [192.168.1.184] => {
    "msg": 9090
}
ok: [192.168.1.186] => {
    "msg": 9090
}
五:ansible-playbook的register

register的用处就是比如有两个任务,第二个任务需要第一个任务中的变量
[root@supervisor yaml]# cat register.yml 
---
- hosts: all
  gather_facts: no
  tasks:
    - name: 获取主机名
      shell: hostname
      register: host   #定义变量
    - name: 打印变量
      debug: msg={{host}}
#获取结果
ok: [192.168.1.182] => {
    "msg": {
        "changed": true, 
        "cmd": "hostname", 
        "delta": "0:00:00.074242", 
        "end": "2018-08-27 21:29:21.502808", 
        "failed": false, 
        "rc": 0, 
        "start": "2018-08-27 21:29:21.428566", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "centos7.4_1",   #这里才是真正的变量(需要把yml文件里的host改为host.stdout)
        "stdout_lines": [
            "centos7.4_1"
        ]
    }
}
#如下
ok: [192.168.1.181] => {
    "msg": "centos6.9_1"
}
==========================比如我们获取到内存大小然后写入文件
[root@supervisor yaml]# cat register2.yml 
---
- hosts: all
  gather_facts: no
  tasks:
    - name: 获取机器负载
      shell: uptime
      register: info
    - name: 写入文件
      shell: echo "{{info.stdout}}" > cpu.txt
[root@supervisor yaml]# ansible all -m shell -a "cat cpu.txt"
192.168.1.184 | SUCCESS | rc=0 >>
 21:34:13 up 16 min,  2 users,  load average: 0.01, 0.06, 0.07
192.168.1.182 | SUCCESS | rc=0 >>
 21:34:14 up 37 min,  2 users,  load average: 0.01, 0.05, 0.05
192.168.1.183 | SUCCESS | rc=0 >>
 21:35:22 up 37 min,  2 users,  load average: 0.16, 0.03, 0.01
192.168.1.181 | SUCCESS | rc=0 >>
 21:35:23 up 37 min,  2 users,  load average: 0.23, 0.06, 0.02
192.168.1.185 | SUCCESS | rc=0 >>
 09:35:23 up 37 min,  2 users,  load average: 0.08, 0.02, 0.01
192.168.1.186 | SUCCESS | rc=0 >>
 21:34:16 up 16 min,  2 users,  load average: 0.05, 0.12, 0.12
六:playbook的条件判断以及循环


=============================================================================基本循环
比如我们需要创建很多个用户,我们可以利用循环
[root@supervisor yaml]# cat loops.yml 
---
- hosts: all
  gather_facts: no
  vars_prompt:
    - name: passwd
      prompt:
  tasks:
    - name: 批量创建用户
      #注意:item是固定语法
      user: state=present name="{{item}}" password={{passwd}}
      with_items:
          - zhuangzhuang
          - zhuangzhuang1
          - zhuangzhuang2
          - zhuangzhuang3
#执行过程
[root@supervisor yaml]# ansible-playbook loops.yml
input for passwd:    #这里提示输入密码(必须是加密的)
 
PLAY [all] **********************************************************************************************************************************************************************************************************************************
 
TASK [批量创建用户] *******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.186] => (item=zhuangzhuang)
changed: [192.168.1.184] => (item=zhuangzhuang)
changed: [192.168.1.182] => (item=zhuangzhuang)
changed: [192.168.1.186] => (item=zhuangzhuang1)
changed: [192.168.1.183] => (item=zhuangzhuang)
changed: [192.168.1.184] => (item=zhuangzhuang1)
changed: [192.168.1.182] => (item=zhuangzhuang1)
changed: [192.168.1.181] => (item=zhuangzhuang)
changed: [192.168.1.186] => (item=zhuangzhuang2)
changed: [192.168.1.183] => (item=zhuangzhuang1)
changed: [192.168.1.184] => (item=zhuangzhuang2)
changed: [192.168.1.186] => (item=zhuangzhuang3)
changed: [192.168.1.181] => (item=zhuangzhuang1)
changed: [192.168.1.182] => (item=zhuangzhuang2)
changed: [192.168.1.184] => (item=zhuangzhuang3)
changed: [192.168.1.183] => (item=zhuangzhuang2)
changed: [192.168.1.182] => (item=zhuangzhuang3)
changed: [192.168.1.181] => (item=zhuangzhuang2)
changed: [192.168.1.183] => (item=zhuangzhuang3)
changed: [192.168.1.185] => (item=zhuangzhuang)
changed: [192.168.1.181] => (item=zhuangzhuang3)
changed: [192.168.1.185] => (item=zhuangzhuang1)
changed: [192.168.1.185] => (item=zhuangzhuang2)
changed: [192.168.1.185] => (item=zhuangzhuang3)
 
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.1.181              : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.182              : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.183              : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.184              : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.185              : ok=1    changed=1    unreachable=0    failed=0   
192.168.1.186              : ok=1    changed=1    unreachable=0    failed=0   
#结果
[root@supervisor yaml]# ansible all -m shell -a "cat /etc/passwd|grep '^zhuangzhuang'"
192.168.1.182 | SUCCESS | rc=0 >>
zhuangzhuang:x:1002:1002::/home/zhuangzhuang:/bin/bash
zhuangzhuang1:x:1003:1003::/home/zhuangzhuang1:/bin/bash
zhuangzhuang2:x:1004:1004::/home/zhuangzhuang2:/bin/bash
zhuangzhuang3:x:1005:1005::/home/zhuangzhuang3:/bin/bash
 
=============================================================================when条件判断
#######################################单一判断
[root@supervisor yaml]# cat when.yml 
---
- hosts: all
  gather_facts: True
  remote_user: root
  ignore_errors: yes
  tasks:
    - name: 判断IP地址是否是192.168.1.182,如果是则创建一个文件
      shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
      when: ansible_all_ipv4_addresses[0] == "192.168.1.182"
注意:不满足条件的会跳过
########################################结合循环判断
#判断ip是否是循环中的IP,如果是则创建文件
[root@supervisor yaml]# cat when2.yml 
---
- hosts: all
  gather_facts: True
  remote_user: root
  tasks:
    - name: 判断IP是否是182,如果是则创建一个文件
      shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
      when: ansible_all_ipv4_addresses[0] == "{{item}}"
      with_items:
          - 192.168.1.182
          - 192.168.1.183
          - 192.168.1.184
          - 192.168.1.185  
​########################################逻辑与
#判断主机IP是否是192.168.1.192并且主机名是否是centos7.4_1,如果是则创建文件
#注意:when条件判断的时候引用变量不需要{{}}
[root@supervisor yaml]# cat when3.yml 
---
- hosts: all
  ignore_errors: yes
  gather_facts: yes
  remote_user: root
  
  tasks:
    - name: 获取主机名
      shell: hostname
      register: host
    - name: 逻辑与的判断
      shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
      when: 
         - ansible_all_ipv4_addresses[0] == "192.168.1.182"
         - host.stdout == "centos7.4_1"

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!