2015-09-25 17 views
9

Na stronie Sprawdzone metody sprawdzania poprawności: http://docs.ansible.com/ansible/playbooks_best_practices.html#top-level-playbooks-are-separated-by-role pokazuje przykład, w którym główny element witryny site.yml zawiera kilka innych podręczników najwyższego poziomu, webservers.yml i dbservers.yml. W tych książeczkach każdy zawiera wspólną rolę. Niektóre pliki inwentarza Mam wszystkie moje grupy uruchomione na jednym hoście. Kolejny plik inwentarzowy Mam hosta na grupę. W przypadku, gdy kiedykolwiek grupa jest na jednym hoście, jeśli uruchomię serwis site.yml, widzimy, że wspólną rolą jest gra dwa razy, jeden dla webservers.yml i jeden dla dbservers.yml.Sprawdzona metoda sprawdzania poprawności nie powtarza wspólnej roli.

Co to jest rozwiązanie, aby tego uniknąć? Domyślam się, że możesz wziąć wspólną rolę z webservers.yml i dbservers.yml, a zamiast tego w witrynie site.yml masz zadanie, które jest kierowane zarówno na wspólną rolę. Ale nie mogę indywidualnie udostępniać serwera WWW lub serwera baz danych ze wspólną.

Odpowiedz

1

Moje podejście polega na tym, że nie ma w nich podręczników. Przynajmniej nie, gdy spowoduje to rola wykonywania wiele razy w jednym zadaniu.

Wszystko, co muszę umieścić w więcej niż jednym czytniku, zostaje przekształcone w rolę i rolę tę można umieścić w wielu podręcznikach. Jeśli skończę z kilkoma książkami, które zawierają zduplikowaną serię ról, mogę połączyć te role w jedną rolę, która zależy od innych ról, aby uniknąć tego duplikowania.

1

Moje podejście polega na utworzeniu pliku lock na serwerze dla każdej roli. Działa to całkiem nieźle.

Na przykład mam rolę nazwie common to jak moja tasks/main.yml wygląda następująco:

- name: check lock file exist 
    stat: path=/tmp/ansible-common-role 
    ignore_errors: true 
    register: lock_file 

- name: install apt packages 
    apt: name={{ item }} state=present 
    with_items: 
    - python-setuptools 
    when: lock_file.stat.exists == false 

..... 
# other tasks with 
# when: lock_file.stat.exists == false 
..... 

- name: Create lock file 
    file: path=/tmp/ansible-common-role state=touch 
    when: lock_file.stat.exists == false 

Jak widać na powyższym przykładzie, PlayBook będzie pominąć wszystkie zadania, jeśli jest już prowadził.

3

Ustalam zależności między rolami, korzystając z plików meta w moim katalogu ról. Zależności ról umożliwiają automatyczne pobieranie innych ról podczas używania roli. Zależności ról są przechowywane w pliku meta/main.yml zawartym w katalogu ról.

Zależności ról są zawsze wykonywane przed rolą, która je zawiera i są rekurencyjne. Domyślnie role mogą być dodane jako zależność tylko raz - jeśli inna rola również wymieni je jako zależność, nie będzie uruchamiana ponownie. To zachowanie można przesłonić, dodając parametr allow_duplicates: yes do pliku meta/main.yml.

See an example in the Ansible documentation.

+1

Lubię to podejście i wydaje się mieć największy sens dla mnie. Jednak kiedy faktycznie próbuję to zaimplementować, to nie działa. Moja wspólna rola nadal działa wiele razy. Próbowałem jawnie ustawić allow_duplicates: no bez efektu. Wydaje się, że są inni ludzie z tym samym problemem? https://github.com/ansible/ansible/issues/5971 – user1087973

0

Można też budować grupę temp użyciu add_host, coś jak:

1. target: webservers--> add hosts to group "common_roles" 
2. target: dbservers --> add hosts to gruop "common_roles" 
3. Target: common_roles --> execute whatever common roles you need 
4. regular group by group execution. 
1

jak inni miałem ten problem, a nawet jeśli rola jest idempotent, to trochę czasu, aby wykonać, więc możemy chcieć wykonać to tylko raz.

Użyłem podobnego podejścia niż @Vor, ale wybieram facts zamiast tworzyć pliki.

Przypomnienie:

Fakty przetrwać między spektakli podczas biegu ansibl, ale nie zostaną zapisane w poprzek egzekucji nawet jeśli używasz fakt cache.

Przykład

site.yml

--- 
- hosts: all 
    roles: [common] 
- include: db.yml 
- include: web.yml 

db.yml

--- 
- hosts: db 
    roles: 
    - { role: common, when: isdef_common_role is not defined } 
    - db 

web.yml

--- 
- hosts: web 
    roles: 
    - { role: common, when: isdef_common_role is not defined } 
    - web 

roles/common/tasks/main.yml

--- 
- debug: 'msg="{{ inventory_hostname }} common"' 
- set_fact: isdef_common_role=1 

To jest rzeczywiście nieco zbędny (co trzeba zrobić warunkowe to za każdym razem), ale mają następujące zalety:

  • działa w większości sytuacji, w których mogę myśleć (ansible-playbook site.yml, ansible-playbook site.yml -l common, ansible-playbook site.yml -l db, ansible-playbook db.yml ...)
  • pozwalają zdecydować, czy chcesz, aby powtórzyć wykonanie wspólnego

Jeśli nie chcesz, aby powtórzyć { role: common, when: isdef_common_role is not defined }, można postawić warunek do wspólnej roli pomocą następujące:

site.yml: nie zmienia

db.yml, web.yml: usunąć warunkowego z ról

roles/common/tasks/main.yml

--- 
- include: tasks.yml 
    when: isdef_common_role is not defined 
- set_fact: isdef_common_role=1 

roles/common/tasks/tasks.yml

--- 
- debug: 'msg="{{ inventory_hostname }} common"' 
3

@ user1087973 Używasz znaczniki? Jeśli używasz tagów wspólna rola z różnymi znacznikami jest pod uwagę jako inna:

Na przykład:

role_common

role1: hosta SRV tag_role_1 zależy role_common

roli 2: host SRV tag_role_2 zależy od role_common

Common rola zostanie wykonane dwa razy, ponieważ jest traktowany jako inna, ponieważ tagów

Spójrz z --list-tasks i widać, że

Prawidłowe rozwiązanie zamiast używać znaczników jest użycie różnych plików yml i umieścić go w swojej site.yml

http://docs.ansible.com/ansible/playbooks_best_practices.html#top-level-playbooks-are-separated-by-role

nadzieję, że może to pomóc

Powiązane problemy