Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Počevši od drugog urezivanja, svaki kod postaje naslijeđe, jer početne ideje počinju da se razlikuju od surove stvarnosti. Ovo nije ni dobro ni loše, to je datost sa kojom se teško raspravljati i sa kojom se mora živjeti. Dio ovog procesa je refaktoring. Refaktoring infrastrukture kao koda. Neka priča počne o tome kako refaktorirati Ansible za godinu dana i ne poludjeti.

Rođenje naslijeđa

Dan #1: Nulti pacijent

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Jednom davno postojao je uslovni projekat. Imao je razvojni tim za razvojne programere i operativne inženjere. Oni su rješavali isti problem: kako postaviti servere i pokrenuti aplikaciju. Problem je bio što je svaki tim rješavao ovaj problem na svoj način. Na projektu je odlučeno da se koristi Ansible za sinhronizaciju znanja između Dev i Ops timova.

Dan #89: Rođenje naslijeđa

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Bez da su to sami primetili, želeli su da to urade što bolje, ali se ispostavilo da je to nasleđe. Kako se to događa?

  • Imamo hitan zadatak ovdje, hajde da napravimo prljavi hak pa onda to popravimo.
  • Ne morate pisati dokumentaciju i sve je jasno o čemu se ovdje radi.
  • Znam Ansible/Python/Bash/Terraform! Vidi kako mogu izbjeći!
  • Ja sam Full Stack Overflow Developer i kopirao sam ovo sa stackoverflow-a, ne znam kako funkcionira, ali izgleda cool i rješava problem.

Kao rezultat, možete dobiti nerazumljiv tip koda za koji nema dokumentacije, nije jasno šta radi, da li je potreban, ali problem je što ga morate razviti, modificirati, dodati štake i nosače , čime se situacija još više pogoršava.

- 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: Svest o problemu

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Dan #139: Da li vam je zaista potreban refaktoring?

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

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

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

Dan #149: Priprema refaktoringa

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Prva stvar je da se pripremite. Odlučite šta ćemo uraditi. Da bismo to učinili, komuniciramo, pronalazimo problematična područja i pronalazimo načine da ih riješimo. Nastale koncepte nekako bilježimo, na primjer članak u stjecanju, tako da kada se postavi pitanje "šta je najbolje?" ili "što je tačno?" Nismo zalutali. U našem slučaju, ostali smo pri ideji zavadi pa vladaj: razbijamo infrastrukturu na male komade/cigle. Ovaj pristup vam omogućava da uzmete izolovani komad infrastrukture, razumete šta radi, pokrijete ga testovima i promenite bez straha da ćete bilo šta pokvariti.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Ispostavilo se da testiranje infrastrukture postaje kamen temeljac i ovdje je vrijedno spomenuti piramidu testiranja infrastrukture. Potpuno ista ideja koja je u razvoju, ali za infrastrukturu: prelazimo sa jeftinih brzih testova koji provjeravaju jednostavne stvari, kao što je udubljenje, na skupe punopravne testove koji postavljaju cijelu infrastrukturu.

Ansible pokušaji testiranja

Pre nego što pređemo na opis načina na koji smo pokrili Ansible testove na projektu, opisaću pokušaje i pristupe koje sam ranije imao prilike da koristim kako bih razumeo kontekst donetih odluka.

Dan br. -997: Odredba SDS-a

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Prvi put kada sam testirao Ansible bio je na projektu razvoja SDS-a (Software Defined Storage). Na ovu temu postoji poseban članak
Kako razbiti bicikle preko štaka kada testirate svoju distribuciju, ali ukratko, završili smo sa obrnutom piramidom testiranja i na testiranje smo potrošili 60-90 minuta na jednu ulogu, što je dosta vremena. Osnova su bili e2e testovi, tj. postavili smo potpunu instalaciju i potom je testirali. Ono što je još više otežavalo je pronalazak sopstvenog 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 projekat za godinu dana i ne poludjeti

Razvoj ideje Ansible testiranja je bio korištenje gotovih alata, odnosno test kuhinja/kuhinja-ci i inspek. Izbor je određen poznavanjem Rubyja (za više detalja pogledajte članak na Habréu: Da li YML programeri sanjaju o testiranju Ansiblea?) radilo brže, oko 40 minuta za 10 uloga. Napravili smo paket virtuelnih mašina i proveli testove unutra.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Općenito, rješenje je funkcioniralo, ali je bilo malo taloga zbog heterogenosti. Kada je broj testiranih ljudi povećan na 13 osnovnih uloga i 2 meta uloge kombinujući manje uloge, onda su odjednom testovi počeli da traju 70 minuta, što je skoro 2 puta duže. Bilo je teško govoriti o XP (ekstremnom programiranju) praksi jer... niko ne želi da čeka 70 minuta. To je bio razlog za promjenu pristupa

Dan # -601: Ansible i molekul

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Povećanjem broja testiranih uloga na 17 i dodavanjem 45 uloga, pokrenuli smo ovo za 28 minuta na 2 roba Jenkinsa.

Dan #167: Dodavanje Ansible testova projektu

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Općenito, nije bitno kako će se to uraditi, možete pisati na komad papira, možete staviti naljepnice na ormar, možete kreirati zadatke u Jira, ili možete otvoriti Google dokumente i zapisati trenutni status tamo. Noge rastu od činjenice da proces nije trenutan, bit će dug i zamoran. Malo je vjerovatno da iko želi da izgorite od ideja, umorite se i budete preopterećeni tokom prepravljanja.

Refaktoriranje je jednostavno:

  • Jedi.
  • Sleep.
  • Šifra.
  • IaC test.
  • ponavljanje

i to ponavljamo dok ne postignemo zacrtani cilj.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Dan #181: Majstor zelene gradnje

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Linting je mali prvi korak ka Green Build Master-u. Ovo neće slomiti gotovo ništa, ali će vam omogućiti da otklanjate greške u procesima i pravite zelene verzije u Jenkinsu. Ideja je razvijanje navika među timom:

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

Dan #193: Od lintinga do jediničnih testova

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Nakon što ste izgradili proces preuzimanja koda u master, možete započeti proces poboljšanja korak po korak - zamjenom lintinga ulogama pokretanja, čak možete to učiniti 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 projekat za godinu dana i ne poludjeti

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

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

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

Jenkins + Docker + Ansible = Testovi

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

  1. Naručite repo i generirajte faze izgradnje.
  2. Paralelno pokrenite faze iz priručnika.
  3. Paralelno pokrenite faze uloga dlačica.
  4. Pokrenite faze uloge provjere sintakse paralelno.
  5. Pokrenite faze testnih uloga paralelno.
    1. Lint uloga.
    2. Provjerite ovisnost o drugim ulogama.
    3. Provjerite sintaksu.
    4. Kreirajte 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 projekat za godinu dana i ne poludjeti

U početku, refaktoring je obavljala mala grupa od dvije ili tri osobe. Pregledali su kod u masteru. Vremenom je tim razvio znanje o tome kako pisati kod, a pregled koda je doprineo širenju znanja o infrastrukturi i kako ona funkcioniše. Vrhunac ovdje je bio da su recenzenti birani jedan po jedan, prema rasporedu, tj. s određenim stepenom vjerovatnoće ćete se popeti u novi dio infrastrukture.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

I ovdje bi trebalo biti udobno. Zgodno je napraviti recenziju, vidjeti u okviru kojeg je zadatka obavljen i historiju diskusija. Integrirali smo jenkins + bitbucket + jira.

Ali kao takav, pregled nije lijek za sve, ušli smo u glavni kod, što nas je natjeralo da propadnemo:

- 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 projekat za godinu dana i ne poludjeti

Vremenom je bilo više testova, gradnje je teklo sporije, do sat vremena u najgorem slučaju. Na jednom od retro modela bila je fraza poput "dobro je da postoje testovi, ali su spori". Kao rezultat toga, napustili smo integracijske testove na virtuelnim mašinama i prilagodili ih za Docker kako bi bili brži. Također smo zamijenili testinfra sa ansible verifikatorom kako bismo smanjili broj korištenih alata.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Strogo govoreći, postojao je set mjera:

  1. Prebacite se na docker.
  2. Uklonite testiranje uloga, koje je duplicirano zbog zavisnosti.
  3. Povećajte broj robova.
  4. Redoslijed probnog rada.
  5. Sposobnost dlačica SVE lokalno sa jednom komandom.

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Kao rezultat toga, Pipeline on jenkins je također ujedinjen

  1. Generirajte faze izgradnje.
  2. Lint sve paralelno.
  3. Pokrenite faze testnih uloga paralelno.
  4. Završi.

naučene lekcije

Izbjegavajte globalne varijable

Ansible koristi globalne varijable, postoji djelomično rješenje u obliku private_role_vars, ali ovo nije panaceja.

Dozvolite mi da vam dam 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 projekat za godinu dana i ne poludjeti

Smiješno je to što će rezultat playbook-a ovisiti o stvarima koje nisu uvijek očigledne, kao što je redoslijed po kojem su uloge navedene. Nažalost, ovo je priroda Ansible-a i najbolja stvar koja se može učiniti je koristiti neku vrstu dogovora, na primjer, unutar uloge, koristiti samo varijablu opisanu u ovoj ulozi.

BAD: koristi globalnu varijablu.

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

GOOD: 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 uloge prefiksa

BAD: koristi globalnu varijablu.

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

GOOD: U ulogama za varijable, koristite varijable sa prefiksom imena uloge, ovo će, gledajući inventar, olakšati razumijevanje onoga što se događa.

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

Koristite kontrolnu varijablu petlje

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

GOOD: Redefinirajte varijablu u petlji preko 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 koristimo promjenjive prefikse, ne bi bilo suvišno provjeriti da li su definirani kako očekujemo i da, na primjer, nisu zamijenjeni praznom vrijednošću;

GOOD: 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 heš rječnike, koristite ravnu strukturu

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

BAD: Koristi hash/rječnik.

---
user:
  name: admin
  group: admin

GOOD: Koristite ravnu varijabilnu strukturu.

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

Kreirajte idempotentne knjige i uloge

Uloge i igre moraju biti idempotentne, jer smanjuje pomjeranje konfiguracije i strah od lomljenja nečega. Ali ako koristite molekulu, onda je ovo zadano ponašanje.

Izbjegavajte korištenje modula komandne ljuske

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

Testirajte svoje uloge putem molekula

Molekul je vrlo fleksibilna stvar, pogledajmo nekoliko scenarija.

Molecule Višestruke instance

В molecule.yml u sekciji 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

Shodno 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

Ansible verifikator

U molekulu je moguće koristiti ansible za provjeru da li je instanca ispravno konfigurirana, štoviše, ovo je zadano od izdanja 3. Nije tako fleksibilan kao testinfra/inspec, ali možemo provjeriti da li sadržaj datoteke odgovara 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 uradite test dima:

---
  - 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, tako da kada radite grananje koda, transformaciju podataka, module ljuske, kod postaje težak za čitanje. Da biste se borili protiv ovoga i da bi bilo jednostavno za razumijevanje, ne bi bilo suvišno boriti se protiv ove složenosti kreiranjem vlastitih modula.

Sažeti savjete i trikove

  1. Izbjegavajte globalne varijable.
  2. Varijable uloge prefiksa.
  3. Koristite kontrolnu varijablu petlje.
  4. Provjerite ulazne varijable.
  5. Izbjegavajte heš rječnike, koristite ravnu strukturu.
  6. Kreirajte idempotentne knjige i uloge.
  7. Izbjegavajte korištenje modula komandne ljuske.
  8. Testirajte svoje uloge putem molekula.
  9. Stavite složenu logiku u module i dodatke.

zaključak

Kako početi testirati Ansible, refaktorirati projekat za godinu dana i ne poludjeti

Ne možete jednostavno 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 profilisanje knjiga koje možete koristiti callback_whitelist = profile_tasks da razumete šta tačno radi duže vreme. Onda idemo Klasika Ansible ubrzanja. Možete i pokušati mitogen
UPD2 2020.05.03 16:34 - engleska verzija

izvor: www.habr.com

Dodajte komentar