Juhend: kuidas testida ansible-rolle ja avastada probleeme enne tootmist

Tere kõigile!

Ma töötan DevOps-insenerina hotellide broneerimise teenuses. Ostrovok.ru. Selles artiklis tahan rääkida meie kogemustest ansible-rollide testimisel.

Ostrovok.ru-s kasutame konfiguratsioonihaldurina ansible't. Hiljuti jõudsime vajaduseni testida rolle, kuid nagu selgus, on selleks olemas vaid vähe tööriistu — kõige populaarsem neist on tõenäoliselt Molecule'i raamistik, seetõttu otsustasime seda kasutada. Kuid selgus, et selle dokumentatsioon vaikib paljusid takistusi. Me ei leidnud piisavalt üksikasjalikku juhendit eesti keeles, seetõttu otsustasime kirjutada selle artikli.

Juhend: kuidas testida ansible-rolle ja avastada probleeme enne tootmist

Molecule

Molekul — raamistik, mis aitab ansible-rollide testimisel.

Lihtsustatud kirjeldus: Molekul loob teie määratud platvormil (pilv, virtuaalmasin, konteiner; lisainfot vaata jaotisest Driver), käivitab teie rolli, seejärel käivitab testid ja kustutab instantsi. Kui ühe sammu käigus ilmneb probleem, teavitab Molekul teid sellest.

Nüüd vaatakse lähemalt.

Veidi teooriat

Uurime kahte peamist Molekuli üksust: Scenario ja Driver.

Scenario

Skenaaria sisaldab kirjelduse sellest, mida, kus, kuidas ja millises järjekorras teostatakse. Ühel rollil võib olla mitu stsenaariumi, kus igaüks on kataloog teel /molecule/, mis sisaldab testimiseks vajalike toimingute kirjeldusi. Kohustuslik on, et olemas oleks skenaarium Seejärel käivitame exec käsu ja ootame 5000 sekundit, et jätkata jälgimist:, mis luuakse automaatselt, kui käivitate rolli Molecule abil. Järgmiste stsenaariumide nimed valitakse teie äranägemisel.

Testimise tegevuste järjekorda stsenaariumis nimetatakse matrix, ja vaikimisi on see järgmine:

(Sammud, mida on märgitud ?, jäetakse vaikimisi vahele, kui kasutaja ei ole neid kirjeldanud)

  • lint — lintri käitamine. Vaikimisi kasutatakse yamllint ja flake8,
  • destroy — instantside kustutamine eelmise Molecule'i käivitamise puhul (kui need on jäänud),
  • dependency? — установка ansible-зависимости тестируемой роли,
  • syntax — rolli süntaksi kontrollimine käsuga ansible-playbook --syntax-check,
  • create — instantsi loomine,
  • prepare? — подготовка инстанса; например, проверка / установка python2
  • converge — testitava playbooki käivitamine,
  • idempotence — playbooki uuesti käivitamine idempotentsuse testi jaoks,
  • side_effect? — действия, не относящиеся непосредственно к роли, но нужные для тестов,
  • verify — saadud konfiguratsiooni testide käitamine testinfra(vaikimisi) /goss/inspec,
  • cleanup? — (в новых версиях) — грубо говоря, «очистка» внешней инфраструктуры, задетой Молекулой,
  • destroy — instantsi kustutamine.

See järjekord katab enamikke juhtumeid, kuid vajadusel võib seda muuta.

Iga eeltoodud sammu saab käivitada eraldi kasutades molecule. Kuid tuleb mõista, et iga sellise CLI-käsu jaoks võib olla oma tegevuste järjekord, mida saab teada käivitades molecule matrix. Näiteks käsu käivitamisel converge (testitava playbooki käitamine) teostatakse järgmised toimingud:

$ molecule matrix converge
...
└── default         # stsenaariumi nimi
    ├── dependency  # sõltuvuste installimine
    ├── create      # instantsi loomine
    ├── prepare     # instantsi ettevalmistamine
    └── converge    # playbooki käitamine

Nende toimingute järjekorda saab redigeerida. Kui mõni nimekirjas juba teostatakse, jäetakse see vahele. Praegust seisundit ja ka instantside konfiguratsiooni hoiab Molecule kaustas $TMPDIR/molecule//.

Sammude lisamine ? on võimalik, kirjeldades soovitud tegevusi ansible-playbooki formaadis, ja faili nimi vastab sammu nimele: prepare.yml/side_effect.yml. Molecule ootab neid faile stsenaariumi kaustas.

Driver

Driver on entiteet, kus luuakse testimiseks instantsid.
Moleculal on järgmiste standardsete draiverite jaoks valmis malli nimekiri: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Enamikul juhtudel on mallid create.yml ja destroy.yml stsenaariumi kaustas, mis kirjeldavad instantsi loomist ja eemaldamist vastavalt.
Eranditeks on Docker ja Vagrant, kuna nende moodulitega võidakse suhelda ilma ülaltoodud failideta.

Tuleb esile tuua Delegated draiver, kuna selle kasutamisel on instantsi loomise ja eemaldamise failides kirjeldatud ainult instantside konfiguratsiooniga töötamine, muu peab kirjeldama insener.

Vaikimisi draiveriks on Docker.

Nüüd lähme praktikale ja vaatleme edasisi omadusi seal.

Esimene samm

Testime lihtsat nginx installimise rolli kui "hello world". Draiveriks valime docker – arvan, et see on enamikul teistest (ja pidagem meeles, et docker on vaikimisi draiver).

Valmistame ette virtualenv ja installime sinna molecule:

> pip install virtualenv
> virtualenv -p `which python2` venv
> source venv/bin/activate
> pip install molecule docker  # molecule installib ansible sõltuvusena; docker draiverina

Järgmine samm on uue rolli initsialiseerimine.
Uue rolli initsialiseerimine, nagu ka uue stsenaariumi, toimub käsu abil molecule init:

> molecule init role -r nginx
--> Initialiseerimine uut rolli nginx...
Rolli initsialiseerimine /nginx edukalt.
> cd nginx
> tree -L 1
.
├── README.md
├── defaults
├── handlers
├── meta
├── molecule
├── tasks
└── vars

6 katalooge, 1 fail

Saime tüüpilise ansible-rollet. Edasi tehtavad kõik interaktsioonid CLI Molekulaga toimuvad rolli juurest.

Vaatame, mis asub rolli kataloogis:

> tree molecule/default/
molecule/default/
├── Dockerfile.j2  # Jinja mall Dockerfile jaoks
├── INSTALL.rst.   # Natuke teavet skripti sõltuvuste installimise kohta
├── molecule.yml   # Konfiguratsioonifail
├── playbook.yml   # Rolli käivitamise playbook
└── tests          # Testide kataloog verify etapis
    └── test_default.py

1 kataloog, 6 faili

Analüüsime konfi molecule/default/molecule.yml (vahetame ainult docker image):

---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
platforms:
  - name: instance
    image: centos:7
provisioner:
  name: ansible
  lint:
    name: ansible-lint
scenario:
  name: default
verifier:
  name: testinfra
  lint:
    name: flake8

dependency

See sektsioon kirjeldab sõltuvuste allikaid.

Võimalikud variandid: galaxy, gilt, shell.

Shell on lihtsalt käsirida, mida kasutatakse juhul, kui galaxy ja gilt ei kata teie vajadusi.

Ma ei jää siia pikalt, piisavalt on juba kirjeldatud dokumentatsioon.

driver

Draiveri nimi. Meil on see docker.

lint

Lintimiseks kasutatakse yamllint'i.

Kasulikud valikud selle konfiosas — see võimalus määrata yamllint'i konfiguratsioonifail, edastada keskkonnamuutujad või keelata lintija:

lint:
  name: yamllint
  options:
    config-file: foo/bar
  env:
    FOO: bar
  enabled: False

platforms

Kirjeldab instantside konfiguratsiooni.
Dockeriga draiveri korral itereerib Molekul selle sektsiooni üle, ja iga loendi element on saadaval Dockerfile.j2 nagu muutuja item.

Draiveri korral, milles on kohustuslikud create.yml ja destroy.yml, sektsioon on neis saadaval nagu molecule_yml.platforms, ja iteratsioonid selle üle on juba nende failide kaudu kirjeldatud.

Kuna Molekul pakub instantside haldamist ansible-moodulitele, tuleb ka võimalike seadistuste loetelu otsida sealt. Näiteks dockeri jaoks kasutatakse moodulit docker_container_module. Milliseid mooduleid kasutatakse ülejäänud draiverite puhul, saab leida dokumentatsioon.

Ja samuti saab erinevate draiverite kasutusnäite leida Molekula enda testides.

Asendame siin centos:7 . Tundub, et ubuntu.

provisioner

„Pakkuja” — üksus, mis haldab instantside. Molekula puhul on see ansible, teiste toetamine pole plaanis, seega võib seda sektsiooni ettevaatlikult nimetada ansible'i laiendatud konfiguratsiooniks.
Siin on võimalik märkida palju asju, toon välja peamised, minu arvates, momendid:

  • playbooks: saab märkida, millised playbook'id peaksid olema kasutusel teatud etappides.

provisioner:
  name: ansible
  playbooks:
    create: create.yml
    destroy: ..\/default\/destroy.yml
    converge: playbook.yml
    side_effect: side_effect.yml
    cleanup: cleanup.yml

provisioner:
  name: ansible
  config_options:
    defaults:
      fact_caching: jsonfile
    ssh_connection:
      scp_if_ssh: True

provisioner:
  name: ansible  
  connection_options:
    ansible_ssh_common_args: "-o 'UserKnownHostsFile=\/dev\/null' -o 'ForwardAgent=yes'"

  • options: Ansible'i parameetrid ja keskkonnamuutujad

provisioner:
  name: ansible  
  options:
    vvv: true
    diff: true
  env:
    FOO: BAR

scenario

Senaariumi järjestuse pealkiri ja kirjeldus.
Muutmaks mõne käsu vaikimisi toimingute maatriksi, saab lisada võtme _sequence ja selle väärtuseks määrata soovitud sammude nimekirja.
Oletame, et soovime muuta toimingute järjestust, kui käivitame käsku playbook'i käitamiseks: molecule converge

# изначально:
# - dependency
# - create
# - prepare
# - converge
scenario:
  name: default
  converge_sequence:
    - create
    - converge

verifier

Testimise ja selle jaoks linteri raamistik. Vaikimisi kasutatakse linterina testinfra ja flake8. Võimalikud valikud on sarnased eelnevatele:

verifier:
  name: testinfra
  additional_files_or_dirs:
    - ..\/path\/to\/test_1.py
    - ..\/path\/to\/test_2.py
    - ..\/path\/to\/directory\/\*
  options:
    n: 1
  enabled: False
  env:
    FOO: bar
  lint:
    name: flake8
    options:
      benchmark: True
    enabled: False
    env:
      FOO: bar

Tagasi meie rolli juurde. Toimetame faili tasks\/main.yml niimoodi:

---
- name: Install nginx
  apt:
    name: nginx
    state: present

- name: Start nginx
  service:
    name: nginx
    state: started

Ja lisame testid faili molecule\/default\/tests\/test_default.py

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed

def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

def test_nginx_config(host):
    host.run("nginx -t")

Valmis, nüüd on jäänud ainult käivitada (mälumahult taas kord):

> molecule test

Pikk väljund varjatud:

--> Skeemi valideerimine /nginx/molecule/default/molecule.yml.
Valideerimine õnnestus.
--> Testi matriits

└── default
    ├── lint
    ├── hävita
    ├── sõltuvus
    ├── süntaks
    ├── loo
    ├── ettevalmistamine
    ├── koondu
    ├── idempotentsus
    ├── külg mõju
    ├── kinnita
    └── hävita

--> Stsenaarium: 'default'
--> Tegevus: 'lint'
--> Käivitan Yamllinti faile /nginx/... leitud failidel.
Lintimine õnnestus.
--> Käivitan Flake8 faile /nginx/molecule/default/tests/... leitud failidel.
Lintimine õnnestus.
--> Käivitan Ansible Linti /nginx/molecule/default/playbook.yml... leitud failidel.
Lintimine õnnestus.
--> Stsenaarium: 'default'
--> Tegevus: 'hävita'

    MÄNG [Hävita] *****************************************************************

    ÜLESANNE [Hävita molekuli instantsid] ********************************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Oota instantside kustutamise lõpuleviimist] *******************************
    ok: [localhost] => (element=Ei üksus)
    ok: [localhost]

    ÜLESANNE [Kustuta docker võrgud] ************************************************

    MÄNG TULEMUSED *********************************************************************
    localhost                  : ok=2    muudetud=1    saavumatu=0    ebaõnnestunud=0

--> Stsenaarium: 'default'
--> Tegevus: 'sõltuvus'
Ülemine, puudub nõuete fail.
--> Stsenaarium: 'default'
--> Tegevus: 'süntaks'

    mänguraamat: /nginx/molecule/default/playbook.yml

--> Stsenaarium: 'default'
--> Tegevus: 'loo'

    MÄNG [Loo] ******************************************************************

    ÜLESANNE [Logi sisse Docker registrisse] **********************************************
    ülemine: [localhost] => (element=Ei üksus)

    ÜLESANNE [Loo Dockerfile'id pildi nimedest] *************************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Avasta kohalikud Docker pildid] ********************************************
    ok: [localhost] => (element=Ei üksus)
    ok: [localhost]

    ÜLESANNE [Loo Ansible’i ühilduv pilt] ***************************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Loo docker võrgud] ************************************************

    ÜLESANNE [Loo molekuli instantsid] *********************************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Oota instantside loomise lõpuleviimist] *******************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    MÄNG TULEMUSED *********************************************************************
    localhost                  : ok=5    muudetud=4    saavumatu=0    ebaõnnestunud=0

--> Stsenaarium: 'default'
--> Tegevus: 'ettevalmistamine'
Ülemine, ettevalmistus mänguraamat pole seadistatud.
--> Stsenaarium: 'default'
--> Tegevus: 'koondu'

    MÄNG [Koondu] ****************************************************************

    ÜLESANNE [Faktide kogumine] *********************************************************
    ok: [instants]

    ÜLESANNE [nginx : Installi nginx] ***************************************************
    muudetud: [instants]

    ÜLESANNE [nginx : Alusta nginx] *****************************************************
    muudetud: [instants]

    MÄNG TULEMUSED *********************************************************************
    instants                   : ok=3    muudetud=2    saavumatu=0    ebaõnnestunud=0

--> Stsenaarium: 'default'
--> Tegevus: 'idempotentsus'
Idempotentsus õnnestus.
--> Stsenaarium: 'default'
--> Tegevus: 'külg mõju'
Ülemine, külg mõju mänguraamat pole seadistatud.
--> Stsenaarium: 'default'
--> Tegevus: 'kinnita'
--> Käivitan Testinfra teste, mis leiti /nginx/molecule/default/tests/... 
    ============================= katse seanss algab ==============================
    platvorm darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    rootdir: /nginx/molecule/default, inifile:
    pistikud: testinfra-1.16.0
kogutud 4 eset

    tests/test_default.py ....                                               [100%]

    ========================== 4 läbis 27,23 sekundit ===========================
Kinnitus õnnestus.
--> Stsenaarium: 'default'
--> Tegevus: 'hävita'

    MÄNG [Hävita] *****************************************************************

    ÜLESANNE [Hävita molekuli instantsid] ********************************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Oota instantside kustutamise lõpuleviimist] *******************************
    muudetud: [localhost] => (element=Ei üksus)
    muudetud: [localhost]

    ÜLESANNE [Kustuta docker võrgud] ************************************************

    MÄNG TULEMUSED *********************************************************************
    localhost                  : ok=2    muudetud=2    saavumatu=0    ebaõnnestunud=0

Meie lihtne roll testiti probleemideta.
Oluline on meeles pidada, et kui töö käigus esines probleeme molekuli test, siis kui te ei ole standardset järjekorda muutnud, Molekul eemaldab instantsi.

Silumise jaoks on kasulikud järgmised käsklused:

> molecule --debug  # silumisinfo. Tavalise käivitamise korral peidab Molekul logisid.
> molecule converge          # Hoidke instantsi pärast testitava rolli käivitamist.
> molecule login             # Sisene loodud instantsse.
> molecule --help            # Täielik käskude nimekiri.

Olemasolev roll

Uue stsenaariumi lisamine olemasolevale rollile toimub rolli kataloogist järgmiste käskudega:

# полный список доступных параметров
> molecule init scenarion --help
# создание нового сценария
> molecule init scenario -r <role_name> -s <scenario_name>

Kui see on rollis esimene stsenaarium, siis parameetrit -s võib jätta vahele, kuna stsenaarium luuakse Seejärel käivitame exec käsu ja ootame 5000 sekundit, et jätkata jälgimist:.

Kokkuvõte

Nagu näete, ei ole Molekul kuigi keeruline ja kasutades oma malle saab uue stsenaariumi kasutuselevõtu viia kokku muutuja muutmisel loomise ja eemaldamise mängude seas. Molekul integreerub probleemideta CI süsteemidega, mis võimaldab arendamise kiirusel kasvada, vähendades käsitsi mängude testimiseks kuluvat aega.

Aitäh tähelepanu eest. Kui teil on kogemusi ansible-rollide testimisel, mis ei ole seotud Molekulaga - rääkige sellest kommentaarides!

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster