Ansible oyun kitaplarını tek bir makineyle güvenli bir şekilde sınırlamak mı?


227

Ansible'ı küçük bir bilgisayar grubuyla bazı basit kullanıcı yönetimi görevleri için kullanıyorum. Şu anda, playbook'ları ayarladım hosts: allve hosts dosyam listelenen tüm makinelerle sadece tek bir grup:

# file: hosts
[office]
imac-1.local
imac-2.local
imac-3.local

Kendimi sık sık tek bir makineyi hedeflemek zorunda buldum. ansible-playbookKomut kutu sınırı bu gibi oynuyor:

ansible-playbook --limit imac-2.local user.yml

Ancak bu, özellikle potansiyel olarak yıkıcı bir oyun kitabı için biraz kırılgan görünüyor. limitBayrağı terk etmek, oyun kitabının her yerde çalıştırılacağı anlamına gelir. Bu araçlar yalnızca ara sıra kullanıldığından, oynatmayı kusursuz hale getirmek için adımlar atmaya değer gibi görünmektedir, bu nedenle aylar sonra yanlışlıkla bir şeyleri nükleer silahlarla doldurmuyoruz.

Başucu kitabı çalışmalarını tek bir makineyle sınırlamak için en iyi uygulama var mı? İdeal olarak, bazı önemli ayrıntıların dışarıda bırakılması durumunda oyun kitapları zararsız olmalıdır.

Yanıtlar:


209

Doğrudan oyun kitabına bir ana bilgisayar adı girmenin mümkün olduğu ortaya çıktı, bu nedenle oynatma kitabını çalıştırmak hosts: imac-2.localiyi çalışacaktır. Ama bu biraz hantal.

Daha iyi bir çözüm, bir değişken kullanarak oynatma kitabının ana bilgisayarlarını tanımlamak ve ardından şu yolla belirli bir ana bilgisayar adresini iletmek olabilir --extra-vars:

# file: user.yml  (playbook)
---
- hosts: '{{ target }}'
  user: ...

Başucu kitabını çalıştırma:

ansible-playbook user.yml --extra-vars "target=imac-2.local"

Eğer {{ target }}tanımlı değil, oyun kitabı hiçbir şey yapmaz. Gerekirse hosts dosyasından bir grup da iletilebilir. Genel olarak, bu potansiyel olarak yıkıcı bir oyun kitabı oluşturmak için çok daha güvenli bir yol gibi görünüyor.

Tek bir ana bilgisayarı hedefleyen oynatma kitabı:

$ ansible-playbook user.yml --extra-vars "target=imac-2.local" --list-hosts

playbook: user.yml

  play #1 (imac-2.local): host count=1
    imac-2.local

Bir grup ana bilgisayar içeren oynatma kitabı:

$ ansible-playbook user.yml --extra-vars "target=office" --list-hosts

playbook: user.yml

  play #1 (office): host count=3
    imac-1.local
    imac-2.local
    imac-3.local

Ana bilgisayar tanımlamak unutmak güvenlidir!

$ ansible-playbook user.yml --list-hosts

playbook: user.yml

  play #1 ({{target}}): host count=0

52
Bu, 1.5.3'te--limit office[0]
NG

4
Değişkenin alıntılanması gerekir - yani: '{{ target }}'- docs.ansible.com/… 'a
Limbo Peng

9
Bu, "başarısız güvenli" bir cevaptır, diğerlerinden farklı olarak - bir şeyi dışarıda bırakırsanız, hiçbir şey yapmaz. Ansible 1.7 kullanarak 'sadece' bir ana bilgisayarda çalıştırmak run_oncehala yıkıcı olabilir, bu yüzden bu iyi bir fikir değil.
RichVel

4
Daha kısa bir komutu isterseniz -eeşdeğer taşımaktadır--extra-vars
William Turrell

1
Ansible yapılandırmanız anasistemlerin boş veya tanımsız olmasını gerektiriyorsa, jinja filtresiyle birleştirilmiş bir değişken kullanılır, örneğin:hosts: "{{ target | default('no_hosts')}}"
Zach Weg

178

Ayrıca, bir ara envanter olmadan komut satırında (veya sanırım birden çok ana bilgisayar) tek bir ana bilgisayarı belirtmenize izin veren şirin bir hile var:

ansible-playbook -i "imac1-local," user.yml

Sonunda virgül ( , ); bu bir liste değil, bir liste olduğunu gösterir.

Şimdi, yanlışlıkla gerçek bir envanter dosyasını içeri aktarırsanız sizi koruyamaz, bu nedenle bu özel soruna iyi bir çözüm olmayabilir. Ama bilmek kullanışlı bir numara!


2
Bu inanılmaz. Düzenli olarak etc / ansible / hosts (EC2 bulma API'sı kullanılarak doldurulur) ile çalışan -l bayrağını kullanıyorum, ancak bazen gerçekten tek bir makineye ihtiyacım var. Teşekkür ederim!
Vic

3
Bu hile hosts dosyasını kullanmalı mıdır? Bizim AWS EC2 sistemi için bir dinamik envanter olarak ana kullanıyorum ve döndürür: skipping: no hosts matched. Belki de bu hile artık işe yaradığından beri --limitçalışmıyor?
hamx0r

1
Bu numara benim için işe yaramadı. Ama bu çalıştı: $ ansible-playbook -kK --limit=myhost1 myplaybook.yml. Marwan'ın cevabına bakınız.
Donn Lee

2
Bunun çalışması için ev sahiplerinin alloyun (lar) a ayarlanması gerektiği belirtilmelidir - bu beni anlamaya biraz zaman aldı ...
Remigius Stalder

83

Play_hosts değişkeni kontrol edilerek tek bir ana bilgisayardan fazlası sağlanmışsa bu yaklaşımdan çıkılır . Başarısız modül tek konak koşul yerine getirilmediği takdirde çıkmak için kullanılır. Aşağıdaki örneklerde iki ana bilgisayar alice ve bob içeren bir ana bilgisayar dosyası kullanılmıştır.

user.yml (oynatma kitabı)

---
- hosts: all
  tasks:
    - name: Check for single host
      fail: msg="Single host check failed."
      when: "{{ play_hosts|length }} != 1"
    - debug: msg='I got executed!'

Ana makine filtreleri olmadan oynatma kitabını çalıştırma

$ ansible-playbook user.yml
PLAY [all] ****************************************************************
TASK: [Check for single host] *********************************************
failed: [alice] => {"failed": true}
msg: Single host check failed.
failed: [bob] => {"failed": true}
msg: Single host check failed.
FATAL: all hosts have already failed -- aborting

Başucu kitabını tek bir ana bilgisayarda çalıştır

$ ansible-playbook user.yml --limit=alice

PLAY [all] ****************************************************************

TASK: [Check for single host] *********************************************
skipping: [alice]

TASK: [debug msg='I got executed!'] ***************************************
ok: [alice] => {
    "msg": "I got executed!"
}

1
Kesinlikle en iyisi, --limitgitmek için yol
berto

7
play_hostsAnsible 2.2'de kullanımdan kaldırıldı ve yerine ansible_play_hosts. Bir ana bilgisayarda gerek kalmadan çalıştırmak için --limitkullanabilirsiniz when: inventory_hostname == ansible_play_hosts[0].
Trevor Robinson

[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{ play_hosts|length }} == ''Ansible 2.8.4.
Thomas

32

IMHO daha uygun bir yol var. Gerçekten, kullanıcıyı oyun kitabını uygulamak istediği makine (ler) için etkileşimli olarak aşağıdakiler sayesinde isteyebilirsiniz vars_prompt:

---

- hosts: "{{ setupHosts }}"
  vars_prompt:
    - name: "setupHosts"
      prompt: "Which hosts would you like to setup?"
      private: no
  tasks:
    […]

2
Çok havalı. Bunun avantajı, oynatma kitabının envanter dosyasına özgü olmamasıdır.
Erfan

2
Düzenleme için teşekkürler! Aslında neden varsayılan olarak tedavi "şifre tarzı" olduğunu merak ediyordum. Bunu dokümanlarda kaçırmıştım :)
Buzut

Ana bilgisayarlar, bu oynatma kitabındaki istemi ortadan kaldırmak için komut satırından ayarlanabilir mi?
andig

1
@ andig ile playbook'unuzda --extra-varsnormal bir var…
Buzut

Aslında, bunu işe alamadım - {{ hosts }}değer girilmeden önce değerlendiriliyor gibi görünüyor - veya özel bir hile var mı?
Remigius Stalder

18

Joemailer'ın cevabını genişletmek için, uzak makinelerin herhangi bir alt kümesini ( ansiblekomutun yaptığı gibi) eşleştirmek için desen eşleştirme yeteneğine sahip olmak istiyorsanız , ancak yine de oynatma kitabını yanlışlıkla tüm makinelerde çalıştırmayı çok zorlaştırmak istiyorsanız, bu ne buldum:

Diğer cevaptaki ile aynı oyun kitabı:

# file: user.yml  (playbook)
---
- hosts: '{{ target }}'
  user: ...

Aşağıdaki ana bilgisayarlara sahip olalım:

imac-10.local
imac-11.local
imac-22.local

Şimdi, komutu tüm cihazlarda çalıştırmak için hedef değişkeni "all" olarak ayarlamanız gerekir.

ansible-playbook user.yml --extra-vars "target=all"

Ve bunu belirli bir modelle sınırlamak için, target=pattern_here

veya alternatif olarak, bağımsız değişkeni bırakıp target=allekleyebilirsiniz --limit, örneğin:

--limit imac-1*

yani. ansible-playbook user.yml --extra-vars "target=all" --limit imac-1* --list-hosts

sonuç:

playbook: user.yml

  play #1 (office): host count=2
    imac-10.local
    imac-11.local

Bu benim takip olduğunu kalıptır yanıtlayıcı '-django-Postgres'e-nginx
Ajoy

13

Tüm cevapların ne kadar karmaşık olduğunu gerçekten anlamıyorum, bunu yapmanın yolu basitçe:

ansible-playbook user.yml -i hosts/hosts --limit imac-2.local --check

checkMod herhangi bir değişiklik yapmadan, kuru işletilen modunda çalışmasını sağlar.


7
Muhtemelen cevapları merak ederek, parametreler yanlışlıkla atlandığında çalışmasını önlemenin bir yolunu soran soruyu kaçırdınız. Gereksinime aykırı daha fazla parametre eklemeyi önerdiniz.
techraf

2
ah, elbette, ama eğer insanlar beni onaylarsa, bunun nedeni bayrak hakkında bile bilmeyen Ansible yeni başlayanlar (cevabımı yazdığım gibi) olabilir --check, bu yüzden sanırım bu hala yararlıdır. bu soru çok googlable
knocte

6

EC2 Harici Envanter Komut Dosyasını kullanan AWS kullanıcıları basitçe örnek kimliğine göre filtre uygulayabilir:

ansible-playbook sample-playbook.yml --limit i-c98d5a71 --list-hosts

Envanter komut dosyası varsayılan gruplar oluşturduğundan bu çalışır .


4
Seçenek - sınır EC2 ile sınırlı değildir ve envanterinizin ana makinelerini / gruplarını barındırmak için kullanılabilir. Teşekkürler.
martinezdelariva

5

Çok sayıda ekip tarafından kullanılabilen bazı jenerik oyun kitaplarımız var. Ayrıca, birden çok grup bildirimi içeren ortama özgü envanter dosyalarımız da vardır.

Bir oynatma kitabını çağıran birini karşı çalışacak bir grup belirtmeye zorlamak için oynatma kitabının üst kısmına sahte bir giriş ekiyoruz:

[ansible-dummy-group]
dummy-server

Ardından, paylaşılan kontrol defterine ilk adım olarak aşağıdaki kontrolü ekleriz:

- hosts: all
  gather_facts: False
  run_once: true
  tasks:
  - fail:
      msg: "Please specify a group to run this playbook against"
    when: '"dummy-server" in ansible_play_batch'

Kukla sunucu ana bilgisayar listesinde görünüyorsa, bu oynatma kitabının (ansible_play_batch) karşı çalışması planlanmışsa, arayan bir grup belirtmedi ve oynatma kitabı yürütme başarısız olur.


ansible_play_batchyalnızca geçerli toplu işi listeler, bu nedenle toplu iş kullanırken hala güvenli değildir. Bunun ansible_play_hostsyerine kullanmak daha iyidir .
Thomas

Bunun dışında, bu hile sorulana en basit ve en yakın gibi görünüyor; Kabul ediyorum!
Thomas

4

1.7 sürümünden beri run_once seçeneği vardır. Bu bölüm aynı zamanda diğer çeşitli tekniklerin tartışmasını da içerir.


4

Bu, oyun kitaplarının hedef sunucunun kendisinde nasıl çalıştırılacağını gösterir.

Yerel bir bağlantı kullanmak istiyorsanız bu biraz daha zordur. Ancak, hosts ayarı için bir değişken kullanırsanız ve hosts dosyasında localhost için özel bir giriş oluşturursanız bu sorun olmamalıdır.

(Tümü) oyun kitaplarında hosts: satırı şu şekilde ayarlanır:

- hosts: "{{ target | default('no_hosts')}}"

Envanter ana bilgisayarları dosyasına, yerel ana bilgisayar için bağlantıyı yerel olarak ayarlayan bir girdi ekleyin:

[localhost]
127.0.0.1  ansible_connection=local

Ardından komut satırında hedefi açıkça belirleyen komutları çalıştırın - örneğin:

$ ansible-playbook --extra-vars "target=localhost" test.yml

Bu, ansible-pull kullanırken de işe yarar:

$ ansible-pull -U <git-repo-here> -d ~/ansible --extra-vars "target=localhost" test.yml

Değişkeni komut satırında ayarlamayı unutursanız, komut aşağıdaki uyarı ile güvenli bir şekilde hata verir ('no_hosts'! Adlı bir ana bilgisayar grubu oluşturmadığınız sürece):

skipping: no hosts matched

Ve yukarıda belirtildiği gibi, tek bir makineyi (ana makineler dosyasında olduğu sürece) aşağıdakilerle hedefleyebilirsiniz:

$ ansible-playbook --extra-vars "target=server.domain" test.yml

veya şuna benzer bir grup:

$ ansible-playbook --extra-vars "target=web-servers" test.yml

0

Hüküm adı denilen bir sarmalayıcı komut dosyası var, hedef seçmek için zorlar, bu yüzden başka bir yerde işlemek zorunda değilsiniz.

Meraklı olanlar için, vagrantfile'mın kullandığı seçenekler için ENV değişkenlerini kullanıyorum (bulut sistemleri için karşılık gelen ansible argümanı ekleyerek) ve ansible argümanların geri kalanının geçmesine izin veriyorum. Bir seferde 10'dan fazla sunucu oluşturduğumda ve yetkilendirdiğimde, başarısız sunucularda bir otomatik yeniden deneme ekliyorum (ilerleme kaydedildiği sürece - bir seferde 100 veya daha fazla sunucu oluştururken buldum, çoğu zaman ilk defa başarısız olur ).

echo 'Usage: [VAR=value] bin/provision [options] dev|all|TARGET|vagrant'
echo '  bootstrap - Bootstrap servers ssh port and initial security provisioning'
echo '  dev - Provision localhost for development and control'
echo '  TARGET - specify specific host or group of hosts'
echo '  all - provision all servers'
echo '  vagrant - Provision local vagrant machine (environment vars only)'
echo
echo 'Environment VARS'
echo '  BOOTSTRAP - use cloud providers default user settings if set'
echo '  TAGS - if TAGS env variable is set, then only tasks with these tags are run'
echo '  SKIP_TAGS - only run plays and tasks whose tags do not match these values'
echo '  START_AT_TASK - start the playbook at the task matching this name'
echo
ansible-playbook --help | sed -e '1d
    s#=/etc/ansible/hosts# set by bin/provision argument#
    /-k/s/$/ (use for fresh systems)/
    /--tags/s/$/ (use TAGS var instead)/
    /--skip-tags/s/$/ (use SKIP_TAGS var instead)/
    /--start-at-task/s/$/ (use START_AT_TASK var instead)/
'

0

Biraz farklı bir çözüm, Ansible'ın geçerli yürütülmesi için CLI seçeneğinin ansible_limitiçeriği olan özel değişkeni kullanmaktır --limit.

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

Burada fazladan bir değişken tanımlamanıza gerek yok, sadece çalışma kitabını --limitbayrakla çalıştırın .

ansible-playbook --limit imac-2.local user.yml
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.