Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

To je prepis predstave o DevOps-40 2020-03-18:

Od druge potrditve katera koli koda postane podedovana, ker začetne ideje se začnejo oddaljiti od krute realnosti. To ni ne dobro ne slabo, je danost, ki ji je težko ugovarjati in z njo je treba živeti. Del tega procesa je preoblikovanje. Preoblikovanje infrastrukture kot kode. Naj se zgodba začne o tem, kako preurediti Ansible v enem letu in ne ponoreti.

Rojstvo dediščine

Dan št. 1: Pacient nič

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Nekoč je bil pogojni projekt. Imel je razvojno ekipo Dev in inženirje Ops. Reševali so isti problem: kako razmestiti strežnike in zagnati aplikacijo. Težava je bila v tem, da je vsaka ekipa ta problem reševala na svoj način. Pri projektu je bilo odločeno, da uporabimo Ansible za sinhronizacijo znanja med ekipama Dev in Ops.

Dan #89: Rojstvo zapuščine

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Ne da bi sami tega opazili, so želeli narediti čim bolje, a se je izkazalo, da gre za zapuščino. Kako se to zgodi?

  • Tukaj imamo nujno nalogo, naredimo umazan kramp in ga nato popravimo.
  • Ni vam treba pisati dokumentacije in vse je jasno, kaj se tukaj dogaja.
  • Poznam Ansible/Python/Bash/Terraform! Poglejte, kako se lahko izmikam!
  • Sem razvijalec Full Stack Overflow in sem to kopiral iz stackoverflowa, ne vem, kako deluje, vendar je videti kul in rešuje težavo.

Posledično lahko dobite nerazumljivo vrsto kode, za katero ni dokumentacije, ni jasno, kaj počne, ali je potrebna, vendar je težava v tem, da jo morate razviti, spremeniti, dodati bergle in opore. , kar še poslabša situacijo.

- 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: Zavedanje problema

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Prvotno zasnovan in implementiran IaC model ne izpolnjuje več zahtev uporabnikov/poslovnih/drugih ekip, čas za spremembe infrastrukture pa ni več sprejemljiv. V tem trenutku pride razumevanje, da je čas za ukrepanje.

Preoblikovanje IaC

Dan #139: Ali res potrebujete preoblikovanje?

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Preden pohitite s preoblikovanjem, morate odgovoriti na številna pomembna vprašanja:

  1. Zakaj potrebuješ vse to?
  2. Imaš čas?
  3. Je znanje dovolj?

Če ne veste, kako odgovoriti na vprašanja, se bo preoblikovanje končalo, preden se sploh začne, ali pa bo le še slabše. Ker imel izkušnje( Kaj sem se naučil pri testiranju 200 vrstic infrastrukturne kode), potem je projekt prejel prošnjo za pomoč, da popravi vloge in jih pokrije s testi.

Dan #149: Priprava refaktoriranja

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Prva stvar je priprava. Odločite se, kaj bomo storili. Da bi to naredili, komuniciramo, poiščemo problematična področja in ugotovimo načine za njihovo rešitev. Nastale koncepte nekako posnamemo, na primer članek v sotočju, tako da ob vprašanju »kaj je najboljše?« ali "kar je pravilno?" Nismo se izgubili. V našem primeru smo ostali pri ideji deli in vladaj: infrastrukturo razdelimo na majhne koščke/kocke. Ta pristop vam omogoča, da vzamete izoliran kos infrastrukture, razumete, kaj počne, ga pokrijete s testi in spremenite, ne da bi se bali, da bi kaj pokvarili.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Izkazalo se je, da testiranje infrastrukture postane temelj in tukaj velja omeniti piramido testiranja infrastrukture. Popolnoma enaka ideja je v razvoju, vendar za infrastrukturo: premikamo se od poceni hitrih testov, ki preverjajo preproste stvari, kot je zamik, k dragim polnim testom, ki uporabljajo celotno infrastrukturo.

Ansible poskusi testiranja

Preden začnemo opisovati, kako smo pokrivali Ansible teste na projektu, bom opisal poskuse in pristope, ki sem jih imel priložnost uporabiti prej, da bi razumel kontekst sprejetih odločitev.

Dan št. -997: Določba SDS

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Ansible sem prvič preizkusil pri projektu razvoja SDS (software Defined Storage). Na to temo je ločen članek
Kako zlomiti kolesa zaradi bergel, ko preizkušate svojo distribucijo, skratka, končali smo z obrnjeno piramido testiranja in za testiranje smo porabili 60-90 minut za eno vlogo, kar je dolga doba. Osnova so bili testi e2e, t.j. namestili smo popolno namestitev in jo nato preizkusili. Kar je bilo še bolj oteževalno, je bil izum lastnega kolesa. Vendar moram priznati, da je ta rešitev delovala in omogočila stabilno izdajo.

Dan # -701: Ansible in testna kuhinja

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Razvoj ideje o testiranju Ansible je bila uporaba že pripravljenih orodij, in sicer testna kuhinja / kuhinja-ci in inspec. Izbiro je določilo poznavanje Rubyja (za več podrobnosti si oglejte članek na Habréju: Ali programerji YML sanjajo o testiranju Ansible?) delal hitreje, približno 40 minut za 10 vlog. Ustvarili smo paket virtualnih strojev in v njih izvajali teste.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Na splošno je rešitev delovala, vendar je bilo nekaj usedlin zaradi heterogenosti. Ko se je število testiranih povečalo na 13 osnovnih vlog in 2 meta vlogi, ki združujeta manjše vloge, so testi nenadoma začeli potekati 70 minut, kar je skoraj 2-krat dlje. Težko je bilo govoriti o praksah XP (ekstremnega programiranja), ker ... nihče ne želi čakati 70 minut. To je bil razlog za spremembo pristopa

Dan # -601: Anzibl in molekula

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Konceptualno je to podobno kot testkitchen, le da smo preizkušanje vlog premaknili v docker in spremenili sklad. Posledično se je čas zmanjšal na stabilnih 20-25 minut za 7 vlog.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

S povečanjem števila testiranih vlog na 17 in liniranjem 45 vlog smo to izvedli v 28 minutah na 2 sužnjih Jenkins.

Dan #167: Dodajanje Ansible testov v projekt

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Najverjetneje naloge refaktoriranja ne bo mogoče izvesti v naglici. Naloga mora biti merljiva, da jo lahko razbiješ na majhne koščke in slončka z žličko poješ kos za kosom. Obstajati mora razumevanje, ali se premikate v pravo smer, koliko časa morate iti.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Na splošno ni pomembno, kako bo to narejeno, lahko pišete na list papirja, lahko nalepite nalepke na omaro, lahko ustvarite naloge v Jiri ali pa odprete Google Docs in zapišete trenutno stanje tam. Noge rastejo zaradi dejstva, da postopek ni takojšen, bo dolg in dolgočasen. Malo verjetno je, da si kdo želi, da med refaktoriranjem izgorevate brez idej, se utrudite in postanete preobremenjeni.

Refactoring je preprost:

  • Jejte.
  • Sleep.
  • Koda.
  • IaC test.
  • Ponovitev

in to ponavljamo, dokler ne dosežemo zastavljenega cilja.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Morda ne bo mogoče začeti testirati vsega takoj, zato je bila naša prva naloga začeti s lintingom in preverjanjem sintakse.

Dan #181: Mojster zelene gradnje

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Linting je majhen prvi korak k Green Build Master. To ne bo pokvarilo skoraj ničesar, vendar vam bo omogočilo odpravljanje napak v procesih in izdelavo zelenih zgradb v Jenkinsu. Ideja je razviti navade med ekipo:

  • Rdeči testi so slabi.
  • Prišel sem nekaj popraviti in hkrati narediti kodo malo boljšo, kot je bila pred vami.

Dan #193: Od lintinga do testov enot

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Ko zgradite postopek pridobivanja kode v master, lahko začnete postopek postopnega izboljšanja - zamenjavo lintinga z zagonom vlog, to lahko storite celo brez idempotence. Razumeti morate, kako uporabiti vloge in kako delujejo.

Dan #211: Od enote do integracijskih testov

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Ko je večina vlog pokrita s testi enote in je vse razčlenjeno, lahko nadaljujete z dodajanjem integracijskih testov. Tisti. testiranje ne ene same opeke v infrastrukturi, temveč njihove kombinacije, na primer popolna konfiguracija instance.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Z uporabo jenkinsa smo ustvarili veliko stopenj, ki so vzporedno povezovale vloge/igre, nato teste enot v vsebnikih in končno teste integracije.

Jenkins + Docker + Ansible = Testi

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

  1. Preverite repo in ustvarite stopnje gradnje.
  2. Vzporedno izvajajte faze lint playbook.
  3. Vzporedno zaženite stopnje vloge lint.
  4. Zaženite stopnje vloge preverjanja sintakse vzporedno.
  5. Vzporedno izvajajte faze preizkusne vloge.
    1. Vloga linta.
    2. Preverite odvisnost od drugih vlog.
    3. Preverite sintakso.
    4. Ustvari primerek dockerja
    5. Zaženite molecule/default/playbook.yml.
    6. Preverite idempotenco.
  6. Izvedite integracijske teste
  7. Konec

Dan #271: Bus Factor

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Sprva je refactoring izvajala majhna skupina dveh ali treh ljudi. Pregledali so kodo v masterju. Sčasoma je ekipa razvila znanje o pisanju kode in pregled kode je prispeval k širjenju znanja o infrastrukturi in njenem delovanju. Vrhunec pri tem je bil, da so recenzente izbirali enega za drugim, po urniku, t.j. z določeno stopnjo verjetnosti se boste povzpeli na nov kos infrastrukture.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

In tukaj bi moralo biti udobno. Primerno je narediti pregled, videti v okviru katere naloge je bilo opravljeno in zgodovino razprav. Integrirali smo jenkins + bitbucket + jira.

Vendar pregled kot tak ni zdravilo; nekako smo prišli do glavne kode, zaradi katere smo opravili neuspešne teste:

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

Potem so ga popravili, a ostanek je ostal.

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: Pospeševanje testov

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Sčasoma je bilo testov več, gradnje so tekle počasneje, v najslabšem primeru do ene ure. Na enem od retro je bil stavek, kot je "dobro je, da obstajajo testi, vendar so počasni." Posledično smo opustili integracijske teste na virtualnih strojih in jih prilagodili Dockerju, da bi bil hitrejši. Prav tako smo zamenjali testinfra z ansible verifier, da zmanjšamo število uporabljenih orodij.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Strogo rečeno, obstajal je niz ukrepov:

  1. Preklopi na docker.
  2. Odstranite testiranje vlog, ki je podvojeno zaradi odvisnosti.
  3. Povečajte število sužnjev.
  4. Vrstni red testnega zagona.
  5. Sposobnost linta VSE lokalno z enim ukazom.

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Posledično je bil poenoten tudi Pipeline on jenkins

  1. Ustvarite stopnje gradnje.
  2. Lint vse vzporedno.
  3. Vzporedno izvajajte faze preizkusne vloge.
  4. Dokončaj.

Nova spoznanja

Izogibajte se globalnim spremenljivkam

Ansible uporablja globalne spremenljivke, v obrazcu je delna rešitev private_role_vars, vendar to ni rešitev.

Naj vam povem primer. Pustite nam 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 začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Smešno je, da bo rezultat knjig iger odvisen od stvari, ki niso vedno očitne, kot je vrstni red, v katerem so navedene vloge. Na žalost je to narava Ansiblea in najboljša stvar, ki jo lahko naredimo, je uporaba nekakšnega dogovora, na primer znotraj vloge uporabite samo spremenljivko, opisano v tej vlogi.

BAD: uporabi globalno spremenljivko.

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

DOBRA: V defaults definirati potrebne spremenljivke in kasneje uporabiti le te.

# 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

Spremenljivke vloge predpone

BAD: uporabi globalno spremenljivko.

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

DOBRA: V vlogah za spremenljivke uporabite spremenljivke s predpono imena vloge; tako boste z ogledom inventarja lažje razumeli, kaj se dogaja.

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

Uporabi kontrolno spremenljivko zanke

BAD: Uporabite standardno spremenljivko v zankah item, če je ta naloga/knjiga iger nekje vključena, lahko to povzroči nepričakovano vedenje

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

DOBRA: Ponovno definirajte spremenljivko v zanki prek loop_var.

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

Preverite vhodne spremenljivke

Dogovorili smo se za uporabo spremenljivih predpon; ne bi bilo odveč preveriti, ali so definirane tako, kot pričakujemo, in jih na primer ne preglasi prazna vrednost

DOBRA: Preverite spremenljivke.

- 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

Izogibajte se zgoščenim slovarjem, uporabljajte ravno strukturo

Če vloga pričakuje razpršitev/slovar v enem od svojih parametrov, bomo morali, če želimo spremeniti enega od podrejenih parametrov, preglasiti celoten razpršitev/slovar, kar bo povečalo zapletenost konfiguracije.

BAD: Uporabi zgoščeno vrednost/slovar.

---
user:
  name: admin
  group: admin

DOBRA: Uporabite ravno spremenljivo strukturo.

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

Ustvarite idempotentne knjige in vloge

Vloge in igre morajo biti idempotentne, ker zmanjša zamik konfiguracije in strah, da bi se kaj pokvarilo. Če pa uporabite molekulo, je to privzeto vedenje.

Izogibajte se uporabi modulov ukazne lupine

Rezultat uporabe lupinskega modula je paradigma imperativnega opisa namesto deklarativne, ki je jedro Ansiblea.

Preizkusite svoje vloge prek molekule

Molekula je zelo prilagodljiva stvar, poglejmo nekaj scenarijev.

Molekula Več primerkov

В molecule.yml v razdelku platforms lahko opišete veliko gostiteljev, ki jih lahko namestite.

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

V skladu s tem so lahko ti gostitelji converge.yml uporaba:

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

V molekuli je mogoče uporabiti ansible za preverjanje, ali je primerek pravilno konfiguriran, poleg tega je to privzeto od izdaje 3. Ni tako prilagodljiv kot testinfra/inspec, vendar lahko preverimo, ali se vsebina datoteke ujema z našimi pričakovanji:

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

Ali pa uvedite storitev, počakajte, da postane na voljo, in opravite 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

Vstavite kompleksno logiko v module in vtičnike

Ansible zagovarja deklarativni pristop, tako da, ko delate razvejanje kode, transformacijo podatkov, lupinske module, postane koda težko berljiva. Da bi se borili proti temu in ohranili preprostost za razumevanje, ne bi bilo odveč, če bi se borili proti tej kompleksnosti z ustvarjanjem lastnih modulov.

Povzemite nasvete in trike

  1. Izogibajte se globalnim spremenljivkam.
  2. Spremenljivke vloge predpone.
  3. Uporabi kontrolno spremenljivko zanke.
  4. Preverite vhodne spremenljivke.
  5. Izogibajte se zgoščenim slovarjem, uporabljajte ravno strukturo.
  6. Ustvarite idempotentne knjige in vloge.
  7. Izogibajte se uporabi modulov ukazne lupine.
  8. Preizkusite svoje vloge prek molekule.
  9. Vstavite kompleksno logiko v module in vtičnike.

Zaključek

Kako začeti testirati Ansible, preurediti projekt v enem letu in ne ponoreti

Ne morete preprosto preoblikovati infrastrukture v projektu, tudi če imate IAC. To je dolgotrajen proces, ki zahteva potrpljenje, čas in znanje.

UPD1 2020.05.01 20:30 — Za primarno profiliranje knjig iger, ki jih lahko uporabite callback_whitelist = profile_tasks razumeti, kaj točno deluje dolgo časa. Potem gremo skozi Klasika antabilnega pospeševanja. Lahko tudi poskusite mitogen
UPD2 2020.05.03 16:34 - angleška verzija

Vir: www.habr.com

Dodaj komentar