Awọn ilana: bii o ṣe le ṣe idanwo awọn ipa Ansible ati wa nipa awọn iṣoro ṣaaju iṣelọpọ

Kaabo gbogbo eniyan!

Mo ṣiṣẹ bi ẹlẹrọ DevOps fun iṣẹ ifiṣura hotẹẹli kan. Ostrovok.ru. Ninu nkan yii Mo fẹ lati sọrọ nipa iriri wa ni idanwo awọn ipa Ansible.

Ni Ostrovok.ru a lo ohun ti o ṣeeṣe bi oluṣakoso iṣeto. Laipe a wa si iwulo lati ṣe idanwo awọn ipa, ṣugbọn, bi o ti wa ni jade, ko si ọpọlọpọ awọn irinṣẹ fun eyi - olokiki julọ, boya, ni ilana Molecule, nitorinaa a pinnu lati lo. Ṣugbọn o wa ni jade pe awọn iwe aṣẹ rẹ dakẹ nipa ọpọlọpọ awọn ọfin. A ko le rii itọsọna alaye ti o to ni Ilu Rọsia, nitorinaa a pinnu lati kọ nkan yii.

Awọn ilana: bii o ṣe le ṣe idanwo awọn ipa Ansible ati wa nipa awọn iṣoro ṣaaju iṣelọpọ

Molekule

Molekulu - ilana lati ṣe iranlọwọ idanwo awọn ipa ti o ṣeeṣe.

Apejuwe irọrun: Molecule ṣẹda apẹẹrẹ lori pẹpẹ ti o pato (awọsanma, ẹrọ foju, eiyan; fun awọn alaye diẹ sii, wo apakan iwakọ), nṣiṣẹ ipa rẹ lori rẹ, lẹhinna ṣiṣe awọn idanwo ati paarẹ apẹẹrẹ naa. Ti ikuna ba wa ni ọkan ninu awọn igbesẹ, Molecule yoo sọ fun ọ nipa rẹ.

Bayi siwaju sii.

A bit ti yii

Jẹ ki a wo awọn nkan pataki meji ti Molecule: Oju iṣẹlẹ ati Awakọ.

Ilana

Iwe afọwọkọ naa ni apejuwe kini, nibo, bii ati ninu ọkọọkan wo ni yoo ṣe. Ọkan ipa le ni orisirisi awọn iwe afọwọkọ, ati kọọkan ni a liana pẹlú awọn ọna <role>/molecule/<scenario>, ti o ni awọn apejuwe ti awọn iṣẹ ti a beere fun idanwo naa. Iwe afọwọkọ gbọdọ wa default, eyi ti yoo ṣẹda laifọwọyi ti o ba bẹrẹ ipa naa nipa lilo Molecule. Awọn orukọ ti awọn iwe afọwọkọ wọnyi wa ni lakaye rẹ.

Ọkọọkan awọn iṣe idanwo ni iwe afọwọkọ ni a pe matrix, ati nipa aiyipada o jẹ bi eleyi:

(Awọn igbesẹ ti samisi ?, ti fo nipasẹ aiyipada ti ko ba jẹ pato nipasẹ olumulo)

  • lint - nṣiṣẹ linters. Nipa aiyipada yamllint и flake8,
  • destroy - piparẹ awọn iṣẹlẹ lati ifilọlẹ Molecule to kẹhin (ti eyikeyi ba wa),
  • dependency? - fifi sori ẹrọ igbẹkẹle ti o ṣeeṣe ti ipa idanwo,
  • syntax - yiyewo ipa sintasi lilo ansible-playbook --syntax-check,
  • create - ṣẹda apẹẹrẹ,
  • prepare? - ngbaradi apẹẹrẹ; fun apẹẹrẹ yiyewo/fifi Python2
  • converge - ifilọlẹ iwe-iṣere ti idanwo,
  • idempotence - tun ṣe iwe-iṣere fun idanwo arapotency,
  • side_effect? - awọn iṣe ti ko ni ibatan taara si ipa, ṣugbọn pataki fun awọn idanwo,
  • verify - nṣiṣẹ igbeyewo ti awọn Abajade iṣeto ni lilo testinfra(aiyipada) /goss/inspec,
  • cleanup? - (ni awọn ẹya tuntun) - ni aijọju sisọ, “ninu” awọn amayederun ita ti Molecule kan kan,
  • destroy - piparẹ ohun apẹẹrẹ.

Ọkọọkan yii bo ọpọlọpọ awọn ọran, ṣugbọn o le ṣe atunṣe ti o ba jẹ dandan.

Ọkọọkan awọn igbesẹ ti o wa loke le ṣee ṣiṣẹ lọtọ ni lilo molecule <command>. Ṣugbọn o yẹ ki o loye pe fun iru aṣẹ cli kọọkan le jẹ lẹsẹsẹ awọn iṣe tirẹ, eyiti o le rii nipasẹ ṣiṣe. molecule matrix <command>. Fun apẹẹrẹ, nigbati o nṣiṣẹ aṣẹ converge (nṣiṣẹ iwe-iṣere ti idanwo) awọn iṣe wọnyi yoo ṣee ṣe:

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

Ilana ti awọn iṣe wọnyi le ṣe atunṣe. Ti nkan kan ninu atokọ ba ti pari tẹlẹ, yoo fo. Ipo ti o wa lọwọlọwọ, bakanna bi atunto apẹẹrẹ, ti wa ni ipamọ ninu itọsọna Molecule $TMPDIR/molecule/<role>/<scenario>.

Fi awọn igbesẹ pẹlu ? O le ṣe apejuwe awọn iṣe ti o fẹ ni ọna kika iwe-iṣere Ansible, ki o ṣe orukọ faili ni ibamu si igbesẹ naa: prepare.yml/side_effect.yml. Reti awọn faili Molecule wọnyi lati wa ninu folda iwe afọwọkọ.

iwakọ

Awakọ jẹ nkan kan nibiti a ti ṣẹda awọn apẹẹrẹ fun awọn idanwo.
Atokọ awọn awakọ boṣewa fun eyiti Molecule ni awọn awoṣe ti a ti ṣetan jẹ: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Aṣoju.

Ni ọpọlọpọ igba, awọn awoṣe jẹ awọn faili create.yml и destroy.yml ninu folda iwe afọwọkọ, eyiti o ṣe apejuwe ẹda ati piparẹ apẹẹrẹ, lẹsẹsẹ.
Awọn imukuro jẹ Docker ati Vagrant, nitori awọn ibaraenisepo pẹlu awọn modulu wọn le waye laisi awọn faili ti o wa loke.

O tọ lati ṣe afihan awakọ Aṣoju, nitori ti o ba lo, iṣẹ nikan pẹlu iṣeto apẹẹrẹ ni a ṣe apejuwe ninu ẹda apẹẹrẹ ati awọn faili piparẹ; iyokù yẹ ki o ṣe apejuwe nipasẹ ẹlẹrọ.

Awakọ aiyipada jẹ Docker.

Bayi jẹ ki a tẹsiwaju lati ṣe adaṣe ati gbero awọn ẹya diẹ sii nibẹ.

Bibẹrẹ

Gẹgẹbi “aye hello” a yoo ṣe idanwo ipa fifi sori ẹrọ nginx kan. Jẹ ki a yan docker bi awakọ - Mo ro pe pupọ julọ ninu rẹ ni o ti fi sii (ki o ranti pe docker jẹ awakọ aiyipada).

Jẹ ki a mura virtualenv ki o si fi sii ninu rẹ molecule:

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

Igbesẹ ti o tẹle ni lati bẹrẹ ipa tuntun kan.
Ibẹrẹ ipa tuntun, bakanna bi iwe afọwọkọ tuntun, ni a ṣe ni lilo aṣẹ naa 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

Abajade jẹ ipa ti o ṣeeṣe aṣoju. Siwaju sii, gbogbo awọn ibaraẹnisọrọ pẹlu Molecules CLI ni a ṣe lati gbongbo ipa.

Jẹ ki a wo kini o wa ninu itọsọna ipa:

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

1 directory, 6 files

Jẹ ká wo ni konfigi molecule/default/molecule.yml (a yoo rọpo aworan docker nikan):

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

igbẹkẹle

Yi apakan apejuwe awọn orisun ti awọn gbára.

Awọn aṣayan ti o ṣeeṣe: galaxy, giltar, ikarahun.

Shell jẹ ikarahun aṣẹ lasan lati lo ti galaxy ati gilt ko ba bo awọn iwulo rẹ.

Emi kii yoo duro nibi fun pipẹ, o ti ṣe apejuwe rẹ ni kikun iwe.

Iwakọ

Orukọ awakọ. Fun wa eyi jẹ docker.

fẹẹrẹ

A lo Yamllint bi linter.

Awọn aṣayan to wulo ni apakan yii ti atunto ni agbara lati pato faili atunto kan fun yamllint, awọn oniyipada ayika siwaju, tabi mu linter naa:

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

Awọn iru ẹrọ

Apejuwe iṣeto ni ti instances.
Ninu ọran ti docker bi awakọ kan, Molecule naa ṣe atunṣe lori apakan yii, ati pe ipin kọọkan ti atokọ wa ni Dockerfile.j2 bi oniyipada item.

Ninu ọran ti awakọ ninu eyiti create.yml и destroy.yml, apakan wa ninu wọn bi molecule_yml.platforms, ati awọn iterations lori rẹ ti wa ni apejuwe tẹlẹ ninu awọn faili wọnyi.

Niwọn igba ti Molecule n pese iṣakoso apẹẹrẹ si awọn modulu Ansible, o yẹ ki o wa atokọ ti awọn eto ti o ṣeeṣe nibẹ. Fun Docker, fun apẹẹrẹ, a lo module naa docker_container_module. Awọn modulu wo ni a lo ninu awọn awakọ miiran ni a le rii ninu iwe.

O tun le wa awọn apẹẹrẹ ti lilo orisirisi awakọ ninu awọn idanwo ti Molecule funrararẹ.

Jẹ ká ropo nibi senti:7 on Ubuntu.

olupese

"Olupese" jẹ nkan ti o ṣakoso awọn iṣẹlẹ. Ninu ọran ti Molecule, eyi ṣee ṣe; atilẹyin fun awọn miiran ko ṣe ipinnu, nitorinaa apakan yii le, pẹlu ifiṣura, ni a pe ni iṣeto ti o gbooro sii.
Pupọ wa ti o le tọka si nibi, ṣugbọn Emi yoo ṣe afihan awọn aaye akọkọ, ni ero mi:

  • awọn iwe-iṣere: O le pato iru awọn iwe-iṣere yẹ ki o lo ni awọn ipele kan.

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

  • awọn aṣayan: Ansible sile ati ayika oniyipada

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

ohn

Akọle ati apejuwe ti awọn ọkọọkan akosile.
O le yi matrix iṣẹ aiyipada ti aṣẹ kan pada nipa fifi bọtini kun <command>_sequence ati bi iye kan fun rẹ, asọye atokọ ti awọn igbesẹ ti a nilo.
Jẹ ki a sọ pe a fẹ yi ọna ti awọn iṣe pada nigba ṣiṣe pipaṣẹ ṣiṣe iwe-iṣere: molecule converge

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

ṣayẹwo

Ṣiṣeto ilana kan fun awọn idanwo ati linter kan fun rẹ. Nipa aiyipada, linter ti lo testinfra и flake8. Awọn aṣayan to ṣeeṣe jẹ iru si eyi:

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

E je ki a pada si ipa wa. Jẹ ki a ṣatunkọ faili naa tasks/main.yml si iwo yii:

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

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

Ati ṣafikun awọn idanwo si 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")

Ti ṣe, gbogbo ohun ti o ku ni lati ṣiṣẹ (lati gbongbo ipa, jẹ ki n leti rẹ):

> molecule test

Imukuro gigun labẹ apanirun:

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

Wa ti o rọrun ipa ni idanwo lai isoro.
O tọ lati ranti pe ti awọn iṣoro ba dide lakoko iṣẹ molecule test, lẹhinna ti o ko ba yi ọna-ọna boṣewa pada, Molecule yoo paarẹ apẹẹrẹ naa.

Awọn aṣẹ wọnyi wulo fun ṣiṣatunṣe:

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

Ipa ti o wa tẹlẹ

Ṣafikun iwe afọwọkọ tuntun si ipa ti o wa tẹlẹ waye lati ipa liana pẹlu awọn aṣẹ wọnyi:

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

Ti eyi ba jẹ iwe afọwọkọ akọkọ ninu ipa, lẹhinna paramita naa -s le ti wa ni ti own niwon a akosile yoo wa ni da default.

ipari

Gẹgẹbi o ti le rii, Molecule ko ni idiju pupọ, ati nigbati o ba lo awọn awoṣe tirẹ, o le dinku imuṣiṣẹ ti iwe afọwọkọ tuntun si awọn oniyipada ṣiṣatunṣe ninu awọn iwe-iṣere fun ṣiṣẹda ati piparẹ awọn apẹẹrẹ. Molikula naa ṣepọ lainidi pẹlu awọn eto CI, eyiti o fun ọ laaye lati mu iyara idagbasoke pọ si nipa idinku akoko fun idanwo afọwọṣe ti awọn iwe-iṣere.

Mo dupe fun ifetisile re. Ti o ba ni iriri idanwo awọn ipa ti o ṣeeṣe, ati pe ko ni ibatan si Molecule, sọ fun wa nipa rẹ ninu awọn asọye!

orisun: www.habr.com

Fi ọrọìwòye kun