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"
越学越感到自己的无知
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现