ansible_role_canal_instance

需求:

在一个服务器添加多个canal_instance.
笨办法定义一个var

ha_group_name: mgr_dev1
master_address: 172.18.12.211:3307
journal_name:
master_position:
master_timestamp:
master_gtid:
tsdb_mysql_host: 172.18.12.211
tsdb_mysql_port: 3311
tsdb_mysql_db: canal_mgr_dev1

多次执行playbook
想换一个办法, 定义一个var, 是一个列表, 循环这个列表

canal_instances:
  - ha_group_name: mgr_dev1
    master_address: 172.18.12.211:3307
    journal_name:
    master_position:
    master_timestamp:
    master_gtid:
    tsdb_mysql_host: 172.18.12.211
    tsdb_mysql_port: 3311
    tsdb_mysql_db: canal_mgr_dev1
  - ha_group_name: mgr_dev2
    master_address: 172.18.12.211:3307
    journal_name:
    master_position:
    master_timestamp:
    master_gtid:
    tsdb_mysql_host: 172.18.12.211
    tsdb_mysql_port: 3311
    tsdb_mysql_db: canal_mgr_dev2

传统的循环是每个task 使用 with_items自己循环自己的, 我这里是希望多个task公用一个循环

使用include_task, with_Items 和 loop_control

main.yaml

---
- include_tasks: add_canal_instance/tasks/add_instance.yaml
  with_items:
    - "{{ canal_instances }}"
  loop_control:
    loop_var: instance

add_instance.yaml

---
# tasks file for add_instance

- name: 创建目录
  file:
    path: "/usr/local/canal/conf/{{ instance.ha_group_name }}"
    state: directory
    mode: 0755
    recurse: true
  register: is_dir_exist

- set_fact: ha_group_name={{ instance.ha_group_name }}
- set_fact: master_address={{ instance.master_address }}
- set_fact: journal_name={{ instance.journal_name }}
- set_fact: master_position={{ instance.master_position }}
- set_fact: master_timestamp={{ instance.master_timestamp }}
- set_fact: master_gtid={{ instance.master_gtid }}
- set_fact: tsdb_mysql_host={{ instance.tsdb_mysql_host }}
- set_fact: tsdb_mysql_port={{ instance.tsdb_mysql_port }}
- set_fact: tsdb_mysql_db={{ instance.tsdb_mysql_db }}

- name: 生成canal.properties
  template:
    src: instance.properties.j2
    dest: "/usr/local/canal/conf/{{ instance.ha_group_name }}/instance.properties"
    mode: 0755
  when:
    - is_dir_exist is changed

模板文件

instance.properties.j2
 canal.instance.master.address={{ master_address }}
 canal.instance.master.journal.name={{ journal_name }}
 canal.instance.master.position={{ master_position }}
 canal.instance.master.timestamp={{ master_timestamp }}
 canal.instance.master.gtid={{ master_gtid }}
 ...

关于 loop_control

https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
New in version 2.1.

In 2.0 you are again able to use loops and task includes (but not playbook includes). This adds the ability to loop over the set of tasks in one shot. Ansible by default sets the loop variable item for each loop, which causes these nested loops to overwrite the value of itemfrom the “outer” loops. As of Ansible 2.1, the loop_control option can be used to specify the name of the variable to be used for the loop:

set_fact 改进版

写那么多set_fact感觉不够优雅
一开始以为可以写词instance.0=instance.1, 然后报错dict object has no element 0
说明字典没有元素0
就想取key value, 但是我的key是不固定的
翻文档https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html 发现dict2items这个filter

于是点进去看

它正好可以把我这种不固定的key弄成一个包含 key value 的列表
用debug测了下没有问题

- debug:
    msg: "key={{ item.key }} value={{ item.value }}"
  loop: "{{ instance|dict2items }}"

于是写成这样

- set_fact: {{ item.key }}={{ item.value }}
  loop: "{{ instance|dict2items }}"

结果报错

google一下 搜索 “set_fact item.key”
https://stackoverflow.com/questions/38143647/set-fact-with-dynamic-key-name-in-ansible/38144157
发现应该这样写

- set_fact: {"{{ item.key }}":"{{ item.value }}"}
  loop: "{{ instance|dict2items }}"

loop 和 with_item的区别

https://stackoverflow.com/questions/50456997/ansible-with-items-vs-loop

参考:
https://www.jianshu.com/p/04516cbba336

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值