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

时间:2015-10-19 19:45:51

标签: ansible ansible-playbook

这是我正在使用的剧本片段(Y):

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的{​​{1}},以便为hosts: web运行此剧本。

我可以直接覆盖一次性事物而不直接编辑server.yml吗?

感谢。

12 个答案:

答案 0 :(得分:88)

我认为Ansible不提供此功能。这是你可以做的事情:

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

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

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

答案 1 :(得分:46)

对于任何可能来寻找解决方案的人。
Play Book

- 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" 因此,您可以在extra-vars中指定组名

答案 2 :(得分:10)

这有点晚了,但我认为您可以使用--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标志来查看将应用此配置的主机。

答案 3 :(得分:6)

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

ansible-playbook site.yml -e working_host=myhost

要执行此操作,您需要一个包含两个剧本的剧本:

  • 首次播放在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 }}"
  

我使用的是ansible 2.4.3和2.3.3

答案 4 :(得分:5)

我将我的默认值更改为无主​​机,并进行了检查以将其捕获。这样,用户或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 == "")

答案 5 :(得分:4)

我们使用简单的fail任务来强制用户指定Ansible limit option,这样就不会默认/意外在所有主机上执行

我发现的最简单的方法是:

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

Limit option docs

  

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

     

限制为一个主机

     

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'

答案 6 :(得分:2)

如果您要运行与主机关联但在不同主机上的任务,则应尝试delegate_to

在您的情况下,您应该委托给您的localhost(ansible master)并调用ansible-playbook命令

答案 7 :(得分:2)

我正在使用ansible 2.5(确切地说是2.5.3),并且似乎在执行主机参数之前加载了 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

答案 8 :(得分:2)

另一种解决方案是使用特殊变量![alt text](./state_transitation.JPG) ![alt text](/state_transitation.JPG) ![alt text](state_transitation.JPG) <p> <img src="state_transitation.JPG" /> </p> ,它是ansible_limit CLI选项的内容,用于当前执行Ansible。

--limit

如果省略了- hosts: "{{ ansible_limit | default(omit) }}" 选项,则Ansible会发出警告,但由于没有主机匹配,因此不会执行任何操作。

--limit

答案 9 :(得分:1)

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

答案 10 :(得分:0)

这是一个很不错的解决方案,我想通过<!-- the button is selected in "JavaScript" based on its ID (move) --> <!-- some styling is used to distinguish between the elements : the ".contaier" has a blue border while the ".con" has a red one. Notice which element has children in it after clicking the "button" --> <button id="move">Move elements</button> <div class="container"> <h1>text</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> <div class="con"></div>选项安全地指定主机。在此示例中,如果在未通过--limit选项指定任何主机的情况下执行了剧本,则该剧结束。

这已在Ansible 2.7.10版上进行了测试

--limit

答案 11 :(得分:0)

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

--extra-vars "host=$(target_host)"

pipeline_variable

我的 ansible 剧本是这样的

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