如何构建您的清单

Ansible 通过使用称为“清单”(inventory)的列表或列表组,来自动化基础设施中受管节点或“主机”上的任务。Ansible 从一个或多个“清单源”中组成其清单。虽然其中一个源可以是您在命令行中传递的主机名列表,但大多数 Ansible 用户会创建清单文件。您的清单定义了您要自动化的受管节点以及与这些主机相关联的变量。您还可以指定组。组允许您引用多个相关联的主机以针对其进行自动化,或批量定义变量。一旦定义了清单,您就可以使用 模式 来选择要 Ansible 执行操作的主机或组。

最简单的清单是一个包含主机和组列表的单个文件。此文件的默认位置是 /etc/ansible/hosts。您可以通过使用 -i <path or expression> 选项或使用配置系统,在命令行中指定不同的清单源。

Ansible 清单插件 支持多种格式和源,这使得您的清单既灵活又可定制。随着清单的扩展,您可能需要多个文件来组织主机和组。除了 /etc/ansible/hosts 文件外,您还有以下常见选项:

  • 您可以动态生成清单。例如,您可以使用清单插件列出一个或多个云提供商或其他源中的资源。请参阅 使用动态清单

  • 您可以为清单使用多个源,包括动态清单和静态文件。请参阅 传递多个清单源

  • 您可以创建一个包含多个静态或动态清单源的目录。请参阅 在目录中组织清单

以下 YAML 代码片段包含省略号(…),表示这些片段是较大 YAML 文件的一部分。您可以在 YAML 基础 中了解更多关于 YAML 语法的信息。

清单基础:格式、主机和组

您可以根据所拥有的清单插件,以多种格式之一创建清单文件。最常见的格式是 INI 和 YAML,因为 Ansible 内置了对它们的支持。本介绍侧重于这两种格式,但也支持许多其他格式和源。

一个基本的 INI /etc/ansible/hosts 可能如下所示:

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

方括号中的标题是组名。您可以使用组名对主机进行分类,并决定在何时以及出于何种目的控制哪些主机。组名应遵循与 创建有效变量名 相同的准则。

这是 YAML 格式中相同的基本清单文件:

ungrouped:
  hosts:
    mail.example.com:
webservers:
  hosts:
    foo.example.com:
    bar.example.com:
dbservers:
  hosts:
    one.example.com:
    two.example.com:
    three.example.com:

默认组

即使您未在清单中定义任何组,Ansible 也会创建两个默认组:allungroupedall 组包含每一台主机。ungrouped 组包含所有不属于任何其他组的主机。每一台主机始终至少属于两个组(allungrouped,或者 all 和另一个组)。例如,在上述基本清单中,主机 mail.example.com 属于 allungrouped 组。主机 two.example.com 属于 alldbservers 组。虽然 allungrouped 始终存在,但它们可能是隐式的,并且可能不会出现在诸如 group_names 之类的组列表中。

属于多个组的主机

您可以将主机放入多个组中。例如,您可以将亚特兰大数据中心中的生产 Web 服务器包含在 [prod][atlanta][webservers] 组中。您可以创建跟踪以下标准的组:

  • 什么 (What) - 应用程序、堆栈或微服务(例如数据库服务器、Web 服务器等)。

  • 哪里 (Where) - 数据中心或区域,用于与本地 DNS、存储等通信(例如 east、west)。

  • 何时 (When) - 开发阶段,以避免在生产资源上进行测试(例如 prod、test)。

以下示例扩展了之前的 YAML 清单,以包含“什么”、“何时”和“哪里”:

ungrouped:
  hosts:
    mail.example.com:
webservers:
  hosts:
    foo.example.com:
    bar.example.com:
dbservers:
  hosts:
    one.example.com:
    two.example.com:
    three.example.com:
east:
  hosts:
    foo.example.com:
    one.example.com:
    two.example.com:
west:
  hosts:
    bar.example.com:
    three.example.com:
prod:
  hosts:
    foo.example.com:
    one.example.com:
    two.example.com:
test:
  hosts:
    bar.example.com:
    three.example.com:

正如示例所示,one.example.com 存在于 dbserverseastprod 组中。

组的组:父/子组关系

您可以在组之间创建父/子关系。父组也称为嵌套组或组的组。例如,如果您的所有生产主机已经位于诸如 atlanta_proddenver_prod 之类的组中,您可以创建一个包含这些较小组的 production 组。这种方法减少了维护工作,因为您可以通过编辑子组来从父组添加或删除主机。

要为组创建父/子关系,请使用以下方法之一:

  • 在 INI 格式中,使用 :children 后缀。

  • 在 YAML 格式中,使用 children: 条目。

以下示例显示了与上述相同的清单,并使用 prodtest 组的父组进行了简化:

ungrouped:
  hosts:
    mail.example.com:
webservers:
  hosts:
    foo.example.com:
    bar.example.com:
dbservers:
  hosts:
    one.example.com:
    two.example.com:
    three.example.com:
east:
  hosts:
    foo.example.com:
    one.example.com:
    two.example.com:
west:
  hosts:
    bar.example.com:
    three.example.com:
prod:
  children:
    east:
test:
  children:
    west:

请注意子组的以下属性:

  • 任何作为子组成员的主机都会自动成为父组的成员。

  • 一个组可以有多个父组和子组,但不能有循环关系。

  • 一台主机可以存在于多个组中,但 Ansible 在运行时仅处理该主机的一个实例。Ansible 会合并来自多个组的数据。

  • 主机和组始终是“全局的”。如果您在不同的“分支”或“实例”下多次定义同一个主机或组,该主机或组仍是同一个实体。多次定义主机或组要么会向其添加新信息,要么会用最新的定义覆盖任何冲突的信息。

添加主机范围

某些插件(如 YAML 和 INI)支持添加主机范围。如果您有许多具有相似模式的主机,您可以以范围的形式添加主机,而不是单独列出每个主机名:

在 INI 中:

[webservers]
www[01:50].example.com

在 YAML 中:

# ...
  webservers:
    hosts:
      www[01:50].example.com:

在定义数字主机范围时,您可以指定步长(序列号之间的增量):

在 INI 中:

[webservers]
www[01:50:2].example.com

在 YAML 中:

# ...
  webservers:
    hosts:
      www[01:50:2].example.com:

上面的示例匹配子域 www01、www03、www05、…、www49,但不匹配 www00、www02、www50 等,因为每一步的步长(增量)为 2 个单位。

对于数字模式,您可以根据需要包含或删除前导零。范围是包含性的。您也可以定义字母范围:

[databases]
db-[a:f].example.com

传递多个清单源

您可以同时针对多个清单源(静态文件、目录、动态清单脚本或清单插件支持的任何内容)。为此,请从命令行指定多个清单源(见下文),或者通过配置指定,即设置 ANSIBLE_INVENTORY 或在 ansible.cfg 中设置 (DEFAULT_HOST_LIST)。当您希望同时针对通常分开的环境(例如暂存和生产环境)执行特定操作时,此功能非常有用。

要从命令行针对两个清单源:

ansible-playbook get_logs.yml -i staging -i production

在目录中组织清单

您可以将多个清单源合并到单个目录中。此方法最简单的版本是一个包含多个文件的目录,而不是单个清单文件。当文件变得过长时,维护单个文件会变得很困难。如果您有多个团队和多个自动化项目,为每个团队或项目创建一个清单文件可以让每个人轻松找到他们关心的主机和组。根据您配置或调用 Ansible 的方式,您仍然可以单独或分部分使用这些文件。

这些文件可以使用所有格式或插件配置(例如 YAML 或 INI)。在这种情况下,您的目录将成为您的“单一”清单源,Ansible 会聚合它在该目录中找到的多个源。默认情况下,Ansible 会忽略某些目录和扩展名,但您可以在配置中更改此行为 (INVENTORY_IGNORE_PATTERNSINVENTORY_IGNORE_EXTS)。

您还可以在清单目录中组合多种清单源类型。此方法对于组合静态和动态主机并将它们作为一个清单进行管理非常有用。以下清单目录组合了清单插件源、动态清单脚本和包含静态主机的文件:

inventory/
  openstack.yml          # configure inventory plugin to get hosts from OpenStack cloud
  dynamic-inventory.py   # add additional hosts with dynamic inventory script
  on-prem                # add static hosts and groups
  parent-groups          # add static hosts and groups

您可以按如下方式定位此清单目录:

ansible-playbook example.yml -i inventory

您也可以在 ansible.cfg 文件中配置清单目录。有关详细信息,请参阅 配置 Ansible

Ansible 会按字母顺序从顶层目录向下读取和加载文件。

管理清单加载顺序

Ansible 会按照您提供的顺序加载清单源。它会在源文件中遇到主机、组和变量时定义它们,并在必要时在最后添加 allungrouped 组。

根据您使用的清单插件,您可能需要重新排列源的顺序,以确保父/子定义的组或主机按插件预期的那样存在。否则,您可能会遇到解析错误。例如,YAML 和 INI 清单插件在完成处理每个源后会丢弃空组(没有关联主机的组)。

如果您多次定义一个变量,Ansible 会覆盖之前的值。最后定义的生效。

向清单添加变量

您可以在清单中定义与特定主机或组相关的变量。一种简单的入门方法是直接将变量添加到 YAML 或 INI 清单源中的主机和组中。

本指南记录了为简单起见如何在清单源中添加变量。但是,您也可以使用 Vars 插件 从许多其他源添加变量。默认情况下,Ansible 随附了 host_group_vars 插件,允许您在单独的主机和组变量文件中定义变量。与在清单源中定义变量相比,使用单独的文件描述系统策略是一种更稳健的方法。有关如何将变量值存储在 ‘host_vars’ 和 ‘group_vars’ 目录下的各个文件中的指南,请参阅 组织主机和组变量

为一台机器分配变量:主机变量

您可以轻松地为单个主机分配变量,然后稍后在 Playbook 中使用该变量。您可以直接在清单文件中执行此操作。

在 INI 中:

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

在 YAML 中:

atlanta:
  hosts:
    host1:
      http_port: 80
      maxRequestsPerChild: 808
    host2:
      http_port: 303
      maxRequestsPerChild: 909

诸如非标准 SSH 端口之类的唯一值很适合作为主机变量。您可以通过在主机名后加上冒号和端口号,将它们添加到您的 Ansible 清单中:

badwolf.example.com:5309

您可以使用主机变量来定义“连接变量”。连接变量配置 connectionshellbecome 插件,以支持在主机上执行任务。例如:

[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_user=myuser
other2.example.com     ansible_connection=ssh        ansible_user=myotheruser

清单别名

inventory_hostname 是 Ansible 中主机的唯一标识符。此标识符可以是 IP 地址或主机名,也可以仅仅是主机的“别名”或简短名称。

在 INI 中:

jumper ansible_port=5555 ansible_host=192.0.2.50

在 YAML 中:

# ...
  hosts:
    jumper:
      ansible_port: 5555
      ansible_host: 192.0.2.50

在此示例中,针对主机别名“jumper”运行 Ansible 将连接到端口 5555 上的 192.0.2.50。请参阅 行为清单参数 以进一步自定义到主机的连接。

此功能对于多次针对同一主机也很有用,但请记住任务可能会并行运行:

在 INI 中:

jumper1 ansible_port=5555 ansible_host=192.0.2.50
jumper2 ansible_port=5555 ansible_host=192.0.2.50

在 YAML 中:

# ...
  hosts:
    jumper1:
      ansible_port: 5555
      ansible_host: 192.0.2.50
    jumper2:
      ansible_port: 5555
      ansible_host: 192.0.2.50

以 INI 格式定义变量

Ansible 会根据您声明它们的位置,以不同方式解释您通过 key=value 语法传递的 INI 格式值:

  • 当您与主机内联声明一个值时,Ansible 会将 INI 值解释为 Python 字面量结构(例如字符串、数字、元组、列表、字典、布尔值或 None)。主机行每行接受多个 key=value 参数。因此,您需要一种方法来指示空格是值的一部分,而不是分隔符。您可以引用包含空格的值(使用单引号或双引号)。有关详细信息,请参阅 Python shlex 解析规则

  • 当您在 :vars 部分声明一个值时,Ansible 会将 INI 值解释为字符串。例如,var=FALSE 创建一个值为 ‘FALSE’ 的字符串。与主机行不同,:vars 部分每行仅接受一个条目,因此 = 之后的所有内容都将成为该条目的值。

如果您需要来自 INI 清单的变量具有特定类型(例如字符串或布尔值),请务必在任务中使用过滤器指定该类型。在使用变量时,不要依赖于在 INI 清单中设置的类型。

请考虑使用 YAML 格式作为清单源,以避免对变量的实际类型产生混淆。YAML 清单插件会始终如一且正确地处理变量值。

为多台机器分配变量:组变量

如果组中的所有主机共享同一个变量值,则可以一次性将该变量应用于整个组。

在 INI 中:

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

在 YAML 中:

atlanta:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.atlanta.example.com
    proxy: proxy.atlanta.example.com

组变量是将变量一次性应用于多个主机的便捷方式。但是,在执行之前,Ansible 总是会将变量(包括清单变量)扁平化到主机级别。如果主机是多个组的成员,Ansible 将读取所有这些组的变量值。如果您在不同的组中为同一个变量分配了不同的值,Ansible 将根据内部的 合并规则 选择要使用的值。

继承变量值:组的组变量

您可以将变量应用于父组(嵌套组或组的组)以及子组。语法相同:INI 格式使用 :vars,YAML 格式使用 vars:

在 INI 中:

[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

在 YAML 中:

usa:
  children:
    southeast:
      children:
        atlanta:
          hosts:
            host1:
            host2:
        raleigh:
          hosts:
            host2:
            host3:
      vars:
        some_server: foo.southeast.example.com
        halon_system_timeout: 30
        self_destruct_countdown: 60
        escape_pods: 2
    northeast:
    northwest:
    southwest:

子组的变量具有更高的优先级(它们会覆盖父组的变量)。

组织主机和组变量

虽然您可以在清单源中定义变量,但也可以使用 Vars 插件 为您的变量定义备选源。

Ansible 随附的默认 vars 插件 host_group_vars 允许您使用单独的主机和组变量文件。此方法有助于您更轻松地组织变量值。您还可以在这些文件中使用列表和哈希数据,这是在主清单文件中无法做到的。

对于 host_group_vars 插件,您的主机和组变量文件必须使用 YAML 语法。有效的文件扩展名为 ‘.yml’、‘.yaml’、‘.json’ 或没有文件扩展名。如果您是 YAML 的新手,请参阅 YAML 语法

host_group_vars 插件通过搜索相对于清单源或 Playbook 文件的路径来加载主机和组变量文件。如果位于 /etc/ansible/hosts 的清单文件包含一个名为 ‘foosball’ 的主机,且该主机属于 raleighwebservers 组,则该主机将使用以下位置 YAML 文件中的变量:

/etc/ansible/group_vars/raleigh # can optionally end in '.yml', '.yaml', or '.json'
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball

例如,如果您在清单中按数据中心对主机进行分组,并且每个数据中心都使用自己的 NTP 服务器和数据库服务器,则可以创建一个名为 /etc/ansible/group_vars/raleigh 的文件,以存储 raleigh 组的变量:

---
ntp_server: acme.example.org
database_server: storage.example.org

您还可以创建以组或主机命名的目录。Ansible 会以字典顺序读取这些目录中的所有文件。以下是 ‘raleigh’ 组的示例:

/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settings

‘raleigh’ 组中的所有主机都可以使用您在这些文件中定义的变量。此方法对于当单个文件变得过大,或者当您想对某些组变量使用 Ansible Vault 时,非常有用。

当您使用 ansible-playbook 时,Ansible 的 host_group_vars vars 插件也可以将 group_vars/host_vars/ 目录添加到您的 Playbook 目录中。但是,并非所有 Ansible 命令都有 Playbook(例如 ansibleansible-console)。对于这些命令,您可以使用 --playbook-dir 选项在命令行上提供目录。如果您既有相对于 Playbook 目录的 vars 插件源,又有相对于清单目录的 vars 插件源,则 Ansible 相对于 Playbook 获取的变量会覆盖它相对于清单源获取的变量。

为了跟踪清单和变量定义的更改,请将您的清单源及其相关的变量目录和文件保存在 Git 存储库或其他版本控制系统中。

变量合并方式

注意

Ansible 会根据一套规则合并来自不同源的变量,并对某些变量赋予比其他变量更高的优先级。例如,清单中较靠前出现的变量可能会覆盖清单中较靠后出现的变量。有关更多信息,请参阅 变量优先级:我应该在哪里放置变量?

在运行 Play 之前,Ansible 会将变量合并并扁平化到特定主机。此过程使 Ansible 专注于主机和任务,因此组不会在清单和主机匹配之外存在。默认情况下,Ansible 会覆盖变量,包括您为组或主机定义的变量(请参阅 DEFAULT_HASH_BEHAVIOUR)。清单实体的顺序/优先级(从最低到最高)为:

以下列表显示了清单实体的优先级顺序,从最低到最高:

  • all 组(因为它是所有其他组的“父组”)

  • 父组

  • 子组

  • host

默认情况下,Ansible 会按字母顺序合并同一父/子级别的组。Ansible 加载的最后一个组中的变量会覆盖先前组中的变量。例如,Ansible 将 a_groupb_group 合并,来自 b_group 的匹配变量会覆盖 a_group 中的变量。

您可以通过设置组变量 ansible_group_priority 来微调此合并行为。此变量会覆盖相同级别组的合并顺序的字母顺序排序(在 Ansible 解析父/子顺序之后)。数字越大,Ansible 合并该组的时间就越晚,从而赋予它更高的优先级。如果您不设置它,此变量默认为 1。例如:

a_group:
  vars:
    testvar: a
    ansible_group_priority: 10
b_group:
  vars:
    testvar: b

在此示例中,如果两个组具有相同的优先级,结果通常为 testvar == b。但是,因为我们赋予了 a_group 更高的优先级,结果为 testvar == a

您只能在清单源中设置 ansible_group_priority,不能在 group_vars/ 中设置。Ansible 在加载 group_vars/ 目录时会使用此变量。

管理清单变量加载顺序

本节介绍如何通过管理清单源的加载顺序来控制变量优先级。您可以在命令行上以特定顺序传递源,或使用目录中源的文件名前缀。

当您使用多个清单源时,请记住 Ansible 会根据 变量合并方式变量优先级:我应该在哪里放置变量? 中描述的规则解决任何变量冲突。您可以控制清单源中变量的合并顺序,以获得所需的变量值。

当您在命令行上传递多个清单源时,Ansible 会按照您传递这些参数的顺序合并变量。如果暂存(staging)清单中的 [all:vars] 部分定义了 myvar = 1,而生产(production)清单定义了 myvar = 2,那么以下结论成立:

  • 如果您传递 -i staging -i production,Ansible 将使用 myvar = 2 运行 Playbook。

  • 如果您传递 -i production -i staging,Ansible 将使用 myvar = 1 运行 Playbook。

当您将多个清单源放入一个目录时,Ansible 会根据文件名按字母顺序合并这些源。您可以通过在文件上添加前缀来控制加载顺序:

inventory/
  01-openstack.yml          # configure inventory plugin to get hosts from Openstack cloud
  02-dynamic-inventory.py   # add additional hosts with dynamic inventory script
  03-static-inventory       # add static hosts
  group_vars/
    all.yml                 # assign variables to all hosts

如果 01-openstack.ymlall 组定义了 myvar = 102-dynamic-inventory.py 定义了 myvar = 2,而 03-static-inventory 定义了 myvar = 3,Ansible 将使用 myvar = 3 运行 Playbook。

有关清单插件和动态清单脚本的更多详细信息,请参阅 清单插件使用动态清单

连接到主机:行为清单参数

如上所述,您可以设置以下变量来控制 Ansible 如何与远程主机进行交互。

主机连接

注意

使用 ssh 连接插件(这是默认插件)时,Ansible 不会公开一个通道来允许用户与 ssh 进程之间的通信以手动接受密码来解密 ssh 密钥。强烈建议使用 ssh-agent

ansible_connection

指定到主机的连接类型。这可以是任何 Ansible 连接插件的名称。SSH 协议类型为 sshparamiko。默认为 ssh

所有连接通用的参数

ansible_host

指定要连接到的主机的可解析名称或 IP(如果它与您希望赋予它的别名不同)。切勿将其设置为依赖 inventory_hostname。如果确实需要类似的东西,请使用 inventory_hostname_short,以便它可以与委托(delegation)一起工作。

ansible_port

连接端口号(如果不是默认值(ssh 为 22))。

ansible_user

连接(登录)到主机时要使用的用户名。

ansible_password

用于向主机进行身份验证的密码。(切勿以明文形式存储此变量。务必使用 vault。请参阅 保持 vault 变量安全可见。)

SSH 连接插件专用参数

ansible_ssh_private_key_file

SSH 使用的私钥文件。如果您使用多个密钥并且不想使用 SSH 代理,这非常有用。

ansible_ssh_common_args

Ansible 始终将此设置附加到 sftpscpssh 的默认命令行中。这对于为特定主机或组配置 ProxyCommand 非常有用。

ansible_sftp_extra_args

Ansible 始终将此设置附加到默认的 sftp 命令行中。

ansible_scp_extra_args

Ansible 始终将此设置附加到默认的 scp 命令行中。

ansible_ssh_extra_args

Ansible 始终将此设置附加到默认的 ssh 命令行中。

ansible_ssh_pipelining

指定是否使用 SSH 管道(pipelining)。这可以覆盖 ansible.cfg 中的 pipelining 设置。

ansible_ssh_executable(在 2.2 版本中添加)

此设置覆盖使用系统 ssh 的默认行为。它可以覆盖 ansible.cfgssh_connection 部分中的 ssh_executable 设置。

特权升级(有关更多详细信息,请参阅 Ansible 特权升级

ansible_become

等同于 ansible_sudoansible_su;允许您强制执行特权升级。

ansible_become_method

允许您将特权升级方法设置为匹配的 become 插件。

ansible_become_user

等同于 ansible_sudo_useransible_su_user;允许您设置通过特权升级成为的用户。

ansible_become_password

等同于 ansible_sudo_passwordansible_su_password;允许您设置特权升级密码。(切勿以明文形式存储此变量。务必使用 vault。请参阅 保持 vault 变量安全可见。)

ansible_become_exe

等同于 ansible_sudo_exeansible_su_exe;允许您设置所选升级方法的可执行文件。

ansible_become_flags

等同于 ansible_sudo_flagsansible_su_flags;允许您设置传递给所选升级方法的标志。您也可以在 ansible.cfgprivilege_escalation 下的 become_flags 选项中全局设置此项。

远程主机环境参数

ansible_shell_type

指定目标系统的 shell 类型。除非您已将 ansible_shell_executable 设置为非 Bourne (sh) 兼容的 shell,否则不应使用此设置。默认情况下,Ansible 使用 sh 风格的语法格式化命令。如果您将其设置为 cshfish,Ansible 在目标系统上执行的命令将遵循这些 shell 的语法。

ansible_python_interpreter

指定目标主机 Python 路径。这对于拥有多个 Python 的系统,或 Python 不位于 /usr/bin/python(例如 *BSD)的系统,或者 /usr/bin/python 不是 2.X 系列 Python 的系统非常有用。我们不使用 /usr/bin/env 机制,因为它要求远程用户的路径设置正确,并且还假设 python 可执行文件被命名为 python,而可执行文件可能被命名为类似 python2.6 的东西。

ansible_*_interpreter

适用于任何语言(如 Ruby 或 Perl),工作方式与 ansible_python_interpreter 相同。此变量替换将在该主机上运行的模块的 shebang。

2.1 版本新功能。

ansible_shell_executable

此设置用于设置 Ansible 控制节点将在目标机器上使用的 shell。它覆盖 ansible.cfg 中的 executable,该值默认为 /bin/sh。您仅在无法使用 /bin/sh 时才应更改此值(换句话说,如果目标机器上未安装 /bin/sh 或无法从 sudo 运行它)。

来自 Ansible-INI 主机文件的示例

some_host         ansible_port=2222     ansible_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

非 SSH 连接类型

如上一节所述,Ansible 默认通过 SSH 执行 Playbook,但不限于这种连接类型。您可以使用特定于主机的参数 ansible_connection=<connection plugin name> 更改连接类型。有关可用插件及其示例的完整列表,请参阅 插件列表

清单设置示例

另请参阅 Ansible 设置示例,其中显示了清单以及 Playbook 和其他 Ansible 工件。

示例:每个环境一个清单

如果您需要管理多个环境,请考虑在每个清单中仅定义单个环境的主机。这样,就不太可能在想要更新某些“暂存”服务器时,意外更改了“测试”环境内节点的状态。

对于上述示例,您可以拥有一个 inventory_test 文件:

[dbservers]
db01.test.example.com
db02.test.example.com

[appservers]
app01.test.example.com
app02.test.example.com
app03.test.example.com

该文件仅包含属于“测试”环境的主机。您可以在名为 inventory_staging 的另一个文件中定义“暂存”机器:

[dbservers]
db01.staging.example.com
db02.staging.example.com

[appservers]
app01.staging.example.com
app02.staging.example.com
app03.staging.example.com

要将名为 site.yml 的 Playbook 应用于测试环境中的所有应用程序服务器,请使用以下命令:

ansible-playbook -i inventory_test -l appservers site.yml

示例:按功能分组

在上一节中,您已经看到了使用组来聚集具有相同功能的主机的示例。这种方法允许您(例如)在 Playbook 或角色中定义仅影响数据库服务器的防火墙规则:

- hosts: dbservers
  tasks:
  - name: Allow access from 10.0.0.1
    ansible.builtin.iptables:
      chain: INPUT
      jump: ACCEPT
      source: 10.0.0.1

示例:按位置分组

其他任务可能侧重于特定主机的位置。假设 db01.test.example.comapp01.test.example.com 位于 DC1,而 db02.test.example.com 位于 DC2:

[dc1]
db01.test.example.com
app01.test.example.com

[dc2]
db02.test.example.com

在实践中,您最终可能会混合所有这些设置。例如,您可能有一天需要更新特定数据中心中的所有节点,而在另一天,您可能需要更新所有应用程序服务器,而不论其位置如何。

另请参阅

清单插件

从动态或静态源提取清单

使用动态清单

从动态源(如云提供商)提取清单

即席命令(ad hoc commands)介绍

基本命令示例

使用 Playbook

学习 Ansible 的配置、部署和编排语言。

交流方式

有疑问?需要帮助?想分享你的想法?请访问 Ansible 通信指南