Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Detta är utskriften föreställningarDevOps-40 2020-03-18:

Från och med den andra commit, blir vilken kod som helst legacy, eftersom initiala idéer börjar avvika från den hårda verkligheten. Det här är varken bra eller dåligt, det är en given given som är svår att argumentera med och måste levas med. En del av denna process är refaktorering. Refaktorering av infrastruktur som kod. Låt historien börja om hur man refaktorerar Ansible om ett år och inte blir galen.

Arvets födelse

Dag #1: Patient Zero

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Det var en gång i tiden ett villkorligt projekt. Den hade ett utvecklingsteam och Ops-ingenjörer. De löste samma problem: hur man distribuerar servrar och kör en applikation. Problemet var att varje lag löste detta problem på sitt eget sätt. Vid projektet beslutades det att använda Ansible för att synkronisera kunskap mellan Dev- och Ops-teamen.

Dag #89: Arvets födelse

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Utan att själva märka det ville de göra det så bra som möjligt, men det visade sig vara arv. Hur går det till?

  • Vi har en brådskande uppgift här, låt oss göra ett smutsigt hack och sedan fixa det.
  • Du behöver inte skriva dokumentation och allt är klart vad som händer här.
  • Jag vet Ansible/Python/Bash/Terraform! Titta hur jag kan smita!
  • Jag är en Full Stack Overflow-utvecklare och kopierade detta från stackoverflow, jag vet inte hur det fungerar, men det ser coolt ut och löser problemet.

Som ett resultat kan du få en obegriplig typ av kod som det inte finns någon dokumentation för, det är inte klart vad den gör, om den behövs, men problemet är att du behöver utveckla den, modifiera den, lägga till kryckor och stöd. vilket gör situationen ännu 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: Medvetenhet om problemet

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Den initialt uttänkta och implementerade IaC-modellen uppfyller inte längre kraven från användare / företag / andra team, och tiden för att göra ändringar i infrastrukturen slutar att vara acceptabel. I detta ögonblick kommer förståelsen att det är dags att vidta åtgärder.

IaC-refaktorering

Dag #139: Behöver du verkligen refaktorering?

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Innan du rusar till refactor måste du svara på ett antal viktiga frågor:

  1. Varför behöver du allt detta?
  2. Har du tid?
  3. Räcker kunskap?

Om du inte vet hur du ska svara på frågorna, så kommer refaktoreringen att sluta innan den ens har börjat, eller så kan det bara bli värre. Därför att hade erfarenhet ( Vad jag lärde mig av att testa 200 000 rader av infrastrukturkod), sedan fick projektet en förfrågan om hjälp att fixa rollerna och täcka dem med tester.

Dag #149: Förberedelse av omstruktureringen

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Det första är att förbereda. Bestäm vad vi ska göra. För att göra detta kommunicerar vi, hittar problemområden och tar reda på sätt att lösa dem. Vi registrerar de resulterande begreppen på något sätt, till exempel en artikel i sammanflöde, så att när frågan uppstår "vad är bäst?" eller "vilket är korrekt?" Vi har inte gått vilse. I vårt fall höll vi fast vid idén söndra och härska: vi bryter upp infrastrukturen i små bitar/tegelstenar. Detta tillvägagångssätt låter dig ta en isolerad del av infrastrukturen, förstå vad den gör, täcka den med tester och ändra den utan rädsla för att gå sönder något.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Det visar sig att infrastrukturtestning blir hörnstenen och här är det värt att nämna infrastrukturtestpyramiden. Exakt samma idé som är under utveckling, men för infrastruktur: vi går från billiga snabba tester som kontrollerar enkla saker, som indrag, till dyra fullfjädrade tester som distribuerar hela infrastrukturen.

Ansible testförsök

Innan vi går för att beskriva hur vi täckte Ansible-tester på projektet kommer jag att beskriva de försök och tillvägagångssätt som jag hade möjlighet att använda tidigare för att förstå sammanhanget för de beslut som fattades.

Dag nr -997: Säkerhetsdatablad

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Första gången jag testade Ansible var på ett projekt för att utveckla SDS (Software Defined Storage). Det finns en separat artikel om detta ämne
Hur man bryter cyklar över kryckor när man testar sin distribution, men kort sagt, vi slutade med en inverterad testpyramid och testning spenderade vi 60-90 minuter på en roll, vilket är lång tid. Grunden var e2e-tester, d.v.s. vi distribuerade en fullfjädrad installation och testade den sedan. Vad som var ännu mer försvårande var uppfinningen av hans egen cykel. Men jag måste erkänna att den här lösningen fungerade och möjliggjorde en stabil release.

Dag # -701: Ansible och provkök

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Utvecklingen av Ansible-testidén var användningen av färdiga verktyg, nämligen testkök/kök-ci och inspec. Valet bestämdes av kunskap om Ruby (för mer information, se artikeln om Habré: Drömmer YML-programmerare om att testa Ansible?) arbetade snabbare, cirka 40 minuter för 10 roller. Vi skapade ett paket med virtuella maskiner och körde tester inuti.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

I allmänhet fungerade lösningen, men det fanns en del sediment på grund av heterogenitet. När antalet personer som testades ökades till 13 basroller och 2 metaroller som kombinerade mindre roller, så började plötsligt testerna pågå i 70 minuter, vilket är nästan 2 gånger längre. Det var svårt att prata om XP (extrem programmering) praxis eftersom... ingen vill vänta 70 minuter. Detta var anledningen till att ändra inställningen

Dag # -601: Ansible och molekyl

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Konceptuellt liknar detta testkitchen, bara vi flyttade rolltestning till docker och ändrade stacken. Som ett resultat minskade tiden till stabila 20-25 minuter för 7 roller.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Genom att öka antalet testade roller till 17 och lindra 45 roller körde vi detta på 28 minuter på 2 jenkins-slavar.

Dag #167: Lägga till Ansible-tester till projektet

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Troligtvis kommer det inte att vara möjligt att göra omstruktureringsuppgiften i all hast. Uppgiften ska vara mätbar så att du kan bryta den i små bitar och äta elefanten bit för bit med en tesked. Det måste finnas en förståelse för om du rör dig i rätt riktning, hur lång tid det ska gå.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Generellt sett spelar det ingen roll hur det kommer att göras, du kan skriva på ett papper, du kan sätta klistermärken på garderoben, du kan skapa uppgifter i Jira, eller så kan du öppna Google Docs och skriva ner aktuell status där. Benen växer av att processen inte är omedelbar, den blir lång och tråkig. Det är osannolikt att någon vill att du ska brinna ut på idéer, tröttna och bli överväldigad under omstruktureringen.

Refaktoreringen är enkel:

  • Äta.
  • Sova.
  • Koda.
  • IaC-test.
  • Upprepa

och vi upprepar detta tills vi når det avsedda målet.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Det kanske inte går att börja testa allt direkt, så vår första uppgift var att börja med linting och kolla syntaxen.

Dag #181: Green Build Master

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Linting är ett litet första steg mot Green Build Master. Detta kommer inte att bryta nästan vad som helst, men det kommer att tillåta dig att felsöka processer och göra gröna builds i Jenkins. Tanken är att utveckla vanor bland teamet:

  • Röda tester är dåliga.
  • Jag kom för att fixa något och samtidigt göra koden lite bättre än den var innan dig.

Dag #193: Från ludd till enhetstester

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Efter att ha byggt in processen för att få in koden i mastern kan du börja processen med steg-för-steg förbättring - ersätt linting med lanseringsroller, du kan till och med göra det utan idempotens. Du måste förstå hur man tillämpar roller och hur de fungerar.

Dag #211: Från enhet till integrationstester

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

När de flesta roller är täckta med enhetstester och allt är ludd kan du gå vidare till att lägga till integrationstester. De där. testar inte en enda sten i infrastrukturen, utan en kombination av dem, till exempel en fullständig instanskonfiguration.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Med hjälp av jenkins genererade vi många stadier som raderade roller/spelböcker parallellt, sedan enhetstester i behållare och slutligen integrationstester.

Jenkins + Docker + Ansible = Tester

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

  1. Kassa repo och generera byggstadier.
  2. Kör lint playbook stadier parallellt.
  3. Kör lintrollsteg parallellt.
  4. Kör syntaxkontrollrollsteg parallellt.
  5. Kör testrollssteg parallellt.
    1. Lint roll.
    2. Kontrollera beroendet av andra roller.
    3. Kontrollera syntaxen.
    4. Skapa docker-instans
    5. Kör molecule/default/playbook.yml.
    6. Kontrollera idempotens.
  6. Kör integrationstester
  7. Finish

Dag #271: Bussfaktor

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Till en början utfördes omfaktorisering av en liten grupp på två eller tre personer. De granskade koden i mastern. Med tiden utvecklade teamet kunskap om hur man skriver kod och kodgranskning bidrog till kunskapsspridningen om infrastrukturen och hur den fungerar. Höjdpunkten här var att recensenterna valdes ut en efter en, enligt ett schema, d.v.s. med en viss grad av sannolikhet kommer du att klättra in i en ny bit av infrastruktur.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Och det ska vara bekvämt här. Det är bekvämt att göra en genomgång, se inom ramen för vilken uppgift det gjordes och diskussionernas historia. Vi har integrerat jenkins + bitbucket + jira.

Men som sådan är en recension inte ett universalmedel; på något sätt kom vi in ​​i masterkoden, vilket fick oss att flopptesta:

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

Sedan fixade de det, men resterna blev kvar.

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: Påskynda testerna

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Med tiden blev det fler tester, byggen gick långsammare, upp till en timme i värsta fall. På en av retroerna fanns en fras som "det är bra att det finns tester, men de är långsamma." Som ett resultat övergav vi integrationstester på virtuella maskiner och anpassade dem för Docker för att göra det snabbare. Vi ersatte även testinfra med en möjlig verifierare för att minska antalet verktyg som används.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Strängt taget fanns det en uppsättning åtgärder:

  1. Byt till docker.
  2. Ta bort rolltestning, som dupliceras på grund av beroenden.
  3. Öka antalet slavar.
  4. Provkörningsordning.
  5. Förmåga att luda ALLT lokalt med ett kommando.

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Som ett resultat förenades också Pipeline på jenkins

  1. Skapa byggstadier.
  2. Ludd allt parallellt.
  3. Kör testrollssteg parallellt.
  4. Finish.

Lärdomar

Undvik globala variabler

Ansible använder globala variabler, det finns en delvis lösning i formuläret privat_roll_vars, men detta är inget universalmedel.

Låt mig ge dig ett exempel. Låt 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}}

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Det roliga är att resultatet av playbooks kommer att bero på saker som inte alltid är uppenbara, till exempel i vilken ordning rollerna listas. Tyvärr är detta Ansibles natur och det bästa som kan göras är att använda någon form av överenskommelse, till exempel inom en roll, använd endast variabeln som beskrivs i denna roll.

DÅLIG: använd global variabel.

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

BRA: V defaults definiera de nödvändiga variablerna och använd senare endast 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

Prefix rollvariabler

DÅLIG: använd global variabel.

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

BRA: I roller för variabler, använd variabler med prefixet rollnamnet; detta, genom att titta på inventering, kommer att göra det lättare att förstå vad som händer.

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

Använd loopkontrollvariabel

DÅLIG: Använd standardvariabel i loopar item, om denna uppgift/spelbok finns med någonstans kan detta leda till oväntat beteende

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

BRA: Omdefiniera en variabel i en loop via loop_var.

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

Kontrollera indatavariabler

Vi gick med på att använda variabla prefix; det skulle inte vara överflödigt att kontrollera att de är definierade som vi förväntar oss och till exempel inte åsidosattes av ett tomt värde

BRA: Kontrollera 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

Undvik hash-ordböcker, använd platt struktur

Om en roll förväntar sig en hash/ordbok i en av dess parametrar, om vi vill ändra en av de underordnade parametrarna, måste vi åsidosätta hela hash/ordboken, vilket kommer att öka konfigurationskomplexiteten.

DÅLIG: Använd hash/ordbok.

---
user:
  name: admin
  group: admin

BRA: Använd en platt variabel struktur.

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

Skapa idempotenta spelböcker och roller

Roller och spelböcker måste vara idempotenta, eftersom minskar konfigurationsdrift och rädsla för att gå sönder något. Men om du använder molekyler är detta standardbeteendet.

Undvik att använda kommandoskalsmoduler

Att använda en skalmodul resulterar i ett imperativt beskrivningsparadigm, istället för det deklarativa, som är kärnan i Ansible.

Testa dina roller via molekyl

Molekyl är en mycket flexibel sak, låt oss titta på några scenarier.

Molekyl Flera instanser

В molecule.yml i avsnitt platforms du kan beskriva många värdar som du kan distribuera.

---
    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öljaktligen kan dessa värdar då vara converge.yml använda sig av:

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

I molekyl är det möjligt att använda ansible för att kontrollera att instansen har konfigurerats korrekt, dessutom har detta varit standard sedan release 3. Det är inte lika flexibelt som testinfra/inspec, men vi kan kontrollera att innehållet i filen matchar våra förväntningar:

---
- 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 distribuera tjänsten, vänta tills den blir tillgänglig och gör ett röktest:

---
  - 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ätt in komplex logik i moduler och plugins

Ansible förespråkar ett deklarativt tillvägagångssätt, så när du gör kodförgrening, datatransformation, skalmoduler blir koden svår att läsa. För att bekämpa detta och hålla det enkelt att förstå, skulle det inte vara överflödigt att bekämpa denna komplexitet genom att skapa dina egna moduler.

Sammanfatta tips och tricks

  1. Undvik globala variabler.
  2. Prefix rollvariabler.
  3. Använd loopkontrollvariabel.
  4. Kontrollera indatavariabler.
  5. Undvik hash-ordböcker, använd platt struktur.
  6. Skapa idempotenta spelböcker och roller.
  7. Undvik att använda kommandoskalsmoduler.
  8. Testa dina roller via molekyl.
  9. Sätt in komplex logik i moduler och plugins.

Slutsats

Hur man börjar testa Ansible, omstrukturera projektet om ett år och inte bli galen

Du kan inte bara gå och omstrukturera infrastrukturen i ett projekt, även om du har IaC. Detta är en lång process som kräver tålamod, tid och kunskap.

UPD1 2020.05.01 20:30 — För primär profilering av spelböcker kan du använda callback_whitelist = profile_tasks att förstå vad som fungerar under lång tid. Sedan går vi igenom Ansible accelerationsklassiker. Du kan också prova mitogen
UPD2 2020.05.03 16:34 - Svensk version

Källa: will.com

Lägg en kommentar