wowoqu 发表于 2025-2-7 01:32:42

不求甚解--详解ansible-playbook中roles的用法(二)

前言

本文将继续介绍ansible-playbook中roles的各种用法
环境准备

组件版本操作系统Ubuntu 22.04.4 LTSansible2.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.yamlinfo: IT paiqiu▶ cat roles/base/tasks/main.yaml- name: firstdebug:    msg: "hello world {{ info }}"运行:
▶ ansible-playbook -i deploy.hosts deploy.yaml...TASK **********************************************************************************************ok: => {    "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: firstdebug:    msg: "hello world {{ info }}"▶ cat roles/base/vars/main.yamlinfo:name: wilsonaddr: cd运行:
▶ ansible-playbook -i deploy.hosts deploy.yaml...TASK **********************************************************************************************ok: => {    "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: firstcopy: src=test.img dest=/tmp/test.imgtest.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: firsttemplate: src=test.conf dest=/tmp/test.conf mode=0644运行:
▶ ansible-playbook -i deploy.hosts -e version=2 deploy.yamlPLAY ****************************************************************************************************TASK **********************************************************************************************changed: PLAY RECAP *******************************************************************************************************10.22.11.166               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0登录到目标机器查看:
▶ cat test.conf210.22.11.1662是本次任务传入的变量,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 handlerdebug:    msg: echo 'hello world'▶ cat roles/base/tasks/main.yaml- name: firsttemplate: src=test.conf dest=/tmp/test.conf mode=0644notify: first handler运行:
▶ ansible-playbook -i deploy.hosts -e version=2 deploy.yamlPLAY ****************************************************************************************************TASK **********************************************************************************************changed: RUNNING HANDLER ***************************************************************************ok: => {    "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: maininclude_tasks: files.yamlvars:    app_version: 0.2▶ cat roles/base/tasks/files.yaml- name: firstdebug:    msg: "version: {{ app_version }}"运行:
▶ ansible-playbook -i deploy.hosts deploy.yamlPLAY ****************************************************************************************************TASK ***********************************************************************************************included: /home/wilson/workspace/ansible/roles/base/tasks/files.yaml for 10.22.11.166TASK **********************************************************************************************ok: => {    "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: maininclude_tasks: "{{ yaml_items }}"loop:    - files.yaml    - packages.yamlloop_control:    loop_var: yaml_itemsvars:    app_version: 0.2补充一下常用的命令

执行命令 shell

- name: displayshell: echo 'hello world'传输文件 copy

copy模块会自动检查待传输文件的md5,如果没有变化,那就不会再传输了
- name: copy filecopy: src=test.img dest=/tmp/test.img修改文件内容(一行) lineinfile


[*]path: 指定要操作的文件路径(必填)
[*]line: 定义要插入或替换的完整行内容(可选)
[*]regexp: 用于匹配现有行的正则表达式。与 line 配合使用,匹配的行将被替换
[*]state:

[*]present(默认):确保指定行存在
[*]absent:移除匹配的行

[*]create: 如果文件不存在,是否创建文件(默认 yes)
[*]insertafter: 指定插入行的位置(默认 EOF)

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

通过正则匹配行之后修改当前行
- name: modifylineinfile: 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 markersblockinfile:    path: /tmp/test.txt    marker: "# {mark} by wilson"    insertafter: '^DC'    block: |      name: wilson      city: cd运行之后查看结果
▶ cat /tmp/test.txtDC=hello# BEGIN by wilsonname: wilsoncity: cd# END by wilson2)删除已标记的内容
- name: Remove the managed blockblockinfile:    marker: "# {mark} by wilson"    path: /tmp/test.txt    state: absent添加内容块打上标记之后会让修改与删除都变得非常方便
使用模版

- name: hostname configtemplate: src=etc/hostname dest=/etc/hostname设置文件权限 file

- name: change file 755file:    path: /tmp/test.txt    owner: wilson    group: wilson    state: file    mode: 755使用循环 with_items

with_items

给多个目录修改权限
- name: change directory 755file:    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 755file:    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 loopdebug:    msg: "{{ item }} {{ item }}"with_nested:    - [ "hello1", "hello2"]    - [ "world1", "world2"]输出结果:
TASK ****************************************************************************************ok: => (item=['hello1', 'world1']) => {    "msg": "hello1 world1"}ok: => (item=['hello1', 'world2']) => {    "msg": "hello1 world2"}ok: => (item=['hello2', 'world1']) => {    "msg": "hello2 world1"}ok: => (item=['hello2', 'world2']) => {    "msg": "hello2 world2"}文件内容循环 with_file

逐行打印文件内容
- name: display file contentdebug:    msg: "{{ item }}"with_file:    - /tmp/test.txt幂等性

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

联系我,做深入的交流
https://img2024.cnblogs.com/blog/1416773/202411/1416773-20241121135740959-1907948957.png#
<hr>至此,本文结束
在下才疏学浅,有撒汤漏水的,请各位不吝赐教...
页: [1]
查看完整版本: 不求甚解--详解ansible-playbook中roles的用法(二)