从命令行覆盖Ansible playbook的hosts变量

luq*_*o33 87 ansible ansible-playbook

这是我正在使用的剧本片段(server.yml):

- name: Determine Remote User
  hosts: web
  gather_facts: false
  roles:
    - { role: remote-user, tags: [remote-user, always] }
Run Code Online (Sandbox Code Playgroud)

我的主机文件有不同的服务器组,例如

[web]
x.x.x.x

[droplets]
x.x.x.x
Run Code Online (Sandbox Code Playgroud)

现在我想执行ansible-playbook -i hosts/<env> server.yml,并覆盖hosts: webserver.yml运行这个剧本的[droplets].

我可以直接覆盖一次性的东西,而不server.yml直接编辑吗?

谢谢.

小智 110

我不认为Ansible提供此功能,它应该.这是你可以做的事情:

hosts: "{{ variable_host | default('web') }}"

并且您可以variable_host从命令行或从vars文件传递,例如:

ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
Run Code Online (Sandbox Code Playgroud)

  • 这是一个注释,我觉得可以完成搜索此解决方案的ansible新手的答案:示例:`ansible-playbook server.yml --extra-vars"variable_host = newtarget(s)"` (13认同)
  • 需要进行小的修正.它应该是`hosts:"{{variable_host | default('web')}}"` (3认同)
  • **何时**(即以什么顺序)解析变量`group_vars/all` 中的变量似乎在剧本的`hosts:` 行之后被解析**。但是,`vars:` 中的变量和 `vars_files:` 中的变量是在 `hosts:` 行之前解析的吗?**注意**我_不是_询问优先级。 (2认同)
  • 您也可以使用-e代替--extra-vars。 (2认同)

Mru*_*sar 62

对于任何可能来寻找解决方案的人.
玩书

- hosts: '{{ host }}'
  tasks:
  - debug: msg="Host is {{ ansible_fqdn }}"
Run Code Online (Sandbox Code Playgroud)

库存

[web]
x.x.x.x

[droplets]
x.x.x.x
Run Code Online (Sandbox Code Playgroud)

命令: ansible-playbook deplyment.yml -i hosts --extra-vars "host=droplets" 因此您可以在extra-vars中指定组名

  • 注意,请注意var命名.我使用`play_hosts`测试这个并没有得到预期的结果,因为我忘了'play_hosts`是当前播放中所有主机的内部Ansible var. (2认同)

TmT*_*ron 23

我们使用一个简单的失败任务来强制用户指定 Ansible限制选项,这样我们就不会在默认/意外情况下在所有主机上执行。

我找到的最简单的方法是这样的:

---
- name: Force limit
  # 'all' is okay here, because the fail task will force the user to specify a limit on the command line, using -l or --limit
  hosts: 'all'

  tasks:
  - name: checking limit arg
    fail:
      msg: "you must use -l or --limit - when you really want to use all hosts, use -l 'all'"
    when: ansible_limit is not defined
    run_once: true
Run Code Online (Sandbox Code Playgroud)

现在我们必须在运行剧本时使用-l(=--limit选项),例如

ansible-playbook playbook.yml -l www.example.com
Run Code Online (Sandbox Code Playgroud)

限制选项文档

限制为一台或多台主机 当一个人想要针对主机组运行剧本时,这是必需的,但仅针对该组的一个或多个成员。

仅限一台主机

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1"

限制为多台主机

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1,host2"

否定限制。
注意:必须使用单引号来防止 bash 插值。

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'all:!host1'

限制到主机组

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'group1'


Jon*_*mel 12

这有点晚了,但我认为您可以使用该--limit or -l命令将模式限制为更具体的主机.(版本2.3.2.0)

你可以有 - hosts: all (or group) tasks: - some_task

然后ansible-playbook playbook.yml -l some_more_strict_host_or_pattern 使用该--list-hosts标志来查看将应用此配置的主机.

  • 这很危险.如果忘记"限制",受影响的主机列表可能会导致很多损坏. (12认同)
  • 我对ansible很新,但我认为这是一个非常有效的解决方案,比其他解决方案更紧凑.它为什么被投票? (3认同)
  • 我发现使用`--extra-vars“ variable_host = newtarget(s)”`就像被接受的解决方案一样是危险且更复杂的解决方案。它使用默认的Web主机,也可以在这里应用主机而不是all。您可以使用严格的主机组作为默认设置来避免出错,并使用--list-hosts标志可以清楚地了解您正在影响哪些主机。 (3认同)
  • 使用extra-vars的解决方案允许将空组(或不存在的)指定为默认值.因此,如果您忘记通过命令行提供变量,则不会发生任何不良情况.使用"--limit"选项的解决方案更危险,因为playbook无法使用空组作为主机的默认值.选项"--llmit"应用于hosts值,因此它将应用于空组并将提供空结果.所以你必须使用"all"或其他非空主机作为默认值.有一天你会忘记提供"--limit"参数和剧本将适用于所有主机. (2认同)
  • 这应该与@TmTron的答案结合起来,以解决调用方未能提供--limit的情况(否则它将影响所有可能的主机,这可能不是您想要的行为) (2认同)

Ton*_*ffe 7

我把我的默认设置改为没有主机,并检查一下它.这样,用户或cron被迫提供单个主机或组等.我喜欢来自@wallydrag的评论中的逻辑.该empty_group包含在库存没有主机.

- hosts: "{{ variable_host | default('empty_group') }}"

然后添加签入任务:

   tasks:
   - name: Fail script if required variable_host parameter is missing
     fail:
       msg: "You have to add the --extra-vars='variable_host='"
     when: (variable_host is not defined) or (variable_host == "")


Nel*_* G. 6

我正在使用不需要任何库存的另一种方法,并且可以使用以下简单命令:

ansible-playbook site.yml -e working_host=myhost
Run Code Online (Sandbox Code Playgroud)

为此,您需要一本包含两个剧本的剧本:

  • 第一次播放在localhost上运行,并在内存清单的已知组中添加主机(来自给定变量)
  • 第二场比赛在这个已知的团体上进行

一个有效的示例(将其复制并使用先前的命令运行):

- hosts: localhost
  connection: local
  tasks:
  - add_host:
      name: "{{ working_host }}"
      groups: working_group
    changed_when: false

- hosts: working_group
  gather_facts: false
  tasks:
  - debug:
      msg: "I'm on {{ ansible_host }}"
Run Code Online (Sandbox Code Playgroud)

我正在使用ansible 2.4.3和2.3.3


小智 5

刚刚遇到这个谷歌搜索解决方案。实际上,Ansible 2.5 中有一个。您可以使用 指定您的库存文件--inventory,如下所示:ansible --inventory configs/hosts --list-hosts all


小智 5

另一种解决方案是使用特殊变量ansible_limit,它是--limitAnsible 当前执行的CLI 选项的内容。

- hosts: "{{ ansible_limit | default(omit) }}"
Run Code Online (Sandbox Code Playgroud)

如果--limit省略该选项,则 Ansible 会发出警告,但由于没有主机匹配,因此什么也不做。

[WARNING]: Could not match supplied host pattern, ignoring: None

PLAY ****************************************************************
skipping: no hosts matched
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是处理此问题的最干净的方法,并且是安全的。 (4认同)