ansible使用jinja2模板

jinja2基本语法

  1. 控制结构 {% %}

            jinja2中的for循环用于迭代Python的数据类型,包括列表,元组和字典

         2.变量取值 {{ }}

            jinja2模板中使用 {{ }} 语法表示一个变量,它是一种特殊的占位符。当利用jinja2进行渲染的时候,它会把这些特殊的占位符进行填充/替换,jinja2支持python中所有的Python数据类型比如列表、字段、对象等。

            所有对变量的操作都必须在{{}}代码块中,{% %}只能使用一些控制语句

        3.注释 {# #}

        4.过滤器

            safe: 渲染时值不转义

           capitialize: 把值的首字母转换成大写,其他子母转换为小写

           lower: 把值转换成小写形式

           upper: 把值转换成大写形式

           title: 把值中每个单词的首字母都转换成大写

           trim: 把值的首尾空格去掉

           striptags: 渲染之前把值中所有的HTML标签都删掉

           join: 拼接多个值为字符串

           replace: 替换字符串的值

           round: 默认对数字进行四舍五入,也可以用参数进行控制

           int: 把值转换成整型

          只需要在变量后面使用管道(|)分割,多个过滤器可以链式调用,前一个过滤器的输出会作为后一个过滤器的输入

模板实例

cluster.name: es-cluster
node.name: node-{{ ansible_default_ipv4['address'].split('.')| last }}
cluster.initial_master_nodes: node-{{ ansible_default_ipv4['address'].split('.')| last }}
path.data: {{ es_path_data }}
path.logs: {{ es_path_logs }}
network.host: 0.0.0.0
{% set hosts = [] %} #定义一个Python列表变量
{% for host in groups['elastic-master'] %} #使用循环控制语句遍历列表 
  {{ hosts.append(host) }}  #对Python列表变量进行操作
{% endfor %}
discovery.seed_hosts: {{ hosts }} #输出变量的值
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
正确模板

     

cluster.name: es-cluster
node.name: node-{{ ansible_default_ipv4['address'].split('.')| last }}
cluster.initial_master_nodes: node-{{ ansible_default_ipv4['address'].split('.')| last }}
path.data: {{ es_path_data }}
path.logs: {{ es_path_logs }}
network.host: 0.0.0.0

{% set seed_hosts = [] %}
{% for host in groups['elastic'] %}
    {% seed_hosts.append("{{ host }}") %} 
    
{% endfor %}

discovery.seed_hosts: {{ seed_hosts }}
 
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
错误模板

   

cluster.name: es-cluster
node.name: node-{{ ansible_default_ipv4['address'].split('.')| last }}
cluster.initial_master_nodes: node-{{ ansible_default_ipv4['address'].split('.')| last }}
path.data: {{ es_path_data }}
path.logs: {{ es_path_logs }}
network.host: 0.0.0.0
{% set hosts = [] %}
{% for host in groups['elastic'] %}
  {%  if hosts.append("{{ host }}") %} 
  {% endif %}
{% endfor %}
discovery.seed_hosts: {{ hosts }}
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
错误模板2

   

jinjia2字符串处理

    使用和python的strip一样,{{ string | trim }} == string.strip()
    python使用函数调用符号.号来进行调用string.strip
    jinjia2使用 | 符号进行调用 {{ string | trim }}

   把一个列表变量拼接成字符串       join函数遍历数组返回一个新的字符串

   zookeeper.connect={{ groups['zookeeper'] |  join(':2181,')  }}:2181 拼接结果:zookeeper.connect=192.168.30.174:2181,192.168.30.175:2181,192.168.30.176:2181

    

 ansible变量声明注意事项

     ansible在vars中声明的变量名称中不能带有横线-号,只能带有下划线_
     flink-history-dir 是错误的,ansible在读取的时候会报错
     flink_history_dir 这样声明变量才可以

     

     

    变量声明不能带.号

     

  变量声明其他规则

          ansible的模板变量渲染后带u(unicode).用template模块渲染,渲染后成了unicode的字符串。这样对应的前端服务无法解析该配置

          - name: Copy setuptools-24.0.2.tar.gz to {{ groups["all"] | to_json }}     ['192.168.1.1','192.168.1.2']

          - name: Copy setuptools-24.0.2.tar.gz to {{ groups["all"]  }}                   [u'192.168.1.1',u'192.168.1.2']

  变量解析带to_json和不带to_json的区别

      

      

    jinjia2遍历数组并操作数组元素

      string方法返回一个新的数组

       

     {% set hosts = [] %}
     {% for host in groups["all"] %}
     {{ hosts.append(host|string+":9100") }}
     {% endfor %}
    - targets: {{ hosts | to_json }}
    labels:
      group: 'client-node-exporter'

jinjia2同时获取循环元素和元素索引

        

        

       代码示例 

- name: populate inventory into hosts file
  vars:
    dns_domain: cluster.local
  blockinfile:
    path: /etc/hosts
    block: |-
          {% for item in (groups['redis-master'] |default([]))|unique -%}
          {{ item }}  redismaster.{{ loop.index }}.{{ dns_domain }}
          {% endfor %}
    state: present
    create: yes
    backup: no
    unsafe_writes: yes
    marker: "# Ansible inventory redis master hosts {mark}"


- name: populate inventory into hosts file
  vars:
    dns_domain: cluster.local
  blockinfile:
    path: /etc/hosts
    block: |-
          {% for item in (groups['mysql'] + groups['redis-master'] + groups['zookeeper']|default([]))|unique -%}
          {{ hostvars[item].ansible_default_ipv4.address }}  {{ item }}.{{ dns_domain }} {{ item }}
          {% endfor %}
    state: present
    create: yes
    backup: yes
    unsafe_writes: yes
    marker: "# Ansible inventory hosts {mark}"
  tags: hoststest
View Code

 

jinji2嵌套变量输出

    

    

#内容
pidfilepath = {{ mongos_server_path }}/log/mongos.pid
logpath = {{ mongos_server_path }}/log/mongos.log
logappend = true

bind_ip = 0.0.0.0
port = {{ mongos_port }}
fork = true

#监听的配置服务器,只能有1个或者3个configs为配置服务器的副本集名字
{% set confighosts =  [] %} 
{% for host in groups["config-server"] %} 
{{ confighosts.append(host | string +":"+config_port | string) }} 
{% endfor %}
configdb = {{ config_name }}/{{ confighosts | join(",") }}
#设置最大连接数
maxConns = 20000

结果
configdb = configs/192.168.227.161:21000,192.168.227.162:21000,192.168.227.163:21000
示例

 

jinjia2遍历交互输入变量

- hosts: shards
  vars_prompt:
    - name: shardscount
      prompt: "输入要创建的shard数量"
      private: no
  roles:
    - { role: shards }

main.yml
- name: echo shards
  debug:
    msg: "{{ shardscount }}"

- name: Create shards path {{ groups["shards"] }}
  file: path="{{ app_dir }}/{{ item+1 }}" state=directory owner={{ app_user }} group={{ app_user }} recurse=yes
  with_items:
    - "{{ range(1, shardscount | int ) | list }}"
View Code
- hosts: shards
  # vars_prompt:
  #   - name: shardscount
  #     prompt: "输入要创建的shard数量"
  #     private: no
  roles:
    - { role: shards }


# - name: echo shards
#   debug:
#     msg: "{{ shardscount }}"

- name: get shards nodes count
  shell: echo {{ groups["shards"] | length }}
  register: shardscount

- name: echo shards
  debug:
    msg: "{{ shardscount.stdout_lines[0] }}"

- name: Create shards data path {{ groups["shards"] }}
  file: path="{{ app_dir }}/shard{{ item+1 }}/data" state=directory owner={{ app_user }} group={{ app_user }} recurse=yes
  with_items:
    - "{{ range(0, shardscount.stdout_lines[0] | int ) | list }}"

- name: Create shards log path {{ groups["shards"] }}
  file: path="{{ app_dir }}/shard{{ item+1 }}/log" state=directory owner={{ app_user }} group={{ app_user }} recurse=yes
  with_items:
    - "{{ range(0, shardscount.stdout_lines[0] | int ) | list }}"

- name: Create shards config file
  blockinfile:
    path: "{{ app_dir }}/conf/shard{{ item+1 }}.conf"
    block: |-
          #配置文件内容
          #——————————————–
          pidfilepath = {{ app_dir }}/shard{{ item+1 }}/log/shard{{ item+1 }}.pid
          dbpath = {{ app_dir }}/shard{{ item+1 }}/data
          logpath = {{ app_dir }}/shard{{ item+1 }}/log/shard{{ item+1 }}.log
          logappend = true

          bind_ip = 0.0.0.0
          {% set number = item+1 %}
          port = {{ 20000 + number }}
          fork = true
 
          #副本集名称
          replSet = shard{{ item+1 }}
 
          #declare this is a shard db of a cluster
          shardsvr = true
 
          #设置最大连接数
          maxConns = 20000
    state: present
    create: yes
    backup: no
    unsafe_writes: yes
  with_items:
    - "{{ range(0, shardscount.stdout_lines[0] | int ) | list }}"
View Code

 

 

 

 

 

posted @ 2021-06-07 19:18  不懂123  阅读(1099)  评论(0编辑  收藏  举报