【自动化运维神器Ansible】playbook变量:使用全流程解析
·
目录
4.5 配置文件模板(templates/nginx.conf.j2)
引言
在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的精髓所在,掌握变量的使用方法能够显著提升自动化运维的灵活性和可维护性。在实际应用中,应建立规范的变量管理体系,结合业务需求合理设计变量结构,同时注重变量安全和文档维护。
更多推荐



所有评论(0)