2015-03-26 10 views
13

Oto mój problem Muszę użyć jednej zmiennej 'target_host', a następnie dopisać '_host' do jej wartości, aby uzyskać inną nazwę zmiennej, której potrzebuję. Jeśli spojrzysz na mój poradnik. Zadanie nbr 1,2,3 przynosi wartość zmiennej, jednak nbr 4 nie jest w stanie wykonać tego, czego się spodziewam. Czy istnieje inny sposób osiągnięcia tego samego w ansibla?Odpowiedź: jak skonstruować zmienną z innej zmiennej, a następnie pobrać jej wartość

--- 
    - name: "Play to for dynamic groups" 
     hosts: local 
     vars: 
     - target_host: smtp 
     - smtp_host: smtp.max.com 
     tasks: 
     - name: testing 
      debug: msg={{ target_host }} 
     - name: testing 
      debug: msg={{ smtp_host }} 
     - name: testing 
      debug: msg={{ target_host }}_host 
     - name: testing 
      debug: msg={{ {{ target_host }}_host }} 


Output: 

TASK: [testing] *************************************************************** 
ok: [127.0.0.1] => { 
    "msg": "smtp" 
} 

TASK: [testing] *************************************************************** 
ok: [127.0.0.1] => { 
    "msg": "smtp.max.com" 
} 

TASK: [testing] *************************************************************** 
ok: [127.0.0.1] => { 
    "msg": "smtp_host" 
} 

TASK: [testing] *************************************************************** 
ok: [127.0.0.1] => { 
    "msg": "{{{{target_host}}_host}}" 
} 

Odpowiedz

3

Musisz umieścić cudzysłowy wokół niego:

- hosts: local 
    vars: [ target_host: smtp ] 
    tasks: 
    debug: msg="{{ target_host }}_host" 

- Edit -

Kashyapa muszę iść jeszcze jeden poziom niż ten. Wyobraź sobie, że istnieje kolejna zmienna "smtp_host" i chcę ją skonstruować przy użyciu środowiska wykonawczego przy użyciu innej zmiennej (target_host) i dołączeniu do niej łańcucha znaków "01host" ( ). = {{{{target_host}} _ host}} - Max

Mój zły. Nie czytałem wystarczająco uważnie.

To (AFAIK) nie jest możliwe. Głównym ograniczeniem, które powstrzymuje nas przed zrobieniem tego (bez względu na to, jak je kręcisz), jest "zmienna ekspansja" w ansible to proces jednoprzejściowy, a to, czego oczekujesz, wymaga wielu przebiegów.

tylko poważnie hacky] [sposobów mogę myśleć to:

  • Tworzenie Playbook dynamicznie z playbook użyciu template i wykonać ją.
  • I słyszał że silnik Jinja2 wykonuje ocenę wieloprzebiegową. Może być, jeśli umieścisz te ciągi w szablonie, a następnie użyjesz filtru lookup('template', ...). Niestety nie mam doświadczenia z szablonami Jinja2, więc nie jestem pewien czy jest to opcja.
+0

Kashyapa I n Aby przejść o jeden poziom wyżej niż to. Wyobraź sobie, że istnieje inna zmienna "smtp_host" i chcę ją skonstruować w czasie wykonywania, używając innej zmiennej (target_host) i dołączając do niej ciąg "_host". = {{{target_host}} _ host}} – Max

+3

Za każdym razem, gdy ktoś dzwoni "ansibli-playbook test.yml -i hosts" w playbooku, kotka umiera. – J0hnG4lt

+0

@ J0hnG4lt: D: D – Kashyap

0

Można gniazdo odpytywanie tak:

--- 
- hosts: local 
    connection: local 
    gather_facts: no 
    vars: 
    target_host: smtp 
    lookup_host: "{{ target_host }}_host" 
    smtp_host: smtp.max.com 
    tasks: 
    - debug: var="{{ lookup_host }}" 
+2

Działa to tylko w przypadku wyjątku 'debug: var =', ponieważ jest wyjątkowe. Nie możesz przekazać go do innego modułu. Na przykład. 'debug: msg =" {{lookup_host}} "' lub 'shell: echo" {{lookup_host}} "' – Kashyap

7

Można użyć "hostvars" przekazać zmienną, fakty gospodarza mogą być ładowane z grupy vars lub host vars

yml

--- 
- name: "Play to for dynamic groups" 
    hosts: x0 
    vars: 
    - target_host: smtp 
    tasks: 
    - set_fact: smtp_host="smtp.max.com" 
    - set_fact: host_var_name={{target_host}}_host 
    - set_fact: dym_target_host={{hostvars[inventory_hostname][host_var_name]}} 

    - name: testing 
     debug: msg={{ target_host }} 
    - name: testing 
     debug: msg={{ smtp_host }} 
    - name: testing 
     debug: msg={{ target_host }}_host 
    - name: testing 
     debug: msg={{ dym_target_host }} 

wyjściowa:

PLAY [Play to for dynamic groups] ********************************************* 

GATHERING FACTS *************************************************************** 
ok: [x0] 

TASK: [set_fact smtp_host="smtp.max.com"] ************************************* 
ok: [x0] 

TASK: [set_fact host_var_name=smtp_host] ************************************** 
ok: [x0] 

TASK: [set_fact dym_target_host={{hostvars[inventory_hostname][host_var_name]}}] *** 
ok: [x0] 

TASK: [testing] *************************************************************** 
ok: [x0] => { 
    "msg": "smtp" 
} 

TASK: [testing] *************************************************************** 
ok: [x0] => { 
    "msg": "smtp.max.com" 
} 

TASK: [testing] *************************************************************** 
ok: [x0] => { 
    "msg": "smtp_host" 
} 

TASK: [testing] *************************************************************** 
ok: [x0] => { 
    "msg": "smtp.max.com" 
} 

PLAY RECAP ******************************************************************** 
x0       : ok=8 changed=0 unreachable=0 failed=0 
2

obecnie używam składni podobnej do tablicy Jinja 2. Nie sądzę, że to świetne rozwiązanie, ale muszę jeszcze znaleźć coś lepszego.

Podam przykład z jednym z moich wyodrębnionych zadań.Zobacz mój zmienna konfiguracja i przykład zadanie poniżej:

# Variables file, available in the task context 
containers: 
    app: 
    image: mynamespace/myappcontainer:snapshot 
    web: 
    image: nginx:latest 
    db: 
    image: mariadb:latest 



# Example task 
- name: Start containers 
    docker_container: 
    name: "{{ item }}" 
    image: "{{ containers[item].image }}" 
    with_items: 
    - app 
    - web 
    - db 

W powyższym przykładzie używam with_items ansibl pętlę, który uruchamia zadanie dla każdej pozycji i sprawia, że ​​zmienna {{ item }} odpowiednio dostępny.
Powoduje to utworzenie 3 kontenerów Docker, każdy z prawidłową nazwą kontenera na podstawie listy elementów oraz prawidłowym obrazem pobranym ze skonfigurowanych zmiennych zewnętrznych.

Mimo że ten przykład używa with_items, można go oczywiście dostosować do problemu za pomocą własnych zmiennych.

Mimo że działa to doskonale w tej sytuacji, obawiam się, że zmienne, do których chcesz uzyskać dostęp, są częścią pewnej zmiennej nadrzędnej (containers w tym przykładzie). Dlatego zaleca się podzielenie zmiennych na ., aby utworzyć hierarchię, a nie na _.

Zmienna, taka jak a.b.c, gdzie b jest dynamiczna, byłaby dostępna pod numerem a[b].c.
Zmienna taka jak a.b, gdzie b jest dynamiczna, byłaby dostępna za pomocą a[b].


Rozwiązaniem byłoby użyć może wyglądać (niesprawdzone):

- name: "Play to for dynamic groups" 
    hosts: local 
    vars: 
    - target: smtp 
    - hosts: 
     smtp: smtp.max.com 
     imap: imap.max.com 
    tasks: 
    - name: testing 
     debug: msg={{ hosts[target] }} 

Zauważ, że zmienne są nieco inaczej skonfigurowany, ponieważ jest to struktura jest hierarchiczny.

+0

To wygląda na zgrabny sposób, aby osiągnąć to, co chciałem. Ważnym punktem uwagi z wyjaśnienia @ kashyap jest "" zmienna ekspansja "w ansible jest procesem jednoprzebiegowym" – Max

+0

Nie sądzę, że jest to pojedynczy przebieg, ponieważ zmienna wewnątrz '[]' jest oceniana, a jej wartość jest używana jako klawisz. W razie potrzeby wiele nawiasów może być połączonych ze sobą. W każdym razie dobrze to usłyszeć! –

+0

Wil widzę, czy mogę to zrobić, patrząc na źródło lub może skorzystać z pomocy społeczności programistów, która pomaga w ansibli. Dziękuję Ci ! – Max

2

Jeśli zmienna jak

vars: myvar: xxx xxx_var: anothervalue

Roboczej ansibl składni:

- debug: msg={{ vars[myvar + '_var'] }}

daje analog:

- debug: msg={{ xxx_var }}

Powiązane problemy