当前位置: 首页 > article >正文

Ansible的重用(include和import)

环境

  • 管理节点:Ubuntu 22.04
  • 控制节点:CentOS 8
  • Ansible:2.15.6

重用

Ansible提供四种可重用的工件:

  • variable文件:只包含变量的文件
  • task文件:只包含task的文件
  • playbook:可包含play、变量、task,以及其它内容
  • role:包含一套task、变量、default、handler,甚至module或其它plugin(通过目录/文件树的结构来组织)

重用playbook

可以通过 import_playbook 把多个playbook集成到一个主playbook里。

创建文件 test1.ym 如下:

---
- import_playbook: playbook1.yml
- import_playbook: playbook2.yml

创建文件 playbook1.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "hello"

创建文件 playbook2.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "world"

运行结果如下:

PLAY [all] *****************************************************************************************

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

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "hello"
}

PLAY [all] *****************************************************************************************

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

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "world"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

import_playbook 是静态引入的,也就是说,相当于在主playbook里直接定义 playbook1playbook2 的内容:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "hello"

- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "world"

下面是一个使用变量的例子。创建文件 test2.yml 如下:

---
- import_playbook: "{{ var1 }}"
  vars:
    var1: "playbook1.yml"
- import_playbook: "{{ var2 }}"

运行时通过命令行的 -e 选项指定变量 var2 ,即: ansible-playbook test2.yml -e var2=playbook2.yml

运行结果如下:

PLAY [all] *****************************************************************************************

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

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "hello"
}

PLAY [all] *****************************************************************************************

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

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "world"
}

PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

可见,可通过两种方式指定变量:

  • vars
  • -e <var=value>

注意:这两种方式其实也是“静态”定义的变量,也就是在刚开始运行时,值就已经确定的变量。

无法使用动态变量。看下面的例子:

创建文件 test3.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      set_fact:
        var3: "playbook3.yml"

- import_playbook: playbook3.yml

创建文件 playbook3.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "{{ var3 }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55]

PLAY [all] *****************************************************************************************

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

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
    "msg": "playbook3.yml"
}

可见,通过 set_fact 定义的变量,可以传到 import_playbook 所引入的playbook里。

但是如果改为下面的写法:

---
- hosts: all
  tasks:
    - name: task1
      set_fact:
        var3: "playbook3.yml"

#- import_playbook: playbook3.yml
- import_playbook: "{{ var3 }}"

运行结果如下:

ERROR! 'var3' is undefined. 'var3' is undefined

这是因为, var3 是动态定义的变量, import_playbook 只能使用静态变量(在刚开始运行时就有值)。

使用role

当playbook较复杂时,使用role会好一些。role把default、handler、变量、task存放到不同目录下,以便于理解和维护。

详见关于role的文档。

重用role,task和变量

  • 动态重用( include_* ):
    • include_role
    • include_tasks
    • include_vars
  • 静态重用( import_* ):
    • import_role
    • import_tasks

include_*

一句话总结:在运行到此处时才动态引入。

import_*

一句话总结:在刚开始运行时就替换为引入的内容。

另:文档上说如果要多次import同一个文件,必须传入变量( You can pass variables to imports. You must pass variables if you want to run an imported file more than once in a playbook. ),但我试了一下,不传变量也没问题,是不是我理解有误?

---
- hosts: all
  tasks:
    - import_tasks: task1.yml
    - import_tasks: task1.yml

include和import的区别

在这里插入图片描述

在handler中重用task

在handler里也可以使用include或import。但要注意它们的区别:

  • include:notify的是handler本身(也就是include的文件),会触发其包含的所有task。
  • import:notify的是import的文件里的某些task。

include

创建 test5.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "I am task1"
      changed_when: true
      notify: handler1

  handlers:
    - name: handler1
      include_tasks: task5.yml

创建 task5.yml 如下:

---
- name: task5_task1
  debug:
    msg: "I am task5_task1"

- name: task5_task2
  debug:
    msg: "I am task5_task2"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
    "msg": "I am task1"
}

RUNNING HANDLER [handler1] *************************************************************************
included: /root/temp/temp1127/task5.yml for 192.168.1.55

RUNNING HANDLER [task5_task1] **********************************************************************
ok: [192.168.1.55] => {
    "msg": "I am task5_task1"
}

RUNNING HANDLER [task5_task2] **********************************************************************
ok: [192.168.1.55] => {
    "msg": "I am task5_task2"
}

可见,notify的是 handler1 ,其代表 task5.yml ,其中所有task都会运行。

import

创建文件 test6.yml 如下:

---
- hosts: all
  tasks:
    - name: task1
      debug:
        msg: "I am task1"
      changed_when: true
      notify: task5_task2

  handlers:
    - name: handler1
      import_tasks: task5.yml

task5.yml 内容不变。

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
    "msg": "I am task1"
}

RUNNING HANDLER [task5_task2] **********************************************************************
ok: [192.168.1.55] => {
    "msg": "I am task5_task2"
}

可见,notify的是 task5_task2 ,它是 task5.yml 里的一个task,只有它会运行

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse.html

http://www.kler.cn/a/146331.html

相关文章:

  • 从 0 开始实现一个 SpringBoot + Vue 项目
  • 利用EXCEL进行XXE攻击
  • IO模型与NIO基础二
  • 数仓建模:如何设计可扩展性较好的同环比计算模型?
  • docker一张图理解
  • js-判断一个object(对象)是否为空
  • 大量索引场景下 Easysearch 和 Elasticsearch 的吞吐量差异
  • 某高级度假村技术人员薪酬体系设计咨询项目纪实
  • 基于Java SSM在线图书推荐与交流平台
  • requests请求django接口跨域问题处理
  • TypeError: ‘_io.TextIOWrapper’ object is not subscriptable
  • React整理总结(七、Hooks)
  • 关于C语言控制浮点数输出精度问题
  • 好用的png图片打包plist工具,推荐使用pngPackerGUI_V2.0
  • java设计模式学习之【抽象工厂模式】
  • i社为什么不出游戏了?
  • ISO27000认证实施意义
  • 计算机网络入门
  • 工信部:1—10月我国软件业务收入98191亿元 同比增长13.7%
  • Qt::Window 、Qt::Tool是 Qt 框架中的一个窗口标志(Window Flag),用于指定窗口的类型和行为
  • 【阿里云】图像识别 智能分类识别 增加网络控制功能点(三)
  • ArcGIS制作广场游客聚集状态及密度图
  • 安卓开发——Android Studio常见报错与解决方法
  • linux chmod命令详解
  • 使用opencv实现图片相似度检测
  • 深入理解main方法-Java