2016-08-22 14 views
5

Po przejrzeniu kilku dokumentacji doszedłem do wniosku, że nie mogę użyć with_items dla roles.Tworzenie dynamicznej roli w ansible

Stworzyłem więc filter_plugin, aby wygenerować listę słowników dla ról.

Oto mój Play:

--- 
- name: Boostrap vpc and subnets with route table 
    hosts: localhost 
    connection: local 
    gather_facts: no 
    pre_tasks: 
    - include_vars: ec2_vars/common/regions.yml 
    - include_vars: environment.yml 
    roles: 
    - { 
     role: vpc, 
     ec2_region: 'ap-southeast-2' 
     } 
    - { 
     role: vpc, 
     ec2_region: "ap-southeast-1", 
     } 
    - { 
     role: vpc, 
     ec2_region: "us-west-2", 
     } 

Chcę, aby wygenerować powyżej ról dynamicznie i że stworzył filter_plugin który generuje listę słowników i że działa prawidłowo.

Oto mój plugin:

# this is for generating vpc roles 

def roles(ec2_regions): 
    return [{'role': 'vpc', 'ec2_region': ec2_region} for ec2_region in ec2_regions] 


class FilterModule(object): 
    def filters(self): 
     return {'vpcroles': roles} 

Mój plan był do generowania role jak następuje:

roles: "{{ EC2_REGIONS | vpcroles }}" 

gdzie EC2_REGIONS jest ['ap-southeast-2', 'us-east-1']

Ale role nie działa w ten sposób.

otrzymuję następujący błąd:

ERROR! A malformed role declaration was encountered.

wszelkie myśli/pomysły?

+0

Nie rozwiązuje twojego problemu, ale twój YAML jest niespójny. Używasz pojedynczych i podwójnych cudzysłowów (dla 'ec2_region'), gdzie nie są one potrzebne, i bez cudzysłowów dla innych wartości skalarnych. Możesz także niekonsekwentnie stosować końcowy przecinek w odwzorowaniu stylu przepływu (elementy wartości dla 'ról'). IMO, jeśli korzystasz z odwzorowań stylu wielowierszowego, zawsze używaj przecinka końcowego lub lepiej korzystaj z odwzorowań stylu blokowego. – Anthon

+0

@Anthon Noted, dziękuję. – Suku

Odpowiedz

2

Kolega pokazał mi drogę do osiągnięcia dynamicznego role. Oto to.

Struktura katalogów:

- vpc.yml 
| 
- roles/vpc/tasks/main.yml 
| 
- roles/vpc/tasks/real.yml 

Play - vpc.yml:

--- 
- name: Boostrap vpc and subnets with route table 
    hosts: localhost 
    connection: local 
    gather_facts: no 
    vars: 
    pre_tasks: 
    - include_vars: environment.yml 
    roles: 
    - { role: "vpc", ec2_regions: "{{ EC2_REGIONS }}"} 

Rola - roles/vpc/tasks/main.yml:

- include: real.yml ec2_region="{{ _region }}" 
    with_items: "{{ ec2_regions }}" 
    loop_control: 
    loop_var: _region 

I dodaje moje zadania w roles/vpc/tasks/real.yml

+0

Edytowałem odpowiedź. zastąpił '{{nazwa_roli}}} rzeczywistą nazwą roli. Lmk, jeśli nie jest to teraz jasne. – Suku

+0

to jest 'loop_var'. Nie mogę użyć 'item' jako nazwy zmiennej, ponieważ już używam' with_items' w 'real.yml'. Tak więc potrzebna jest inna nazwa zmiennej – Suku

+0

W ścieżce katalogu wystąpił błąd. Opuściłem katalog 'tasks' po napisaniu odpowiedzi. domyślnie 'main.yml' zostanie wykonany. – Suku

1

Bardzo ostry dowód koncepcji. Byłem ciekawy, czy to zadziała i tak będzie.

Głównym problemem jest to, że dynamicznie tworzony zakładka jest wywoływana z wewnątrz zadania, a jego standardowe wyjście nie przechodzi do głównego dziennika odpowiedzi (można go zarejestrować w zmiennej głównego podręcznika i wyświetlać jako taki). Błędy rozprzestrzeniają się do rodzica-playbooka.

główna PlayBook:

--- 
- hosts: localhost 
    connection: local 
    vars: 
    params: 
     - val1 
     - val2 
    tasks: 
    - template: 
     src: role_call.yml.j2 
     dest: ./dynamic/role_call.yml 
    - command: ansible-playbook ./dynamic/role_call.yml 

Dynamiczny szablon PlayBook w templates/role_call.yml.j2 file:

- hosts: localhost 
    connection: local 
    roles: 
    {% for param in params %} 
    - { role: role1, par: {{param}} } 
    {% endfor %} 

roles/role1/tasks/main.yml:

- debug: var=par 

Chyba wewnętrzne polecenie ansible-playbook można nazwać z oddzielnym ansible.cfg jako argument do zapisania dziennika w innym pliku.

Ogólnie rzecz biorąc nie jest to warte kłopotów w twoim przypadku, ale dla problemu, który nie może być rozwiązany inaczej like this wygląda obiecująco.

+0

dzięki technice. Mój kolega pokazał mi inną drogę i postanowił pójść z tym. Zaktualizuję wątek z tym samym. – Suku

1

Można użyć dummy-gospodarze jako obejście:

--- 
- hosts: localhost 
    vars: 
    ec2_regions: 
     - ap-southeast-2 
     - ap-southeast-1 
     - us-west-2 
    tasks: 
    - add_host: name=vpc_{{ item }} ansible_connection=local group=vpcs ec2_region={{ item }} 
     with_items: "{{ ec2_regions }}" 

- hosts: vpcs 
    roles: 
    - role: my_role