Ansible 清单管理 #

什么是 Inventory? #

Inventory(清单)是 Ansible 管理主机的列表,定义了 Ansible 要管理哪些主机以及如何连接这些主机。

text
┌─────────────────────────────────────────────────────────────┐
│                      Inventory                               │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  主机列表        主机组         连接变量        其他变量      │
│  ──────────     ──────────     ──────────     ──────────    │
│  IP 地址        webservers     ansible_user   自定义变量     │
│  域名           databases      ansible_port   环境变量       │
│  别名           production     ansible_host   应用配置       │
│                                                              │
└─────────────────────────────────────────────────────────────┘

静态清单 #

INI 格式 #

ini
# inventory/hosts

# 直接指定主机(IP 或域名)
192.168.1.100
192.168.1.101
server1.example.com

# 主机别名
web1 ansible_host=192.168.1.100
web2 ansible_host=192.168.1.101

# 定义主机组
[webservers]
web1
web2
192.168.1.102

[databases]
db1 ansible_host=192.168.1.200
db2 ansible_host=192.168.1.201

# 嵌套组(组包含其他组)
[production:children]
webservers
databases

[staging:children]
staging_web
staging_db

# 组变量
[webservers:vars]
ansible_user=admin
ansible_port=22
nginx_port=80

[databases:vars]
ansible_user=dbadmin
mysql_port=3306

# 全局变量
[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_ssh_private_key_file=~/.ssh/id_ed25519

YAML 格式 #

yaml
# inventory/hosts.yml
all:
  hosts:
    192.168.1.100:
    192.168.1.101:
  
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.168.1.100
          ansible_user: admin
        web2:
          ansible_host: 192.168.1.101
          ansible_user: admin
        192.168.1.102:
      vars:
        nginx_port: 80
    
    databases:
      hosts:
        db1:
          ansible_host: 192.168.1.200
        db2:
          ansible_host: 192.168.1.201
      vars:
        ansible_user: dbadmin
        mysql_port: 3306
    
    production:
      children:
        webservers:
        databases:
    
    staging:
      children:
        staging_web:
          hosts:
            staging-web1:
              ansible_host: 192.168.2.100
        staging_db:
          hosts:
            staging-db1:
              ansible_host: 192.168.2.200

  vars:
    ansible_python_interpreter: /usr/bin/python3
    ansible_ssh_private_key_file: ~/.ssh/id_ed25519

主机定义 #

基本主机定义 #

ini
# 使用 IP 地址
192.168.1.100

# 使用域名
server1.example.com

# 使用别名(推荐)
web1 ansible_host=192.168.1.100
db1 ansible_host=db1.example.com

连接参数 #

ini
# 完整的连接参数
web1 ansible_host=192.168.1.100 \
     ansible_user=admin \
     ansible_port=2222 \
     ansible_ssh_private_key_file=~/.ssh/web_key \
     ansible_python_interpreter=/usr/bin/python3

# 常用连接参数说明
# ansible_host          - 目标主机地址
# ansible_port          - SSH 端口
# ansible_user          - SSH 用户
# ansible_password      - SSH 密码(不推荐明文)
# ansible_ssh_private_key_file - SSH 私钥路径
# ansible_python_interpreter - Python 解释器路径
# ansible_connection    - 连接类型(ssh, winrm, local)
# ansible_become        - 是否提权
# ansible_become_method - 提权方式(sudo, su)
# ansible_become_user   - 提权用户
# ansible_become_password - 提权密码

主机范围 #

ini
# 数字范围
[webservers]
web[01:10].example.com

# 等同于
# web01.example.com
# web02.example.com
# ...
# web10.example.com

# 字母范围
[databases]
db-[a:f].example.com

# 等同于
# db-a.example.com
# db-b.example.com
# ...
# db-f.example.com

主机组 #

基本分组 #

ini
# 定义多个组
[webservers]
web1
web2

[databases]
db1
db2

[cache]
cache1
cache2

[loadbalancers]
lb1
lb2

嵌套组 #

ini
# 组包含其他组
[web:children]
webservers
loadbalancers

[data:children]
databases
cache

# 多层嵌套
[production:children]
web
data

[staging:children]
staging_web
staging_data

组的用途 #

text
┌─────────────────────────────────────────────────────────────┐
│                      主机组用途示例                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  按功能分组          按环境分组        按位置分组            │
│  ──────────         ──────────        ──────────           │
│  [webservers]       [production]      [beijing]            │
│  [databases]        [staging]         [shanghai]           │
│  [caches]           [development]     [guangzhou]          │
│                                                              │
│  按系统分组          按应用分组        按角色分组            │
│  ──────────         ──────────        ──────────           │
│  [ubuntu]           [nginx]           [frontend]           │
│  [centos]           [mysql]           [backend]            │
│  [windows]          [redis]           [monitoring]         │
│                                                              │
└─────────────────────────────────────────────────────────────┘

变量管理 #

内联变量 #

ini
# 主机变量
web1 ansible_host=192.168.1.100 nginx_port=80 app_name=myapp

# 组变量
[webservers:vars]
nginx_port=80
document_root=/var/www/html

目录结构管理变量 #

text
inventory/
├── hosts                    # 主机清单
├── group_vars/              # 组变量目录
│   ├── all.yml              # 所有主机的变量
│   ├── webservers.yml       # webservers 组的变量
│   ├── databases.yml        # databases 组的变量
│   └── production/          # 组目录
│       └── vars.yml
└── host_vars/               # 主机变量目录
    ├── web1.yml             # web1 主机的变量
    ├── web2.yml             # web2 主机的变量
    └── db1.yml              # db1 主机的变量

group_vars 示例 #

yaml
# inventory/group_vars/all.yml
---
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: ~/.ssh/id_ed25519
ntp_servers:
  - 0.pool.ntp.org
  - 1.pool.ntp.org

# inventory/group_vars/webservers.yml
---
nginx_port: 80
nginx_worker_processes: auto
document_root: /var/www/html
php_version: "8.1"

# inventory/group_vars/databases.yml
---
mysql_port: 3306
mysql_root_password: "{{ vault_mysql_root_password }}"
mysql_databases:
  - name: app_production
    encoding: utf8mb4
  - name: app_staging
    encoding: utf8mb4

host_vars 示例 #

yaml
# inventory/host_vars/web1.yml
---
ansible_host: 192.168.1.100
ansible_user: admin
nginx_server_name: web1.example.com
ssl_enabled: true

# inventory/host_vars/db1.yml
---
ansible_host: 192.168.1.200
ansible_user: dbadmin
mysql_innodb_buffer_pool_size: 4G
mysql_max_connections: 500

动态清单 #

什么是动态清单? #

动态清单是通过脚本或插件从外部系统(如云平台、CMDB)动态获取主机列表。

text
┌─────────────────────────────────────────────────────────────┐
│                      动态清单来源                            │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  云平台              配置管理          其他系统              │
│  ──────────         ──────────        ──────────           │
│  AWS EC2            Ansible Tower     自定义 API            │
│  Azure VMs          Foreman           数据库                │
│  GCP Compute        Spacewalk         LDAP/AD               │
│  Alibaba Cloud      Cobbler           Consul                │
│                                                              │
└─────────────────────────────────────────────────────────────┘

动态清单脚本格式 #

python
#!/usr/bin/env python3
# my_inventory.py

import json

inventory = {
    "webservers": {
        "hosts": ["web1", "web2"],
        "vars": {
            "ansible_user": "admin"
        }
    },
    "databases": {
        "hosts": ["db1", "db2"]
    },
    "_meta": {
        "hostvars": {
            "web1": {
                "ansible_host": "192.168.1.100"
            },
            "web2": {
                "ansible_host": "192.168.1.101"
            },
            "db1": {
                "ansible_host": "192.168.1.200"
            },
            "db2": {
                "ansible_host": "192.168.1.201"
            }
        }
    }
}

print(json.dumps(inventory))

使用动态清单 #

bash
# 使用动态清单脚本
ansible all -i my_inventory.py -m ping

# 查看清单内容
ansible-inventory -i my_inventory.py --list

# 查看主机列表
ansible-inventory -i my_inventory.py --graph

AWS EC2 动态清单 #

bash
# 安装 AWS 集合
ansible-galaxy collection install amazon.aws

# 配置 AWS 凭证
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_REGION=us-east-1

# 使用 AWS 动态清单插件
# ansible.cfg
[inventory]
enable_plugins = aws_ec2

# inventory/aws_ec2.yml
plugin: aws_ec2
regions:
  - us-east-1
  - us-west-2
filters:
  tag:Environment: production
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: tags.Application
    prefix: app
  - key: instance_type
    prefix: type
compose:
  ansible_host: private_ip_address

Azure 动态清单 #

yaml
# inventory/azure_rm.yml
plugin: azure_rm
auth_source: auto
subscription_id: your-subscription-id
include_vm_resource_groups:
  - production-rg
  - staging-rg
conditional_groups:
  webservers: "'web' in tags.role"
  databases: "'database' in tags.role"
keyed_groups:
  - prefix: tag
    key: tags

清单命令 #

ansible-inventory 命令 #

bash
# 查看清单内容(JSON 格式)
ansible-inventory -i inventory/hosts --list

# 查看清单结构(图形格式)
ansible-inventory -i inventory/hosts --graph

# 查看特定主机变量
ansible-inventory -i inventory/hosts --host web1

# 输出到文件
ansible-inventory -i inventory/hosts --list --output inventory.json

# 验证清单
ansible-inventory -i inventory/hosts --verify

图形输出示例 #

bash
ansible-inventory -i inventory/hosts --graph

# 输出示例:
# @all:
#   |--@databases:
#   |  |--db1
#   |  |--db2
#   |--@production:
#   |  |--@databases:
#   |  |  |--db1
#   |  |  |--db2
#   |  |--@webservers:
#   |  |  |--web1
#   |  |  |--web2
#   |--@ungrouped:
#   |--@webservers:
#   |  |--web1
#   |  |--web2

验证主机连接 #

bash
# 列出所有主机
ansible all --list-hosts -i inventory/hosts

# 列出特定组的主机
ansible webservers --list-hosts -i inventory/hosts

# 测试连接
ansible all -m ping -i inventory/hosts

# 测试特定组
ansible webservers -m ping -i inventory/hosts

清单模式 #

选择主机 #

bash
# 所有主机
ansible all -m ping

# 特定组
ansible webservers -m ping

# 多个组
ansible webservers:databases -m ping

# 排除组
ansible all:!databases -m ping

# 组交集
ansible 'webservers:&production' -m ping

# 通配符
ansible 'web*' -m ping

# 正则表达式
ansible '~web[0-9]+' -m ping

# 特定主机
ansible web1 -m ping

# 多个主机
ansible web1,web2 -m ping

# 使用序号
ansible webservers[0] -m ping
ansible webservers[0:2] -m ping

模式运算符 #

运算符 说明 示例
: 或(并集) webservers:databases
:! 排除 all:!databases
:& 交集 webservers:&production
* 通配符 web*
~ 正则表达式 ~web[0-9]+

复杂模式示例 #

bash
# 生产环境的 Web 服务器
ansible 'webservers:&production' -m ping

# 非数据库服务器
ansible 'all:!databases' -m ping

# 生产环境的 Web 服务器,排除特定主机
ansible 'webservers:&production:!web1' -m ping

# 所有以 web 开头的主机
ansible 'web*' -m ping

# 匹配 web 后跟数字的主机
ansible '~web[0-9]+' -m ping

多环境清单 #

目录结构方式 #

text
inventory/
├── production/
│   ├── hosts
│   ├── group_vars/
│   │   ├── all.yml
│   │   └── webservers.yml
│   └── host_vars/
│       └── web1.yml
├── staging/
│   ├── hosts
│   ├── group_vars/
│   │   └── all.yml
│   └── host_vars/
│       └── web1.yml
└── development/
    ├── hosts
    └── group_vars/
        └── all.yml

使用方式 #

bash
# 生产环境
ansible-playbook -i inventory/production site.yml

# 预发环境
ansible-playbook -i inventory/staging site.yml

# 开发环境
ansible-playbook -i inventory/development site.yml

单文件多环境 #

ini
# inventory/hosts

[production_web]
prod-web1 ansible_host=192.168.1.100
prod-web2 ansible_host=192.168.1.101

[production_db]
prod-db1 ansible_host=192.168.1.200

[production:children]
production_web
production_db

[staging_web]
stage-web1 ansible_host=192.168.2.100

[staging_db]
stage-db1 ansible_host=192.168.2.200

[staging:children]
staging_web
staging_db

清单最佳实践 #

1. 使用有意义的命名 #

ini
# 好的命名
[webservers]
web-prod-01 ansible_host=192.168.1.100
web-prod-02 ansible_host=192.168.1.101

[databases]
db-prod-master ansible_host=192.168.1.200
db-prod-slave ansible_host=192.168.1.201

# 不好的命名
[servers]
server1
server2

2. 分离变量 #

text
# 推荐结构
inventory/
├── hosts
├── group_vars/
│   ├── all.yml
│   ├── webservers.yml
│   └── databases.yml
└── host_vars/
    ├── web1.yml
    └── db1.yml

3. 使用组继承 #

ini
# 基础组
[ubuntu]
web1
web2

[centos]
db1
db2

# 功能组
[webservers]
web1
web2

[databases]
db1
db2

# 环境组
[production:children]
webservers
databases

4. 敏感变量使用 Vault #

yaml
# inventory/group_vars/databases.yml
mysql_root_password: "{{ vault_mysql_root_password }}"
mysql_replication_password: "{{ vault_mysql_replication_password }}"

5. 文档化清单 #

ini
# inventory/hosts
#
# 生产环境清单
# 维护者: DevOps Team
# 更新日期: 2024-01-15
#
# 主机组说明:
# - webservers: Web 服务器集群
# - databases: 数据库服务器
# - cache: 缓存服务器
# - monitoring: 监控服务器

[webservers]
# Nginx 负载均衡 + PHP-FPM
web1 ansible_host=192.168.1.100
web2 ansible_host=192.168.1.101

下一步 #

现在你已经掌握了 Inventory 清单管理,接下来学习 Ad-hoc 命令 了解如何快速执行临时任务!

最后更新:2026-03-29