Juhend: kuidas testida ansible-rolle ja teada saada probleemidest enne tootmisse minekut.

Tere kõigile!

Ma töötan DevOps-ingeniirina hotellide broneerimise teenuses. Ostrovok.ru. Selles artiklis tahan jagada meie kogemust ansible-rollide testimisel.

Ostrovok.ru-s kasutame konfiguratsioonihaldurina ansible't. Hiljuti jõudsime vajaduseni testida rolle, kuid nagu selgus, ei ole selleks palju tööriistu – kõige populaarsem neist on ilmselt raamistik Molecule, seetõttu otsustasime seda kasutada. Selgus aga, et selle dokumentatsioon ei käsitle paljusid peidetud probleeme. Me ei leidnud piisavalt üksikasjalikku juhendit venekeeles, seega otsustasime kirjutada selle artikli.

Juhend: kuidas testida ansible-rolle ja teada saada probleemidest enne tootmisse minekut.

Molecule

Molekul – raamistik, mis aitab ansible-rollide testimisel.

Lihtsustatud kirjeldus: Molekul loob instantsi määratud platvormil (pilv, virtuaalmasin, konteiner; rohkem detailide kohta vaata peatükki Driver), käivitab teie rolli, seejärel käivitab testid ja kustutab instantsi. Kui mõne sammu täitmisel tekib ebaõnnestumine, teatab Molekul sellest.

Nüüd lähemalt.

Natuke teooriat

Vaatame kahte peamist Molekuli elementi: Scenario ja Driver.

Scenario

Süntaks sisaldab kirjelduse sellest, mis, kus, kuidas ja millises järjekorras teostatakse. Ühel rollil võib olla mitmeid süntakse, kus igaüks neist on kataloog teel. /molecule/, mis sisaldab testimiseks vajalike tegevuste kirjeldusi. Süntaks peab kindlasti olema olemas. default, mis luuakse automaatselt, kui algatate rolli Molekuli abil. Järgmiste süntakse nimed valitakse teie äranägemise järgi.

Testimise tegevuste järjestus süntaksis nimetatakse matrix, ja vaikimisi on see järgmine:

(Sammud, mis on märgistatud ?, vahepeal jäetakse vahele, kui neid ei ole kasutaja poolt kirjeldatud)

  • lint — linteerimise läbiviimine. Vaikimisi kasutatakse yamllint ja flake8,
  • destroy — instantside kustutamine eelmistest Molekuli käivitustest (kui need on jäänud),
  • sõltuvus? — установка 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 — testide käivitamine saadud konfiguratsiooniga vahendusel testinfra(vaikimisi) /goss/inspec,
  • cleanup? — (в новых версиях) — грубо говоря, «очистка» внешней инфраструктуры, задетой Молекулой,
  • destroy — instantsi kustutamine.

See jada katab katab, kuid vajadusel saab seda kohandada.

Iga ülaltoodud sammu saab eraldi käivitada, kasutades molecule. Kuid tasub mõista, et iga sellise CLI käsu jaoks võib olla olemas oma tegevuste järjestus, mille teada saamiseks tuleb käivitada molecule matrix. Näiteks käsu käivitamisel converge (testitava mängu käitamine) teostatakse järgmised toimingud:

$ molecule matrix converge
...
└── default         # stsenaariumi nimi
    ├── dependency  # sõltuvuste installimine
    ├── create      # instantsi loomine
    ├── prepare     # instantsi ettevalmistamine
    └── converge    # mängu läbiviimine

Selle tegevuste järjestust saab redigeerida. Kui mõni nimekirjast on juba täidetud, siis see vahele jäetakse. Praegune seisund ja ka instantside konfigureerimine salvestatakse katalooge $TMPDIR/molecule//.

Sammude lisamine ? on võimalik, kui kirjeldada soovitud tegevusi ansible mängu formaadis ja nimetada fail vastavalt sammule: prepare.yml/side_effect.yml. Need failid ootab Moolikula stsenaariumi kaustas.

Driver

Juht on olek, kus luuakse instantsid testimiseks.
Molekuli on valmis šablone standardsete draiverite jaoks: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Enamikul juhtudel on šablonid failid create.yml ja destroy.yml , mis asuvad stsenaariumi kaustas ja kirjeldavad vastavalt instantsi loomist ja kustutamist.
Erandiks on Docker ja Vagrant, kuna nende moodulitega suhtlemine võib toimuda ilma eespool nimetatud failideta.

Erakordne on Delegated draiver, kuna selle kasutamisel instantsi loomise ja kustutamise failides on kirjeldatud ainult instantside konfigureerimist, ülejäänu peab kirjeldama insener.

Vaikimisi draiver on Docker.

Nüüd liigume praktika juurde ja arutame edasisi eripärasid seal.

Alustamine

Katsena ‘hello world’ testime lihtsat nginx-i installimise rolli. Draiverina valime Docker’i – arvan, et see on enamikul teie arvutitest juba paigaldatud (ja meenutame, et Docker on vaikimisi draiver).

Valmistame ette virtualenv ja installime sellesse molekuli:

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

Järgmiseks samuks initsialiseerime uue rolli.
Uue rolli, sama nagu uue stsenaariumi, initsialiseerimine toimub käsu abil molecule init:

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

6 kausta, 1 fail

Saime tüüpilise ansible-rolli. Edasi toimub kõik koostöö CLI Molekulaga rolli juurest.

Vaadakem, mis asub rolli kaustas:

> tree molecule/default/
molecule/default/
├── Dockerfile.j2  # Jinja mall Dockerfile'ile
├── INSTALL.rst.   # Veidi teavet stsenaariumi sõltuvuste installimise kohta
├── molecule.yml   # Konfigureerimisfail
├── playbook.yml   # Rolli käivitamise playbook
└── tests          # Verifitseerimise etapi testide kaust
    └── test_default.py

1 kaust, 6 faili

Analüüsime konfi molecule/default/molecule.yml (muudame 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

sõltuvus

See sektsioon kirjeldab sõltuvuste allikat.

Võimalikud variandid: galaxy, gilt, shell.

Shell on lihtsalt käsurea liides, mis on kasutusel juhul, kui galaxy ja gilt ei kata teie vajadusi.

Ei jää kaua peatuma, piisavalt on kirjeldatud dokumentatsioonis.

driver

Juhi nimi. Meil on see docker.

lint

Lintimise jaoks kasutatakse yamllint'i.

Selles konfi osas on kasulikud valikud - võimalus määrata yamllint'i konfi fail, edastada keskkonnamuutujad või keelata lintimine:

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

platvormid

Kirjeldab instantside konfiguratsiooni.
Dockerit kasutava draiveri puhul iteratiivne Molekul selles osas, ja iga loendi element on saadaval Dockerfile.j2 kui muutuja elemendi.

Nendes draiverites, kus on kohustuslikud create.yml ja destroy.yml, on sektsioon neis saadaval kui molecule_yml.platforms, ja iteratsioonid selle üle on juba nendes failides kirjeldatud.

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

Samuti saab leida näiteid erinevate draiverite kasutamisest Molekuli testides.

Asendame siin centos:7 järgnevaga ubuntu.

provisioner

„Tarnija“ on üksus, mis haldab instantsse. Molekuli puhul on see ansible, teiste toetamine pole plaanis, seega võib seda osa tinglikult nimetada ansible'i täiustatud konfiguratsiooniks.
Siin võib märkida palju asju, kuid välja toon peamised, minu arvates, punktid:

  • playbook'id: saab määrata, milliseid playbook’e tuleb kasutada teatud etappidel.

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

Skeemi jadade nimetus ja kirjeldus.
Muutmaks mingisuguse käsu vaike toimingute maatrikssi, saab lisada võtme <command>_sequence ja selle väärtuseks määrata vajalik tegevuste nimekiri.
Oletame, et soovime muuta tegevuste järjestust käsu playbook'i käivitamisel: molecule converge

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

verifier

Testide ja selle lintersüsteemi seadistamine. Vaikimisi kasutatav lint on testinfra ja flake8. Saadaval valikud on sarnased eelnevalt mainitutele:

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

Naaseme meie rolli. Redigeerime faili tasks/main.yml selliseks:

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

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

Ja lisame testid 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 tuleb ainult käivitada (rolli juurest, meenutan):

> molecule test

Pikk väljund peidetud spoileris:

--> Schéma valideerimine /nginx/molecule/default/molecule.yml.
Valideerimine lõpetatud.
--> Testide jaotus

└── default
    ├── lint
    ├── destroy
    ├── dependency
    ├── syntax
    ├── create
    ├── prepare
    ├── converge
    ├── idempotence
    ├── side_effect
    ├── verify
    └── destroy

--> Scenarid: 'default'
--> Tegevus: 'lint'
--> Käivitame Yamllinti failide jaoks, mis leiti /nginx/... 
Lintimist lõpetati edukalt.
--> Käivitame Flake8 failide jaoks, mis leiti /nginx/molecule/default/tests/... 
Lintimist lõpetati edukalt.
--> Käivitame Ansible Linti /nginx/molecule/default/playbook.yml... 
Lintimist lõpetati edukalt.
--> Scenarid: 'default'
--> Tegevus: 'destroy'

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

    ÜLESANNE [Molekuli instantside hävitamine] ********************************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

    ÜLESANNE [Oodata instantside eemaldamise lõpetamist] *******************************
    okei: [localhost] => (item=None)
    okei: [localhost]

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

    MÄNGU KOKKUVÕTE *********************************************************************
    localhost                  : okei=2    muutunud=1    saavutatav=0    ebaõnnestunud=0

--> Scenarid: 'default'
--> Tegevus: 'dependency'
Ülesanne vahele jäetud, puudub nõuete fail.
--> Scenarid: 'default'
--> Tegevus: 'syntax'

    mängu fail: /nginx/molecule/default/playbook.yml

--> Scenarid: 'default'
--> Tegevus: 'create'

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

    ÜLESANNE [Logi sisse Docker registrisse] **********************************************
    vahele jäetud: [localhost] => (item=None)

    ÜLESANNE [Loo Dockerfile'id piltide nimedest] *************************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

    ÜLESANNE [Avasta kohalikud Docker pildid] ********************************************
    okei: [localhost] => (item=None)
    okei: [localhost]

    ÜLESANNE [Ehita Ansible'i ühilduv pilt] ***************************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

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

    ÜLESANNE [Loo molekuli instantsid] *********************************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

    ÜLESANNE [Oodata instantside loomise lõpetamist] *******************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

    MÄNGU KOKKUVÕTE *********************************************************************
    localhost                  : okei=5    muutunud=4    saavutatav=0    ebaõnnestunud=0

--> Scenarid: 'default'
--> Tegevus: 'prepare'
Ülesanne vahele jäetud, valmistamise mängu fail ei ole seadistatud.
--> Scenarid: 'default'
--> Tegevus: 'converge'

    MÄNG [Kokkuviimine] ****************************************************************

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

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

    ÜLESANNE [nginx : Käivita nginx] *****************************************************
    muutunud: [instants]

    MÄNGU KOKKUVÕTE *********************************************************************
    instants                   : okei=3    muutunud=2    saavutatav=0    ebaõnnestunud=0

--> Scenarid: 'default'
--> Tegevus: 'idempotence'
Idempotentsus lõpetatud edukalt.
--> Scenarid: 'default'
--> Tegevus: 'side_effect'
Ülesanne vahele jäetud, kõrvaltoimete mängu fail ei ole seadistatud.
--> Scenarid: 'default'
--> Tegevus: 'verify'
--> Käivitame Testinfra teste, mis leiti /nginx/molecule/default/tests/... 
    ============================= test seanss algab ==============================
    platvorm darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    juurdirekt: /nginx/molecule/default, inifile:
    pistikprogrammid: testinfra-1.16.0
kokku korjatud 4 elementi

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

    ========================== 4 läbitud 27.23 sekundi jooksul ===========================
Verifitseerimine lõpetatud edukalt.
--> Scenarid: 'default'
--> Tegevus: 'destroy'

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

    ÜLESANNE [Hävita molekuli instantsid] ********************************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

    ÜLESANNE [Oodata instantside eemaldamise lõpetamist] *******************************
    muutunud: [localhost] => (item=None)
    muutunud: [localhost]

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

    MÄNGU KOKKUVÕTE *********************************************************************
    localhost                  : okei=2    muutunud=2    saavutatav=0    ebaõnnestunud=0

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

Vigaotsimiseks on kasulikud järgmised käsud:

> molecule --debug  # veainformatsioon. Tavalise käivitamise puhul peidab Molekul logid.
> molecule converge          # Jätab instantsi pärast testitava rolli käivitamist.
> molecule login             # Siseneb loodud instantsisse.
> molecule --help            # Täielik käsude loetelu.

Olemasolev roll

Uue stsenaariumi lisamine olemasolevale rollile toimub rolli kataloogist järgnevate käskude abil:

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

Juhul, kui see on rolli esimene stsenaarium, võib parameetri -s jätmise vahele jätta, kuna stsenaarium luuakse. default.

Kokkuvõte

Nagu näete, ei ole Molekul väga keeruline, ja oma mallide kasutamisel saab uue stsenaariumi käitamise viia minimaalsete muutustega loomise ja eemaldamise mänguraamatu muutmisele. Molekul integreerub probleemideta CI süsteemidega, võimaldades arenduse kiirusel kasvada, vähendades käsitsi mänguraamatute testimise aega.

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

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster