- PVSM.RU - https://www.pvsm.ru -
Всем привет! Мы продолжаем серию статей про DevOps и ищем наиболее эффективные способы управлять конфигурацией, делясь с вами опытом. В прошлых статьях [1] мы рассматривали, как выстроить управление конфигурацией Ansible с помощью Jenkins и Serverspec, а теперь по вашим просьбам рассмотрим, как организовать управление конфигурацией с помощью GitLab-CI.
Ansible-lint [2] — это утилита для проверки корректности синтаксиса плейбука и стиля кода, которую можно интегрировать в CI-сервис. В нашем случае мы внедряем её в gitlab-ci для проверки плейбуков на этапе принятия Merge-Request и выставления статуса проверок.
GitLab [3] (GitLab Community Edition) — это opensource-проект, менеджер git-репозиториев, изначально разрабатывающийся как альтернатива платной корпоративной версии Github.
Установка GitLab CE описана в этой статье [4].
Устанавливаем gitlab-ci-multirunner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
yum install gitlab-ci-multi-runner
Регистрируем runner
gitlab-ci-multi-runner register
Теперь нужно ответить на вопросы:
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
http://domain.example.com/ci
Please enter the gitlab-ci token for this runner:
your_token
Please enter the gitlab-ci description for this runner:
[domain.example.com]:
Please enter the gitlab-ci tags for this runner (comma separated):
ansible
Registering runner... succeeded runner=
Please enter the executor: docker-ssh+machine, docker, docker-ssh, parallels, shell, ssh, virtualbox, docker+machine:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Токен и URL берем со страницы настроек проекта.
Один раннер может обрабатывать несколько проектов. Для того, чтоб один раннер обрабатывал всё подряд, нужно просто зарегистрировать новый раннер, не указывая теги. Токен для shared-раннера берем в Admin Area:
Можно пачку раннеров разнести по разным серверам. И ещё: в gitlab, как и в Jenkins, есть такое понятие, как теги. Проект с тегом ansible будет обрабатывать раннер, помеченный тегом ansible, а для других проектов, без метки или с другой меткой, этот раннер работать не будет.
Также в админке можно настроить соответствие раннера и проекта.
domain.example.com/admin/runners [5]
Ansible-lint устанавливается через python-pip или из репозитория EPEL.
Сначала устанавливаем python-pip, затем через него ставим ansible-lint:
sudo yum groupinstall @Development Tools
sudo yum install python-pip
sudo pip install --upgrade pip
sudo pip install ansible-lint
Всё просто — ставим epel-release и ставим ansible-lint через пакетный менеджер:
sudo yum install epel-release
sudo yum install ansible-lint
Создаем в корне репозитория файл .gitlab-ci.yml. Важно соблюдать количество пробелов, иначе будет ошибка — yaml такое не прощает, ага.
stages:
[два пробела]- test
test_job:
[два пробела]stage: test
[два пробела]script:
[четыре пробела]- ansible-lint *.yml
[два пробела]tags:
[четыре пробела]- ansible
stages — обязательно описываем стадии сборки.
stages:
- stagename
test_job — произвольное название джоба.
stage: test —обязательно описываем стадию test, указанную в секции stages.
jobname:
stage: stagename
script — проводим тест в корне репозитория
tags — метка для раннера.
Название стадии stage: test может быть любым, например: converge, pre-test, post-test, deploy.
Название джоба test_job также может быть любым.
В GitLab есть встроенный линтер для пайплайнов. Проверить корректность синтаксиса пайплайна можно по URL domain.example.com/ci/lint [6]
Вставляем пайплайн, жмём Validate.
При ошибке линтер будет ругаться и укажет на ошибку.
Должно быть stages, а не stage.
Таким образом ansible-lint будет автоматически при каждом коммите проверять все плейбуки с расширением .yml из корня репозитория.
У нас в репозитории две роли:
roles
├── monit
└── openssh
И два плейбука, накатывающих эти роли:
├── monit.yml
├── openssh.yml
├── README.md
└── roles
openssh.yml
---
- hosts: all
user: ansible
become: yes
roles:
- openssh
monit.yml
---
- hosts: all
user: ansible
become: yes
roles:
- monit
Следовательно, проверяя плейбук, присваивающий роль, мы проверяем все ее содержимое:
roles/openssh/tasks/
├── configure_iptables.yml
├── configure_monitoring.yml
├── configure_ssh.yml
└── main.ym
roles/monit/tasks/
├── configure_monit.yml
├── configure_monit_checks.yml
├── install_monit.yml
└── main.yml
Теперь, при коммите ansible-lint будет запущен автоматически и проверит все перечисленные в плейбуках роли.
Если попробовать что-нибудь закоммитить и перейти в веб-интерфейс (вкладка pipelines), то можно увидеть джоб в статусе failed.
Для того, чтоб отключить проверки lint'ом при пуше в репозиторий, достаточно вычистить в файле .gittab-ci.yml все стейджи, касающиеся запуска проверок ansible-lint.
Параметры проверки плейбуков также настраиваются:
╰─>$ ansible-lint --help
Usage: ansible-lint playbook.yml
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-L list all the rules
-q quieter, although not silent output
-p parseable output in the format of pep8
-r RULESDIR specify one or more rules directories using one or
more -r arguments. Any -r flags override the default
rules in /usr/local/lib/python2.7/dist-
packages/ansiblelint/rules, unless -R is also used.
-R Use default rules in /usr/local/lib/python2.7/dist-
packages/ansiblelint/rules in addition to any extra
rules directories specified with -r. There is no need
to specify this if no -r flags are used
-t TAGS only check rules whose id/tags match these values
-T list all the tags
-v Increase verbosity level
-x SKIP_LIST only check rules whose id/tags do not match these
values
--nocolor disable colored output
--exclude=EXCLUDE_PATHS
path to directories or files to skip. This option is
repeatable.
╰─>$ ansible-lint -L
ANSIBLE0002: Trailing whitespace
There should not be any trailing whitespace
ANSIBLE0004: Git checkouts must contain explicit version
All version control checkouts must point to an explicit commit or tag, not just "latest"
ANSIBLE0005: Mercurial checkouts must contain explicit revision
All version control checkouts must point to an explicit commit or tag, not just "latest"
ANSIBLE0006: Using command rather than module
Executing a command when there is an Ansible module is generally a bad idea
ANSIBLE0007: Using command rather than an argument to e.g. file
Executing a command when there is are arguments to modules is generally a bad idea
ANSIBLE0008: Deprecated sudo
Instead of sudo/sudo_user, use become/become_user.
ANSIBLE0009: Octal file permissions must contain leading zero
Numeric file permissions without leading zero can behavein unexpected ways. See http://docs.ansible.com/ansible/file_module.html
ANSIBLE0010: Package installs should not use latest
Package installs should use state=present with or without a version
ANSIBLE0011: All tasks should be named
All tasks should have a distinct name for readability and for --start-at-task to work
ANSIBLE0012: Commands should not change things if nothing needs doing
Commands should either read information (and thus set changed_when) or not do something if it has already been done (using creates/removes) or only do it if another check has a particular result (when)
ANSIBLE0013: Use shell only when shell functionality is required
Shell should only be used when piping, redirecting or chaining commands (and Ansible would be preferred for some of those!)
ANSIBLE0014: Environment variables don't work as part of command
Environment variables should be passed to shell or command through environment argument
ANSIBLE0015: Using bare variables is deprecated
Using bare variables is deprecated. Update yourplaybooks so that the environment value uses the full variablesyntax ("{{your_variable}}").
Некоторые таски можно пропускать при проверке ansible-lint не очень любит модули command [7] и shell [8], так как в идеологии ansible считается, что штатных core-модулей хватает для всех задач. На самом деле, это не всегда так.
К примеру, у нас в роли встречается таск, использующий модуль command:
- name: Installing monit
command:
yum -y install monit
tags: monit
И если пролинтим плейбук с этой ролью, то ansible-lint сругнётся на то, что мы используем модуль command
╰─>$ ansible-lint monit.yml
[ANSIBLE0002] Trailing whitespace
monit.yml:7
- monit
[ANSIBLE0012] Commands should not change things if nothing needs doing
/tmp/ansible-lint/roles/monit/tasks/install_monit.yml:8
Task/Handler: Installing monit
[ANSIBLE0006] yum used in place of yum module
/tmp/ansible-lint/roles/monit/tasks/install_monit.yml:8
Task/Handler: Installing monit
Чтобы этого избежать, можно пометить таск тегом skip_ansible_lint:
- name: Installing monit
command:
yum -y install monit
tags: monit,skip_ansible_lint
Теперь при прогоне lint'а по плейбуку он не будет ругаться на используемый модуль command:
╰─>$ ansible-lint monit.yml
[ANSIBLE0002] Trailing whitespace
monit.yml:7
- monit
Забегая вперёд, пару слов о функционале проверок в MR. По-умолчанию, merge-request принимается только при успешной проверке. Отключить это можно в настройках проекта, в разделе Merge Requests:
Ansible-lint также можно запустить на локалхосте, не делая коммиты и не дожидаясь проверки CI-сервисом. Если у на десктопе Linux или OS X — просто установите его к себе.
1. Открываем файл во встроенном редакторе GitLab:
2. Вносим изменения. Например, yaml очень чувствителен к пробелам, попробуем добавить лишний пробел в начале какой-нибудь строки:
Жмём Commit Changes, возвращаемся к изменённому файлу. Справа вверху появится пиктограмма со статусом проверки:
Сейчас она в статусе Pending, так как проверка ещё не завершена. Если ткнуть на пиктограмму — перейдем к статусу проверки нашего свежесделанного коммита:
Он сейчас в статусе Failed, так как мы умышленно допустили ошибку в синтаксисе. Если ткнуть на пиктограмму Failed, то мы сможем увидеть результат работы ansible-lint:
Можно прилепить симпатичный баджик со статусом сборки в README.md
[![build status](http://domain.example.com/projectname/badges/master/build.svg)](http://domain.example.com/projectname/commits/master)
Взять его можно в настройках проекта, в разделе CI/CD Pipelines
Копипастим маркдаун и добавляем в README.md в корне проекта, коммитим, теперь статус проверки отображается на главной странице проекта:
Зеленый / Passed — если проверка прошла успешна.
Красный / Failed — если проверка завершилась с ошибкой.
Во вкладке Pipelines можно посмотреть статусы всех коммитов:
Таким образом, мы выстроили процесс контроля корректности синтаксиса при управлении конфигурацией. Спасибо за внимание и всем удачной автоматизации!
Автор: DevOps-администратор Centos-admin — Виктор Батуев.
Автор: Centos-admin.ru
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/it-infrastruktura/190091
Ссылки в тексте:
[1] прошлых статьях: https://habrahabr.ru/company/centosadmin/blog/303762/
[2] Ansible-lint: https://github.com/willthames/ansible-lint
[3] GitLab: https://about.gitlab.com/
[4] этой статье: https://habrahabr.ru/company/centosadmin/blog/306596/
[5] domain.example.com/admin/runners: http://domain.example.com/admin/runners
[6] domain.example.com/ci/lint: http://domain.example.com/ci/lint
[7] command: https://docs.ansible.com/ansible/command_module.html
[8] shell: https://docs.ansible.com/ansible/shell_module.html
[9] Источник: https://habrahabr.ru/post/310278/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.