介绍
本教程将指导你使用 Ansible 的 vars_files 进行高效的配置管理。Ansible 是一个强大的自动化工具,它通过简单、人类可读的 YAML 文件来帮助管理基础设施。 vars_files 功能允许你将配置数据与自动化逻辑分开,使你的 Ansible 项目更具组织性和可维护性。
通过本教程,你将学习如何创建和组织 vars_files,将它们整合到 playbook 中,并利用它们来有效地管理不同的环境。这些知识将帮助你构建更具可扩展性和可维护性的基础设施自动化。
安装 Ansible 并创建你的第一个 vars_file
在第一步中,我们将在系统上安装 Ansible,并创建我们的第一个 vars_file 来存储配置数据。
安装 Ansible
让我们从在 Ubuntu 系统上安装 Ansible 开始:
sudo apt update
sudo apt install -y ansible
安装完成后,验证 Ansible 是否已正确安装:
ansible --version
你应该看到类似这样的输出,显示 Ansible 的版本和配置:
ansible [core 2.12.x]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.x (default, Mar 14 2023, 14:21:35) [GCC 11.3.0]
jinja version = 3.0.3
libyaml = True
创建项目目录结构
让我们为我们的 Ansible 项目创建一个目录结构:
mkdir -p ~/project/ansible-vars-demo/vars
cd ~/project/ansible-vars-demo
理解 Ansible vars_files
Ansible vars_files 是 YAML 文件,用于存储可以导入到 playbook 中的变量定义。这些文件允许你:
- 将配置数据与自动化逻辑分开
- 在多个 playbook 中重用相同的变量
- 为不同的环境维护不同的配置
创建你的第一个 vars_file
让我们创建我们的第一个 vars_file 来存储 Web 服务器配置设置。使用 WebIDE,在 ~/project/ansible-vars-demo/vars/webserver.yml 处创建一个新文件,内容如下:
---
## Web Server Configuration
http_port: 80
server_name: example.com
document_root: /var/www/html
max_clients: 200
这个 vars_file 定义了四个可能用于配置 Web 服务器的变量:
http_port:Web 服务器将监听的端口server_name:Web 服务器的域名document_root:存储网站文件的目录max_clients:同时连接的最大客户端数量
为了帮助理解这在 WebIDE 中的样子,请导航到左侧的文件资源管理器,展开 project 文件夹,然后是 ansible-vars-demo,然后是 vars,你应该看到你的 webserver.yml 文件。单击它以查看或编辑其内容。
创建一个 Inventory 文件
接下来,我们需要创建一个 inventory 文件来告诉 Ansible 要管理哪些主机。在真实环境中,这将包含实际的服务器地址,但对于本教程,我们将使用 localhost。
在 ~/project/ansible-vars-demo/inventory.ini 处创建一个新文件,内容如下:
[webservers]
localhost ansible_connection=local
这个简单的 inventory 定义了一个名为 webservers 的组,其中仅包含我们的本地机器。
理解项目结构
此时,你的项目结构应该如下所示:
ansible-vars-demo/
├── inventory.ini
└── vars/
└── webserver.yml
这个基本结构将我们的 inventory(要管理的主机)与我们的变量定义(如何配置这些主机)分离开来。
使用 vars_files 创建一个基本的 Playbook
现在我们已经创建了 vars_file,让我们构建一个使用这些变量的简单 Ansible playbook。这将演示如何从 vars_files 导入和使用配置数据。
理解 Ansible Playbooks
Ansible playbooks 是 YAML 文件,用于定义要在受管主机上执行的一组任务。Playbooks 是 Ansible 功能的核心,允许你自动化复杂的配置过程。
创建一个简单的 Playbook
让我们创建一个 playbook,它将使用我们在 vars_file 中定义的变量来模拟配置 Web 服务器。在 ~/project/ansible-vars-demo/webserver_setup.yml 处创建一个新文件,内容如下:
---
- name: Configure Web Server
hosts: webservers
vars_files:
- vars/webserver.yml
tasks:
- name: Display web server configuration
debug:
msg: "Web server will be configured with: Port={{ http_port }}, ServerName={{ server_name }}, DocumentRoot={{ document_root }}"
- name: Create a directory for document root
file:
path: "/tmp/{{ document_root }}"
state: directory
mode: "0755"
- name: Create a sample index.html file
copy:
content: |
<html>
<head>
<title>Welcome to {{ server_name }}</title>
</head>
<body>
<h1>Welcome to {{ server_name }}</h1>
<p>This server is configured to handle {{ max_clients }} simultaneous connections.</p>
</body>
</html>
dest: "/tmp/{{ document_root }}/index.html"
mode: "0644"
让我们理解一下这个 playbook 的作用:
hosts: webservers- 指定此 playbook 应该在 inventory 中的 "webservers" 组的所有主机上运行。vars_files: - vars/webserver.yml- 从我们的vars_file导入变量。- 第一个任务使用
debug模块显示一条消息,显示变量。 - 第二个任务创建一个目录结构,该结构将用于 Web 服务器的 document root。
- 第三个任务创建一个示例 HTML 文件,其中包含来自我们的
vars_file的变量。
运行 Playbook
现在,让我们运行 playbook 看看它的实际效果:
cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini webserver_setup.yml
你应该看到类似这样的输出:
PLAY [Configure Web Server] ****************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Display web server configuration] ****************************************
ok: [localhost] => {
"msg": "Web server will be configured with: Port=80, ServerName=example.com, DocumentRoot=/var/www/html"
}
TASK [Create a directory for document root] ************************************
changed: [localhost]
TASK [Create a sample index.html file] *****************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
验证结果
让我们验证一下我们的 playbook 是否创建了预期的文件:
ls -la /tmp/var/www/html/
cat /tmp/var/www/html/index.html
你应该看到目录结构和 index.html 文件的内容,其中应该包含来自我们的 vars_file 的值:
<html>
<head>
<title>Welcome to example.com</title>
</head>
<body>
<h1>Welcome to example.com</h1>
<p>This server is configured to handle 200 simultaneous connections.</p>
</body>
</html>
理解工作流程
让我们回顾一下我们已经完成的工作:
- 我们将配置数据存储在一个单独的
vars_file(vars/webserver.yml) 中。 - 我们创建了一个 playbook,它导入并使用了这些配置数据。
- 我们运行了 playbook 来执行使用变量的任务。
这种将配置数据(vars_files)与自动化逻辑(playbooks)分离的做法使我们的 Ansible 代码更具可维护性和可重用性。我们现在可以通过仅编辑 vars_file 来更新配置,而无需更改 playbook 本身。
使用多个 vars_files
现在我们了解了 vars_files 的基础知识,让我们探讨如何使用多个 vars_files 来管理不同的环境。这在现实世界中很常见,你可能需要为开发、预发布和生产环境使用不同的配置。
创建特定于环境的 vars_files
让我们为不同的环境创建 vars_files。首先,让我们创建一个开发环境配置:
在 ~/project/ansible-vars-demo/vars/dev_environment.yml 处创建一个新文件,内容如下:
---
## Development Environment Configuration
environment_name: development
debug_mode: true
log_level: debug
backup_frequency: weekly
max_memory: 512MB
接下来,让我们创建一个生产环境配置:
在 ~/project/ansible-vars-demo/vars/prod_environment.yml 处创建一个新文件,内容如下:
---
## Production Environment Configuration
environment_name: production
debug_mode: false
log_level: error
backup_frequency: daily
max_memory: 2048MB
创建一个包含多个 vars_files 的 Playbook
现在,让我们创建一个 playbook,它同时使用我们的 Web 服务器配置和特定于环境的配置。在 ~/project/ansible-vars-demo/environment_setup.yml 处创建一个新文件,内容如下:
---
- name: Configure Environment
hosts: webservers
vars:
env: dev
vars_files:
- vars/webserver.yml
- "vars/{{ env }}_environment.yml"
tasks:
- name: Display environment details
debug:
msg: >
Setting up {{ environment_name }} environment with the following parameters:
- Web Server: {{ server_name }} on port {{ http_port }}
- Debug Mode: {{ debug_mode }}
- Log Level: {{ log_level }}
- Backup Frequency: {{ backup_frequency }}
- Max Memory: {{ max_memory }}
- Max Clients: {{ max_clients }}
- name: Create environment config file
copy:
content: |
## Environment Configuration for {{ server_name }}
ENVIRONMENT={{ environment_name }}
DEBUG={{ debug_mode }}
LOG_LEVEL={{ log_level }}
BACKUP_FREQUENCY={{ backup_frequency }}
MAX_MEMORY={{ max_memory }}
HTTP_PORT={{ http_port }}
MAX_CLIENTS={{ max_clients }}
dest: "/tmp/{{ environment_name }}_config.env"
mode: "0644"
这个 playbook 引入了几个新概念:
- 我们在 playbook 本身中设置了一个变量
env: dev。 - 我们同时包含了我们的 webserver
vars_file和一个特定于环境的vars_file。 - 环境
vars_file路径包含一个变量:"vars/{{ env }}_environment.yml",它评估为vars/dev_environment.yml。 - 任务使用来自两个
vars_files的变量。
使用不同环境运行 Playbook
让我们首先使用开发环境运行 playbook(这已经是默认设置):
cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini environment_setup.yml
你应该看到包含开发环境设置的输出:
TASK [Display environment details] ********************************************
ok: [localhost] => {
"msg": "Setting up development environment with the following parameters:\n- Web Server: example.com on port 80\n- Debug Mode: True\n- Log Level: debug\n- Backup Frequency: weekly\n- Max Memory: 512MB\n- Max Clients: 200"
}
现在,让我们运行同一个 playbook,但覆盖 env 变量以使用生产环境:
ansible-playbook -i inventory.ini environment_setup.yml -e "env=prod"
你应该看到包含生产环境设置的输出:
TASK [Display environment details] ********************************************
ok: [localhost] => {
"msg": "Setting up production environment with the following parameters:\n- Web Server: example.com on port 80\n- Debug Mode: False\n- Log Level: error\n- Backup Frequency: daily\n- Max Memory: 2048MB\n- Max Clients: 200"
}
验证配置文件
让我们验证一下我们的 playbook 是否创建了环境配置文件:
cat /tmp/development_config.env
cat /tmp/production_config.env
你应该看到两个不同的配置文件,每个文件都包含来自相应环境 vars_file 的设置。
理解变量优先级
重要的是要理解,在使用多个 vars_files 时,Ansible 会遵循特定的变量优先级顺序。如果相同的变量名称出现在多个位置,则稍后定义的值将覆盖较早的定义。
在我们的示例中,如果我们在 webserver.yml 和 dev_environment.yml 文件中都定义了 http_port,则来自 dev_environment.yml 的值将优先,因为它在 vars_files 列表中包含在后面。
这种行为允许你定义一个文件中的通用默认值,然后为不同的环境覆盖特定的值。
高级 vars_files 技术
在最后一步中,我们将探讨一些使用 Ansible 的 vars_files 的高级技术,包括分层组织变量和实现基于角色的变量组织。
分层组织变量
在复杂的项目中,分层组织变量通常很有帮助。让我们创建一个结构,其中包含:
- 适用于所有环境的通用变量
- 特定于环境的变量
- 特定于应用程序的变量
首先,让我们创建一个通用变量文件:
在 ~/project/ansible-vars-demo/vars/common.yml 处创建一个新文件,内容如下:
---
## Common variables for all environments
organization: "Example Corp"
admin_email: "admin@example.com"
timezone: "UTC"
接下来,让我们创建特定于应用程序的变量:
在 ~/project/ansible-vars-demo/vars/database.yml 处创建一个新文件,内容如下:
---
## Database application variables
db_port: 3306
db_user: "dbuser"
db_name: "appdb"
db_max_connections: 100
创建一个分层 Playbook
现在,让我们创建一个 playbook,它演示了如何使用这些分层变量。在 ~/project/ansible-vars-demo/hierarchical_setup.yml 处创建一个新文件,内容如下:
---
- name: Hierarchical Variable Demo
hosts: webservers
vars:
env: dev
app: database
vars_files:
- "vars/common.yml"
- "vars/{{ env }}_environment.yml"
- "vars/{{ app }}.yml"
tasks:
- name: Display hierarchical configuration
debug:
msg: >
Configuration for {{ app }} in {{ environment_name }} environment:
- Organization: {{ organization }}
- Admin Email: {{ admin_email }}
- Timezone: {{ timezone }}
- Debug Mode: {{ debug_mode }}
- Log Level: {{ log_level }}
- DB Port: {{ db_port }}
- DB User: {{ db_user }}
- DB Max Connections: {{ db_max_connections }}
- name: Create hierarchical config file
copy:
content: |
## {{ organization }} Configuration
## {{ environment_name }} Environment
## Common Settings
ADMIN_EMAIL={{ admin_email }}
TIMEZONE={{ timezone }}
## Environment Settings
DEBUG={{ debug_mode }}
LOG_LEVEL={{ log_level }}
BACKUP_FREQUENCY={{ backup_frequency }}
## {{ app | capitalize }} Settings
DB_PORT={{ db_port }}
DB_USER={{ db_user }}
DB_NAME={{ db_name }}
DB_MAX_CONNECTIONS={{ db_max_connections }}
dest: "/tmp/{{ environment_name }}_{{ app }}_config.conf"
mode: "0644"
理解组和主机变量
除了 vars_files 之外,Ansible 还支持将变量存储在名为 group_vars 和 host_vars 的特殊目录中。让我们看看它们是如何工作的:
为组和主机变量创建目录结构:
mkdir -p ~/project/ansible-vars-demo/group_vars
mkdir -p ~/project/ansible-vars-demo/host_vars
现在,为 'webservers' 组创建一个组变量文件:
在 ~/project/ansible-vars-demo/group_vars/webservers.yml 处创建一个新文件,内容如下:
---
## Variables for all webservers
firewall_enabled: true
ssh_port: 22
monitoring_enabled: true
并为 'localhost' 创建一个主机变量文件:
在 ~/project/ansible-vars-demo/host_vars/localhost.yml 处创建一个新文件,内容如下:
---
## Variables specific to localhost
local_backup_path: "/tmp/backups"
is_development_machine: true
创建一个包含所有变量类型的 Playbook
让我们创建一个最终的 playbook,它演示了如何将所有变量类型一起使用。在 ~/project/ansible-vars-demo/complete_setup.yml 处创建一个新文件,内容如下:
---
- name: Complete Variable Demo
hosts: webservers
vars:
env: prod
app: database
vars_files:
- "vars/common.yml"
- "vars/{{ env }}_environment.yml"
- "vars/{{ app }}.yml"
tasks:
- name: Display complete configuration
debug:
msg: >
Complete configuration for {{ inventory_hostname }}:
- Organization: {{ organization }}
- Environment: {{ environment_name }}
- Debug Mode: {{ debug_mode }}
- Firewall Enabled: {{ firewall_enabled }}
- SSH Port: {{ ssh_port }}
- Monitoring Enabled: {{ monitoring_enabled }}
- Local Backup Path: {{ local_backup_path }}
- Is Development Machine: {{ is_development_machine }}
- name: Create complete config file
copy:
content: |
## {{ organization }} - {{ environment_name }} Environment
## Host: {{ inventory_hostname }}
## Common Settings
ADMIN_EMAIL={{ admin_email }}
TIMEZONE={{ timezone }}
## Environment Settings
DEBUG={{ debug_mode }}
LOG_LEVEL={{ log_level }}
## Server Settings
FIREWALL_ENABLED={{ firewall_enabled }}
SSH_PORT={{ ssh_port }}
MONITORING_ENABLED={{ monitoring_enabled }}
## Host-specific Settings
LOCAL_BACKUP_PATH={{ local_backup_path }}
IS_DEVELOPMENT_MACHINE={{ is_development_machine }}
## {{ app | capitalize }} Settings
DB_PORT={{ db_port }}
DB_USER={{ db_user }}
DB_NAME={{ db_name }}
dest: "/tmp/complete_config.conf"
mode: "0644"
运行高级 Playbooks
让我们运行我们的分层 playbook:
cd ~/project/ansible-vars-demo
ansible-playbook -i inventory.ini hierarchical_setup.yml
你应该看到包含来自所有三个 vars_files 的变量的输出。
现在,让我们运行我们的完整 playbook:
ansible-playbook -i inventory.ini complete_setup.yml
这次,你应该看到包含来自 vars_files、group_vars 和 host_vars 的变量的输出。
验证配置文件
让我们检查一下我们的高级 playbook 创建的配置文件:
cat /tmp/dev_database_config.conf
cat /tmp/complete_config.conf
理解 Ansible 中的变量优先级
在使用多个变量源时,Ansible 遵循特定的优先级顺序:
- 命令行变量(
-e或--extra-vars) - 在 play 中定义的变量
- 来自包含的文件和角色的变量
- 主机事实
- 主机变量
- 组变量
- Inventory 变量
- 角色默认变量
这意味着在 host_vars 中定义的变量将覆盖在 group_vars 中定义的相同变量,而 group_vars 中的变量将覆盖在 vars_files 中定义的相同变量。
这种分层结构为你提供了一种强大的方式来管理跨不同环境、主机和应用程序的配置。
总结
在本教程中,你已经学习了如何有效地使用 Ansible vars_files 进行配置管理。你已经:
- 安装了 Ansible,并创建了你的第一个
vars_file来存储配置数据 - 创建并运行了一个基本的 playbook,它使用
vars_files将配置与自动化逻辑分离 - 使用了多个
vars_files来管理不同的环境 - 探索了高级技术,包括分层变量组织以及使用
group_vars和host_vars
这些技能为构建可扩展且可维护的 Ansible 自动化奠定了坚实的基础。通过将你的配置数据与你的自动化逻辑分离,你可以:
- 使你的 playbooks 在不同的环境中更具可重用性
- 简化更新配置值的过程
- 以结构化的方式管理复杂的配置
- 通过清晰地组织配置数据来改善协作
在继续使用 Ansible 时,请记住,有效的变量管理是构建可维护的自动化的关键。你在本教程中学习的技术将帮助你组织你的 Ansible 项目,随着它们复杂性的增长。


