Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

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

Fra den andre commit, blir enhver kode legacy, fordi de første ideene begynner å avvike fra den harde virkeligheten. Dette er verken bra eller dårlig, det er en gitt som er vanskelig å argumentere med og må leves med. En del av denne prosessen er refaktorisering. Refaktorering av infrastruktur som kode. La historien begynne om hvordan du refaktoriserer Ansible om et år og ikke blir gal.

Arvens fødsel

Dag #1: Pasient Zero

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Det var en gang et betinget prosjekt. Den hadde et Dev-utviklingsteam og Ops-ingeniører. De løste det samme problemet: hvordan distribuere servere og kjøre en applikasjon. Problemet var at hvert lag løste dette problemet på sin egen måte. På prosjektet ble det besluttet å bruke Ansible til å synkronisere kunnskap mellom Dev- og Ops-teamene.

Dag #89: Arvens fødsel

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Uten å merke det selv ønsket de å gjøre det best mulig, men det viste seg å være arv. Hvordan skjer dette?

  • Vi har en presserende oppgave her, la oss gjøre et skittent hack og så fikse det.
  • Du trenger ikke å skrive dokumentasjon og alt er klart hva som skjer her.
  • Jeg kjenner Ansible/Python/Bash/Terraform! Se hvordan jeg kan unnslippe!
  • Jeg er en Full Stack Overflow-utvikler og kopierte dette fra stackoverflow, jeg vet ikke hvordan det fungerer, men det ser kult ut og løser problemet.

Som et resultat kan du få en uforståelig type kode som det ikke er dokumentasjon for, det er ikke klart hva den gjør, om den er nødvendig, men problemet er at du må utvikle den, endre den, legge til krykker og støtter , noe som gjør situasjonen enda verre.

- 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: Bevissthet om problemet

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Den opprinnelig utformede og implementerte IaC-modellen oppfyller ikke lenger kravene til brukere / bedrifter / andre team, og tiden for å gjøre endringer i infrastrukturen slutter å være akseptabel. I dette øyeblikket kommer forståelsen at det er på tide å ta grep.

IaC-refaktorering

Dag #139: Trenger du virkelig refaktorering?

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Før du skynder deg til refaktorisering, må du svare på en rekke viktige spørsmål:

  1. Hvorfor trenger du alt dette?
  2. Har du tid?
  3. Er kunnskap nok?

Hvis du ikke vet hvordan du skal svare på spørsmålene, vil refaktoriseringen avsluttes før den i det hele tatt begynner, eller det kan bare bli verre. Fordi hadde erfaring( Hva jeg lærte av å teste 200 000 linjer med infrastrukturkode), så mottok prosjektet en forespørsel om hjelp til å fikse rollene og dekke dem med tester.

Dag #149: Forbereder refaktoriseringen

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Det første er å forberede seg. Bestem hva vi skal gjøre. For å gjøre dette, kommuniserer vi, finner problemområder og finner ut måter å løse dem på. Vi registrerer de resulterende konseptene på en eller annen måte, for eksempel en artikkel i sammenløp, slik at når spørsmålet oppstår "hva er best?" eller "som er riktig?" Vi har ikke mistet veien. I vårt tilfelle holdt vi fast ved ideen dele og herske: vi bryter opp infrastrukturen i små biter/klosser. Denne tilnærmingen lar deg ta et isolert stykke infrastruktur, forstå hva det gjør, dekke det med tester og endre det uten frykt for å ødelegge noe.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Det viser seg at infrastrukturtesting blir hjørnesteinen og her er det verdt å nevne infrastrukturtestpyramiden. Akkurat samme ideen som er under utvikling, men for infrastruktur: vi går fra billige hurtigtester som sjekker enkle ting, som for eksempel innrykk, til dyre fullverdige tester som distribuerer hele infrastrukturen.

Ansible testforsøk

Før vi går for å beskrive hvordan vi dekket Ansible-tester på prosjektet, vil jeg beskrive forsøkene og tilnærmingene som jeg hadde mulighet til å bruke tidligere for å forstå konteksten til beslutningene som ble tatt.

Dag nr. -997: SDS-bestemmelse

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Første gang jeg testet Ansible var på et prosjekt for å utvikle SDS (Software Defined Storage). Det er en egen artikkel om dette emnet
Hvordan knuse sykler over krykker når du tester distribusjonen din, men kort sagt, vi endte opp med en omvendt testpyramide og testing brukte vi 60-90 minutter på én rolle, som er lang tid. Grunnlaget var e2e-tester, d.v.s. vi distribuerte en fullverdig installasjon og testet den deretter. Det som var enda mer skjerpende var oppfinnelsen av sin egen sykkel. Men jeg må innrømme at denne løsningen fungerte og muliggjorde en stabil utgivelse.

Dag # -701: Ansible og prøvekjøkken

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Utviklingen av Ansible-testideen var bruk av ferdige verktøy, nemlig testkjøkken/kjøkken-ci og inspec. Valget ble bestemt av kunnskap om Ruby (for flere detaljer, se artikkelen om Habré: Drømmer YML-programmerere om å teste Ansible?) jobbet raskere, ca 40 minutter for 10 roller. Vi laget en pakke med virtuelle maskiner og kjørte tester inne.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Generelt fungerte løsningen, men det var noe sediment på grunn av heterogenitet. Da antallet personer som ble testet ble økt til 13 grunnleggende roller og 2 metaroller som kombinerte mindre roller, begynte plutselig testene å kjøre i 70 minutter, som er nesten 2 ganger lengre. Det var vanskelig å snakke om XP (ekstrem programmering) praksis fordi... ingen ønsker å vente 70 minutter. Dette var grunnen til å endre tilnærmingen

Dag # -601: Ansible og molekyl

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Konseptuelt ligner dette på testkitchen, bare vi flyttet rolletesting til docker og endret stabelen. Som et resultat ble tiden redusert til stabile 20-25 minutter for 7 roller.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Ved å øke antallet testede roller til 17 og lining av 45 roller, kjørte vi dette på 28 minutter på 2 jenkins-slaver.

Dag #167: Legger til Ansible-tester til prosjektet

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Mest sannsynlig vil det ikke være mulig å gjøre refaktoriseringsoppgaven i en hast. Oppgaven skal være målbar slik at du kan bryte den i små biter og spise elefanten bit for bit med en teskje. Det må være en forståelse for om du beveger deg i riktig retning, hvor lenge du skal gå.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Generelt spiller det ingen rolle hvordan det skal gjøres, du kan skrive på et stykke papir, du kan sette klistremerker på skapet, du kan lage oppgaver i Jira, eller du kan åpne Google Docs og skrive ned gjeldende status der. Bena vokser av at prosessen ikke er umiddelbar, den blir lang og kjedelig. Det er usannsynlig at noen vil at du skal brenne ut av ideer, bli sliten og bli overveldet under refaktorisering.

Refaktoreringen er enkel:

  • Spise.
  • Sov.
  • Kode.
  • IaC-test.
  • Gjenta

og vi gjentar dette til vi når det tiltenkte målet.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Det er kanskje ikke mulig å begynne å teste alt med en gang, så vår første oppgave var å begynne med linting og sjekke syntaksen.

Dag #181: Green Build Master

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Linting er et lite første skritt mot Green Build Master. Dette vil ikke ødelegge nesten noe, men det vil tillate deg å feilsøke prosesser og lage grønne bygg i Jenkins. Tanken er å utvikle vaner blant teamet:

  • Røde tester er dårlige.
  • Jeg kom for å fikse noe og samtidig gjøre koden litt bedre enn den var før deg.

Dag #193: Fra linting til enhetstester

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Etter å ha bygget prosessen med å få koden inn i masteren, kan du begynne prosessen med trinnvise forbedringer - erstatte linting med lanseringsroller, du kan til og med gjøre det uten idempotens. Du må forstå hvordan du bruker roller og hvordan de fungerer.

Dag #211: Fra enhet til integrasjonstester

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Når de fleste rollene er dekket med enhetstester og alt er lined, kan du gå videre til å legge til integrasjonstester. De. tester ikke en enkelt kloss i infrastrukturen, men en kombinasjon av dem, for eksempel en full forekomstkonfigurasjon.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Ved å bruke jenkins genererte vi mange stadier som lined roller/playbooks parallelt, deretter enhetstester i containere og til slutt integrasjonstester.

Jenkins + Docker + Ansible = Tester

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

  1. Sjekk ut repo og generer byggestadier.
  2. Kjør lo-playbook-etapper parallelt.
  3. Kjør lo-rolletrinn parallelt.
  4. Kjør syntakssjekk rollestadier parallelt.
  5. Kjør testrolletrinn parallelt.
    1. Lint rolle.
    2. Sjekk avhengighet av andre roller.
    3. Sjekk syntaks.
    4. Opprett docker-forekomst
    5. Kjør molecule/default/playbook.yml.
    6. Sjekk idempotens.
  6. Kjør integrasjonstester
  7. Finish

Dag #271: Bussfaktor

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Til å begynne med ble refaktorisering utført av en liten gruppe på to eller tre personer. De gjennomgikk koden i masteren. Over tid utviklet teamet kunnskap om hvordan man skriver kode og kodegjennomgang bidro til formidling av kunnskap om infrastrukturen og hvordan den fungerer. Høydepunktet her var at anmelderne ble plukket ut én etter én, etter en tidsplan, d.v.s. med en viss grad av sannsynlighet vil du klatre inn i et nytt stykke infrastruktur.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Og det skal være behagelig her. Det er praktisk å gjøre en gjennomgang, se innenfor rammen av hvilken oppgave det ble gjort, og historien til diskusjoner. Vi har integrert jenkins + bitbucket + jira.

Men som sådan er en anmeldelse ikke et universalmiddel; på en eller annen måte kom vi inn i masterkoden, som fikk oss til å flopptester:

- 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å fikset de det, men sedimentet ble igjen.

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: Fremskynde tester

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Over tid ble det flere tester, byggene gikk tregere, opptil en time i verste fall. På en av retroene var det en setning som "det er bra at det er tester, men de er trege." Som et resultat forlot vi integrasjonstester på virtuelle maskiner og tilpasset dem for Docker for å gjøre det raskere. Vi erstattet også testinfra med en mulig verifikator for å redusere antall verktøy som brukes.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Strengt tatt var det et sett med tiltak:

  1. Bytt til docker.
  2. Fjern rolletesting, som dupliseres på grunn av avhengigheter.
  3. Øk antallet slaver.
  4. Testkjøringsrekkefølge.
  5. Evne til å lo ALLE lokalt med én kommando.

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Som et resultat ble også Pipeline på jenkins samlet

  1. Generer byggestadier.
  2. Lo alt parallelt.
  3. Kjør testrolletrinn parallelt.
  4. Bli ferdig.

Erfaringer

Unngå globale variabler

Ansible bruker globale variabler, det er en delvis løsning i skjemaet private_rolle_vars, men dette er ikke et universalmiddel.

La meg gi deg et eksempel. La oss ha 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}}

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Det morsomme er at resultatet av lekebøker vil avhenge av ting som ikke alltid er åpenbare, for eksempel rekkefølgen rollene er oppført i. Dessverre er dette Ansibles natur, og det beste som kan gjøres er å bruke en slags avtale, for eksempel innenfor en rolle, bruk kun variabelen som er beskrevet i denne rollen.

BAD: bruk global variabel.

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

GOD: V defaults definere de nødvendige variablene og senere bare bruke 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

Prefiks rollevariabler

BAD: bruk global variabel.

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

GOD: I roller for variabler, bruk variabler foran med rollenavnet; dette, ved å se på inventar, vil gjøre det lettere å forstå hva som skjer.

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

Bruk sløyfekontrollvariabel

BAD: Bruk standardvariabel i løkker item, hvis denne oppgaven/spilleboken er inkludert et sted, kan dette føre til uventet oppførsel

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

GOD: Redefiner en variabel i en loop via loop_var.

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

Sjekk inngangsvariabler

Vi ble enige om å bruke variable prefikser; det ville ikke være overflødig å kontrollere at de er definert som vi forventer og for eksempel ikke ble overstyrt av en tom verdi

GOD: Sjekk 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

Unngå hashe-ordbøker, bruk flat struktur

Hvis en rolle forventer en hash/ordbok i en av sine parametere, så hvis vi ønsker å endre en av de underordnede parameterne, må vi overstyre hele hash/ordboken, noe som vil øke konfigurasjonskompleksiteten.

BAD: Bruk hash/ordbok.

---
user:
  name: admin
  group: admin

GOD: Bruk en flat variabel struktur.

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

Lag idempotente lekebøker og roller

Roller og lekebøker må være idempotente, fordi reduserer konfigurasjonsdrift og frykt for å bryte noe. Men hvis du bruker molekyl, er dette standardoppførselen.

Unngå å bruke kommandoskallmoduler

Å bruke en skallmodul resulterer i et imperativt beskrivelsesparadigme, i stedet for det deklarative, som er kjernen i Ansible.

Test rollene dine via molekyl

Molekyl er en veldig fleksibel ting, la oss se på noen få scenarier.

Molekyl Flere forekomster

В molecule.yml i seksjon platforms du kan beskrive mange verter som du kan distribuere.

---
    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 vertene være converge.yml bruk:

---
- 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 molekyl er det mulig å bruke ansible for å sjekke at instansen er riktig konfigurert, dessuten har dette vært standard siden utgivelse 3. Det er ikke så fleksibelt som testinfra/inspec, men vi kan sjekke at innholdet i filen samsvarer med forventningene våre:

---
- 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 distribuer tjenesten, vent til den blir tilgjengelig og gjør en røyktest:

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

Sett kompleks logikk inn i moduler og plugins

Ansible tar til orde for en deklarativ tilnærming, så når du gjør kodeforgrening, datatransformasjon, skallmoduler, blir koden vanskelig å lese. For å bekjempe dette og holde det enkelt å forstå, ville det ikke være overflødig å bekjempe denne kompleksiteten ved å lage dine egne moduler.

Oppsummer tips og triks

  1. Unngå globale variabler.
  2. Prefiks rollevariabler.
  3. Bruk sløyfekontrollvariabel.
  4. Sjekk inngangsvariabler.
  5. Unngå hash-ordbøker, bruk flat struktur.
  6. Lag idempotente lekebøker og roller.
  7. Unngå å bruke kommandoskallmoduler.
  8. Test rollene dine via molekyl.
  9. Sett kompleks logikk inn i moduler og plugins.

Konklusjon

Hvordan begynne å teste Ansible, refaktorer prosjektet om et år og ikke bli gal

Du kan ikke bare gå og refaktorere infrastrukturen på et prosjekt, selv om du har IaC. Dette er en lang prosess som krever tålmodighet, tid og kunnskap.

UPD1 2020.05.01 20:30 — For primær profilering av playbooks kan du bruke callback_whitelist = profile_tasks å forstå hva som fungerer i lang tid. Så går vi gjennom Ansible akselerasjonsklassikere. Du kan også prøve mitogen
UPD2 2020.05.03 16:34 - Angielski versjon

Kilde: www.habr.com

Legg til en kommentar