不求甚解--详解ansible-playbook中roles的用法(二)
前言
本文将详细介绍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的用法(二)的更多相关文章
- 详解shell编程中2>&1用法
在使用 linux 命令或者 shell 编程时,这个用法常会遇到 2>&1 下面看一个命令示例,然后分析下他是如何工作的: ls foo > /dev/null 2>&am ...
- 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别
详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别 http://blog.sina.com.cn/s/blog_686999de0100jgda.html 实例: ...
- 详解 Go 语言中的 time.Duration 类型
swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...
- 详解jquery插件中(function ( $, window, document, undefined )的作用。
1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...
- zz详解深度学习中的Normalization,BN/LN/WN
详解深度学习中的Normalization,BN/LN/WN 讲得是相当之透彻清晰了 深度神经网络模型训练之难众所周知,其中一个重要的现象就是 Internal Covariate Shift. Ba ...
- [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表
[转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...
- 详解WebService开发中四个常见问题(2)
详解WebService开发中四个常见问题(2) WebService开发中经常会碰到诸如WebService与方法重载.循环引用.数据被穿该等等问题.本文会给大家一些很好的解决方法. AD:WO ...
- 详解WebService开发中四个常见问题(1)
详解WebService开发中四个常见问题(1) WebService开发中经常会碰到诸如WebService与方法重载.循环引用.数据被穿该等等问题.本文会给大家一些很好的解决方法. AD:WO ...
- 详解Python编程中基本的数学计算使用
详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...
- 第7.16节 案例详解:Python中classmethod定义的类方法
第7.16节 案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一. 案例说明 本节定义的一个 ...
随机推荐
- QT QML实用效果之实现页面切换效果
简介 本文介绍了如何使用QT QML和JavaScript实现页面动态加载和切换的效果. 文章目录 效果 JavaScript代码:butianyun.js文件 QML代码:主页面 页面A QML代码 ...
- 推荐一款轻量级 eBPF 前端工具 ply
1 Overview ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可 ...
- 2023年5月中国数据库排行榜:OTO组合回归育新机,华为高斯蓄势待发展雄心
路漫漫其修远兮,吾将上下而求索. 2023年5月的 墨天轮中国数据库流行度排行 火热出炉,本月共有262个数据库参与排名.本月排行榜前十变动较大,可以用一句话概括为:openGauss 立足创新夺探花 ...
- 好文分享 | 记一次Oracle12c数据库SQL短暂缓慢问题分析
本文为墨天轮社区作者 张sir 原创作品,记录了日常运维Oracle数据库过程中遇到的一个慢SQL问题的解决.优化过程,文章内容全面具体.分析到位,且含有经验总结,分享给各位. 问题现象 这次出问题的 ...
- 区分::after和:before中的单冒号和双冒号的作用
单冒号:一般指的是伪类,如鼠标悬停状态设置样式:选择器:hover {设置样式} 双冒号一般指伪元素,给元素的前面/后面添加内容.内容数据按堆栈数据结构存储.
- 01-react的基本使用
// 导入react和react-dom包 类似 vue 中的 import vue from 'vue' import react from 'react' // 内部的组件 import reac ...
- 驻扎初篇(markdown)
markdown的初级使用语法 本片作为开始使用博客的第一篇笔记 只为了方便为日后的编辑博客做基础的语言记录 以下为markdown的语法 ##标题 # 标题一 ## 标题二 ### 标题三 #### ...
- KubeSphere 社区双周报|2024.06.21-07.04
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- 在 KubeSphere 上快速安装和使用 KDP 云原生数据平台
作者简介:金津,智领云高级研发经理,华中科技大学计算机系硕士.加入智领云 8 余年,长期从事云原生.容器化编排领域研发工作,主导了智领云自研的 BDOS 应用云平台.云原生大数据平台 KDP 等产品的 ...
- 一次彻底讲清如何处理mysql 的死锁问题
MySQL 死锁 是指两个或多个事务互相等待对方持有的锁,从而导致所有事务都无法继续执行的现象.在 InnoDB 存储引擎中,死锁是通过锁机制产生的,特别是在并发较高.业务逻辑复杂的情况下,更容易发生 ...