目录

引言

1 变量基础规范

1.1 变量命名规则

1.2 变量定义方式

1.3 变量调用方式

2 变量来源深度解析

2.1 Ansible Facts(远程主机变量)

2.2 命令行变量

2.3 Playbook文件内变量

2.4 独立变量文件

2.5 Inventory文件变量

主机变量(Host Variables)

组变量(Group Variables)

2.6 Role变量

3 变量优先级解析

3.1 变量优先级顺序

3.2 优先级示例

4 案例:多环境变量管理

4.1 项目结构

4.2 变量文件定义

4.3 Inventory文件

4.4 Playbook文件(deploy.yml)

4.5 配置文件模板(templates/nginx.conf.j2)

4.6 执行方式

5 变量高级技巧

5.1 变量过滤与处理

5.2 变量注册与条件判断

5.3 变量循环与列表处理

5.4 变量查找与默认值

6 总结


引言

在Ansible自动化运维中, 变量是实现动态配置和灵活部署的核心组件。通过使用变量,我们可以将硬编码的值替换为可动态替换的占位符,实现一套Playbook适配多种环境(开发、测试、生产)、不同主机配置的需求。变量机制使Playbook具备了 可重用性可维护性,是Ansible声明式自动化的精髓所在。

1 变量基础规范

1.1 变量命名规则

语法规范
  • 仅能由字母、数字和下划线组成
  • 必须以字母开头
  • 变量名区分大小写(http_port和HTTP_PORT是不同的变量)
  • 示例
# 合法的变量名
http_port
server_name
mysql_root_password
app_version

# 非法的变量名
1st_server    # 不能以数字开头
server-name    # 不能包含连字符
server name    # 不能包含空格

1.2 变量定义方式

variable=value
  • 示例
http_port=80
server_name="webserver01"
mysql_root_password="SecurePass123!"

1.3 变量调用方式

  • 基本调用
- name: Configure web server
  copy: 
    src: config.j2 
    dest: /etc/nginx/nginx.conf
    content: "listen {{ http_port }};"
调用规范
  • 变量名前后建议加空格:listen {{ http_port }};
  • 特殊情况下需使用双引号:"{{ variable_name }}"
  • 示例对比
# 推荐方式(前后有空格)
server_name: "{{ inventory_hostname }}"
port: {{ http_port }}

# 必须使用双引号的情况
- name: 使用变量作为字典键
  debug: 
    msg: "Server {{ hostvars[inventory_hostname]['ansible_hostname'] }}"

2 变量来源深度解析

2.1 Ansible Facts(远程主机变量)

定义:Ansible自动收集的远程主机系统信息,可直接调用。
特点
  • 自动收集,无需手动定义
  • 包含丰富的系统信息(操作系统、硬件、网络等)
  • 优先级较低(可被其他来源覆盖)
  • 常用Facts变量
ansible_hostname          # 主机名
ansible_os_family         # 操作系统家族
ansible_distribution      # 发行版名称
ansible_default_ipv4.address # 默认IPv4地址
ansible_processor_vcpus   # CPU核心数
ansible_memtotal_mb       # 总内存(MB)
  • 调用示例
- name: 显示主机信息
  debug: 
    msg: 
      - "主机名: {{ ansible_hostname }}"
      - "操作系统: {{ ansible_distribution }} {{ ansible_distribution_version }}"
      - "IP地址: {{ ansible_default_ipv4.address }}"
  • Facts收集流程

2.2 命令行变量

定义:通过-e参数在命令行直接指定变量。
特点
  • 优先级最高(覆盖所有其他来源)
  • 适合临时覆盖变量值
  • 支持复杂值(字典、列表)
  • 语法
ansible-playbook -e "var1=value1 var2=value2" playbook.yml
ansible-playbook -e @vars.json playbook.yml  # 从JSON文件加载
  • 示例
# 简单变量
ansible-playbook -e "http_port=8080 deploy.yml"

# 复杂变量(JSON格式)
ansible-playbook -e '{"db_config": {"host": "db.example.com", "port": 3306}}' deploy.yml

2.3 Playbook文件内变量

定义:在Playbook文件中使用vars关键字定义变量。
  • 语法
---
- hosts: webservers
  vars:
    http_port: 80
    server_name: "webserver"
  tasks:
    - name: Configure Nginx
      copy: 
        src: nginx.conf.j2 
        dest: /etc/nginx/nginx.conf
特点
  • 作用域限于当前Playbook
  • 适合配置相对固定的值
  • 支持多行定义和复杂数据结构
  • 示例
vars:
  app_config:
    database:
      host: "localhost"
      port: 5432
      name: "myapp"
    features:
      - authentication
      - logging
      - caching

2.4 独立变量文件

定义:在独立的YAML文件中定义变量,通过vars_files引入。
  • 语法
---
- hosts: webservers
  vars_files:
    - vars/development.yml
    - vars/common.yml
  tasks:
    - name: Deploy application
      copy: src=app.war dest=/opt/tomcat/webapps/
  • 变量文件示例(vars/development.yml):
---
http_port: 8080
debug_mode: true
db_host: "dev-db.example.com"
特点
  • 支持多个变量文件(后面的会覆盖前面的)
  • 适合环境分离(开发、测试、生产)
  • 支持YAML格式和JSON格式

2.5 Inventory文件变量

主机变量(Host Variables)

定义:在Inventory文件中为特定主机定义变量。
  • 语法
# /etc/ansible/hosts
[webservers]
web1.example.com http_port=8080 maxRequestsPerChild=1000
web2.example.com http_port=8081 maxRequestsPerChild=2000
  • 调用方式:
- name: Configure web server
  copy: 
    src: httpd.conf.j2 
    dest: /etc/httpd/conf/httpd.conf
    content: "Listen {{ http_port }} MaxRequestsPerChild {{ maxRequestsPerChild }}"

组变量(Group Variables)

定义:在Inventory文件中为整个主机组定义变量。
  • 语法
# /etc/ansible/hosts
[webservers]
web1.example.com
web2.example.com

[webservers:vars]
http_port=8080
maxRequestsPerChild=1500
特点
  • 组变量优先级高于主机变量
  • 适用于组内所有主机的公共配置
  • 支持嵌套组变量

2.6 Role变量

定义:在Role的defaults/main.yml中定义默认变量。
  • 结构
roles/
└── common/
    ├── defaults/
    │   └── main.yml
    ├── vars/
    │   └── main.yml
    └── tasks/
        └── main.yml
  • 调用方式
---
- hosts: webservers
  roles:
    - common
  • 变量文件示例(roles/common/defaults/main.yml):
---
# 默认变量(优先级最低)
nginx_port: 80
php_version: "7.4"

3 变量优先级解析

3.1 变量优先级顺序

从高到低优先级:
  • 命令行变量(-e)
  • Playbook文件内变量(vars)
  • Inventory主机变量
  • Inventory组变量
  • Role变量(defaults/main.yml)
  • Facts变量
  • 优先级流程

3.2 优先级示例

  • 场景:多个来源定义了http_port变量
# 命令行:ansible-playbook -e "http_port=9000" deploy.yml
# Playbook文件内:
vars:
  http_port: 8080
# Inventory组变量:
[webservers:vars]
http_port=8081
# Role变量:
roles/common/defaults/main.yml:
  http_port: 80
结果:最终使用的值是9000(命令行变量优先级最高)

4 案例:多环境变量管理

4.1 项目结构

ansible-project/
├── inventory/
│   ├── production
│   ├── staging
│   └── development
├── group_vars/
│   ├── all.yml
│   ├── production.yml
│   ├── staging.yml
│   └── development.yml
├── deploy.yml
└── templates/
    └── nginx.conf.j2

4.2 变量文件定义

  • 全局变量(group_vars/all.yml)
---
# 通用配置
nginx_user: nginx
ssl_path: /etc/nginx/ssl
  • 生产环境变量(group_vars/production.yml)
---
# 生产环境特定配置
http_port: 80
https_port: 443
server_name: "prod.example.com"
ssl_enabled: true
max_workers: 4
  • 开发环境变量(group_vars/development.yml)
---
# 开发环境特定配置
http_port: 8080
https_port: 8443
server_name: "dev.example.com"
ssl_enabled: false
max_workers: 2

4.3 Inventory文件

  • 生产环境Inventory(inventory/production)
[webservers]
web1.prod.example.com
web2.prod.example.com

[webservers:vars]
ansible_ssh_user=deploy
ansible_ssh_private_key_file=~/.ssh/prod_key
  • 开发环境Inventory(inventory/development)
[webservers]
dev1.example.com
dev2.example.com

[webservers:vars]
ansible_ssh_user=devuser
ansible_ssh_private_key_file=~/.ssh/dev_key

4.4 Playbook文件(deploy.yml)

---
- name: Deploy Nginx Configuration
  hosts: webservers
  vars_files:
    - group_vars/all.yml
    - "group_vars/{{ environment | default('development') }}.yml"
  
  tasks:
    - name: Install Nginx
      yum: name=nginx state=present
    
    - name: Create SSL directory
      file: 
        path: "{{ ssl_path }}" 
        state=directory 
        owner={{ nginx_user }} 
        group={{ nginx_user }}
    
    - name: Deploy Nginx configuration
      template: 
        src: nginx.conf.j2 
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
    
    - name: Start Nginx service
      service: 
        name=nginx 
        state=started 
        enabled=yes
  
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted

4.5 配置文件模板(templates/nginx.conf.j2)

user {{ nginx_user }};
worker_processes {{ max_workers }};
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    server {
        listen {{ http_port }};
        {% if ssl_enabled %}
        listen {{ https_port }} ssl;
        ssl_certificate {{ ssl_path }}/cert.pem;
        ssl_certificate_key {{ ssl_path }}/key.pem;
        {% endif %}
        
        server_name {{ server_name }};
        
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
        
        location /health {
            access_log off;
            return 200 "OK";
            add_header Content-Type text/plain;
        }
    }
}

4.6 执行方式

# 部署生产环境
ansible-playbook -i inventory/production -e "environment=production" deploy.yml

# 部署开发环境
ansible-playbook -i inventory/development -e "environment=development" deploy.yml

5 变量高级技巧

5.1 变量过滤与处理

  • 使用过滤器
- name: 格式化日期
  debug: 
    msg: "部署日期: {{ ansible_date_time.iso8601 }}"

- name: 转换为大写
  debug: 
    msg: "服务器名: {{ inventory_hostname | upper }}"

- name: 计算哈希值
  debug: 
    msg: "密码哈希: {{ 'mypassword' | password_hash('sha512') }}"

5.2 变量注册与条件判断

  • 注册变量
- name: 检查磁盘空间
  command: df -h /var
  register: disk_check

- name: 显示磁盘信息
  debug: 
    msg: "磁盘使用率: {{ disk_check.stdout }}"
  when: "'Use%' in disk_check.stdout"

5.3 变量循环与列表处理

  • 循环使用变量
- name: 安装多个包
  yum: 
    name: "{{ item }}" 
    state=present
  loop:
    - nginx
    - php-fpm
    - mysql-server

- name: 创建多个目录
  file: 
    path: "{{ item }}" 
    state=directory
  loop:
    - /opt/app/logs
    - /opt/app/cache
    - /opt/app/temp

5.4 变量查找与默认值

  • 使用默认值
- name: 设置默认端口
  debug: 
    msg: "端口: {{ http_port | default(80) }}"

- name: 安全获取嵌套变量
  debug: 
    msg: "数据库主机: {{ db_config.host | default('localhost') }}"

6 总结

变量机制是Ansible Playbook的精髓所在,掌握变量的使用方法能够显著提升自动化运维的灵活性和可维护性。在实际应用中,应建立规范的变量管理体系,结合业务需求合理设计变量结构,同时注重变量安全和文档维护。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐