从命令行重写安塞尔剧本的主机变量

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

- name: Determine Remote User
hosts: web
gather_facts: false
roles:
- { role: remote-user, tags: [remote-user, always] }

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

[web]
x.x.x.x


[droplets]
x.x.x.x

现在,我想执行 ansible-playbook -i hosts/<env> server.yml并从 server.yml覆盖 hosts: web,以便为 [droplets]运行这个剧本。

我能不能不用直接编辑 server.yml就一次性重写?

谢谢。

175922 次浏览

如果要运行与主机关联的任务,但是在不同的主机上,应该尝试 委托 _ to

在您的情况下,您应该委托给本地主机(可见主机)并调用 ansible-playbook命令

我不认为 Anble 提供了这个特性,它应该提供这个特性:

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

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

ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"

对于任何可能来寻找解决方案的人来说。
剧本

- hosts: '\{\{ host }}'
tasks:
- debug: msg="Host is \{\{ ansible_fqdn }}"

库存

[web]
x.x.x.x


[droplets]
x.x.x.x

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

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

你本可以的 - 主办单位: 全体(或小组) 任务: - 一些 _ 任务

然后是 ansible-playbook playbook.yml -l some_more_strict_host_or_pattern 并使用 --list-hosts标志查看将在哪些主机上应用此配置。

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

ansible-playbook site.yml -e working_host=myhost

要做到这一点,你需要一个有两个剧本的剧本:

  • 第一次播放在本地主机上运行,并在内存库中的已知组中添加一个主机(来自给定的变量)
  • 第二次行动是针对这个已知组织

一个工作示例(复制它并使用前面的命令运行它) :

- 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 }}"

我用的是2.4.3和2.3.3

我在谷歌上找到了一个解决方案。实际上,在安赛波2.5有一个。您可以使用 --inventory指定库存文件,如下所示: ansible --inventory configs/hosts --list-hosts all

我使用的是 anable 2.5(确切地说是2.5.3) ,而且似乎在执行 hosts 参数之前就已经加载了 Vars 文件。因此,您可以在 Vars.yml文件中设置主机,并在您的剧本中编写 hosts: \{\{ host_var }}

例如,在我的 playbook.yml 中:

---
- hosts: "\{\{ host_name }}"
become: yes
vars_files:
- vars/project.yml
tasks:
...

在 vars/project.yml 中:

---


# general
host_name: your-fancy-host-name

我改变了我的默认为没有主机,并有一个检查捕捉它。这样,用户或 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 == "")

这里有一个很酷的解决方案,我想通过 --limit选项来安全地指定主机。在本例中,如果在没有通过 --limit选项指定任何主机的情况下执行剧本,则该剧本将结束。

这是在安赛尔2.7.10版本上测试的

---
- name: Playbook will fail if hosts not specified via --limit option.
# Hosts must be set via limit.
hosts: "\{\{ play_hosts }}"
connection: local
gather_facts: false
tasks:
- set_fact:
inventory_hosts: []
- set_fact:
inventory_hosts: "\{\{inventory_hosts + [item]}}"
with_items: "\{\{hostvars.keys()|list}}"


- meta: end_play
when: "(play_hosts|length) == (inventory_hosts|length)"


- debug:
msg: "About to execute tasks/roles for \{\{inventory_hostname}}"

我们使用一个简单的 失败任务来强制用户指定 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

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

ansible-playbook playbook.yml -l www.example.com

限制选项文件 :

限制为一个或多个主机 针对主机组的战术手册,但只针对主机组的一个或多个成员 那个组织。

限制 一个宿主

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'

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

- hosts: "\{\{ ansible_limit | default(omit) }}"

如果省略了 --limit选项,那么 Anble 会发出警告,但是由于没有主机匹配,所以不执行任何操作。

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


PLAY ****************************************************************
skipping: no hosts matched

在我使用 Azure devops 使用 CICD 管道部署应用程序时,这对我很有用。我必须使这个主机(在 yml 文件中)更加动态,以便在发布管道中添加它的值,例如:

额外的 vars“ host = $(target _ host)”

管道 _ 变量

我的智能手册是这样的

- name: Apply configuration to test nodes
hosts: '\{\{ host }}'