Argibideak: nola probatu rol ansibleak eta nola aurkitu arazoei buruz produkzioa baino lehen

Hola a todos!

DevOps ingeniari gisa lan egiten dut hotelen erreserba zerbitzu batean. Ostrovok.ru. Artikulu honetan, rol ansibleak probatzen dugun esperientziari buruz hitz egin nahi dut.

Ostrovok.ru-n, ansible erabiltzen dugu konfigurazio-kudeatzaile gisa. Duela gutxi, rolak probatzeko beharra ikusi genuen, baina ondorioztatu zenez, ez dago horrenbeste tresna horretarako - ezagunena, agian, Molecule esparrua da, beraz, erabiltzea erabaki genuen. Baina ondorioztatu zen bere dokumentazioa tranpa askori buruz isiltzen dela. Errusieraz ezin izan genuen eskuliburu behar bezain zehatzik aurkitu, beraz, artikulu hau idaztea erabaki genuen.

Argibideak: nola probatu rol ansibleak eta nola aurkitu arazoei buruz produkzioa baino lehen

molekula

Molekula - rol ansibleak probatzen laguntzeko esparru bat.

Deskribapen sinplifikatua: molekulak instantzia bat sortzen du zuk zehazten duzun plataforman (hodeia, makina birtuala, edukiontzia; xehetasun gehiagorako, ikusi atala. Driver), zure rola exekutatzen du bertan, ondoren probak exekutatzen ditu eta instantzia ezabatzen du. Urratsetako batean huts egiten bada, Molekulak horren berri emango dizu.

Orain gehiago.

Teoria apur bat

Demagun Molekularen bi funtsezko entitate: Eszenarioa eta Gidaria.

eszenatokia

Gidoiak zer, non, nola eta zein sekuentziatan interpretatuko den deskribatzen du. Rol batek hainbat script izan ditzake, eta bakoitza bideko direktorio bat da <role>/molecule/<scenario>, probarako beharrezkoak diren ekintzen deskribapenak jasotzen dituena. Gidoia sartu behar da default, Molekula batekin rola hasieratzen baduzu automatikoki sortuko dena. Ondorengo gidoien izenak zure esku daude.

Script bateko proba-ekintzen sekuentziari deitzen zaio matrizea, eta berez hau da:

(Etiketatutako urratsak ?, lehenespenez saltatuta, erabiltzaileak zehaztu ez badu)

  • lint - linters martxan. Lehenespenez erabiltzen dira yamllint и flake8,
  • destroy - Molekularen azken abiarazteko instantziak ezabatzea (halakorik badago),
  • dependency? — probatutako rolaren menpekotasun ansiblea instalatzea,
  • syntax - rolaren sintaxia egiaztatzea erabiliz ansible-playbook --syntax-check,
  • create - instantzia bat sortzea,
  • prepare? — instantzia prestatzea; adibidez, egiaztatu/instalatu python2
  • converge — probatzen ari den playbook-a abian jartzea,
  • idempotence - Idempotentzia probarako playbook-a berrabiarazi,
  • side_effect? - eginkizunarekin zerikusirik ez duten ekintzak, baina probetarako beharrezkoak,
  • verify - Sortutako konfigurazioaren probak egitea erabiliz testinfra(lehenetsia) /goss/inspec,
  • cleanup? - (bertsio berrietan) - gutxi gorabehera, Molekulak eragindako kanpoko azpiegitura "garbitzea",
  • destroy - Instantzia bat ezabatzea.

Sekuentzia honek kasu gehienak hartzen ditu, baina behar izanez gero alda daiteke.

Aurreko urratsetako bakoitza bereizita exekutatu daiteke molecule <command>. Baina ulertu behar da cli-komando bakoitzarentzat bere ekintza-sekuentzia propioa egon daitekeela, exekutatuta aurki dezakezuna. molecule matrix <command>. Adibidez, komandoa exekutatzean converge (proban dagoen jolas liburua exekutatzen), ekintza hauek egingo dira:

$ molecule matrix converge
...
└── default         # название сценария
    ├── dependency  # установка зависимостей
    ├── create      # создание инстанса
    ├── prepare     # преднастройка инстанса
    └── converge    # прогон плейбука

Ekintza hauen sekuentzia editatu daiteke. Zerrendako zerbait dagoeneko eginda badago, saltatu egingo da. Uneko egoera, baita instantzien konfigurazioa ere, Molekulak direktorioa gordetzen du $TMPDIR/molecule/<role>/<scenario>.

Gehitu urratsak honekin ? nahi dituzun ekintzak deskriba ditzakezu ansible-playbook formatuan eta egin fitxategiaren izena urratsaren arabera: prepare.yml/side_effect.yml. Espero fitxategi hauek Molekula script karpetan egongo da.

Driver

Gidari bat proba-instantziak sortzen diren entitate bat da.
Molecule-k txantiloiak prest dituen kontrolatzaile estandarren zerrenda hau da: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Kasu gehienetan, txantiloiak fitxategiak dira create.yml и destroy.yml instantzia bat sortzea eta ezabatzea deskribatzen duen script karpetan, hurrenez hurren.
Salbuespenak Docker eta Vagrant dira, haien moduluekin elkarrekintzak aipatutako fitxategirik gabe gerta daitezkeelako.

Azpimarratzekoa da Delegated kontrolatzailea, izan ere, instantzia bat sortzeko eta ezabatzeko fitxategietan erabiltzen bada, instantzien konfigurazioarekin bakarrik funtzionatzea deskribatzen da, gainerakoak ingeniariak deskribatu beharko lituzke.

Gidari lehenetsia Docker da.

Orain, praktikara pasa gaitezen eta bertan ezaugarri gehiago aztertu.

Pizten

"Kaixo mundua" gisa, proba dezagun nginx instalazio-funtzio sinple bat. Aukera dezagun docker kontrolatzaile gisa - uste dut gehienek instalatuta daukazutela (eta gogoratu docker kontrolatzaile lehenetsia dela).

prestatu virtualenv eta bertan instalatu molecule:

> pip install virtualenv
> virtualenv -p `which python2` venv
> source venv/bin/activate
> pip install molecule docker  # molecule установит ansible как зависимость; docker для драйвера

Hurrengo urratsa rol berria hasieratzea da.
Rol berri baten hasieratzea, baita script berri bat ere, komandoa erabiliz egiten da molecule init <params>:

> molecule init role -r nginx
--> Initializing new role nginx...
Initialized role in <path>/nginx successfully.
> cd nginx
> tree -L 1
.
├── README.md
├── defaults
├── handlers
├── meta
├── molecule
├── tasks
└── vars

6 directories, 1 file

Ansible-rol tipikoa izan zen. Gainera, CLI Molekulen interakzio guztiak rolaren errotik egiten dira.

Ikus dezagun zer dagoen rol-direktorioan:

> tree molecule/default/
molecule/default/
├── Dockerfile.j2  # Jinja-шаблон для Dockerfile
├── INSTALL.rst.   # Немного информации об установке зависимостей сценария
├── molecule.yml   # Файл конфигурации
├── playbook.yml   # Плейбук запуска роли
└── tests          # Директория с тестами стадии verify
    └── test_default.py

1 directory, 6 files

Azter dezagun konfigurazioa molecule/default/molecule.yml (ordeztu docker irudia soilik):

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

mendekotasun

Atal honek menpekotasunen iturria deskribatzen du.

Aukera posibleak: galaxia, aplikatzen, maskorra.

Shell komando-shell bat besterik ez da, galaxiak eta urrezkoak zure beharrak estaltzen ez badira.

Hemen ez naiz denbora luzez biziko, nahikoa da deskribatua dokumentazioa.

kontrolatzailea

Gidariaren izena. Gurea docker da.

Lint

Lintera yamllint da.

Konfigurazioaren zati honetako aukera erabilgarriak yamllint-erako konfigurazio-fitxategi bat zehazteko, ingurune-aldagaiak birbidaltzeko edo linter-a desgaitzeko aukera dira:

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

plataformak

Instantziaren konfigurazioa deskribatzen du.
Docker gidari gisa, Molekula errepikatzen da atal honetan, eta zerrendako elementu bakoitza eskuragarri dago. Dockerfile.j2 aldagai gisa item.

eskatzen duen gidari baten kasuan create.yml и destroy.yml, atala eskuragarri dago horietan bezala molecule_yml.platforms, eta haren gaineko errepikapenak dagoeneko deskribatzen dira fitxategi hauetan.

Molekulak modulu ansibleen instantzien kontrola eskaintzen duenez, ezarpen posibleen zerrenda ere bertan bilatu behar da. Docker-erako, adibidez, modulua erabiltzen da docker_container_module. Beste kontrolatzaile batzuetan zein modulu erabiltzen diren aurki daiteke dokumentazioa.

Baita hainbat gidariren erabileraren adibideak ere aurki daitezke Molekularen beraren probetan.

Ordezkatu hemen zentimoak:7 on ubuntu.

hornitzaile

"Hornitzailea" - instantziak kudeatzen dituen entitate bat. Molekularen kasuan, hau ansible da, besteentzako laguntza ez dago aurreikusita, beraz, atal honi konfigurazio hedatu ansible dei daiteke ohar batekin.
Hemen gauza asko zehaztu ditzakezu, puntu nagusiak nabarmenduko ditut, nire ustez:

  • playbooks: fase jakin batzuetan zein jolas-liburu erabili behar diren zehaztu dezakezu.

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

  • aukera: Ansible aukerak eta ingurune-aldagaiak

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

agertokia

Gidoi-sekuentzien izena eta deskribapena.
Edozein komandoren ekintza-matrize lehenetsia alda dezakezu tekla gehituta <command>_sequence eta horretarako balio gisa behar ditugun urratsen zerrenda zehaztuz.
Demagun playbook run komandoa exekutatzean ekintzen sekuentzia aldatu nahi dugula: molecule converge

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

egiaztatu

Probak egiteko esparru bat eta horri buruzko linter bat ezartzea. Linter lehenetsia da testinfra и flake8. Aukera posibleak goiko berdinak dira:

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

Itzuli gaitezen gure paperera. Editatu dezagun fitxategia tasks/main.yml mota honetara:

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

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

Eta probak gehitu 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")

Eginda, korrika egitea baino ez da geratzen (rolaren errotik, gogorarazten dizut):

> molecule test

Ihes luzea spoiler azpian:

--> Validating schema <path>/nginx/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix

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

--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in <path>/nginx/...
Lint completed successfully.
--> Executing Flake8 on files found in <path>/nginx/molecule/default/tests/...
Lint completed successfully.
--> Executing Ansible Lint on <path>/nginx/molecule/default/playbook.yml...
Lint completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'syntax'

    playbook: <path>/nginx/molecule/default/playbook.yml

--> Scenario: 'default'
--> Action: 'create'

    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Create Dockerfiles from image names] *************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image] ***************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Create docker network(s)] ************************************************

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) creation to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'

    PLAY [Converge] ****************************************************************

    TASK [Gathering Facts] *********************************************************
    ok: [instance]

    TASK [nginx : Install nginx] ***************************************************
    changed: [instance]

    TASK [nginx : Start nginx] *****************************************************
    changed: [instance]

    PLAY RECAP *********************************************************************
    instance                   : ok=3    changed=2    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'idempotence'
Idempotence completed successfully.
--> Scenario: 'default'
--> Action: 'side_effect'
Skipping, side effect playbook not configured.
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in <path>/nginx/molecule/default/tests/...
    ============================= test session starts ==============================
    platform darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    rootdir: <path>/nginx/molecule/default, inifile:
    plugins: testinfra-1.16.0
collected 4 items

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

    ========================== 4 passed in 27.23 seconds ===========================
Verifier completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0

Gure rol sinplea arazorik gabe probatu zen.
Lanean zehar arazoak egonez gero gogoratzea komeni da molecule test, orduan sekuentzia lehenetsia aldatu ez baduzu, Molekulak instantzia ezabatuko du.

Komando hauek erabilgarriak dira arazketarako:

> molecule --debug <command> # debug info. При обычном запуске Молекула скрывает логи.
> molecule converge          # Оставляет инстанс после прогона тестируемой роли.
> molecule login             # Зайти в созданный инстанс.
> molecule --help            # Полный список команд.

Dauden Rola

Lehendik dagoen rol bati script berri bat gehitzea da Rolen direktoriotik komando hauekin:

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

Rolaren lehenengo eszenatokia bada, gero parametroa -s ezabatu egin daiteke script bat sortuko baitu default.

Ondorioa

Ikus dezakezunez, Molekula ez da oso konplexua, eta zure txantiloiak erabiliz, script berri bat zabaltzea instantzia sortzeko eta ezabatzeko liburuxketan aldagaiak editatzera murriztu daiteke. Molekula ezin hobeto integratzen da CI sistemekin, eta horrek garapen-abiadura handitzeko aukera ematen du, jolas-liburuen eskuzko probak egiteko denbora murriztuz.

Eskerrik asko zure arretagatik. Rol ansibleak probatzen esperientzia baduzu eta Molekularekin erlazionatuta ez badago, konta iezaguzu iruzkinetan!

Iturria: www.habr.com

Gehitu iruzkin berria