Enstriksyon: ki jan yo teste wòl ansible epi chèche konnen sou pwoblèm anvan pwodiksyon an

Всем Привет!

Mwen travay kòm yon enjenyè DevOps nan yon sèvis anrjistreman otèl. Ostrovok.ru. Nan atik sa a, mwen vle pale sou eksperyans nou nan tès wòl ansible.

Nan Ostrovok.ru, nou itilize ansible kòm yon manadjè konfigirasyon. Dènyèman, nou te rive nan bezwen an teste wòl, men kòm li te tounen soti, pa gen anpil zouti pou sa a - pi popilè a, petèt, se fondasyon an Molekil, kidonk nou deside sèvi ak li. Men, li te tounen soti ke dokiman li an an silans sou anpil enkonvenyans. Nou pa t 'kapab jwenn yon manyèl ase detaye an Ris, se konsa nou deside ekri atik sa a.

Enstriksyon: ki jan yo teste wòl ansible epi chèche konnen sou pwoblèm anvan pwodiksyon an

Molekil

Molekil - yon kad pou ede teste wòl ansible.

Deskripsyon senplifye: Molekil la kreye yon egzanp sou platfòm ou presize a (nwaj, machin vityèl, veso; pou plis detay, gade seksyon an. Chofè), kouri wòl ou sou li, Lè sa a, kouri tès ak efase egzanp lan. Nan ka echèk nan youn nan etap yo, Molekil la ap enfòme w sou li.

Kounye a plis.

Yon ti jan nan teyori

Konsidere de antite kle nan Molekil la: Senaryo ak Chofè.

Senaryo

Script la gen yon deskripsyon kisa, ki kote, ki jan ak nan ki sekans yo pral fèt. Yon wòl ka gen plizyè scripts, epi chak se yon anyè sou chemen an <role>/molecule/<scenario>, ki gen deskripsyon aksyon ki nesesè pou tès la. Script dwe enkli default, ki pral otomatikman kreye si ou inisyalize wòl la ak yon Molekil. Non scripts sa yo se ou menm.

Yo rele sekans aksyon tès yo nan yon script matris, ak pa default li se:

(Etap ki make ?, sote pa default si itilizatè a pa espesifye)

  • lint - kouri linters. Pa default yo itilize yamllint и flake8,
  • destroy - efase ka nan dènye lansman Molekil la (si genyen),
  • dependency? - enstalasyon depandans ansible nan wòl teste a,
  • syntax - tcheke sentaks wòl la lè l sèvi avèk ansible-playbook --syntax-check,
  • create - kreye yon egzanp,
  • prepare? - preparasyon egzanp lan; pa egzanp tcheke/enstale python2
  • converge - lansman liv jwèt yo ap teste a,
  • idempotence - rekòmanse liv la pou tès idempotans la,
  • side_effect? - aksyon ki pa dirèkteman gen rapò ak wòl la, men ki nesesè pou tès yo,
  • verify - kouri tès nan konfigirasyon an ki kapab lakòz lè l sèvi avèk testinfra(default) /goss/inspec,
  • cleanup? - (nan nouvo vèsyon) - apeprè pale, "netwaye" enfrastrikti ekstèn ki afekte nan Molekil la,
  • destroy - Efase yon egzanp.

Sekans sa a kouvri pifò ka yo, men yo ka chanje si sa nesesè.

Chak nan etap ki anwo yo ka kouri separeman ak molecule <command>. Men, li ta dwe konprann ke pou chak cli-kòmand sa yo ka gen pwòp sekans aksyon li yo, ki ou ka jwenn nan egzekite. molecule matrix <command>. Pou egzanp, lè w ap kouri lòd la converge (kouri liv jwèt la anba tès), aksyon sa yo pral fèt:

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

Sekans aksyon sa yo ka modifye. Si yon bagay nan lis la deja fè, li pral sote. Eta aktyèl la, osi byen ke konfigirasyon ka yo, Molekil la estoke nan anyè a $TMPDIR/molecule/<role>/<scenario>.

Ajoute etap ak ? ou ka dekri aksyon yo vle nan fòma ansible-playbook, epi fè non fichye a dapre etap la: prepare.yml/side_effect.yml. Atann fichye sa yo Molekil la pral nan katab script la.

Chofè

Yon chofè se yon antite kote tès yo kreye.
Lis chofè estanda pou Molecule gen modèl pare yo se jan sa a: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Nan pifò ka yo, modèl yo se dosye create.yml и destroy.yml nan katab la script ki dekri kreyasyon an ak efase nan yon egzanp, respektivman.
Eksepsyon yo se Docker ak Vagrant, kòm entèraksyon ak modil yo ka rive san dosye yo mansyone pi wo a.

Li vo mete aksan sou chofè a Delege, paske si li se itilize nan dosye yo pou kreye ak efase yon egzanp, se sèlman travay ak konfigirasyon an nan ka dekri, rès la ta dwe dekri pa enjenyè a.

Chofè a default se Docker.

Koulye a, kite a deplase sou pratik ak konsidere plis karakteristik la.

Pou kòmanse

Kòm yon "bonjou mond", ann teste yon senp wòl enstalasyon nginx. Nou pral chwazi Docker kòm chofè a - Mwen panse ke pifò nan ou gen li enstale (epi sonje ke Docker se chofè a default).

Prepare virtualenv epi enstale ladan l molecule:

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

Pwochen etap la se inisyalize nouvo wòl la.
Inisyalizasyon yon nouvo wòl, osi byen ke yon nouvo script, fèt lè l sèvi avèk lòd la 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

Li te tounen soti yon tipik ansible-wòl. Pli lwen, tout entèraksyon ak molekil CLI yo fèt soti nan rasin wòl la.

Ann wè sa ki nan anyè wòl la:

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

1 directory, 6 files

Ann analize konfigirasyon an molecule/default/molecule.yml (ranplase imaj docker sèlman):

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

depandans

Seksyon sa a dekri sous depandans yo.

Opsyon posib: galaxy galaksi, Dore, kokiy.

Shell se jis yon kokiy kòmand ki itilize nan ka galaksi ak dore pa kouvri bezwen ou yo.

Mwen pa pral rete isit la pou yon tan long, li se ase dekri nan dokiman.

chofè

Non chofè a. Nou se docker.

pousye

Linter la se yamllint.

Opsyon itil nan pati sa a nan konfigirasyon an se kapasite pou presize yon fichye konfigirasyon pou yamllint, varyab anviwònman avanse, oswa enfim linter la:

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

tribin

Dekri konfigirasyon ka yo.
Nan ka docker kòm yon chofè, Molekil la repete sou seksyon sa a, epi chak eleman nan lis la disponib nan Dockerfile.j2 kòm yon varyab item.

Nan ka yon chofè ki mande create.yml и destroy.yml, seksyon an disponib nan yo kòm molecule_yml.platforms, ak iterasyon sou li yo deja dekri nan dosye sa yo.

Depi Molekil la bay kontwòl enstans nan modil ansible, lis paramèt posib yo ta dwe gade tou la. Pou Docker, pou egzanp, modil la itilize docker_container_module. Ki modil yo itilize nan lòt chofè yo ka jwenn nan dokiman.

Osi byen ke egzanp sou itilizasyon divès chofè ka jwenn nan tès yo nan Molekil nan tèt li.

Ranplase isit la santim:7 sou ubentu.

pwovizyon

"Souplis" - yon antite ki jere ka yo. Nan ka Molekil, sa a se ansible, sipò pou lòt moun pa te planifye, kidonk seksyon sa a ka rele konfigirasyon ansible pwolonje ak yon opozisyon.
Isit la ou ka presize anpil bagay, mwen pral mete aksan sou pwen prensipal yo, nan opinyon mwen:

  • liv jwèt: ou ka presize ki liv jwèt yo ta dwe itilize nan sèten etap.

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

  • connection_options: opsyon konekte

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

  • opsyon: Opsyon Ansible ak varyab anviwònman an

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

scénario

Non ak deskripsyon sekans script.
Ou ka chanje matris aksyon default nenpòt kòmand lè w ajoute kle a <command>_sequence ak kòm yon valè pou li pa defini lis etap nou bezwen an.
Ann di nou vle chanje sekans aksyon yo lè w ap kouri lòd kouri liv playbook la: molecule converge

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

tcheke

Mete kanpe yon fondasyon pou tès ak yon linter nan li. Linter la default se testinfra и flake8. Opsyon posib yo se menm jan ak pi wo a:

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

Ann retounen nan wòl nou. Ann edite fichye a tasks/main.yml nan kalite sa a:

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

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

Epi ajoute tès yo 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")

Fè, li rete sèlman nan kouri (soti nan rasin wòl la, kite m 'fè ou sonje):

> molecule test

Long tiyo echapman anba spoiler la:

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

Wòl senp nou an te teste san pwoblèm.
Li vo sonje ke si gen pwoblèm pandan travay la molecule test, Lè sa a, si ou pa t chanje sekans default la, Molekil la pral efase egzanp lan.

Kòmandman sa yo itil pou debogaj:

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

Wòl ki egziste

Ajoute yon nouvo script nan yon wòl ki deja egziste se soti nan anyè wòl la ak kòmandman sa yo:

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

Nan ka sa a se premye senaryo nan wòl la, Lè sa a, paramèt la -s ka omisyon paske li pral kreye yon script default.

Konklizyon

Kòm ou ka wè, Molekil la pa trè konplèks, epi lè w sèvi ak modèl pwòp ou yo, deplwaye yon nouvo script ka redwi a koreksyon varyab nan liv kreyasyon ak efase egzanp. Molekil la entegre san pwoblèm ak sistèm CI, ki pèmèt ou ogmante vitès la nan devlopman pa diminye tan an pou tès manyèl nan playbooks.

Mèsi pou atansyon ou. Si ou gen eksperyans nan tès wòl ansible, epi li pa gen rapò ak Molekil la, di nou sou li nan kòmantè yo!

Sous: www.habr.com

Add nouvo kòmantè