Python 如何运行Ansible而不指定库存,而是直接指定主机?

Python 如何运行Ansible而不指定库存,而是直接指定主机?,python,ansible,Python,Ansible,我希望在Python中运行Ansible,而不通过(Ansible_HOST)指定清单文件,但只通过以下方式: ansible.run.Runner( module_name='ping', host='www.google.com' ) 实际上,我可以在fabric中轻松实现这一点,但我只是想知道如何在Python中实现这一点。另一方面,Ansible API for python的文档并不是很完整。令人惊讶的是,诀窍是附加一个, # Host and IP address ansi

我希望在Python中运行Ansible,而不通过(Ansible_HOST)指定清单文件,但只通过以下方式:

ansible.run.Runner(
  module_name='ping',
  host='www.google.com'
)

实际上,我可以在fabric中轻松实现这一点,但我只是想知道如何在Python中实现这一点。另一方面,Ansible API for python的文档并不是很完整。

令人惊讶的是,诀窍是附加一个

# Host and IP address
ansible all -i example.com,
ansible all -i 93.184.216.119,

前面的主机参数可以是主机名,也可以是IPv4/v6地址。

您可以通过以下方式执行此操作:

hosts = ["webserver1","webserver2"]

webInventory = ansible.inventory.Inventory(hosts)

webPing = ansible.runner.Runner(
    pattern='webserver*',
    module_name='ping',
    inventory = webInventory
).run()

主机中的任何内容都将成为您的资源清册,您可以使用模式进行搜索(或执行“全部”)。

我还需要驱动,并且宁愿将主机作为参数传递,也不愿保留资源清册。我使用了一个临时文件来绕过Ansible的要求,这可能对其他人有所帮助:

from tempfile import NamedTemporaryFile

from ansible.inventory import Inventory
from ansible.runner import Runner

def load_temporary_inventory(content):
    tmpfile = NamedTemporaryFile()
    try:
        tmpfile.write(content)
        tmpfile.seek(0)
        inventory = Inventory(tmpfile.name)
    finally:
        tmpfile.close()
    return inventory

def ping(hostname):
    inventory = load_temporary_inventory(hostname)
    runner = Runner(
        module_name='ping',
        inventory=inventory,
    )
    return runner.run()

我知道这个问题很老了,但我认为这个小技巧可能对未来需要帮助的用户有所帮助:

ansible-playbook -i 10.254.3.133, site.yml
如果为本地主机运行:

ansible-playbook -i localhost, --connection=local site.yml
诀窍在于,在ip地址/dns名称之后,在引号中加逗号,并在剧本中要求“
hosts:all


希望这会有所帮助

在我的例子中,我不想在我的剧本中包含
主机:all
,因为如果有人运行剧本,忘记包含
-I 10.254.3.133,

这就是我的解决方案(ansible 2.6):

然后,在剧本中:

- hosts: "{{ target }}"
  remote_user: donn
  vars_files:
    - myvars
  roles:
    - myrole

这是一个特殊的用例,当我需要配置主机,并且我不想/不需要将其添加到清单中时。

根据我的理解,这是一个非常简单的解决方案,如果这会分散我的注意力,请道歉

这里有三个主要步骤需要完成

  • 命令行选项
  • 需要在playbook.yml中公开哪些内容
  • 上面说的
  • 1.命令行选项 ansible剧本-l“主机名”

    请注意,主机名是节点的$hostname

    2.剧本中需要暴露的内容。yml 3.上面说什么?看一看:)
    这就是我们如何使用--limit或-l选项在特定节点上执行任务的方法

    您知道如何在本地\u操作上下文中运行模块吗,例如,ec2模块应该作为本地主机(127.0.0.1)和本地\u操作调用。谢谢你,我回答我自己的问题:-)runner=ansible.runner(module_name=“ec2_group”,complex_args={},forks=paralel,#private_key_file=“~/.ssh/office.pem”,inventory=inventory([“127.0.0.1”),transport=“local”)在Ansible 1.9.1中,当您调用Ansible playbook时,返回runner.run(),从命令行中删除“all”,但将其保留在playbook.yml中。这是正确的答案“ansible playbook-i example.com,playbook.yml”。那么,我应该在playbook中将什么设置为“主机”,以便它可以与任何服务器一起工作呢?@azmeuk在playbook中,“主机:所有”都可以正常工作。我通常会这样做,然后在命令行上使用-I或--limit来指定主机。如果playbook有两个不同的阶段,并且连接到不同的主机/IP,该怎么办?注意,我不是要针对多个ip运行一个部分,而是针对不同的ip运行两个不同的部分?对于Python程序员来说可能并不奇怪。值得一提的是,这里的引号是不可用的。如果使用
    'localhost',
    localhost,
    ,在这两种情况下
    ansible playbook
    将从shell接收相同的参数。而
    'localhost',
    将以同样的方式进行计算(这里的关键是,在shell将参数传递给您的命令之前,引号由shell进行解释)。这是可行的,但为什么以Merlin's beard的名义,ansible的这一行为是可以接受的?!人们究竟应该如何知道这一点?我拼命寻找上述解决办法。我知道我迟到了,但我刚刚无意中听到了你的评论,想在这里提供一些见解。之所以这样做,是因为-i标志要求您传递一个有效的库存目标,它可以是INI文件、Ansible有效库存可执行文件或Ansible库存插件可以处理的任意字符串。有一个名为“host_list”的Ansible插件,它获取由逗号分隔的主机列表,并使用该信息创建一个动态清单,以允许在未知主机上执行特别命令。这个插件默认包含在Ansible上。当我打算一次只在一台主机上运行时,我觉得使用带有
    hosts:all
    的playbook有点冒险。同事可能在没有
    -i
    的情况下运行剧本。这是一个很好的解决方案,但我会继续寻找更安全的解决方案。仍在搜索…这是可行的,但如何从库存中加载变量?以前我使用的是
    -I live
    ,但现在切换到单IP时,我没有选择从
    live
    文件夹加载VAR。您能否给出一个如何使用它的示例
    $ ansible-playbook myplaybook.yml -e "{target: 10.1.1.1}" -i 10.1.1.1, ...
    
    - hosts: "{{ target }}"
      remote_user: donn
      vars_files:
        - myvars
      roles:
        - myrole
    
    - hosts: webservers
      tasks:
        - debug:
            msg: "{{ ansible_ssh_host }}"
          when: inventory_hostname in groups['webservers']
    
    TASK [debug] ***********************************************************************************************************************************************************
    Thursday 10 December 2020  13:01:07 +0530 (0:00:03.153)       0:00:03.363 *****
    ok: [node1] => {
        "msg": "192.168.1.186"
    }