跳转至

清单文件

1. Inventory 简介

1. 什么是 inventory?

  1. Ansible 的 Inventory(清单)是 Ansible 用来描述和组织需要管理的主机列表的文件或系统。清单中不仅可以定义哪些主机参与自动化管理,还可以设定主机分组、变量等。详细了解 Ansible Inventory 的各个要点能帮助你更有效地管理和执行自动化任务。

  2. Ansible 中,inventory 地址清单文件用于定义管理的主机和主机组。它是 Ansible 操作的基础,包含了所有目标主机的信息。通常,inventory 文件位于 /etc/ansible/hosts,但您也可以在任何地方定义并在运行 Ansible 命令时指定不同的地址清单文件。可以是一个简单的 INI 风格文件,也可以是复杂的 YAML 文件,甚至可以是通过动态处理生成的 JSON 文件

Note

/etc/ansible/hosts 文件格式

  • inventory文件遵循INI文件风格,中括号中的字符为组名

  • 可以将同一个主机同时归并到多个不同的组中

  • 目标主机使用了非默认的SSH端口,可在主机名称后使用冒号加端口号来标明

Inventory 清单

Inventory 主机清单是 Ansible 的主机清单文件,其中包含了目标主机的 IP 地址、用户名、密码等信息。可以使用脚本或者手工方式来维护这个文件。

  • ansible 的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在 inventory 中将其分组命名

  • 默认的 inventory 为/etc/ansible/hosts

  • inventory 可以有多个,且也可以通过 Dynamic Inventory 来动态生成

  • 可以在每个主机后面指定用户名+密码+端口:

    • ansible_ssh_port: 指定 ssh 端口
    • ansible_ssh_user:指定 ssh 用户
    • ansible_ssh_pass: 指定 ssh 用户登录是认证密码(明文密码不安全)
    • ansible_sudo_pass: 指明 sudo 时候的密码

2. 静态 Inventory

静态 Inventory 是一个静态文件,其中列出了所有的主机及其相关的配置信息。常见格式有 INI 和 YAML 格式。

# 文件名:hosts

# 单个主机
webserver ansible_host=192.168.1.10 ansible_user=root  ansible_pass='1' ansible_port='22'

# 定义一个分组的主机 
[webservers]                 # 组内包含多个主机。
web1 ansible_host=192.168.1.11 ansible_user=root
web2 ansible_host=192.168.1.12 ansible_user=root

[dbservers]                  # 组内包含多个主机。
db1 ansible_host=192.168.1.21 ansible_user=root
db2 ansible_host=192.168.1.22 ansible_user=root

# 组中的子组 
[staging:children]           # 定义了 staging 组,其中包含 webservers 和 dbservers 子组。
webservers
dbservers

# 附加组级变量
[webservers:vars]           # 为组内所有主机指定了 SSH 私钥文件。
ansible_ssh_private_key_file=/path/to/keyfile
# 文件名:hosts.yaml

all:
  hosts:
    webserver:
      ansible_host: 192.168.1.10
      ansible_user: root
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.168.1.11
          ansible_user: root
        web2:
          ansible_host: 192.168.1.12
          ansible_user: root
      vars:
        ansible_ssh_private_key_file: /path/to/keyfile
    dbservers:
      hosts:
        db1:
          ansible_host: 192.168.1.21
          ansible_user: root
        db2:
          ansible_host: 192.168.1.22
          ansible_user: root
    staging:
      children:
        webservers:
        dbservers:

使用地址清单文件

  1. 指定地址清单文件: 您可以在运行 Ansible 命令时指定使用哪个地址清单文件。
    ansible-playbook -i /path/to/your/inventory playbook.yml
    
  2. 动态地址清单: 除了静态的文件,Ansible 也支持动态地址清单。动态地址清单通过脚本从外部资源(如云提供商的 API)获取主机信息。要启用动态地址清单,只需在 Ansible 命令中指定该脚本即可。
    ansible-playbook -i /path/to/your/dynamic_inventory.py playbook.yml
    

3. 动态 Inventory

1. 什么是动态 Inventory?

  1. 动态 Inventory 是通过脚本或插件来生成和更新的主机列表。对于有大量变动主机的环境,使用动态 Inventory 更为方便。Ansible 提供了多种动态 Inventory 插件(如 AWS、GCP、Azure 等),也可以编写自定义动态 Inventory 脚本。
  2. 动态 Inventory 允许您在运行时从外部系统或服务中获取主机信息。这意味着您可以根据当前环境自动获取和更新主机列表,而不需要手动修改 static Inventory 文件。

常见的动态 Inventory 数据源包括:

  1. 云服务提供商:如 AWS、GCP、Azure
  2. 容器编排系统:如 Kubernetes
  3. 定制的配置管理数据库(CMDB)系统

使用动态 Inventory,您可以更高效地管理和操作大规模、快速变化的环境,减轻了手动更新静态 Inventory 文件的负担。

2. 如何实现动态 Inventory?

实现动态 Inventory 通常涉及三个步骤:

  1. 编写或获取动态 Inventory 脚本: 这个脚本从数据源获取主机信息并输出为 JSON 格式。Ansible 提供了很多现成的动态 Inventory 脚本,也可以自己编写。
  2. 配置 Ansible 使用动态 Inventory 脚本: 修改 Ansible 配置,让它使用动态 Inventory 脚本。
  3. 运行 Ansible 命令: 使用动态 Inventory 脚本运行 Ansible 命令。

Inventory 相关使用

1. 使用动态 Inventory
#!/usr/bin/env python

import json

inventory = {
    "webservers": {
        "hosts": ["web1.example.com", "web2.example.com"],
        "vars": {
            "ansible_user": "webuser"
        }
    },
    "dbservers": {
        "hosts": ["db1.example.com", "db2.example.com"],
        "vars": {
            "ansible_user": "dbuser"
        }
    },
    "_meta": {
        "hostvars": {
            "web1.example.com": {"ansible_host": "192.168.1.10"},
            "web2.example.com": {"ansible_host": "192.168.1.11"},
            "db1.example.com": {"ansible_host": "192.168.1.12"},
            "db2.example.com": {"ansible_host": "192.168.1.13"},
        }
    }
}

print(json.dumps(inventory, indent=2))
  1. 然后,在 Ansible 配置文件 ansible.cfg 中指定这个动态 Inventory 脚本:
# 文件名:ansible.cfg

[defaults]
inventory = ./动态_inventory.py

4. Ansible Inventory 变量

Ansible 允许在 Inventory 文件中定义变量,可以是主机变量、组变量、甚至是嵌套的组变量。

定义变量

一. 主机变量: 定义某个主机的变量

ini
# INI 格式
host1.example.com ansible_user=someuser ansible_port=2222
YAML
# YAML 格式
all:
hosts:
    host1.example.com:
    ansible_user: someuser
    ansible_port: 2222

二. 组变量: 定义某个组所有主机定义的变量

可以通过在组名后的 :vars 段落中定义
# INI 格式

[webservers:vars]
ansible_user=webuser
ansible_port=2222
# YAML 格式

all:
children:
    webservers:
    vars:
        ansible_user: webuser
        ansible_port: 2222

三. 子组和父组的变量继承

  • all:包含清单中所有的主机
  • ungrouped:未属于任何组的主机
  • group_name:children:子组定义,用于更复杂的组结构
使用 children 定义子组和父组。父组的变量可以继承到子组中
# INI 格式

[all:vars]
ansible_user=commonuser

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com

# 定义一个 webgroup,包含 webs 和 dbs 两个子组
[webgroup:children]
webservers
dbservers
# YAML 格式

all:
vars:
    ansible_user: commonuser
children:
    webservers:
    hosts:
        web1.example.com:
        web2.example.com:
    dbservers:
    hosts:
        db1.example.com:
        db2.example.com:
    webgroup:
    children:
        webservers:
        dbservers:

怎么使用变量

一. 定义变量

inventory.ini
# INI 格式
# Web服务器组
[webservers]
web1 ansible_host=192.168.1.101 ansible_user=root
web2 ansible_host=192.168.1.102 ansible_user=root

# DB服务器组
[dbservers]
db1 ansible_host=192.168.1.201 ansible_user=root
db2 ansible_host=192.168.1.202 ansible_user=root

# 定义组变量
[webservers:vars]
ansible_python_interpreter=/usr/bin/python3

[dbservers:vars]
ansible_python_interpreter=/usr/bin/python3
inventory.yml
all:
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.168.1.101
          ansible_user: root
        web2:
          ansible_host: 192.168.1.102
          ansible_user: root
      vars:
        ansible_python_interpreter: /usr/bin/python3
    dbservers:
      hosts:
        db1:
          ansible_host: 192.168.1.201
          ansible_user: root
        db2:
          ansible_host: 192.168.1.202
          ansible_user: root
      vars:
        ansible_python_interpreter: /usr/bin/python3

二. 在 Playbooks 中使用变量 假设我们有一个简单的 playbook.yaml,需要在远程主机上执行一些任务并使用这些变量。

playbook.yaml
---
- name: Configure web and db servers
  hosts: all
  tasks:
    - name: Ensure we are using the correct Python interpreter
      command: "{{ ansible_python_interpreter }} --version"
      register: python_version_output

    - name: Display Python version
      debug:
        msg: "Python version on {{ inventory_hostname }} is {{ python_version_output.stdout }}"

    - name: Ensure Apache is installed
      yum: 
        name: httpd
        state: present
      when: "'webservers' in group_names"

    - name: Ensure MySQL is installed
      yum: 
        name: mysql-server
        state: present
      when: "'dbservers' in group_names"

三、变量的优先级 在 Ansible 中,变量的优先级从低到高依次是:

  1. Inventory 文件(inventory.ini 或 inventory.yml)。
  2. 分组变量文件(group_vars)。
  3. 主机变量文件(host_vars)。
  4. 播放变量(使用 vars 块定义)。
  5. 针对特定任务的变量(使用 vars 块定义在任务内部)。

四、定义分组变量文件

group_vars/webservers.yml
---
# Web服务器变量
ansible_python_interpreter: /usr/bin/python3
httpd_port: 80
group_vars/dbservers.yml
---
# 数据库服务器变量
ansible_python_interpreter: /usr/bin/python3
mysql_port: 3306

五、定义主机变量文件

host_vars/web1.yml
---
ansible_host: 192.168.1.101
httpd_site_name: web1.example.com
host_vars/web2.yml
---
ansible_host: 192.168.1.102
httpd_site_name: web2.example.com

六、在 Playbooks 中使用更多自定义变量

增强版的 playbook.yml
---
- name: Configure web and db servers
  hosts: all
  vars_files:
    - group_vars/webservers.yml
    - group_vars/dbservers.yml
  tasks:
    - name: Ensure we are using the correct Python interpreter
      command: "{{ ansible_python_interpreter }} --version"
      register: python_version_output

    - name: Display Python version
      debug:
        msg: "Python version on {{ inventory_hostname }} is {{ python_version_output.stdout }}"

    - name: Ensure Apache is installed and configured
      when: "'webservers' in group_names"
      block:
        - name: Ensure Apache is installed
          yum: 
            name: httpd
            state: present

        - name: Ensure Apache is started
          service:
            name: httpd
            state: started

        - name: Ensure Apache listens on the correct port
          lineinfile:
            path: /etc/httpd/conf/httpd.conf
            regexp: '^Listen '
            line: "Listen {{ httpd_port }}"

        - name: Ensure Apache site name is configured
          lineinfile:
            path: /etc/httpd/conf/httpd.conf
            regexp: '^ServerName '
            line: "ServerName {{ httpd_site_name }}"

    - name: Ensure MySQL is installed and configured
      when: "'dbservers' in group_names"
      block:
        - name: Ensure MySQL is installed
          yum: 
            name: mysql-server
            state: present

        - name: Ensure MySQL is started
          service:
            name: mysqld
            state: started

        - name: Ensure MySQL listens on the correct port
          lineinfile:
            path: /etc/my.cnf
            regexp: '^port '
            line: "port={{ mysql_port }}"