Ansible_静态和动态清单文件管理

一、利用主机模式选择主机

 1、应用静态清单主机

 1️⃣:主机模式用于指定要作为play或临时命令的目标的主机;在最简单的形式中,清单中受管主机或主机组的名称就是指定该主机或主机组的主机模式

  • 简单演示实例:
    [root@localhost ~]# cat inventory 
    1.1.1.1
    2.2.2.2
    
    [test]
    aaa.test.com
    bbb.test.com
    
    [server]
    www.server.com
    www.mairadb.com

 2、受管主机

1️⃣:在该playbook运行时,第一个Gathering Facts任务应在与主机模式匹配的所有受管主机上运行

2️⃣:如果清单中明确列出了IP地址,而不是主机名,则可以将其用作主机模式;如果IP地址未列在清单中,我们就无法用它来指定主机,即使该IP地址会在DNS中解析到这个主机名

  •  简单演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: client.example.com
      tasks:
        - name:
          ping:
    
    [root@localhost ~]# ansible-playbook playbook.yaml 
    
    PLAY [client.example.com] *************************************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************************************************
    ok: [client.example.com]
    
    TASK [ping] ***************************************************************************************************************************************************************
    ok: [client.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************************************
    client.example.com         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

3️⃣:可以通过设置ansible_host主机变量,在清单中将某一别名指向特定的IP地址

  • 简单演示实例:
    [root@localhost ansible]# cat inventory 
    host
    
    
    [root@localhost ansible]# cat host_vars/host 
    ansible_host: 192.168.121.81
    ansible_ssh_user: root
    ansible_ssh_pass: root
    
    
    [root@localhost ansible]# ansible all --list-hosts
      hosts (1):
        host
    
    
    [root@localhost ansible]# ansible all -m ping
    host | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": false,
        "ping": "pong"
    }

 3、使用组指定主机

 1️⃣:当组名称用作主机模式时,它指定Ansible将对属于该组的成员的主机执行操作

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: server
      tasks:
        - name:
          ping:

 2️⃣:当有一个名为all的特别组,它匹配清单中的所有受管主机

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: all
      tasks:
        - name:
          ping:

 3️⃣:还有一个名为ungrouped的特别组,它包括清单中不属于任何其他组的所有受管主机

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: ungrouped
      tasks:
        - name:
          ping:

 4、使用通配符匹配多个主机

1️⃣:若要达成与all主机模式相同的目标,另一种方法是使用(*)通配符,它将匹配任意字符串。

2️⃣:如果主机模式只是带引号的星号,则清单中的所有主机都将匹配

  • 演示实例
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: '*'       //此处的引号必须加
      tasks:
        - name:
          ping:

3️⃣:重要提示:

一些在主机模式中使用的字符对shell也有意义。通过ansible使用主机模式从命令行运行临时命令时,这可能会有问题。建议大家在命令行中使用单引号括起使用的主机模式,防止它们被shell意外扩展。
类似的,如果在Ansible Playbook中使用了任何特殊通配符或列表字符,必须将主机模式放在单引号里,确保能够正确解析主机模式。

4️⃣:其他演示实例:(用的比较少,不常用)

  • 实例一: 
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: '192.168.121.*'
      tasks:
        - name:
          ping:

 

  • 实例二:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: '*.example.com'
      tasks:
        - name:
          ping:
    

      

  • 实例三:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: 'client.example.com,www.test.com'
      tasks:
        - name:
          ping:

 

  • 实例四:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: '!client.example.com,www.test.com'
      tasks:
        - name:
          ping:

 

 5、列表

1️⃣:可以通过逻辑列表来引用清单中的多个条目;主机模式的逗号分隔列表匹配符合任何这些主机模式的所有主机

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: client.example.com,www.test.com,192.168.121.81
      tasks:
        - name:
          ping:

2️⃣:也可以混合使用受管主机、主机组和通配符

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: '*.example.com,www.test.com,192.168.121.81'
      tasks:
        - name:
          ping:

3️⃣:注意:也可以用冒号(:)取代逗号。不过,逗号是首选的分隔符,特别是将IPv6地址用作受管主机名称时

4️⃣:如果列表中的某一项以与符号(&)开头,则主机必须与该项匹配才能匹配主机模式

  • 演示实例:
    [root@localhost ~]# cat playbook.yaml 
    ---
    - hosts: host,&test
      tasks:
        - name:
          ping:

 

 二、管理动态清单文件

1、动态生成清单

1️⃣:Ansible支持动态清单脚本,这些脚本在每当Ansible执行时从这些类型的来源检索当前的信息,使清单能够实时得到更新

2️⃣:这些脚本是可以执行的程序,能够从一些外部来源收集信息,并以JSON格式输出清单

3️⃣:动态清单脚本的使用方式与静态清单文本文件一样。清单的位置可以直接在当前的ansible.cfg文件中指定,或者通过-i选项指定

4️⃣:如果清单文件可以执行,则它将被视为动态清单程序,Ansible会尝试运行它来生成清单。如果文件不可执行,则它将被视为静态清单

 5️⃣:清单位置可以在ansible.cfg配置文件中通过inventory参数进行配置。默认情况下,它被配置为/etc/ansible/hosts

 2、开源社区脚本

1️⃣:开源社区向Ansible项目贡献了大量现有的动态清单脚本。它们没有包含在ansible软件包中

2️⃣:Ansible GigHub网站:https://github.com/ansible/ansible/tree/devel/examples

3、编写动态清单文件

1️⃣:ansible-inventory命令是学习如何以JSON格式编写Ansible清单的有用工具;

2️⃣:要以JSON格式显示清单文件的内容,请运行ansible-inventory --list命令,可以使用-i选项指定要处理的清单文件的位置,或仅使用当前Ansible配置设置的默认清单

  • [root@localhost ~]# ansible-inventory -i inventory --list

3️⃣:如果要自己编写动态清单脚本,可以通过部署动态清单来源:https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html 获得更详细的信息

4️⃣:脚本以适当的解释器行(例如,#!/usr/bin/python)开头并且可以执行,以便Ansible能够运行它

5️⃣:注意

  • 通过--host hostname选项调用时,该脚本必须显示指定主机的变量的JSON散列/字典。如果不提供任何变量,则可能显示空白的JSON散列或字典
  • 另外,如果--list选项返回名为_meta的顶级元素,则可以在一次脚本调用中返回所有主机变量,从而提升脚本性能。此时,不会进行--host调用
  • 有关详细信息,请参见部署动态清单来源:https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html
  • 脚本示例:
    [root@localhost ~]# vim inventory.py
    #!/usr/bin/env python
    
    '''
    Example custom dynamic inventory script for Ansible, in Python.
    '''
    
    import os
    import sys
    import argparse
    
    try:
        import json
    except ImportError:
        import simplejson as json
    
    class ExampleInventory(object):
    
        def __init__(self):
            self.inventory = {}
            self.read_cli_args()
    
            # Called with `--list`.
            if self.args.list:
                self.inventory = self.example_inventory()
            # Called with `--host [hostname]`.
            elif self.args.host:
                # Not implemented, since we return _meta info `--list`.
                self.inventory = self.empty_inventory()
            # If no groups or vars are present, return empty inventory.
            else:
                self.inventory = self.empty_inventory()
    
            print json.dumps(self.inventory);
    
        # Example inventory for testing.
        def example_inventory(self):
            return {
                'group': {
                    'hosts': ['172.16.103.129', '172.16.103.130'],
                    'vars': {
                        'ansible_ssh_user': 'root',
                        'ansible_ssh_pass': '123456',
                        'example_variable': 'value'
                    }
                },
                '_meta': {
                    'hostvars': {
                        '172.16.103.129': {
                            'host_specific_var': 'foo'
                        },
                        '172.16.103.130': {
                            'host_specific_var': 'bar'
                        }
                    }
                }
            }
    
        # Empty inventory for testing.
        def empty_inventory(self):
            return {'_meta': {'hostvars': {}}}
    
        # Read the command line args passed to the script.
        def read_cli_args(self):
            parser = argparse.ArgumentParser()
            parser.add_argument('--list', action = 'store_true')
            parser.add_argument('--host', action = 'store')
            self.args = parser.parse_args()
    
    # Get the inventory.
    ExampleInventory()
    脚本示例

     

    • 使用该脚本方法
      chmod +x inventory.py
      ./inventory.py --list
      ./inventory.py --host 172.16.103.129
    • ansible使用这个动态清单来管理主机
      ansible all -i inventory.py -m ping
      ansible 172.16.103.129 -i inventory.py -m ping

4、管理多个清单

1️⃣:Ansible支持在同一运行中使用多个清单。如果清单的位置是一个目录(不论是由-i选项设置的、是inventory参数的值,还是以某种其他方式设置的),将组合该目录中包含的所有清单文件(不论是静态还是动态)来确定清单

  • 该目录中的可执行文件将用于检索动态清单,其他文件则被用作静态清单

2️⃣:清单文件不应依赖于其他清单文件或脚本来解析

3️⃣:注意

  • 清单文件的解析顺序不是由文档指定的。如果存在多个清单文件,它们会按照字母顺序进行解析
  • 如果一个清单源依赖于另一个清单源的信息,则它们的加载顺序可能会确定清单文件是按预期工作还是引发错误。因此,务必要确保所有文件都自相一致,从而避免意外的错误

4️⃣:Ansible会忽略清单目录中以特定后缀结尾的文件。这可以通过在Ansible配置文件中的inventory_ignore_extensions指令来控制

 

posted @ 2020-09-09 10:00  阮小言  阅读(1032)  评论(0编辑  收藏  举报