कमांड लाइन से Ansible playbook के होस्ट वेरिएबल को ओवरराइड करें


110

यह एक प्लेबुक का टुकड़ा है जिसका मैं उपयोग कर रहा हूं ( 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और ओवरराइड hosts: webसे server.ymlके लिए इस प्लेबुक को चलाने के लिए [droplets]

क्या मैं server.ymlसीधे एडिटिंग के बिना, केवल एक बार की चीज़ से दूर हो सकता हूं ?

धन्यवाद।

जवाबों:


128

मुझे नहीं लगता कि Ansible यह सुविधा प्रदान करता है, जिसे यह करना चाहिए। यहाँ कुछ है जो आप कर सकते हैं:

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

और आप variable_hostकमांड लाइन से या vars फ़ाइल से पास कर सकते हैं , जैसे:

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

3
एक छोटे से सुधार की आवश्यकता है। यह होना चाहिएhosts: "{{ variable_host | default('web')}}"
एसपीएम

16
यहाँ एक नोट है कि मुझे लगता है कि इस समाधान के लिए खोज करने वाले नएansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
नए शौक के

1
जब (यानी किस क्रम में) में ansible पार्स चर चर करता group_vars/allदिखाई देता है पार्स किया जा सकता के बादhosts: प्लेबुक की लाइन। हालाँकि, चर vars:और चर में लाइन vars_files:से पहले पार्स किया जाता है hosts:? ध्यान दें मैं पूर्वता के बारे में नहीं पूछ रहा हूँ ।
फेलिप अल्वारेज़

2
तुम भी उपयोग कर सकते हैं -eके बजाय --extra-vars
संज्ञा

अधिक जानकारी के लिए अन्य उत्तरों को देखें
आनंद वर्की फिलिप्स

63

किसी के लिए जो समाधान की तलाश में आ सकता है।
प्ले बुक

- 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" तो आप ग्रुप का नाम एक्स्ट्रा-वैर में निर्दिष्ट कर सकते हैं


2
ध्यान दें, var नामकरण के साथ सावधान रहें। मैं इसका उपयोग कर परीक्षण कर रहा था play_hostsऔर अपेक्षित परिणाम प्राप्त नहीं कर रहा था क्योंकि मैं भूल गया था कि play_hostsवर्तमान नाटक में सभी मेजबानों के लिए एक आंतरिक Ansible var है।
रयान फिशर

मुझे लगता है कि डिफ़ॉल्ट को ऊपर दिए गए उत्तर में सेट किया जाना चाहिए।
काकज

19

यह थोड़ा देर से है, लेकिन मुझे लगता है कि आप --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
मैं बहुत नया हूं, लेकिन मैं इसे बहुत प्रभावी उपाय मानता हूं, जो दूसरों की तुलना में बहुत अधिक कॉम्पैक्ट है। इसे क्यों ठुकरा दिया गया?
एलेसेंड्रो डेंटेला

16
यह खतरनाक है। यदि कोई एक limitमेजबानों को प्रभावित करता है तो मेजबानों की सूची में भूल जाने से बहुत नुकसान हो सकता है।
अलेक्जेंडर शेकब्लिकिन

3
मुझे लगता है कि --extra-vars "variable_host=newtarget(s)"स्वीकृत समाधान की तरह उपयोग करना उतना ही खतरनाक और अधिक जटिल समाधान है। यह एक डिफ़ॉल्ट होस्ट का उपयोग करता है webजिसके बजाय यहाँ भी लागू किया जा सकता है all। आप एक गलती से बचने के लिए डिफ़ॉल्ट के रूप में एक सख्त होस्ट समूह का उपयोग कर सकते हैं और --list-hostsध्वज का उपयोग करने के लिए एक स्पष्ट समझ रख सकते हैं कि आप किस मेजबान को प्रभावित कर रहे हैं।
जोनाथन हैमेल

3
अतिरिक्त-संस्करण के साथ समाधान खाली समूह (या गैर-मौजूदा) को डिफ़ॉल्ट मान के रूप में निर्दिष्ट करने की अनुमति देता है। इसलिए यदि आप कमांड लाइन के माध्यम से चर प्रदान करना भूल जाते हैं तो कुछ भी बुरा नहीं होता है। "--Limit" विकल्प के साथ समाधान अधिक खतरनाक है क्योंकि प्लेबुक मेजबान के लिए डिफ़ॉल्ट मान के रूप में खाली समूह का उपयोग नहीं कर सकता है। विकल्प "--llmit" को मेजबान मूल्य पर लागू किया जाता है इसलिए इसे खाली समूहों पर लागू किया जाएगा और खाली परिणाम प्रदान करेगा। तो आपको डिफ़ॉल्ट मान के रूप में "सभी" या कुछ अन्य गैर-खाली होस्ट का उपयोग करना होगा। और किसी दिन आप "- प्रारंभिक" तर्क प्रदान करना भूल जाएंगे और प्लेबुक सभी मेजबानों पर लागू होगी।
ग्रेगरी पेटुखोव

4
इस मामले को पकड़ने के लिए @ TmTron के उत्तर के साथ जोड़ा जाना चाहिए जहां कॉलर आपूर्ति करने में विफल रहा --limit(अन्यथा यह सभी संभावित मेजबानों को प्रभावित करेगा, जो कि आप चाहते हैं कि व्यवहार नहीं हो सकता है)
ncoghlan

14

हम एक सरल विफल कार्य का उपयोग उपयोगकर्ता को बाध्य सीमा विकल्प को निर्दिष्ट करने के लिए करने के लिए करते हैं , ताकि हम डिफ़ॉल्ट / दुर्घटना द्वारा सभी मेजबानों पर निष्पादित न करें।

सबसे आसान तरीका मुझे यह मिला:

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

अब हमें playbook चलाने पर -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"

नकारात्मक सीमा।
नोट: बैश प्रक्षेप को रोकने के लिए एकल उद्धरण का उपयोग किया जाना चाहिए।

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

मेजबान समूह की सीमा

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


7

मैं एक और दृष्टिकोण का उपयोग कर रहा हूं जिसे किसी भी सूची की आवश्यकता नहीं है और इस सरल कमांड के साथ काम करता है:

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

मैं ansible 2.4.3 और 2.3.3 का उपयोग कर रहा हूं


7

मैंने बिना किसी होस्ट के डिफ़ॉल्ट को बदल दिया और इसे पकड़ने के लिए एक चेक किया। इस तरह उपयोगकर्ता या क्रोन को एक एकल होस्ट या समूह आदि प्रदान करने के लिए मजबूर किया जाता है। मुझे @wallydrag की टिप्पणी पसंद है। empty_groupसूची में कोई मेजबान शामिल हैं।

- होस्ट करता है: "{{variable_host | default ('खाली_ग्रुप')}}"

फिर कार्यों में चेक जोड़ें:

   कार्य:
   - नाम: यदि आवश्यक चर_होस्ट पैरामीटर अनुपलब्ध है तो स्क्रिप्ट विफल है
     असफल:
       संदेश: "आपको theextra-vars = 'variable_host =' जोड़ना होगा"
     कब: (variable_host परिभाषित नहीं है) या (variable_host == "" ")

5

बस एक समाधान के लिए इस googling भर में आया था। दरअसल, Ansible 2.5 में एक है। आप अपनी इन्वेंट्री फ़ाइल को --inventoryइस तरह निर्दिष्ट कर सकते हैं :ansible --inventory configs/hosts --list-hosts all


मेरा मानना ​​है कि यह हमारे भगवान के 2019 के वर्ष में सबसे सही उत्तर है। Ansible 2.8.4 -h से:-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated
pyansharp

3

आप एक काम है कि एक मेजबान के साथ जुड़ा हुआ है, लेकिन अलग अलग मेजबान पर चलाना चाहते हैं, तो आप की कोशिश करनी चाहिए delegate_to

आपके मामले में, आपको अपने लोकलहोस्ट (अयोग्य मास्टर) और कॉलिंग ansible-playbookकमांड को सौंपना चाहिए


2

मैं ansible 2.5 (2.5.3 बिल्कुल) का उपयोग कर रहा हूं, और ऐसा लगता है कि मेजबान फाइल को मेजर परम के निष्पादित होने से पहले लोड किया गया है। तो आप होस्ट को एक vars.yml फ़ाइल में सेट कर सकते हैं और बस hosts: {{ host_var }}अपनी प्लेबुक में लिख सकते हैं

उदाहरण के लिए, मेरी playbook.yml में:

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

और अंदर var / project.yml:

---

# general
host_name: your-fancy-host-name

0

यहां एक शांत समाधान है जो मैं --limitविकल्प के माध्यम से मेजबानों को सुरक्षित रूप से निर्दिष्ट करने के लिए आया था । इस उदाहरण में, नाटक समाप्त हो जाएगा यदि प्लेबुक को --limitविकल्प के माध्यम से निर्दिष्ट किसी भी होस्ट के बिना निष्पादित किया गया था ।

इसका परीक्षण Ansible संस्करण 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}}"

0

एक अन्य समाधान विशेष चर का उपयोग करना है ansible_limitजो --limitAnsible के वर्तमान निष्पादन के लिए CLI विकल्प की सामग्री है ।

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

यदि --limitविकल्प छोड़ दिया जाता है, तो अन्सिबल एक चेतावनी जारी करता है, लेकिन तब तक कुछ भी नहीं होता है जब कोई मेजबान मिलान नहीं करता है।

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

PLAY ****************************************************************
skipping: no hosts matched
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.