前言

本文将详细介绍ansible-playbook中roles的各种用法

环境准备

组件 版本
操作系统 Ubuntu 22.04.4 LTS
ansible 2.17.6

基本用法

文件结构

.
├── deploy.hosts
├── deploy.yaml
└── roles
└── base
└── tasks
└── main.yaml

定义全局公共变量

新增group_vars目录,并且新增文件

.
├── deploy.hosts
├── deploy.yaml
├── group_vars
│   └── all.yaml
└── roles
└── base
└── tasks
└── main.yaml
 cat group_vars/all.yaml
info: IT paiqiu
 cat roles/base/tasks/main.yaml
- name: first
debug:
msg: "hello world {{ info }}"

运行:

 ansible-playbook -i deploy.hosts deploy.yaml

...
TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
"msg": "hello world IT paiqiu"
}
...

定义role级变量

可以覆盖全局变量

在role base 下面新增vars目录,并且新增main.yaml文件

.
├── deploy.hosts
├── deploy.yaml
├── group_vars
│   └── all.yaml
└── roles
└── base
├── tasks
│   └── main.yaml
└── vars
└── main.yaml
 cat roles/base/tasks/main.yaml
- name: first
debug:
msg: "hello world {{ info }}"
 cat roles/base/vars/main.yaml
info:
name: wilson
addr: cd

运行:

 ansible-playbook -i deploy.hosts deploy.yaml

...
TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
"msg": "hello world {'name': 'wilson', 'addr': 'cd'}"
}
...

定义静态文件目录

相当于定义role级别的根目录,更好的管理需要传输的文件,在role base下面创建目录files,并且在files下面放入需要传输的文件test.img

.
├── deploy.hosts
├── deploy.yaml
├── group_vars
│   └── all.yaml
└── roles
└── base
├── files
│   └── test.img
├── tasks
│   └── main.yaml
└── vars
└── main.yaml

传输test.img至目标机器

- name: first
copy: src=test.img dest=/tmp/test.img

test.img默认回去roles/base/files当中寻找,所以前面不需要添加路径

copy模块会自动检查待传输文件的md5,如果没有变化,那就不会再传输了

定义模版

每次传输文件都会通过输入的变量重新渲染之后再传输,在role base下面创建目录templates,并且创建文件 test.conf

.
├── deploy.hosts
├── deploy.yaml
├── group_vars
│   └── all.yaml
└── roles
└── base
├── files
│   └── test.img
├── tasks
│   └── main.yaml
├── templates
│   └── test.conf
└── vars
└── main.yaml

在模版文件中定义了两个变量,一个是手动设置的变量version,一个是ansible内建变量inventory_hostname

 cat roles/base/templates/test.conf
{{ version }}
{{ inventory_hostname }}
 cat roles/base/tasks/main.yaml
- name: first
template: src=test.conf dest=/tmp/test.conf mode=0644

运行:

 ansible-playbook -i deploy.hosts -e version=2 deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166] PLAY RECAP *******************************************************************************************************
10.22.11.166 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

登录到目标机器查看:

 cat test.conf
2
10.22.11.166

2是本次任务传入的变量,10.22.11.166则是目标机器的ip地址

定义事件驱动

通常用于某些任务完成之后需要触发的动作,比如:发布完某个配置文件之后需要重启服务。在role base下创建目录handlers,并创建文件main.yaml

.
├── deploy.hosts
├── deploy.yaml
├── group_vars
│   └── all.yaml
└── roles
└── base
├── files
│   └── test.img
├── handlers
│   └── main.yaml
├── tasks
│   └── main.yaml
├── templates
│   └── test.conf
└── vars
└── main.yaml

创建事件first handler

 cat roles/base/handlers/main.yaml
- name: first handler
debug:
msg: echo 'hello world'
 cat roles/base/tasks/main.yaml
- name: first
template: src=test.conf dest=/tmp/test.conf mode=0644
notify: first handler

运行:

 ansible-playbook -i deploy.hosts -e version=2 deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166] RUNNING HANDLER [base : first handler] ***************************************************************************
ok: [10.22.11.166] => {
"msg": "echo 'hello world'"
} PLAY RECAP *******************************************************************************************************
10.22.11.166 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

同样的,如果事件前驱没有发生,那事件通知也不会发生了,比如事件前驱是传输一个文件,如果文件没有变化,就不会再传输,那事件也不会再发生了

新增更多的task任务

当前只有main.yaml,在增加一个专门用于传输文件的任务files.yaml

 cat roles/base/tasks/main.yaml
- name: main
include_tasks: files.yaml
vars:
app_version: 0.2
 cat roles/base/tasks/files.yaml
- name: first
debug:
msg: "version: {{ app_version }}"

运行:

 ansible-playbook -i deploy.hosts deploy.yaml

PLAY [deploy] ****************************************************************************************************

TASK [base : main] ***********************************************************************************************
included: /home/wilson/workspace/ansible/roles/base/tasks/files.yaml for 10.22.11.166 TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
"msg": "version: 0.2"
} PLAY RECAP *******************************************************************************************************
10.22.11.166 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

如果文件过多,可以通过循环来处理:

- name: main
include_tasks: "{{ yaml_items }}"
loop:
- files.yaml
- packages.yaml
loop_control:
loop_var: yaml_items
vars:
app_version: 0.2

补充一下常用的命令

执行命令 shell

- name: display
shell: echo 'hello world'

传输文件 copy

copy模块会自动检查待传输文件的md5,如果没有变化,那就不会再传输了

- name: copy file
copy: src=test.img dest=/tmp/test.img

修改文件内容(一行) lineinfile

  • path: 指定要操作的文件路径(必填)
  • line: 定义要插入或替换的完整行内容(可选)
  • regexp: 用于匹配现有行的正则表达式。与 line 配合使用,匹配的行将被替换
  • state:
    • present(默认):确保指定行存在
    • absent:移除匹配的行
  • create: 如果文件不存在,是否创建文件(默认 yes)
  • insertafter: 指定插入行的位置(默认 EOF)
    • EOF:文件末尾
    • BOF:文件开头
    • 正则表达式:在匹配行之后插入

      insertbefore: 和 insertafter 类似,但在匹配行之前插入

通过正则匹配行之后修改当前行

- name: modify
lineinfile: dest=/tmp/test.txt regexp='^DC' line="DC=hello" state=present

修改文件内容(多行/块) blockinfile

  • path: 指定要操作的文件路径(必填)
  • block: 定义要插入的文本内容(必填)
  • marker: 指定标记块的开始和结束字符串,默认为 # {mark} ANSIBLE MANAGED BLOCK
  • state:
    • present(默认):确保块存在
    • absent:移除块
  • create: 如果文件不存在,是否创建文件(默认 yes)
  • insertafter: 指定插入块的位置(默认 EOF)
    • 可用值:

      • EOF:文件末尾
      • BOF:文件开头
      • 正则表达式:在匹配行之后插入
  • insertbefore: 和 insertafter 类似,但是在匹配行之前插入

1)在某一行下面增加新的内容,并且将增加的内容打上标记

- name: add new content with markers
blockinfile:
path: /tmp/test.txt
marker: "# {mark} by wilson"
insertafter: '^DC'
block: |
name: wilson
city: cd

运行之后查看结果

 cat /tmp/test.txt
DC=hello
# BEGIN by wilson
name: wilson
city: cd
# END by wilson

2)删除已标记的内容

- name: Remove the managed block
blockinfile:
marker: "# {mark} by wilson"
path: /tmp/test.txt
state: absent

添加内容块打上标记之后会让修改与删除都变得非常方便

使用模版

- name: hostname config
template: src=etc/hostname dest=/etc/hostname

设置文件权限 file

- name: change file 755
file:
path: /tmp/test.txt
owner: wilson
group: wilson
state: file
mode: 755

使用循环 with_items

with_items

给多个目录修改权限

- name: change directory 755
file:
path: '{{ item.dir }}'
owner: wilson
group: wilson
state: directory
mode: '{{ item.mode }}'
with_items:
- { dir: '/tmp/1', mode: '0755'}
- { dir: '/tmp/2', mode: '0755'}

loop

当然使把with_items 替换成 loop也是可以的

- name: change directory 755
file:
path: '{{ item.dir }}'
owner: wilson
group: wilson
state: directory
mode: '{{ item.mode }}'
with_items:
- { dir: '/tmp/1', mode: '0755'}
- { dir: '/tmp/2', mode: '0755'}

嵌套循环 with_nested

输出每一种组合,相当于笛卡尔积

- name: nested loop
debug:
msg: "{{ item[0] }} {{ item[1] }}"
with_nested:
- [ "hello1", "hello2"]
- [ "world1", "world2"]

输出结果:

TASK [base : nested loop] ****************************************************************************************
ok: [127.0.0.1] => (item=['hello1', 'world1']) => {
"msg": "hello1 world1"
}
ok: [127.0.0.1] => (item=['hello1', 'world2']) => {
"msg": "hello1 world2"
}
ok: [127.0.0.1] => (item=['hello2', 'world1']) => {
"msg": "hello2 world1"
}
ok: [127.0.0.1] => (item=['hello2', 'world2']) => {
"msg": "hello2 world2"
}

文件内容循环 with_file

逐行打印文件内容

- name: display file content
debug:
msg: "{{ item }}"
with_file:
- /tmp/test.txt

幂等性

使用roles去管理多设备的时候,编写脚本需要时刻注意幂等性,即每一次执行都要保证同样的结果

联系我

联系我,做深入的交流


至此,本文结束

在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

不求甚解--详解ansible-playbook中roles的用法(二)的更多相关文章

  1. 详解shell编程中2>&1用法

    在使用 linux 命令或者 shell 编程时,这个用法常会遇到 2>&1 下面看一个命令示例,然后分析下他是如何工作的: ls foo > /dev/null 2>&am ...

  2. 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别

    详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别 http://blog.sina.com.cn/s/blog_686999de0100jgda.html   实例: ...

  3. 详解 Go 语言中的 time.Duration 类型

    swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...

  4. 详解jquery插件中(function ( $, window, document, undefined )的作用。

    1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...

  5. zz详解深度学习中的Normalization,BN/LN/WN

    详解深度学习中的Normalization,BN/LN/WN 讲得是相当之透彻清晰了 深度神经网络模型训练之难众所周知,其中一个重要的现象就是 Internal Covariate Shift. Ba ...

  6. [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    [转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...

  7. 详解WebService开发中四个常见问题(2)

    详解WebService开发中四个常见问题(2)   WebService开发中经常会碰到诸如WebService与方法重载.循环引用.数据被穿该等等问题.本文会给大家一些很好的解决方法. AD:WO ...

  8. 详解WebService开发中四个常见问题(1)

    详解WebService开发中四个常见问题(1)   WebService开发中经常会碰到诸如WebService与方法重载.循环引用.数据被穿该等等问题.本文会给大家一些很好的解决方法. AD:WO ...

  9. 详解Python编程中基本的数学计算使用

    详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...

  10. 第7.16节 案例详解:Python中classmethod定义的类方法

    第7.16节  案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一.    案例说明 本节定义的一个 ...

随机推荐

  1. Genuine Intel(R) CPU型号

    起因: 在盘点固定资产的时候,发现有一台电脑CPU不显示具体型号,而是 英特尔 @ 2.60GHz (X2) ,通过主板型号来判断是至强系列的CPU,后经软件识别为 Genuine ,然后去查资料才了 ...

  2. AD域下,环境下办公机系统时间不准确

    事件起因: 某部门一同事电脑时间和AD域控时间相差3分钟,虽然说时间相差5分钟内问题不大,但是本着有问题就解决的原则,还是花了点时间去查资料解决. (小小吐槽一下,在我看来域控机是掌管下面所有的办公机 ...

  3. ROS基础入门——实操教程

    ROS基础入门--实操教程 前言 本教程实操为主,少说书.可供参考的文档中详细的记录了ROS的实操和理论,只是过于详细繁杂了,看得脑壳疼,于是做了这个笔记. Ruby Rose,放在这里相当合理 前言 ...

  4. USB通讯架构及数据模型

    注意: (1)一个usb设备由一个或者多个接口组成: (2)每一个接口为usb设备的一个功能,比如上面的usb设备由两个接口,一个可用于鼠标,一个可用于键盘: (3)每个接口占用usb设备的多个端口资 ...

  5. Perfetto分析进阶

    一.Perfetto介绍 Perfetto是Android Q中引入的全新下一代平台级跟踪工具,为Android.Linux和Chrome平台提供了一种通用的性能检测和跟踪分析工具集.其核心是引入了一 ...

  6. 利用 ACME 实现SSL证书自动化配置更新

    最近收到腾讯云的通知SSL证书要到期了,本想直接申请的发现现在申请的免费SSL证书有效期只有90天了,顺便了解了一下原因是包括Google在内的国际顶级科技公司一直都有在推进免费证书90天有效期的建议 ...

  7. 如何实现高效运维?来谈谈性能优化那些事(含直播回顾 Q&A)

    数据库性能问题,常常是困扰DBA高效运维的难题之一.如何多角度地帮助DBA,找到"数据库慢"的原因,保证系统高效.稳定.安全地运行? 2021年10月14日,云和恩墨技术顾问,拥有 ...

  8. apisix~为自定义插件设计一个configmap脚本

    configMap Kubernetes 中的 ConfigMap 是一种用来存储配置数据的 API 资源,它允许您将配置信息以键值对的形式保存,并在容器中使用这些配置信息.ConfigMap 提供了 ...

  9. Termux 使用笔记

    第一次安装完成后 发现这里面啥都没有 所以 更新源 apt update 也做不到 这是因为 源是国外 由于有墙 所以连接不上 下面这个命令可以 切换更新源 termux-change-repo 切换 ...

  10. mysql进阶-锁

    锁 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源. 如何保证数据并发访问的一致性.有效性 ...