Ansible başucu kitabının ana bilgisayar değişkenini komut satırından geçersiz kılın


110

Bu, kullandığım bir başucu kitabının bir parçası ( server.yml):

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

Ana bilgisayarlar dosyamın farklı sunucu grupları var, ör.

[web]
x.x.x.x

[droplets]
x.x.x.x

Şimdi yürütmek istiyorum ansible-playbook -i hosts/<env> server.ymlve geçersiz hosts: webgelen server.ymlbu senaryo çalıştırmak için [droplets].

server.ymlDoğrudan düzenlemeden tek seferlik bir şey olarak geçersiz kılabilir miyim ?

Teşekkürler.

Yanıtlar:


128

Ansible'ın olması gereken bu özelliği sağladığını sanmıyorum. İşte yapabileceğiniz bir şey:

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

ve variable_hostkomut satırından veya değişken dosyasından geçebilirsiniz , örneğin:

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

3
Küçük bir düzeltme gerekli. O olmalıhosts: "{{ variable_host | default('web')}}"
SPM

16
İşte bu çözümü arayan yeni başlayanlar için cevabı tamamlayacağımı düşündüğüm bir not: Örnek:ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"
Frobbit

1
NE ZAMAN (yani, hangi sırayla) değişkenler yanıtlanabilir ayrıştırılır içindeki değişkenler, başucu kitabının satırından sonragroup_vars/all ayrıştırılmış görünüyor . Ancak, içindeki değişkenler ve içindeki değişkenler satırdan önce çözümlenir ? NOT ı am değil önceliği hakkında soran. hosts:vars:vars_files:hosts:
Felipe Alvarez

2
Bunun -eyerine de kullanabilirsiniz --extra-vars.
isim

Daha fazla ayrıntı için diğer yanıtlara bakın
Anand Varkey Philips

63

Çözüm aramaya gelebilecek herkes için.
Kitap Oynat

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

Envanter

[web]
x.x.x.x

[droplets]
x.x.x.x

Komut: ansible-playbook deplyment.yml -i hosts --extra-vars "host=droplets" Böylece ekstra değişkenlerde grup adını belirtebilirsiniz.


2
Not, değişken adlandırma konusunda dikkatli olun. Bunu kullanarak test ediyordum play_hostsve beklenen sonuçları alamıyordum çünkü play_hostsbunun mevcut oyundaki tüm ana bilgisayarlar için dahili bir Ansible varyantı olduğunu unuttum .
Ryan Fisher

Sanırım varsayılan yukarıdaki cevapta olduğu gibi ayarlanmalıdır.
kakaz

19

Bu biraz geç, ancak bence bu --limit or -lkomutu, kalıbı daha belirli ana bilgisayarlarla sınırlamak için kullanabileceğinizi düşünüyorum . (sürüm 2.3.2.0)

Alabilirdin - hosts: all (or group) tasks: - some_task

ve sonra bu yapılandırmanın hangi ana bilgisayarlara uygulanacağını görmek ansible-playbook playbook.yml -l some_more_strict_host_or_pattern için --list-hostsbayrağı kullanın.


3
Yanıtlayıcı konusunda çok yeniyim ancak bunun çok etkili bir çözüm olduğunu düşünüyorum, diğerlerinden çok daha kompakt. Neden reddedildi?
Alessandro Dentella

16
Bu tehlikeli. limitEtkilenen ana bilgisayarların listesini unutursanız , oyun kitabı çok fazla zarara neden olabilir.
Alexander Shcheblikin

3
--extra-vars "variable_host=newtarget(s)"Kabul edilen çözüm gibi kullanmanın da tehlikeli ve daha karmaşık bir çözüm olduğunu görüyorum . Bunun webyerine burada da uygulanabilecek varsayılan bir ana bilgisayar kullanır all. Hata yapmaktan kaçınmak için varsayılan olarak katı bir ana bilgisayar grubunu kullanabilir ve --list-hostshangi ana bilgisayarları etkilediğinizi net bir şekilde anlamak için bayrağı kullanabilirsiniz .
Jonathan Hamel

3
Ekstra değişkenli çözüm, boş grubu (veya mevcut olmayan) varsayılan değer olarak belirtmeye izin verir. Yani değişkeni komut satırı ile sağlamayı unutursanız, kötü bir şey olmaz. "--Limit" seçeneğiyle çözüm daha tehlikelidir çünkü başucu kitabı ana bilgisayarlar için varsayılan değer olarak boş grubu kullanamaz. "--Llmit" seçeneği ana bilgisayar değerine uygulanır, bu nedenle boş gruplara uygulanacak ve boş sonuç verecektir. Bu nedenle, varsayılan değer olarak "tümünü" veya boş olmayan başka bir ana bilgisayarı kullanmanız GEREKİR. Ve bir gün "--limit" argümanını sağlamayı unutacaksınız ve oyun kitabı tüm ev sahiplerine uygulanacak.
Gregory Petukhov

4
Arayanın tedarik edemediği durumu yakalamak için bu, @ TmTron'un cevabı ile birleştirilmelidir --limit(aksi takdirde, istediğiniz davranış olmayabilir, olası tüm ana bilgisayarları etkileyecektir)
ncoghlan

14

Kullanıcıyı Ansible limit seçeneğini belirtmeye zorlamak için basit bir başarısızlık görevi kullanırız , böylece varsayılan / kaza olarak tüm ana bilgisayarlarda çalıştırmayız.

Bulduğum en kolay yol şuydu:

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

Şimdi başucu kitabını çalıştırdığımızda -l(= --limitseçeneğini) kullanmalıyız, örneğin

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

Seçenek belgelerini sınırla :

Bir veya daha fazla ana bilgisayarla sınırlayın Bu, bir oyun kitabını bir ana bilgisayar grubuna karşı, ancak yalnızca o grubun bir veya daha fazla üyesine karşı çalıştırmak istediğinde gereklidir.

Bir ana bilgisayarla sınırlayın

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

Birden çok ana bilgisayarla sınırlayın

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

Olumsuz sınır.
NOT: Bash enterpolasyonunu önlemek için tek tırnak işaretleri KULLANILMALIDIR.

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

Ev sahibi grubuyla sınırla

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


7

Envantere ihtiyaç duymayan ve şu basit komutla çalışan başka bir yaklaşım kullanıyorum:

ansible-playbook site.yml -e working_host=myhost

Bunu gerçekleştirmek için iki oyun içeren bir oyun kitabına ihtiyacınız var:

  • ilk oyun localhost üzerinde çalışır ve bellek içi envanterde bilinen bir gruba bir ana bilgisayar (belirli bir değişkenden) ekler
  • bu bilinen grupta ikinci oyun çalışır

Çalışan bir örnek (kopyalayın ve önceki komutla çalıştırın):

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

Yanıtlanabilir 2.4.3 ve 2.3.3 kullanıyorum


7

Benimkini varsayılan olarak ana bilgisayar yok olarak değiştirdim ve onu yakalamak için bir çekim var. Bu şekilde kullanıcı veya cron, tek bir ana bilgisayar veya grup vb. Sağlamak zorunda kalır. @Wallydrag'dan gelen yorumdaki mantığı seviyorum. empty_groupEnvanter hiçbir makineleri içerir.

- ana bilgisayarlar: "{{değişken_ ana bilgisayar | varsayılan ('boş_grup')}}"

Ardından check-in görevlerini ekleyin:

   görevler:
   - isim: Gerekli variable_host parametresi eksikse, başarısız komut dosyası
     başarısız:
       msg: "--extra-vars = 'variable_host =' eklemelisiniz"
     ne zaman: (variable_host tanımlı değil) veya (variable_host == "")

5

Bir çözüm için bu Google'a rastladım. Aslında Ansible 2.5'te bir tane var. Envanter dosyanızı şu şekilde belirtebilirsiniz --inventory:ansible --inventory configs/hosts --list-hosts all


Bunun, Rabbimiz 2019 -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated
Yılındaki

3

Bir ana bilgisayarla ilişkili ancak farklı bir ana bilgisayarda bir görevi çalıştırmak istiyorsanız, delegate_to'yu denemelisiniz .

Sizin durumunuzda, localhost'unuza (cevap verilebilir yönetici) ve çağrı ansible-playbookkomutuna yetki vermelisiniz


2

Ansible 2.5 (tam olarak 2.5.3) kullanıyorum ve ana bilgisayar parametresi çalıştırılmadan önce vars dosyası yüklenmiş görünüyor . Böylece ana bilgisayarı bir vars.yml dosyasında ayarlayabilir ve sadece hosts: {{ host_var }}oyun kitabınıza yazabilirsiniz .

Örneğin, playbook.yml'de:

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

Ve vars / project.yml içinde:

---

# general
host_name: your-fancy-host-name

0

İşte ana bilgisayarları --limitseçenek aracılığıyla güvenli bir şekilde belirtmek için geldiğim harika bir çözüm . Bu örnekte, oyun kitabı, aracılığıyla herhangi bir ana bilgisayar belirtilmeden çalıştırıldıysa sona erecektir.--limit seçenek .

Bu Ansible 2.7.10 sürümünde test edildi

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

Diğer bir çözüm, Ansible'ın mevcut ansible_limitçalışması için --limitCLI seçeneğinin içeriği olan özel değişkeni kullanmaktır .

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

Eğer --limitseçenek, daha sonra yanıtlayıcı 'konuları bir uyarı atlanmış, ancak eşleşen hiçbir dizi beri hiçbir şey yapmaz edilir.

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

PLAY ****************************************************************
skipping: no hosts matched
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.