Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Toto je přepis představení na DevOps-40 2020-03-18:

Počínaje druhým potvrzením se jakýkoli kód stane dědictvím, protože počáteční představy se začínají rozcházet s drsnou realitou. To není dobré ani špatné, je to danost, se kterou se těžko polemizuje a musí se s ní žít. Součástí tohoto procesu je refaktoring. Refaktoring Infrastructure as Code. Nechť začne příběh o tom, jak za rok zrefaktorovat Ansible a nezbláznit se.

Zrození dědictví

Den #1: Pacient nula

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Kdysi dávno existoval podmíněný projekt. Měl vývojářský tým a inženýry Ops. Řešili stejný problém: jak nasadit servery a spustit aplikaci. Problém byl v tom, že každý tým tento problém vyřešil po svém. V projektu bylo rozhodnuto použít Ansible k synchronizaci znalostí mezi týmy Dev a Ops.

Den #89: Zrození dědictví

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Aniž by si toho sami všimli, chtěli to udělat co nejlépe, ale ukázalo se, že je to dědictví. Jak se to stane?

  • Máme tady naléhavý úkol, pojďme udělat špinavý hack a pak to opravit.
  • Nemusíte psát dokumentaci a vše je jasné, co se zde děje.
  • Znám Ansible/Python/Bash/Terraform! Podívej, jak můžu uhnout!
  • Jsem Full Stack Overflow Developer a zkopíroval jsem to ze stackoverflow, nevím, jak to funguje, ale vypadá to skvěle a řeší problém.

Výsledkem je, že můžete získat nesrozumitelný typ kódu, pro který neexistuje žádná dokumentace, není jasné, co dělá, zda je potřeba, ale problém je, že jej musíte vyvinout, upravit, přidat berličky a podpory , což situaci ještě zhoršuje.

- hosts: localhost
  tasks:
    - shell: echo -n Z >> a.txt && cat a.txt
      register: output
      delay: 1
      retries: 5
      until: not output.stdout.find("ZZZ")

Den #109: Uvědomění si problému

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Původně koncipovaný a implementovaný IaC model již nesplňuje požadavky uživatelů / business / jiných týmů a čas na změny v infrastruktuře přestává být akceptovatelný. V tuto chvíli přichází pochopení, že je čas jednat.

IaC refaktoring

Den #139: Opravdu potřebujete refaktoring?

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Než se vrhnete na refaktor, musíte si odpovědět na několik důležitých otázek:

  1. Proč tohle všechno potřebuješ?
  2. Máš čas?
  3. Stačí znalosti?

Pokud nebudete vědět, jak odpovědět na otázky, pak refaktoring skončí dříve, než vůbec začne, nebo se může jen zhoršit. Protože měl zkušenosti ( Co jsem se naučil při testování 200 000 řádků kódu infrastruktury), poté projekt obdržel žádost o pomoc s opravou rolí a jejich pokrytím testy.

Den #149: Příprava refaktoringu

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

První věcí je připravit se. Rozhodněte se, co budeme dělat. Za tímto účelem komunikujeme, nacházíme problémové oblasti a hledáme způsoby, jak je vyřešit. Výsledné koncepty nějak zaznamenáme, například článek v konfluenci, takže když vyvstane otázka „co je nejlepší?“ nebo "co je správné?" Neztratili jsme cestu. V našem případě jsme se drželi myšlenky rozděl a panuj: rozbijeme infrastrukturu na malé kousky/cihly. Tento přístup vám umožňuje vzít izolovanou část infrastruktury, pochopit, co dělá, pokrýt ji testy a změnit ji, aniž byste se museli bát, že něco rozbijete.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Ukazuje se, že testování infrastruktury se stává základním kamenem a zde stojí za zmínku pyramida testování infrastruktury. Úplně stejná myšlenka, která je ve vývoji, ale pro infrastrukturu: přecházíme od levných rychlých testů, které kontrolují jednoduché věci, jako je odsazení, k drahým plnohodnotným testům, které nasadí celou infrastrukturu.

Možné pokusy o testování

Než se pustíme do popisu toho, jak jsme na projektu pokryli testy Ansible, popíšu pokusy a přístupy, které jsem měl možnost dříve použít, abych porozuměl kontextu přijatých rozhodnutí.

Den č. -997: Poskytnutí SDS

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Poprvé jsem Ansible testoval na projektu vývoje SDS (Software Defined Storage). Na toto téma existuje samostatný článek
Jak lámat kola přes berle při testování vaší distribuce, ale zkrátka jsme skončili u obrácené testovací pyramidy a testování jsme strávili na jedné roli 60-90 minut, což je dlouhá doba. Základem byly testy e2e, tzn. nasadili jsme plnohodnotnou instalaci a následně otestovali. Co bylo ještě horší, byl vynález vlastního kola. Ale musím uznat, že toto řešení fungovalo a umožňovalo stabilní vydání.

Den # -701: Přístupná a testovací kuchyně

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Rozvinutím myšlenky testování Ansible bylo použití hotových nástrojů, konkrétně test kitchen / kitchen-ci a inspec. Výběr byl dán znalostí Ruby (podrobněji viz článek o Habré: Sní programátoři YML o testování Ansible?) pracoval rychleji, asi 40 minut na 10 rolí. Vytvořili jsme balíček virtuálních strojů a spustili testy uvnitř.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Obecně roztok fungoval, ale kvůli heterogenitě tam byl nějaký sediment. Když se počet testovaných lidí zvýšil na 13 základních rolí a 2 meta role kombinující menší role, pak najednou začaly testy běžet 70 minut, což je téměř 2x déle. Bylo těžké mluvit o praktikách XP (extrémní programování), protože... nikdo nechce čekat 70 minut. To byl důvod ke změně přístupu

Den # -601: Ansible a molekula

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Koncepčně je to podobné jako testkitchen, pouze jsme přesunuli testování rolí do dockeru a změnili zásobník. Díky tomu se čas zkrátil na stabilních 20-25 minut pro 7 rolí.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Tím, že jsme zvýšili počet testovaných rolí na 17 a lintali 45 rolí, jsme to provedli za 28 minut na 2 otrokech Jenkins.

Den #167: Přidání testů Ansible do projektu

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

S největší pravděpodobností nebude možné provést refaktoring ve spěchu. Úkol musí být měřitelný, abyste ho mohli rozlámat na malé kousky a slona sníst kousek po kousku lžičkou. Musí existovat pochopení, zda se pohybujete správným směrem, jak dlouho jít.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Obecně je jedno, jak se to bude dělat, můžete psát na papír, můžete dávat samolepky na skříň, můžete vytvářet úkoly v Jira nebo můžete otevřít Dokumenty Google a zapsat aktuální stav tam. Nohy rostou z toho, že proces není okamžitý, bude dlouhý a zdlouhavý. Je nepravděpodobné, že by po vás někdo chtěl, abyste během refaktoringu vyhořeli z nápadů, unavili se a byli ohromeni.

Refaktoring je jednoduchý:

  • Jíst.
  • Spát.
  • Kód.
  • IaC test.
  • Opakovat

a toto opakujeme, dokud nedosáhneme zamýšleného cíle.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Začít testovat vše hned nemusí být možné, takže naším prvním úkolem bylo začít s lintingem a kontrolou syntaxe.

Den #181: Mistr zelené stavby

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Lining je prvním malým krokem k Green Build Master. Tím se téměř nic nezlomí, ale umožní vám to ladit procesy a vytvářet zelené sestavení v Jenkins. Cílem je rozvíjet v týmu návyky:

  • Červené testy jsou špatné.
  • Přišel jsem něco opravit a zároveň udělat kód o něco lepší, než byl před vámi.

Den č. 193: Od žmolkování k jednotkovým testům

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Po vytvoření procesu získávání kódu do hlavního serveru můžete zahájit proces postupného zlepšování – nahrazení lintingu spouštěcími rolemi, můžete to dokonce udělat bez idempotence. Musíte pochopit, jak aplikovat role a jak fungují.

Den #211: Od jednotky k integračním testům

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Když je většina rolí pokryta jednotkovými testy a vše je podložené, můžete přejít k přidávání integračních testů. Tito. testování ne jedné cihly v infrastruktuře, ale jejich kombinace, například konfigurace plné instance.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Pomocí jenkins jsme vygenerovali mnoho fází, které paralelně propojovaly role/playbooky, pak testy jednotek v kontejnerech a nakonec integrační testy.

Jenkins + Docker + Ansible = Testy

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

  1. Pokladna repo a generování fází sestavení.
  2. Paralelně spouštějte fáze lint playbooku.
  3. Paralelně spouštějte fáze role lint.
  4. Paralelně spouštějte fáze kontroly syntaxe.
  5. Spusťte paralelně fáze testovací role.
    1. Lint role.
    2. Zkontrolujte závislost na jiných rolích.
    3. Zkontrolujte syntaxi.
    4. Vytvořte instanci dockeru
    5. Spusťte molekulu/default/playbook.yml.
    6. Zkontrolujte idempotenci.
  6. Spusťte integrační testy
  7. úprava

Den #271: Autobusový faktor

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Nejprve refaktorování prováděla malá skupina dvou nebo tří lidí. Zkontrolovali kód v masteru. Postupem času tým vyvinul znalosti o tom, jak psát kód a kontrola kódu přispěla k šíření znalostí o infrastruktuře a o tom, jak funguje. Vrcholem zde bylo, že recenzenti byli vybíráni jeden po druhém, podle harmonogramu, tzn. s určitou mírou pravděpodobnosti vlezete do nového kusu infrastruktury.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

A tady by to mělo být pohodlné. Je vhodné udělat recenzi, vidět v rámci toho, jaký úkol byl proveden, a historii diskusí. Máme integrované jenkins + bitbucket + jira.

Recenze jako taková ale není všelék; nějak jsme se dostali do hlavního kódu, což nás přimělo propadnout testy:

- get_url:
    url: "{{ actk_certs }}/{{ item.1 }}"
    dest: "{{ actk_src_tmp }}/"
    username: "{{ actk_mvn_user }}"
    password: "{{ actk_mvn_pass }}"
  with_subelements:
    - "{{ actk_cert_list }}"
    - "{{ actk_certs }}"
  delegate_to: localhost

- copy:
    src: "{{ actk_src_tmp }}/{{ item.1 }}"
    dest: "{{ actk_dst_tmp }}"
  with_subelements:
    - "{{ actk_cert_list }}"
    - "{{ actk_certs }}"

Pak to opravili, ale zbytek zůstal.

get_url:
    url: "{{ actk_certs }}/{{ actk_item }}"
    dest: "{{ actk_src_tmp }}/{{ actk_item }}"
    username: "{{ actk_mvn_user }}"
    password: "{{ actk_mvn_pass }}"
  loop_control:
    loop_var: actk_item
  with_items: "{{ actk_cert_list }}"
  delegate_to: localhost

- copy:
    src: "{{ actk_src_tmp }}/{{ actk_item }}"
    dest: "{{ actk_dst_tmp }}"
  loop_control:
    loop_var: actk_item
  with_items: "{{ actk_cert_list }}"

Den #311: Urychlení testů

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Postupem času bylo testů více, sestavení probíhalo pomaleji, v nejhorším případě až o hodinu. Na jednom z retro filmů byla fráze jako „je dobré, že existují testy, ale jsou pomalé“. V důsledku toho jsme opustili integrační testy na virtuálních počítačích a upravili je pro Docker, aby byl rychlejší. Také jsme nahradili testinfra za ansible verifikátor, abychom snížili počet používaných nástrojů.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Přesně řečeno, existoval soubor opatření:

  1. Přepnout na docker.
  2. Odstraňte testování rolí, které je duplicitní kvůli závislostem.
  3. Zvyšte počet otroků.
  4. Pořadí zkušebního provozu.
  5. Schopnost žmolkování VŠE lokálně jedním příkazem.

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

V důsledku toho byl také Pipeline na jenkins sjednocen

  1. Generovat fáze sestavení.
  2. Lint vše paralelně.
  3. Spusťte paralelně fáze testovací role.
  4. Dokončit.

Poučení

Vyhněte se globálním proměnným

Ansible používá globální proměnné, ve formuláři je částečné řešení private_role_vars, ale to není všelék.

Dovolte mi uvést příklad. Nechte nás role_a и role_b

# cat role_a/defaults/main.yml
---
msg: a

# cat role_a/tasks/main.yml
---
- debug:
    msg: role_a={{ msg }}

# cat role_b/defaults/main.yml
---
msg: b

# cat role_b/tasks/main.yml
---
- set_fact:
    msg: b
- debug:
    msg: role_b={{ msg }}

- hosts: localhost
  vars:
    msg: hello
  roles:
    - role: role_a
    - role: role_b
  tasks:
    - debug:
        msg: play={{msg}}

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Legrační je, že výsledek playbooků bude záviset na věcech, které nejsou vždy zřejmé, jako je pořadí, ve kterém jsou role uvedeny. Bohužel taková je povaha Ansible a nejlepší, co lze udělat, je použít nějakou dohodu, například v rámci role používejte pouze proměnnou popsanou v této roli.

BAD: použijte globální proměnnou.

# cat roles/some_role/tasks/main.yml
---
debug:
  var: java_home

DOBRÝ: V defaults definovat potřebné proměnné a později pouze je používat.

# cat roles/some_role/defaults/main.yml
---
r__java_home:
 "{{ java_home | default('/path') }}"

# cat roles/some_role/tasks/main.yml
---
debug:
  var: r__java_home

Předpona proměnných role

BAD: použijte globální proměnnou.

# cat roles/some_role/defaults/main.yml
---
db_port: 5432

DOBRÝ: V rolích pro proměnné používejte proměnné s předponou s názvem role; při pohledu na inventář to usnadní pochopení toho, co se děje.

# cat roles/some_role/defaults/main.yml
---
some_role__db_port: 5432

Použijte proměnnou řízení smyčky

BAD: Použijte standardní proměnnou ve smyčkách item, pokud je tento úkol/příručka někde zahrnuta, může to vést k neočekávanému chování

---
- hosts: localhost
  tasks:
    - debug:
        msg: "{{ item }}"
      loop:
        - item1
        - item2

DOBRÝ: Předefinování proměnné ve smyčce přes loop_var.

---
- hosts: localhost
  tasks:
    - debug:
        msg: "{{ item_name }}"
      loop:
        - item1
        - item2
      loop_control:
        loop_var: item_name

Zkontrolujte vstupní proměnné

Souhlasili jsme s používáním předpon proměnných; nebylo by zbytečné kontrolovat, zda jsou definovány tak, jak očekáváme, a nebyly například přepsány prázdnou hodnotou

DOBRÝ: Zkontrolujte proměnné.

- name: "Verify that required string variables are defined"
  assert:
    that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
    fail_msg: "{{ ahs_var }} needs to be set for the role to work "
    success_msg: "Required variables {{ ahs_var }} is defined"
  loop_control:
    loop_var: ahs_var
  with_items:
    - ahs_item1
    - ahs_item2
    - ahs_item3

Vyhněte se hashovým slovníkům, používejte plochou strukturu

Pokud role očekává hash/slovník v jednom ze svých parametrů, pak pokud chceme změnit jeden z podřízených parametrů, budeme muset přepsat celý hash/slovník, což zvýší složitost konfigurace.

BAD: Použijte hash/slovník.

---
user:
  name: admin
  group: admin

DOBRÝ: Použijte plochou variabilní strukturu.

---
user_name: admin
user_group: "{{ user_name }}"

Vytvářejte idempotentní příručky a role

Role a playbooky musí být idempotentní, protože snižuje posun konfigurace a strach, že něco rozbijete. Ale pokud použijete molekulu, pak je to výchozí chování.

Vyhněte se používání modulů příkazového prostředí

Použití modulu shellu vede k imperativnímu paradigmatu popisu namísto deklarativního, které je jádrem Ansible.

Otestujte své role prostřednictvím molekuly

Molekula je velmi flexibilní věc, podívejme se na pár scénářů.

Molekula Více instancí

В molecule.yml v sekci platforms můžete popsat mnoho hostitelů, které můžete nasadit.

---
    driver:
      name: docker
    platforms:
      - name: postgresql-instance
        hostname: postgresql-instance
        image: registry.example.com/postgres10:latest
        pre_build_image: true
        override_command: false
        network_mode: host
      - name: app-instance
        hostname: app-instance
        pre_build_image: true
        image: registry.example.com/docker_centos_ansible_tests
        network_mode: host

Podle toho pak mohou být tito hostitelé converge.yml použití:

---
- name: Converge all
  hosts: all
  vars:
    ansible_user: root
  roles:
    - role: some_role

- name: Converge db
  hosts: db-instance
  roles:
    - role: some_db_role

- name: Converge app
  hosts: app-instance
  roles:
    - role: some_app_role

Ansible ověřovatel

V molekule je možné pomocí ansible zkontrolovat, zda je instance správně nakonfigurována, navíc je to od vydání 3 výchozí. Není to tak flexibilní jako testinfra/inspec, ale můžeme zkontrolovat, zda obsah souboru odpovídá našim očekáváním:

---
- name: Verify
  hosts: all
  tasks:
    - name: copy config
      copy:
        src: expected_standalone.conf
        dest: /root/wildfly/bin/standalone.conf
        mode: "0644"
        owner: root
        group: root
      register: config_copy_result

    - name: Certify that standalone.conf changed
      assert:
        that: not config_copy_result.changed

Nebo službu nasaďte, počkejte, až bude dostupná, a proveďte kouřový test:

---
  - name: Verify
    hosts: solr
    tasks:
      - command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
      - uri:
          url: http://127.0.0.1:8983/solr
          method: GET
          status_code: 200
        register: uri_result
        until: uri_result is not failed
        retries: 12
        delay: 10
      - name: Post documents to solr
        command: /blah/solr/bin/post -c master /exampledocs/books.csv

Vložte komplexní logiku do modulů a pluginů

Ansible obhajuje deklarativní přístup, takže když děláte větvení kódu, transformaci dat, moduly shellu, kód se stává obtížně čitelným. Abychom tomu zabránili a aby to bylo jednoduché na pochopení, nebylo by zbytečné bojovat proti této složitosti vytvářením vlastních modulů.

Shrňte tipy a triky

  1. Vyhněte se globálním proměnným.
  2. Předpona proměnných role.
  3. Použijte proměnnou řízení smyčky.
  4. Zkontrolujte vstupní proměnné.
  5. Vyhněte se hashovým slovníkům, používejte plochou strukturu.
  6. Vytvářejte idempotentní příručky a role.
  7. Vyhněte se používání modulů příkazového prostředí.
  8. Otestujte své role prostřednictvím molekuly.
  9. Vložte komplexní logiku do modulů a pluginů.

Závěr

Jak začít testovat Ansible, za rok projekt zrefaktorovat a nezbláznit se

Nemůžete prostě jít a refaktorovat infrastrukturu na projektu, i když máte IaC. Je to dlouhý proces vyžadující trpělivost, čas a znalosti.

UPD1 2020.05.01 20:30 — Pro primární profilování příruček, které můžete použít callback_whitelist = profile_tasks pochopit, co přesně funguje po dlouhou dobu. Pak projdeme Klasika s povolenou akcelerací. Můžete to také zkusit mitogen
UPD2 2020.05.03 16:34 - anglická verze

Zdroj: www.habr.com

Přidat komentář