Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Dette er udskriften forestillingerDevOps-40 2020-03-18:

Fra den anden commit bliver enhver kode legacy, fordi oprindelige ideer begynder at afvige fra den barske virkelighed. Dette er hverken godt eller dårligt, det er en given given, som er svær at argumentere med og skal leves med. En del af denne proces er refaktorering. Refaktorering af infrastruktur som kode. Lad historien begynde om, hvordan man refaktorerer Ansible om et år og ikke bliver skør.

Arvens fødsel

Dag #1: Patient Zero

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Der var engang et betinget projekt. Det havde et udviklingsteam og Ops-ingeniører. De løste det samme problem: hvordan man installerer servere og kører en applikation. Problemet var, at hvert hold løste dette problem på sin egen måde. På projektet blev det besluttet at bruge Ansible til at synkronisere viden mellem Dev- og Ops-teamet.

Dag #89: Arvens fødsel

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Uden selv at bemærke det, ville de gøre det bedst muligt, men det viste sig at være arv. Hvordan sker dette?

  • Vi har en presserende opgave her, lad os lave et beskidt hack og så ordne det.
  • Du behøver ikke at skrive dokumentation, og alt er klart, hvad der foregår her.
  • Jeg kender Ansible/Python/Bash/Terraform! Se hvordan jeg kan undvige!
  • Jeg er en Full Stack Overflow-udvikler og kopierede dette fra stackoverflow, jeg ved ikke hvordan det virker, men det ser cool ud og løser problemet.

Som et resultat kan du få en uforståelig type kode, som der ikke er dokumentation for, det er ikke klart, hvad det gør, om det er nødvendigt, men problemet er, at du skal udvikle det, ændre det, tilføje krykker og understøtter , hvilket gør situationen endnu værre.

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

Dag #109: Bevidsthed om problemet

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Den oprindeligt udtænkte og implementerede IaC-model opfylder ikke længere kravene fra brugere/virksomheder/andre teams, og tiden til at foretage ændringer i infrastrukturen holder op med at være acceptabel. I dette øjeblik kommer forståelsen af, at det er tid til at handle.

IaC refactoring

Dag #139: Har du virkelig brug for refactoring?

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Прежде чем кидаться рефакторить вы должны ответить на ряд важных вопросов:

  1. Hvorfor har du brug for alt dette?
  2. Har du tid?
  3. Er viden nok?

Hvis du ikke ved, hvordan du skal besvare spørgsmålene, slutter refaktoreringen, før den overhovedet begynder, ellers bliver den måske kun værre. Fordi havde erfaring ( Hvad jeg lærte af at teste 200 linjer med infrastrukturkode), så modtog projektet en anmodning om hjælp til at fikse rollerne og dække dem med test.

Dag #149: Forberedelse af refactoring

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Den første ting er at forberede. Beslut hvad vi vil gøre. For at gøre dette kommunikerer vi, finder problemområder og finder ud af måder at løse dem på. Vi registrerer de resulterende begreber på en eller anden måde, for eksempel en artikel i sammenløb, så når spørgsmålet opstår "hvad er bedst?" eller "hvilket er korrekt?" Vi er ikke gået vild. I vores tilfælde holdt vi fast i ideen del og hersk: vi deler infrastrukturen op i små stykker/klodser. Denne tilgang giver dig mulighed for at tage et isoleret stykke infrastruktur, forstå, hvad det gør, dække det med test og ændre det uden frygt for at bryde noget.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Det viser sig, at infrastrukturtest bliver hjørnestenen, og her er det værd at nævne infrastrukturtestpyramiden. Præcis den samme idé, som er under udvikling, men for infrastruktur: Vi bevæger os fra billige hurtige test, der tjekker simple ting, såsom indrykning, til dyre fuldgyldige test, der implementerer hele infrastrukturen.

Ansible testforsøg

Før vi går i gang med at beskrive, hvordan vi dækkede Ansible-tests på projektet, vil jeg beskrive de forsøg og tilgange, som jeg havde mulighed for at bruge tidligere for at forstå sammenhængen i de beslutninger, der blev truffet.

Dag nr. -997: SDS-bestemmelse

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Første gang jeg testede Ansible var på et projekt om at udvikle SDS (Software Defined Storage). Der er en separat artikel om dette emne
Sådan knækker du cykler over krykker, når du tester din distribution, men kort fortalt endte vi med en omvendt testpyramide og testning brugte vi 60-90 minutter på én rolle, hvilket er lang tid. Grundlaget var e2e tests, dvs. vi implementerede en fuldgyldig installation og testede den derefter. Hvad der var endnu mere skærpende var opfindelsen af ​​hans egen cykel. Men jeg må indrømme, at denne løsning fungerede og muliggjorde en stabil udgivelse.

Dag # -701: Ansible og testkøkken

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Udviklingen af ​​Ansible-testideen var brugen af ​​færdige værktøjer, nemlig testkøkken/køkken-ci og inspec. Valget blev bestemt af viden om Ruby (for flere detaljer, se artiklen om Habré: Мечтают ли YML программисты о тестировании ansible?) arbejdede hurtigere, omkring 40 minutter for 10 roller. Vi lavede en pakke virtuelle maskiner og kørte test indeni.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Generelt virkede løsningen, men der var noget sediment på grund af heterogenitet. Da antallet af testede personer blev øget til 13 basisroller og 2 metaroller, der kombinerede mindre roller, så begyndte testene pludselig at køre i 70 minutter, hvilket er næsten 2 gange længere. Det var svært at tale om XP (ekstrem programmering) praksis, fordi... ingen ønsker at vente 70 minutter. Dette var grunden til at ændre tilgangen

Dag # -601: Ansible og molekyle

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Konceptuelt ligner dette testkitchen, kun vi flyttede rolletest til docker og ændrede stakken. Som et resultat blev tiden reduceret til stabile 20-25 minutter for 7 roller.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Ved at øge antallet af testede roller til 17 og lining af 45 roller kørte vi dette på 28 minutter på 2 jenkins-slaver.

Dag #167: Tilføjelse af Ansible-tests til projektet

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Mest sandsynligt vil det ikke være muligt at udføre refaktoriseringsopgaven i en fart. Opgaven skal være målbar, så du kan brække den i små stykker og spise elefanten stykke for stykke med en teske. Der skal være en forståelse for, om du bevæger dig i den rigtige retning, hvor lang tid endnu.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Generelt er det lige meget, hvordan det bliver gjort, du kan skrive på et stykke papir, du kan sætte klistermærker på skabet, du kan oprette opgaver i Jira, eller du kan åbne Google Docs og skrive den aktuelle status ned. der. Benene vokser af, at processen ikke er øjeblikkelig, den bliver lang og trættende. Det er usandsynligt, at nogen ønsker, at du brænder ud af ideer, bliver træt og bliver overvældet under refactoring.

Refaktoreringen er enkel:

  • Spise.
  • Sleep.
  • Kode.
  • IaC test.
  • Gentag

og vi gentager dette, indtil vi når det tilsigtede mål.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Det er måske ikke muligt at begynde at teste alt med det samme, så vores første opgave var at starte med linting og tjekke syntaksen.

Dag #181: Green Build Master

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Linting er et lille første skridt mod Green Build Master. Dette vil ikke bryde næsten noget, men det vil give dig mulighed for at fejlsøge processer og lave grønne builds i Jenkins. Idéen er at udvikle vaner blandt teamet:

  • Røde tests er dårlige.
  • Jeg kom for at ordne noget og samtidig gøre koden lidt bedre, end den var før dig.

Dag #193: Fra fnug til enhedstest

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Efter at have bygget processen med at få koden ind i masteren, kan du begynde processen med trin-for-trin forbedring - udskiftning af linting med lanceringsroller, du kan endda gøre det uden idempotens. Du skal forstå, hvordan du anvender roller, og hvordan de fungerer.

Dag #211: Fra enhed til integrationstest

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Når de fleste roller er dækket af enhedstest, og alt er fnug, kan du gå videre til at tilføje integrationstest. De der. tester ikke en enkelt klods i infrastrukturen, men en kombination af dem, for eksempel en fuld instanskonfiguration.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Ved at bruge jenkins genererede vi mange stadier, der foret roller/playbooks parallelt, derefter enhedstests i containere og til sidst integrationstests.

Jenkins + Docker + Ansible = Tests

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

  1. Check ud repo og generer byggefaser.
  2. Kør fnug-playbook-stadier parallelt.
  3. Kør fnugrolletrin parallelt.
  4. Kør syntakskontrolrolletrin parallelt.
  5. Kør testrollefaser parallelt.
    1. Lint rolle.
    2. Tjek afhængighed af andre roller.
    3. Tjek syntaks.
    4. Opret docker-instans
    5. Kør molecule/default/playbook.yml.
    6. Tjek idempotens.
  6. Kør integrationstest
  7. Finish

Dag #271: Busfaktor

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Til at begynde med blev refactoring udført af en lille gruppe på to eller tre personer. De gennemgik koden i masteren. Med tiden udviklede teamet viden om, hvordan man skriver kode, og kodegennemgang bidrog til formidlingen af ​​viden om infrastrukturen og hvordan den fungerer. Højdepunktet her var, at anmelderne blev udvalgt én efter én, efter et skema, dvs. med en vis grad af sandsynlighed vil du klatre ind i et nyt stykke infrastruktur.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Og det skal være behageligt her. Det er praktisk at lave en gennemgang, se inden for rammerne af, hvilken opgave det blev udført, og historien om diskussioner. Vi har integreret jenkins + bitbucket + jira.

Men som sådan er en anmeldelse ikke et vidundermiddel; på en eller anden måde kom vi ind i masterkoden, som fik os til at floptests:

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

Så ordnede de det, men bundfaldet forblev.

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

Dag #311: Fremskyndelse af tests

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Med tiden var der flere tests, builds kørte langsommere, op til en time i værste fald. På en af ​​retroerne var der en sætning som "det er godt, at der er tests, men de er langsomme." Som følge heraf opgav vi integrationstest på virtuelle maskiner og tilpassede dem til Docker for at gøre det hurtigere. Vi erstattede også testinfra med en mulig verifikator for at reducere antallet af brugte værktøjer.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Strengt taget var der en række foranstaltninger:

  1. Skift til docker.
  2. Fjern rolletest, som duplikeres på grund af afhængigheder.
  3. Øg antallet af slaver.
  4. Prøvekørselsrækkefølge.
  5. Evne til at fnug ALLE lokalt med én kommando.

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Som et resultat blev Pipeline på jenkins også samlet

  1. Generer byggefaser.
  2. Fnug alt sammen parallelt.
  3. Kør testrollefaser parallelt.
  4. Afslut.

Erfaringer

Undgå globale variabler

Ansible bruger globale variabler, der er en delvis løsning i formularen private_rolle_vars, men dette er ikke et vidundermiddel.

Lad mig give dig et eksempel. Lad os have 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}}

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Det sjove er, at resultatet af playbooks vil afhænge af ting, der ikke altid er indlysende, såsom den rækkefølge, rollerne er opført i. Desværre er dette Ansibles natur, og det bedste, der kan gøres, er at bruge en form for aftale, for eksempel inden for en rolle, brug kun den variabel, der er beskrevet i denne rolle.

BAD: brug global variabel.

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

GOD: V defaults definere de nødvendige variabler og senere kun bruge dem.

# 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

Præfiks rollevariabler

BAD: brug global variabel.

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

GOD: I roller for variabler, brug variabler foranstillet med rollenavnet; dette, ved at se på inventar, vil gøre det lettere at forstå, hvad der sker.

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

Brug sløjfekontrolvariabel

BAD: Brug standardvariabel i sløjfer item, hvis denne opgave/playbook er inkluderet et sted, kan dette føre til uventet adfærd

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

GOD: Omdefiner en variabel i en loop via loop_var.

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

Tjek inputvariabler

Vi blev enige om at bruge variable præfikser; det ville ikke være overflødigt at kontrollere, at de er defineret, som vi forventer, og for eksempel ikke blev tilsidesat af en tom værdi

GOD: Tjek variabler.

- 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

Undgå hash-ordbøger, brug flad struktur

Hvis en rolle forventer en hash/ordbog i en af ​​dens parametre, så hvis vi vil ændre en af ​​de underordnede parametre, bliver vi nødt til at tilsidesætte hele hash/ordbogen, hvilket vil øge konfigurationskompleksiteten.

BAD: Brug hash/ordbog.

---
user:
  name: admin
  group: admin

GOD: Brug en flad variabel struktur.

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

Skab idempotente spillebøger og roller

Roller og spillebøger skal være idempotente, fordi reducerer konfigurationsdrift og frygt for at bryde noget. Men hvis du bruger molekyle, så er dette standardadfærden.

Undgå at bruge kommandoskalmoduler

Brug af et shell-modul resulterer i et imperativt beskrivelsesparadigme i stedet for det deklarative, som er kernen i Ansible.

Test dine roller via molekyle

Molekyle er en meget fleksibel ting, lad os se på et par scenarier.

Molekyle Flere tilfælde

В molecule.yml i afsnit platforms du kan beskrive mange værter, som du kan implementere.

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

Følgelig kan disse værter så være converge.yml brug:

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

I molekyle er det muligt at bruge ansible til at kontrollere, at instansen er konfigureret korrekt, desuden har dette været standard siden release 3. Det er ikke så fleksibelt som testinfra/inspec, men vi kan kontrollere, at indholdet af filen matcher vores forventninger:

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

Eller implementer tjenesten, vent på, at den bliver tilgængelig, og lav en røgtest:

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

Sæt kompleks logik i moduler og plugins

Ansible går ind for en deklarativ tilgang, så når du laver kodeforgrening, datatransformation, shell-moduler, bliver koden svær at læse. For at bekæmpe dette og holde det nemt at forstå, ville det ikke være overflødigt at bekæmpe denne kompleksitet ved at oprette dine egne moduler.

Opsummer tips og tricks

  1. Undgå globale variabler.
  2. Præfiks rollevariabler.
  3. Brug sløjfekontrolvariabel.
  4. Tjek inputvariabler.
  5. Undgå hash-ordbøger, brug flad struktur.
  6. Skab idempotente spillebøger og roller.
  7. Undgå at bruge kommandoskalmoduler.
  8. Test dine roller via molekyle.
  9. Sæt kompleks logik i moduler og plugins.

Konklusion

Sådan begynder du at teste Ansible, refaktorer projektet om et år og ikke gå amok

Du kan ikke bare gå og refaktorere infrastrukturen på et projekt, selvom du har IaC. Dette er en lang proces, der kræver tålmodighed, tid og viden.

UPD1 2020.05.01 20:30 — Til primær profilering af spillebøger kan du bruge callback_whitelist = profile_tasks at forstå, hvad der præcist virker i lang tid. Så går vi igennem Ansible accelerationsklassikere. Du kan også prøve mitogen
UPD2 2020.05.03 16:34engelsk version

Kilde: www.habr.com

Tilføj en kommentar