对主机组成员及其 host_vars Ansible - 嵌套循环Jinja2 - 预生成结构

如何解决对主机组成员及其 host_vars Ansible - 嵌套循环Jinja2 - 预生成结构

有人可以帮助我构建嵌套循环吗?

我正在创建简单的备份角色,它将为备份准备客户端服务器,它还将准备备份服务器。备份服务器将在定义的时间从客户端下载备份。我想为每个客户端定义不同的时间和不同的文件夹(通过 host_vars)。

我的工作流程:

  1. 备份服务器

    • 安装软件包
    • 创建备份用户
    • 创建备份目录
  2. 客户

    • 安装软件包
    • 将备份的服务器 ssh 密钥添加到 authorized_keys(有限制)
    • 一些 ssh 设置
    • 重新加载 sshd
  3. 备份服务器

    • 为下载备份设置 cron 作业(每个客户端都应该有自己的 cron 条目 - 不同的时间和不同的备份文件夹集)

我有这个角色的第一个版本,它被应用于服务器的客户端组。备份服务器是在 delegate_to: 语句的帮助下配置的。但是在备份服务器上创建 cron 文件存在问题,因为存在诸如“竞争条件”之类的东西。当 playbook 完成时,备份的服务器 cron 文件中只有一个随机条目。但我希望所有客户端服务器都应该有条目。我试图打开问题 https://github.com/ansible/ansible/issues/74189 - 我得到了答案,我应该更改对此问题的访问权限。

我的第二次尝试是重写 ansible 角色。然后我可以将它应用于备份服务器而不是客户端组。现在我在客户端服务器组上使用 delegate_to:

备份服务器上(简化的)预期 cron 作业的示例:

0 0 * * * backup -include /home --include /var/www --include /srv --exclude '**' backup.lab.local::/ /home/backup/srv1.lab.local
# -> similar entry for srv2
# -> similar entry for srv3

我的场景:

# hosts file
[backup_servers]
backup.lab.local

[testing_servers]
srv1.lab.local
srv2.lab.local
srv3.lab.local

host_vars 文件示例:

# host_vars/srv1.lab.local
backup_folders:
  - /home
  - /var/www
  - /srv

我坚持在备份服务器上创建 cron 条目的任务。我需要循环 groups['testing_servers'] 并且在这个循环中我需要创建另一个 hostvars[<each_host_from_group>]['backup_folder'] 循环。

请问怎么做?

解决方法

我不会遍历 backup_folder,我会 join 这些值。

假设您正确循环 groups['testing_servers'] 主机,例如

0 0 * * * backup {{ ([''] + hostvars[item]['backup_folder']) | join(' --include ') }}  --exclude '**' backup.lab.local::/ /home/backup/{{ item }}

会给:

0 0 * * * backup --include /home --include /var/www --include /srv --exclude '**' backup.lab.local::/ /home/backup/srv1.lab.local

注意:这个奇怪的结构:([''] + hostvars[item]['backup_folder']) 是为了在列表的开头创建一个空元素,使其以 --include 开头,否则你会有

... backup /home --include /var/www --include /srv --exclude '**' ...
##        ^--- missing "--include " here
,

Cron 模块和并行写入

关于提到的 GitHub 问题,您可以使用 throttle: 1 (documentation)

即您的 cron 剧本应包含:

  tasks:
    - name: "Set backup cron job"
      ansible.builtin.cron:
        name: "Backup cron job for {{ inventory_hostname }}"
        user: root
        minute: "{{ backup_minute }}"
        hour: "{{ backup_hour }}"
        day: "{{ backup_day }}"
        month: "{{ backup_month }}"
        weekday: "{{ backup_weekday }}"
        job: "rdiff-backup --create-full-path --remote-schema \"ssh -C -i /home/backup/.ssh/id_rsa -p {{ ansible_port | default(22) }} -o 'StrictHostKeyChecking no' \\%s rdiff-backup --server\" --include /path/to/dir --exclude '**' {{ ansible_host }}::/ /home/backup/{{ inventory_hostname }}"
      delegate_to: deb10.lab.local
      throttle: 1                       # <--------- THIS IS THE IMPORTANT LINE

嵌套循环

你提到的使用嵌套循环的另一种方式可以通过在 Ansible 中使用嵌套循环来完成,或者通过预先构建嵌套结构,然后对其进行迭代:

Ansible - 嵌套循环

Documentation

您可以按照文档所述在循环中构建循环,方法是将一个任务用作带有 include_tasks 模块的外循环,以及一个带有重命名的循环控制变量 (loop_var) 的循环。

如文档中的示例所示,您需要将其分成两个文件:

# main.yml tasks file
- include_tasks: inner.yml
  loop:
    - 1
    - 2
    - 3
  loop_control:
    loop_var: outer_item

# inner.yml tasks file
- name: Print outer and inner items
  ansible.builtin.debug:
    msg: "outer item={{ outer_item }} inner item={{ item }}"
  loop:
    - a
    - b
    - c

Jinja2 - 预生成结构

Documentation

使用产品过滤器创建列表列表:

['alice','bob'] |product(['clientdb','employeedb','providerdb'])|list

创造

[('alice','clientdb'),('alice','employeedb'),'providerdb'),('bob','providerdb')]

例如文档状态中的示例,您可以使用类似于以下的代码:

- name: Give users access to multiple databases
  community.mysql.mysql_user:
    name: "{{ item[0] }}"
    priv: "{{ item[1] }}.*:ALL"
    append_privs: yes
    password: "foo"
  loop: "{{ ['alice','providerdb'])|list }}"

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-