Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Ovo je transkript izvedbe na DevOps-40 2020-03-18:

Počevši od drugog urezivanja, svaki kod postaje naslijeđen, jer početne ideje počinju odudarati od surove stvarnosti. To nije ni dobro ni loše, to je datost s kojom se teško raspravlja i s kojom se mora živjeti. Dio ovog procesa je refaktoriranje. Refaktoriranje infrastrukture kao koda. Neka priča počne o tome kako refaktorirati Ansible u godinu dana i ne poludjeti.

Rođenje naslijeđa

Dan #1: Nulti pacijent

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Jednom davno postojao je uvjetni projekt. Imao je Dev razvojni tim i Ops inženjere. Rješavali su isti problem: kako postaviti poslužitelje i pokrenuti aplikaciju. Problem je bio što je svaki tim taj problem rješavao na svoj način. Na projektu je odlučeno koristiti Ansible za sinkronizaciju znanja između Dev i Ops timova.

Dan #89: Rođenje naslijeđa

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Ne primjećujući to sami, željeli su to učiniti što je moguće bolje, ali pokazalo se da je to nasljeđe. Kako se to događa?

  • Ovdje imamo hitan zadatak, napravimo prljavi hak i onda to popravimo.
  • Ne morate pisati dokumentaciju i sve je jasno o čemu se ovdje radi.
  • Znam Ansible/Python/Bash/Terraform! Vidi kako mogu izmicati!
  • Ja sam Full Stack Overflow Developer i kopirao sam ovo sa stackoverflowa, ne znam kako radi, ali izgleda super i rješava problem.

Kao rezultat možete dobiti nerazumljiv tip koda za koji ne postoji dokumentacija, nije jasno čemu služi, je li potreban, ali problem je što ga morate razvijati, modificirati, dodavati štake i potpore , čineći situaciju još gorom.

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

Dan #109: Svijest o problemu

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Inicijalno zamišljen i implementiran IaC model više ne zadovoljava zahtjeve korisnika/poslovnih/drugih timova, a vrijeme za izmjene infrastrukture prestaje biti prihvatljivo. U ovom trenutku dolazi do razumijevanja da je vrijeme za akciju.

IaC refactoring

Dan #139: Trebate li stvarno refactoring?

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Prije nego što požurite s refaktoriranjem, morate odgovoriti na nekoliko važnih pitanja:

  1. Zašto ti sve ovo treba?
  2. Imaš li vremena?
  3. Je li znanje dovoljno?

Ako ne znate kako odgovoriti na pitanja, tada će refaktoriranje završiti prije nego što uopće počne, ili se može samo pogoršati. Jer imao iskustva ( Što sam naučio testirajući 200 linija infrastrukturnog koda), tada je projekt dobio zahtjev za pomoć da popravi uloge i pokrije ih testovima.

Dan #149: Priprema refaktoriranja

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Prva stvar je pripremiti se. Odlučite što ćemo učiniti. Da bismo to učinili, komuniciramo, pronalazimo problematična područja i smišljamo načine za njihovo rješavanje. Dobivene koncepte nekako bilježimo, primjerice članak u konfluenciji, tako da kad se pojavi pitanje “što je najbolje?” ili "što je točno?" Nismo izgubili put. U našem slučaju, ostali smo pri ideji podijeli pa vladaj: razbijamo infrastrukturu na male komadiće/kockice. Ovaj vam pristup omogućuje da uzmete izolirani dio infrastrukture, shvatite što radi, pokrijete ga testovima i promijenite bez straha da ćete nešto pokvariti.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Ispada da testiranje infrastrukture postaje kamen temeljac i ovdje vrijedi spomenuti piramidu testiranja infrastrukture. Potpuno ista ideja koja je u razvoju, ali za infrastrukturu: prelazimo s jeftinih brzih testova koji provjeravaju jednostavne stvari, kao što je uvlačenje, na skupe potpune testove koji postavljaju cijelu infrastrukturu.

Anzibilni pokušaji testiranja

Prije nego krenemo opisivati ​​kako smo pokrili Ansible testove na projektu, opisat ću pokušaje i pristupe koje sam ranije imao priliku koristiti kako bih razumio kontekst donesenih odluka.

Dan br. -997: SDS odredba

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Ansible sam prvi put testirao na projektu razvoja SDS-a (Software Defined Storage). O ovoj temi postoji poseban članak
Kako slomiti bicikle preko štaka kada testirate svoju distribuciju, ali ukratko, završili smo s obrnutom piramidom testiranja i testiranja smo potrošili 60-90 minuta na jednu ulogu, što je dugo vremena. Osnova su bili e2e testovi, t.j. postavili smo potpunu instalaciju i zatim je testirali. Ono što je bilo još teže bio je izum vlastitog bicikla. Ali moram priznati da je ovo rješenje funkcioniralo i omogućilo stabilno izdanje.

Dan # -701: Ansible i testna kuhinja

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Razvoj ideje Ansible testiranja bio je korištenje gotovih alata, naime test kuhinje / kuhinja-ci i inspec. Izbor je presudilo poznavanju Rubyja (više detalja pogledajte u članku na Habréu: Sanjaju li YML programeri o testiranju Ansiblea?) radio brže, oko 40 minuta za 10 uloga. Stvorili smo paket virtualnih strojeva i izveli testove unutar njih.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Općenito, rješenje je djelovalo, ali bilo je nešto taloga zbog heterogenosti. Kada je broj testiranih ljudi povećan na 13 osnovnih uloga i 2 meta uloge kombinirajući manje uloge, odjednom su testovi počeli trajati 70 minuta, što je gotovo 2 puta duže. Bilo je teško govoriti o praksi XP-a (ekstremnog programiranja) jer... nitko ne želi čekati 70 minuta. To je bio razlog promjene pristupa

Dan # -601: Anzibl i molekula

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Konceptualno, ovo je slično testkitchenu, samo što smo testiranje uloga premjestili na docker i promijenili stog. Kao rezultat toga, vrijeme je smanjeno na stabilnih 20-25 minuta za 7 uloga.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Povećanjem broja testiranih uloga na 17 i lintiranjem 45 uloga, ovo smo pokrenuli za 28 minuta na 2 jenkinsova podređena.

Dan #167: Dodavanje Ansible testova projektu

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Najvjerojatnije neće biti moguće izvršiti zadatak refaktoriranja u žurbi. Zadatak mora biti mjerljiv da ga možete razlomiti na male komadiće i žličicom pojesti slona komad po komad. Mora postojati razumijevanje krećete li se u pravom smjeru, koliko dugo ići.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Općenito, nije bitno kako će se to raditi, možete pisati na komad papira, možete staviti naljepnice na ormar, možete kreirati zadatke u Jiri ili možete otvoriti Google Docs i zapisati trenutni status tamo. Noge rastu od činjenice da proces nije neposredan, bit će dug i zamoran. Malo je vjerojatno da itko želi da izgorite bez ideja, umorite se i preopteretite tijekom refaktoriranja.

Refaktoriranje je jednostavno:

  • Jesti.
  • Sleep.
  • Kodirati.
  • IaC test.
  • Ponoviti

i to ponavljamo dok ne postignemo zacrtani cilj.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Možda neće biti moguće odmah početi testirati sve, pa je naš prvi zadatak bio započeti s lintiranjem i provjerom sintakse.

Dan #181: Majstor zelene gradnje

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Linting je mali prvi korak prema Green Build Masteru. Ovo neće pokvariti gotovo ništa, ali će vam omogućiti otklanjanje pogrešaka u procesima i izradu zelenih nadogradnji u Jenkinsu. Ideja je razviti navike u timu:

  • Crveni testovi su loši.
  • Došao sam popraviti nešto i u isto vrijeme učiniti kod malo boljim nego što je bio prije vas.

Dan #193: Od lintinga do jediničnih testova

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Nakon što ste izgradili proces unosa koda u master, možete započeti proces poboljšanja korak po korak - zamjenjujući linting s ulogama pokretanja, možete to učiniti čak i bez idempotencije. Morate razumjeti kako primijeniti uloge i kako one funkcioniraju.

Dan #211: Od jediničnih do integracijskih testova

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Kada je većina uloga pokrivena jediničnim testovima i sve je ocrtano, možete prijeći na dodavanje integracijskih testova. Oni. testiranje ne jedne cigle u infrastrukturi, već njihove kombinacije, na primjer, potpuna konfiguracija instance.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Koristeći jenkins, generirali smo mnoge faze koje su paralelno iscrtavale uloge/priručnike, zatim jedinične testove u spremnicima i na kraju integracijske testove.

Jenkins + Docker + Ansible = Testovi

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

  1. Provjerite repo i generirajte faze izgradnje.
  2. Paralelno izvodite faze lint playbooka.
  3. Paralelno izvodite faze uloga lint.
  4. Paralelno pokreni faze uloge provjere sintakse.
  5. Paralelno izvodite faze testne uloge.
    1. Lint uloga.
    2. Provjerite ovisnost o drugim ulogama.
    3. Provjerite sintaksu.
    4. Stvorite docker instancu
    5. Pokrenite molecule/default/playbook.yml.
    6. Provjerite idempotenciju.
  6. Pokrenite integracijske testove
  7. završiti

Dan #271: Faktor autobusa

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

U početku je refactoring provodila mala grupa od dvoje ili troje ljudi. Pregledali su šifru u masteru. S vremenom je tim razvio znanje o tome kako napisati kod, a pregled koda pridonio je širenju znanja o infrastrukturi i načinu na koji ona funkcionira. Ovdje je vrhunac bio da su recenzenti birani jedan po jedan, prema rasporedu, tj. s određenim stupnjem vjerojatnosti ćete se popeti na novi dio infrastrukture.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

I ovdje bi trebalo biti ugodno. Zgodno je napraviti pregled, vidjeti u okviru kojeg je zadatka učinjeno i povijest rasprava. Integrirali smo jenkins + bitbucket + jira.

Ali kao takva, recenzija nije lijek; nekako smo ušli u glavni kod, što nas je natjeralo na neuspjele testove:

- 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 }}"

Onda su to popravili, ali talog je ostao.

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 }}"

Dan #311: Ubrzavanje testova

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

S vremenom je bilo više testova, buildovi su radili sporije, do sat vremena u najgorem slučaju. Na jednom od retro primjeraka bila je rečenica poput "dobro je što postoje testovi, ali su spori". Kao rezultat toga, napustili smo integracijske testove na virtualnim strojevima i prilagodili ih za Docker kako bi bili brži. Također smo zamijenili testinfra s ansible verifikatorom kako bismo smanjili broj korištenih alata.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Strogo govoreći, postojao je niz mjera:

  1. Prebaci se na docker.
  2. Uklonite testiranje uloga, koje se duplicira zbog ovisnosti.
  3. Povećajte broj robova.
  4. Redoslijed probnog rada.
  5. Sposobnost dlačica SVE lokalno jednom naredbom.

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Kao rezultat toga, Pipeline na jenkinsu također je unificiran

  1. Generirajte faze izgradnje.
  2. Lint sve paralelno.
  3. Paralelno izvodite faze testne uloge.
  4. Završi.

Naučene lekcije

Izbjegavajte globalne varijable

Ansible koristi globalne varijable, postoji djelomično zaobilazno rješenje u obrascu privatne_promjene_uloga, ali ovo nije lijek za sve.

Dat ću vam primjer. Pustite nas 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}}

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Smiješno je to što će rezultat igranih knjiga ovisiti o stvarima koje nisu uvijek očite, kao što je redoslijed kojim su uloge navedene. Nažalost, to je priroda Ansiblea i najbolja stvar koja se može učiniti je koristiti neku vrstu sporazuma, na primjer, unutar uloge, koristiti samo varijablu opisanu u ovoj ulozi.

LOŠE: koristi globalnu varijablu.

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

DOBRO: V defaults definirati potrebne varijable i kasnije koristiti samo njih.

# 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

Varijable uloga prefiksa

LOŠE: koristi globalnu varijablu.

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

DOBRO: U ulogama za varijable koristite varijable s prefiksom imena uloge; to će, gledajući inventar, olakšati razumijevanje što se događa.

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

Koristi varijablu kontrole petlje

LOŠE: Koristite standardnu ​​varijablu u petljama item, ako je ovaj zadatak/priručnik negdje uključen, to može dovesti do neočekivanog ponašanja

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

DOBRO: Redefinirajte varijablu u petlji putem loop_var.

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

Provjerite ulazne varijable

Dogovorili smo se da ćemo koristiti varijabilne prefikse; ne bi bilo suvišno provjeriti jesu li definirani kako očekujemo i, na primjer, nisu nadjačani praznom vrijednošću

DOBRO: Provjerite varijable.

- 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

Izbjegavajte hash rječnike, koristite ravnu strukturu

Ako uloga očekuje hash/rječnik u jednom od svojih parametara, tada ako želimo promijeniti jedan od podređenih parametara, morat ćemo nadjačati cijeli hash/rječnik, što će povećati složenost konfiguracije.

LOŠE: Koristite hash/rječnik.

---
user:
  name: admin
  group: admin

DOBRO: Koristite ravnu varijabilnu strukturu.

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

Stvorite idempotentne knjige i uloge

Uloge i igre moraju biti idempotentne, jer smanjuje pomicanje konfiguracije i strah od kvara. Ali ako koristite molekulu, onda je ovo zadano ponašanje.

Izbjegavajte korištenje modula naredbene ljuske

Korištenje modula ljuske rezultira paradigmom imperativnog opisa, umjesto deklarativne, koja je srž Ansiblea.

Testirajte svoje uloge putem molekule

Molekula je vrlo fleksibilna stvar, pogledajmo nekoliko scenarija.

Molekula Više instanci

В molecule.yml u odjeljku platforms možete opisati mnoge hostove koje možete postaviti.

---
    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

Prema tome, ovi domaćini tada mogu biti converge.yml koristiti:

---
- 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

Anzibilni verifikator

U molekuli je moguće koristiti ansible za provjeru je li instanca ispravno konfigurirana, štoviše, to je zadana postavka od izdanja 3. Nije tako fleksibilan kao testinfra/inspec, ali možemo provjeriti odgovara li sadržaj datoteke našim očekivanjima:

---
- 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

Ili implementirajte uslugu, pričekajte da postane dostupna i napravite dimni 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

Stavite složenu logiku u module i dodatke

Ansible zagovara deklarativni pristup, pa kada radite grananje koda, transformaciju podataka, module ljuske, kod postaje teško čitljiv. Da biste se borili protiv toga i održali ga jednostavnim za razumijevanje, ne bi bilo suvišno boriti se protiv ove složenosti stvaranjem vlastitih modula.

Sažeti savjete i trikove

  1. Izbjegavajte globalne varijable.
  2. Varijable uloga prefiksa.
  3. Koristi varijablu kontrole petlje.
  4. Provjerite ulazne varijable.
  5. Izbjegavajte hash rječnike, koristite ravnu strukturu.
  6. Stvorite idempotentne knjige i uloge.
  7. Izbjegavajte korištenje modula naredbene ljuske.
  8. Testirajte svoje uloge putem molekule.
  9. Stavite složenu logiku u module i dodatke.

Zaključak

Kako početi testirati Ansible, refaktorirati projekt u godinu dana i ne poludjeti

Ne možete samo otići i refaktorirati infrastrukturu na projektu, čak i ako imate IAC. Ovo je dug proces koji zahtijeva strpljenje, vrijeme i znanje.

UPD1 2020.05.01 20:30 — Za primarno profiliranje knjiga igara koje možete koristiti callback_whitelist = profile_tasks razumjeti što točno radi dugo vremena. Zatim prolazimo Klasici anzibilnog ubrzanja. Možete i pokušati mitogen
UPD2 2020.05.03 16:34 - Croato verziju

Izvor: www.habr.com

Dodajte komentar