如何在不指定清单但直接指定主机的情况下运行Ansible?


78

我想在Python中运行Ansible,而不通过(ANSIBLE_HOST)指定清单文件,而仅通过以下方式:

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

我实际上可以轻松地在Fabric中执行此操作,但只是想知道如何在Python中执行此操作。另一方面,用于Python的Ansible API的文档还不是很完整。

Answers:


173

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

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

要么

# Requires 'hosts: all' in your playbook
ansible-playbook -i example.com, playbook.yml

之前的host参数,可以是主机名或IPv4 / v6地址。


1
在Ansible 1.9.1中,当您调用ansible-playbook时,请从命令行中删除“ all”,但将其保留在playbook.yml中。这是正确的答案“ ansible-playbook -i example.com,playbook.yml”
PinoSan

1
然后,我应该在剧本中将其设置为“主机”以使其与任何服务器一起使用吗?
azmeuk

2
在剧本中,@ azmeuk的“主持人:所有人”应该都能正常工作。我通常这样做,然后在命令行上使用-i或--limit指定主机。
戴夫

如果剧本有两个不同的阶段,分别连接到不同的主机/ ip,该怎么办?注意我不是要在多个IP上同时运行一个部分,而是要针对不同的IP运行2个不同的部分?
openCivilisation

53

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

ansible-playbook -i 10.254.3.133, site.yml

如果您为本地主机运行:

ansible-playbook -i localhost, --connection=local site.yml

诀窍是,在ip地址/ dns名称后,在逗号中加上逗号,并hosts: all在剧本中要求' '。

希望这会有所帮助。


6
对于它的价值,这里的引号是禁止操作的。如果使用'localhost,'localhost,,则在两种情况下ansible-playbook都会从shell接收相同的参数。并且'localhost',将以相同的方式求值(这里的关键是引号在将参数传递给命令之前由外壳程序解释)。
larsks 2015年

7
这是可行的,但是为什么以ansible的名义以Merlin的胡须的名义进行这种行为呢?人们应该如何确切地知道这一点?我撕掉头发,寻找修复方法。
雏形

1
我知道我来晚了,但是我偶然发现了您的评论,并希望在此提供一些见解。之所以起作用,是因为-i标志要求您传递有效的清单目标,该目标可以是INI文件,Ansible有效的清单可执行文件或可以由Ansible清单插件处理的任何任意字符串。有一个名为“ host_list”的Ansible插件,它使用逗号分隔主机列表,并使用该信息创建动态清单,以允许在未知主机上执行即席命令。默认情况下,Ansible中包含此插件。
埃克托卢阿塞斯诺

hosts: all当我打算一次只在一台主机上运行一本剧本时,我感到有些冒险。一位同事可能不使用而运行剧本-i。这是一个不错的解决方案,但我仍在寻找更安全的方法。仍在搜寻...
Donn Lee

7

您可以执行以下操作:

hosts = ["webserver1","webserver2"]

webInventory = ansible.inventory.Inventory(hosts)

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

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


您知道如何在local_action上下文中运行模块吗,例如ec2模块应该再次调用localhost(127.0.0.1)并作为local_action。谢谢
kamiseq

没关系,我回答我自己的问题:-) Runner = ansible.Runner(module_name =“ ec2_group”,complex_args = {},forks = paralel,#private_key_file =“〜/ .ssh / office.pem”,venture = Inventory([ “” 127.0.0.1“]),transport =” local“)返回Runner.run()
kamiseq,2015年

6

就我而言,我不想加入hosts: all我的剧本,因为如果有人跑了这本剧本而忘记了包含它,那将是不好的-i 10.254.3.133,

这是我的解决方案(可使用2.6):

$ 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

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


1

我还需要驱动Ansible Python API,并且宁愿将主机作为参数传递,而不是保留清单。我使用了一个临时文件来解决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()

可你也举一个例子,你如何使用它
Arbab纳扎尔

0

这不是一个完整的答案,但是此讨论线程中对此主题进行了一些讨论。在该线程的第一篇文章的结尾,建议创建一个用于ansible-playbook的包装器bash脚本,这有点hack但可行。

我一直在考虑的其他事情是使用“ ansible-pull”和创建ansible库存插件。我也有兴趣找到该问题的答案,并在找到更多信息时不断更新此答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.