ansible 变量计算

Ansible 变量支持算术运算、字符串拼接、列表操作、条件判断等,主要通过 Jinja2 模板引擎处理。

1. 基本算术运算

Ansible 变量可以直接进行数值计算。

复制代码
- hosts: localhost
  gather_facts: no
  vars:
    a: 10
    b: 3
  tasks:
    - debug:
        msg:
          - "加法: {{ a + b }}"    # 13
          - "减法: {{ a - b }}"    # 7
          - "乘法: {{ a * b }}"    # 30
          - "除法: {{ a / b }}"    # 3.333333
          - "整除: {{ a // b }}"   # 3
          - "取模: {{ a % b }}"    # 1
          - "幂次方: {{ a ** b }}" # 1000
复制代码

2. 变量类型转换

变量可以通过 int(), float(), str(), list() 进行转换。

复制代码
- hosts: localhost
  gather_facts: no
  vars:
    num_str: "100"
    float_str: "3.14"
    bool_str: "true"
  tasks:
    - debug:
        msg:
          - "字符串转整数: {{ num_str | int }}"  # 100
          - "字符串转浮点数: {{ float_str | float }}"  # 3.14
          - "字符串转布尔: {{ bool_str | bool }}"  # True
复制代码

3. 字符串操作

3.1 字符串拼接

- hosts: localhost
  gather_facts: no
  vars:
    first_name: "John"
    last_name: "Doe"
  tasks:
    - debug:
        msg: "{{ first_name + ' ' + last_name }}"  # "John Doe"

3.2 字符串格式化

- hosts: localhost
  gather_facts: no
  vars:
    name: "Alice"
    age: 25
  tasks:
    - debug:
        msg: "姓名: {{ name }}, 年龄: {{ age }}"

3.3 字符串大小写转换

- debug:
    msg:
      - "大写: {{ 'ansible' | upper }}"  # "ANSIBLE"
      - "小写: {{ 'ANSIBLE' | lower }}"  # "ansible"
      - "首字母大写: {{ 'ansible' | capitalize }}"  # "Ansible"

3.4 子字符串检查

- debug:
    msg: "{{ 'ansible' in 'ansible playbook' }}"  # True

3.5 字符串分割与拼接

- debug:
    msg:
      - "{{ 'hello world' | split(' ') }}"  # ['hello', 'world']
      - "{{ ['hello', 'world'] | join('-') }}"  # "hello-world"

4. 列表操作

4.1 列表基本操作

复制代码
- hosts: localhost
  gather_facts: no
  vars:
    mylist: [1, 2, 3, 4, 5]
  tasks:
    - debug:
        msg:
          - "第一个元素: {{ mylist[0] }}"  # 1
          - "最后一个元素: {{ mylist[-1] }}"  # 5
          - "子列表: {{ mylist[1:4] }}"  # [2, 3, 4]
复制代码

4.2 列表拼接

- debug:
    msg: "{{ [1, 2, 3] + [4, 5] }}"  # [1, 2, 3, 4, 5]

4.3 列表长度

- debug:
    msg: "{{ mylist | length }}"  # 5

4.4 列表排序

- debug:
    msg: "{{ [3, 1, 2] | sort }}"  # [1, 2, 3]

4.5 去重

- debug:
    msg: "{{ [1, 2, 2, 3, 3, 4] | unique }}"  # [1, 2, 3, 4]

4.6 列表遍历

- hosts: localhost
  gather_facts: no
  vars:
    users: ["Alice", "Bob", "Charlie"]
  tasks:
    - debug:
        msg: "{{ item }}"
      loop: "{{ users }}"

5. 字典操作

5.1 字典取值

复制代码
- hosts: localhost
  gather_facts: no
  vars:
    mydict:
      name: "Alice"
      age: 25
  tasks:
    - debug:
        msg:
          - "姓名: {{ mydict['name'] }}"
          - "年龄: {{ mydict.age }}"
复制代码

5.2 字典遍历

- debug:
    msg: "{{ item.key }} -> {{ item.value }}"
  loop: "{{ mydict | dict2items }}"

5.3 合并字典

- debug:
    msg: "{{ {'a': 1} | combine({'b': 2}) }}"  # {'a': 1, 'b': 2}

6. 条件判断
6.1 三元表达式

- debug:
    msg: "{{ '大于10' if 15 > 10 else '小于10' }}"  # "大于10"

6.2 比较运算

- debug:
    msg:
      - "{{ 5 > 3 }}"  # True
      - "{{ 5 < 3 }}"  # False
      - "{{ 5 == 5 }}"  # True

6.3 布尔取反

- debug:
    msg: "{{ not False }}"  # True

案例

1. 在j2文件或者vars.yml对变量进行二次运算

错误示范

复制代码
- hosts: elasticsearch
  remote_user: root
  # 收集远程主机信息
  gather_facts: yes

    - name: 修改JVM内存
      ansible.builtin.lineinfile:
        path: "{{ es_install_dir }}/config/jvm.options"
        regexp: "^-Xms"
        #line: "-Xms{{ (system_info.ansible_facts.ansible_memtotal_mb / 2)|int }}m"
        #line: "-Xms{{ (ansible_memtotal_mb / 3)|int }}m"
        line: "-Xms{{ jvm_mem }}m"
      tags: xms

    - name: 修改JVM最大使用内存
      ansible.builtin.lineinfile:
        path: "{{ es_install_dir }}/config/jvm.options"
        regexp: "^-Xmx"
        #line: "-Xmx{{ (system_info.ansible_facts.ansible_memtotal_mb / 2)|int }}m"
        #line: "-Xmx{{ (ansible_memtotal_mb / 3)|int }}m"
        line: "-Xmx{{ jvm_mem }}m"
      tags: xmx
复制代码

变量文件

复制代码
[root@master-1 es]# cat vars.yaml
JAVA_HOME: "/opt/jdk1.8.0_341"
cluster_name: cluster
listen_port: 9200
es_version: 7.16.3
es_install_dir: "/opt/elasticsearch-{{ es_version }}"
password: "$1$6NXikaln$64e67B6Q2C0xK0fuNkVw30"
es_ca_pass: 123456
es_cert_pass: 123456
jvm_mem: "{{ (ansible_memtotal_mb / 2) |int }}"
复制代码

执行

ansible-playbook -i inventory.yaml -t xms,xmx  deploy.yaml

结果是jvm_mem根本没生效。

问题分析:

  • ansible_memtotal_mb 变量可能不可用

    • ansible_memtotal_mb 变量是 gather_facts: yes 之后自动收集的
    • 但你在 vars.yaml 里定义 jvm_mem 时,ansible_memtotal_mb 可能还未被收集
    • 直接在 vars.yaml 里使用 ansible_memtotal_mb 计算值可能不会生效。
  • 变量解析顺序问题

    • vars.yaml 加载时,ansible_memtotal_mb 还未被定义,所以 jvm_mem 计算会失败。

 正确示范

user  nginx;
#worker_processes 2;
worker_processes {{ ansible_processor_vcpus // 3 }};  # 取余操作

这是因为 Jinja2 的除法 / 默认返回浮点数。如果直接 / 运算,会得到 worker_processes 2.0;

注意:

1. 由于需要获取 ansible_processor_vcpus 变量,则在渲染配置文件时,需要提前使用setup模块或者

- hosts: nginx
  remote_user: root
  # 收集远程主机信息
  gather_facts: yes

2. 由于触发handlers加了判断,如果直接触发handlers,无法获取判断状态

复制代码
    - name: check nginx pidfile
      ansible.builtin.stat:
        path: "{{ nginx_install_dir }}/logs/nginx.pid"
      register: nginx_pid
      tags: check_pid

  handlers:
    - name: reload nginx
      #ansible.builtin.systemd:
      #  name: redis
      #  state: restarted
      #ansible.builtin.shell: |
      #  #pkill nginx
      #  "{{ nginx_install_dir }}/sbin/nginx" -s reload
      ansible.builtin.systemd:
        name: nginx
        state: reloaded
      when: nginx_pid.stat.exists
复制代码

错误方法

[root@master-1 nginx]# ansible-playbook -t template_nginx_conf deploy-nginx.yaml

正确方法:

[root@master-1 nginx]# ansible-playbook -t check_pid,template_nginx_conf deploy-nginx.yaml

2. 二进制安装es分布式集群,动态修改jvm内存

Ansible 可以根据目标主机的总内存大小动态设置 jvm.options,分配一半的内存给 JVM。这里可以利用 setup 模块 获取系统信息,并结合 template 模块 或 lineinfile 模块 修改 jvm.options

复制代码
- hosts: elasticsearch
  remote_user: root
  # 收集远程主机信息
  gather_facts: yes
  vars_files:
    - vars.yaml
  tasks:
    ...

    - name: 修改JVM内存
      ansible.builtin.lineinfile:
        path: "{{ es_install_dir }}/config/jvm.options"
        regexp: "^## -Xms"
        #line: "-Xms{{ (system_info.ansible_facts.ansible_memtotal_mb / 2)|int }}m"
        line: "-Xms{{ (ansible_memtotal_mb / 3)|int }}m"

    - name: 修改JVM最大使用内存
      ansible.builtin.lineinfile:
        path: "{{ es_install_dir }}/config/jvm.options"
        regexp: "^## -Xmx"
        #line: "-Xmx{{ (system_info.ansible_facts.ansible_memtotal_mb / 2)|int }}m"
        line: "-Xmx{{ (ansible_memtotal_mb / 3)|int }}m"
复制代码

 

posted @   不会跳舞的胖子  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示