Ansible Playbook

1、Playbook 组成

图片[1]-Ansible Playbook-李佳程的个人主页
  • 一个 playbook(剧本)文件是一个YAML语言编写的文本文件
  • 通常一个playbook只包括一个play
  • 一个 play的主要包括两部分:主机和tasks。 即实现在指定一组主机上执行一个tasks定义好的任务列表。
  • 一个tasks中可以有一个或多个task任务
  • 每一个Task本质上就是调用ansible的一个module
  • 在复杂场景中,一个playbook中也可以包括多个play,实现对多组不同的主机执行不同的任务

2、Playbook 与 Ad-Hoc 对比

  • Playbook 是对多个 AD-Hoc 的一种编排组合的实现方式
  • Playbook 能控制任务执行的先后顺序
  • Playbook 可以持久保存到文件中从而方便多次调用运行,而Ad-Hoc只能临时运行。
  • Playbook 适合复杂的重复性的任务,而Ad-Hoc适合做快速简单的一次性任务

3、Playbook 核心组件

https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.
html#playbook-keywords

一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:

  • Hosts 执行的远程主机列表
  • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task
  • Variables 内置变量或自定义变量在playbook中调用
  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

3.1、hosts 组件

Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中

one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs        #或者,两个组的并集
Websrvs:&dbsrvs       #与,两个组的交集
webservers:!dbsrvs    #在websrvs组,但不在dbsrvs组
- hosts: websrvs:appsrvs

- hosts: all

3.2、remote_user 组件

remote_user:可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- hosts: websrvs
 remote_user: root

 tasks:
   - name: test connection
     ping:
     remote_user: devop
     sudo: yes          #默认sudo为root
     sudo_user: test    #sudo为test

3.3、task列表和action组件

play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出

task两种格式

action: module arguments           #示例: action: shell wall hello
module: arguments         #建议使用 #示例: shell: wall hello 

注意:shell和command模块后面跟命令,而非key=value

# 范例
[root@ansible ansible]# vim hello.yml
---

# 第一个yaml文件

- hosts: webservers
  remote_user: root
  gather_facts: no                   # 不收集系统信息,提高执行效率

  tasks:
    - name: task1
      debug: msg="task1 running"
    - name: task2
      debug: msg="task2 running"

- hosts: appservers
  remote_user: root
  gather_facts: no

  tasks:
    - name: task3
      debug: msg="task3 running"
    - name: task4
      debug: msg="task4 running"
# 范例
[root@ansible ansible]#vim hello1.yaml
---

- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
    - name: test network connection
      ping:
    - name: excute command
      command: wall "hello world!"
# 范例
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
    - name: install httpd
      yum: name=httpd
    - name: start httpd
      service: name=httpd state=started enabled=yes

3.4、其它组件说明

某任务的状态在运行后为changed时,可通过”notify”通知给相应的handlers任务
还可以通过”tags”给task 打标签,可在ansible-playbook命令上使用-t指定进行调用

3.5、ShellScripts VS Playbook 案例

# SHELL脚本实现

#!/bin/bash
# 安装Apache
yum install -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd 
#Playbook实现
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
    - name: "安装Apache"
      yum: name=httpd
    - name: "复制配置文件"
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
    - name: "复制配置文件"
      copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
    - name: "启动Apache,并设置开机启动"
      service: name=httpd state=started enabled=yes

4、playbook 命令

格式

ansible-playbook <filename.yml> ... [options]

常见选项

--syntax,--syntax-check      #语法检查,功能相当于bash -n
-C --check            #模拟执行dry run ,只检测可能会发生的改变,但不真正执行操作
--list-hosts          #列出运行任务的主机
--list-tags           #列出tag
--list-tasks          #列出task
--limit 主机列表       #只针对主机列表中的特定主机执行
-i INVENTORY, --inventory INVENTORY  #指定主机清单文件,通常一个项对应一个主机清单文件
--start-at-task START_AT_TASK        #从指定task开始执行,而非从头开始,START_AT_TASK
                                      为任务的
name
-v -vv  -vvv          #显示过程
# 一个简单的playbook
[root@ansible ansible]# vim hello.yml

---

- hosts: webservers
  tasks:
    - name: hello
      command: echo "Hello World"


[root@ansible ansible]# ansible-playbook hello.yml

PLAY [webservers] *****************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************
ok: [192.168.1.12]
ok: [192.168.1.13]

TASK [hello] **********************************************************************************************************************
changed: [192.168.1.12]
changed: [192.168.1.13]

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


[root@ansible ansible]# ansible-playbook -v hello.yml
Using /etc/ansible/ansible.cfg as config file

PLAY [webservers] *****************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************
ok: [192.168.1.13]
ok: [192.168.1.12]

TASK [hello] **********************************************************************************************************************
changed: [192.168.1.13] => {"changed": true, "cmd": ["echo", "Hello World"], "delta": "0:00:00.001742", "end": "2022-12-14 07:21:29.981835", "rc": 0, "start": "2022-12-14 07:21:29.980093", "stderr": "", "stderr_lines": [], "stdout": "Hello World", "stdout_lines": ["Hello World"]}
changed: [192.168.1.12] => {"changed": true, "cmd": ["echo", "Hello World"], "delta": "0:00:00.001698", "end": "2022-12-14 07:21:29.982687", "rc": 0, "start": "2022-12-14 07:21:29.980989", "stderr": "", "stderr_lines": [], "stdout": "Hello World", "stdout_lines": ["Hello World"]}

PLAY RECAP ************************************************************************************************************************
192.168.1.12               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.13               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
# 检查和限制主机
ansible-playbook file.yml  --check #只检测
ansible-playbook file.yml
ansible-playbook file.yml  --limit webservers
# 一个playbook 多个play
[root@ansible ansible]# vim test.yml

---
- hosts: webservers
  remote_user: root
  gather_facts: no
  tasks:
    - name: play1
      command: echo "hello play1"
- hosts: appservers
  remote_user: root
  gather_facts: no
  tasks:
    - name: play2
      command: echo "hello play2"


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

PLAY [webservers] *****************************************************************************************************************

TASK [play1] **********************************************************************************************************************
changed: [192.168.1.12]
changed: [192.168.1.13]

PLAY [appservers] *****************************************************************************************************************

TASK [play2] **********************************************************************************************************************
changed: [192.168.1.11]

PLAY RECAP ************************************************************************************************************************
192.168.1.11               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.12               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.13               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


[root@ansible ansible]# ansible-playbook -v test.yml
Using /etc/ansible/ansible.cfg as config file

PLAY [webservers] *****************************************************************************************************************

TASK [play1] **********************************************************************************************************************
changed: [192.168.1.12] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": ["echo", "hello play1"], "delta": "0:00:00.001720", "end": "2022-12-14 07:24:56.507854", "rc": 0, "start": "2022-12-14 07:24:56.506134", "stderr": "", "stderr_lines": [], "stdout": "hello play1", "stdout_lines": ["hello play1"]}
changed: [192.168.1.13] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": ["echo", "hello play1"], "delta": "0:00:00.001556", "end": "2022-12-14 07:24:56.508019", "rc": 0, "start": "2022-12-14 07:24:56.506463", "stderr": "", "stderr_lines": [], "stdout": "hello play1", "stdout_lines": ["hello play1"]}

PLAY [appservers] *****************************************************************************************************************

TASK [play2] **********************************************************************************************************************
changed: [192.168.1.11] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": ["echo", "hello play2"], "delta": "0:00:00.001611", "end": "2022-12-14 07:24:57.018406", "rc": 0, "start": "2022-12-14 07:24:57.016795", "stderr": "", "stderr_lines": [], "stdout": "hello play2", "stdout_lines": ["hello play2"]}

PLAY RECAP ************************************************************************************************************************
192.168.1.11               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.12               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.13               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享