Ansible之Playbook(三):变量应用

张开发
2026/4/16 4:53:22 15 分钟阅读

分享文章

Ansible之Playbook(三):变量应用
Ansible Playbook 变量应用详解一、为什么需要变量想象一下你要给10台OpenEuler服务器安装nginx软件包。如果每台机器的安装路径、配置文件位置都不同难道要写10个Playbook吗变量就是来解决这个问题的它让你一份Playbook多处使用通过改变变量的值适应不同的服务器环境。配置更灵活轻松管理不同主机组的差异如开发环境、测试环境、生产环境。减少重复避免错误重要信息如密码、路径只定义一次。二、变量在哪里定义(OpenEuler常见场景)变量可以存放在很多地方Ansible会按优先级合并命令行传递 (最高优先级)ansible-playbook site.yml -e package_namenginx openEuler_version22.03临时覆盖其他变量适合测试或一次性操作。-e或--extra-vars后面跟变量。多个变量用空格隔开。Playbook 中定义 (vars块)- hosts: webservers # 假设这是你的OpenEuler服务器组 vars: http_port: 80 config_path: /etc/nginx/nginx.conf openEuler_pkg_manager: dnf # OpenEuler 主要使用 dnf tasks: - name: Install {{ package_name }} using {{ openEuler_pkg_manager }} ansible.builtin.package: name: {{ package_name }} state: present直接在Playbook里写作用范围是这个Play。适合这个Playbook专用的变量。主机清单文件 (inventory) 中定义针对主机组 (group_vars)创建目录group_vars/在里面创建文件文件名对应主机组名如webservers.yml# group_vars/webservers.yml nginx_worker_processes: 4 openEuler_timezone: Asia/Shanghai针对特定主机 (host_vars)创建目录host_vars/在里面创建文件文件名对应主机名如openeuler-server01.yml# host_vars/openeuler-server01.yml server_ip: 192.168.1.101 special_config: true这是最推荐的方式将变量与主机/组管理分离Playbook更通用清晰。vars_files引入外部文件- hosts: all vars_files: - secrets.yml # 存放密码等敏感信息(注意用ansible-vault加密) - common_vars.yml # 存放通用变量 tasks: ...将变量定义在独立的YAML文件中然后在Playbook中引用。方便管理大量变量或敏感信息。任务执行结果注册为变量 (register)- name: Check if nginx is installed ansible.builtin.command: rpm -q nginx register: nginx_installed # 将命令执行结果存入变量 nginx_installed ignore_errors: yes # 即使命令失败(未安装)也继续 - name: Start nginx if installed ansible.builtin.service: name: nginx state: started when: nginx_installed.rc 0 # 使用注册变量的返回码(rc)做判断将某个task的执行结果标准输出、返回码等保存下来供后续task使用。非常强大的功能Facts (系统信息变量) Ansible在执行Playbook前会自动收集目标主机的信息称为Gathering Facts。这些信息本身就是变量- name: Print OpenEuler OS version ansible.builtin.debug: msg: This host is running {{ ansible_distribution }} {{ ansible_distribution_version }}ansible_distribution: 系统发行版 (如 openEuler)ansible_distribution_version: 发行版版本 (如 22.03 LTS)ansible_hostname: 主机名ansible_default_ipv4.address: 默认IPv4地址使用ansible -m setup hostname命令可以查看所有Facts。三、如何在Playbook中使用变量(语法)在Playbook的任何地方只要用双花括号{{ variable_name }}包裹变量名即可- name: Create configuration file for {{ app_name }} on OpenEuler ansible.builtin.template: src: templates/myapp.conf.j2 # 模板文件 dest: {{ config_path }}/myapp.conf # 使用变量指定目标路径 owner: root group: root mode: 0644ansible.builtin.template模块这是使用变量的超级常用场景它结合了模板文件(.j2)。模板文件(.j2)一个文本文件如nginx.conf.j2里面可以包含变量和Jinja2控制结构。Ansible会将变量替换成实际值后把文件复制到目标主机。示例模板片段 (nginx.conf.j2)worker_processes {{ nginx_worker_processes }}; listen {{ http_port }}; server_name {{ ansible_hostname }};四、OpenEuler系统下变量应用实战案例场景配置多台OpenEuler服务器上的Nginx不同服务器监听端口可能不同且需要设置时区。主机清单 (inventory.ini):[webservers] openeuler01 ansible_host192.168.1.101 openeuler02 ansible_host192.168.1.102 http_port8080 # 给02单独指定端口组变量 (group_vars/webservers.yml):openEuler_pkg_manager: dnf package_name: nginx config_path: /etc/nginx openEuler_timezone: Asia/Shanghai nginx_worker_processes: 4 # 默认值主机变量 (host_vars/openeuler02.yml):http_port: 8080 # 覆盖组变量或Playbook中的默认值Playbook (deploy_nginx.yml):- hosts: webservers become: yes # 提权 tasks: - name: Set OpenEuler timezone to {{ openEuler_timezone }} ansible.builtin.timezone: name: {{ openEuler_timezone }} - name: Ensure {{ package_name }} is installed (via {{ openEuler_pkg_manager }}) ansible.builtin.package: name: {{ package_name }} state: present - name: Configure Nginx ansible.builtin.template: src: templates/nginx.conf.j2 dest: {{ config_path }}/nginx.conf owner: root group: root mode: 0640 notify: Restart Nginx # 触发handler - name: Ensure Nginx is enabled and running ansible.builtin.service: name: nginx state: started enabled: yes handlers: - name: Restart Nginx ansible.builtin.service: name: nginx state: restartedNginx 模板 (templates/nginx.conf.j2):user nginx; worker_processes {{ nginx_worker_processes }}; ... server { listen {{ http_port }} default_server; # 这里会使用主机或组定义的端口 server_name {{ ansible_hostname }}; ... }执行ansible-playbook -i inventory.ini deploy_nginx.yml对于openeuler01http_port使用组变量webservers.yml中的值如果没定义则可能报错说明组变量里也应该给个默认值。对于openeuler02http_port使用host_vars/openeuler02.yml中定义的8080。openEuler_timezone,package_name,config_path等都来自组变量。五、变量优先级小贴士当同一个变量在多个地方定义时优先级高的覆盖优先级低的 命令行 Playbook中vars 主机变量(host_vars) 组变量(group_vars) Playbook中vars_files Facts六、给OpenEuler新手的建议从简单开始先在Playbook里用vars定义测试成功后再移到group_vars或host_vars。命名清晰变量名要有意义如openEuler_dns_server比dns_ip好。善用debug不确定变量值用debug模块打印出来看看- name: Show variable value ansible.builtin.debug: var: my_variable_name # 直接打印变量值模板是神器template模块加.j2文件是配置管理的核心手段一定要掌握。注意空格{{ variable }}花括号里不要有多余空格容易出错。安全第一密码等敏感变量务必用ansible-vault加密

更多文章