Ansible — Система управления конфигурациями, с использованием декларативного языка разметки для описания конфигураций. Написанная на Python
Gitlab — Изначально система контроля версий, в настоящее время полноценный инструмент разработки, включающий в себя множество функций, от системы контроля версий до сборочных линий, хранилища образов и прочих функций.
В данной статье опишу своё видение совместного использования этих инструментов, с целью упрощения своей работы, и работы команды в целом. Так как основная проблема командной работы — это множественные Inventory, куча одинаковых по своей сути, но разных по написанию ролей и плейбуков, Логичней в такой ситуации хранить код в системе контроля версий, например Gitlab. И уж если пользоваться им для хранения — почему бы не автоматизировать процесс.
Общая схема процесса:
В Gitlab создаем группу с именем Ansible, в ней будут располагаться все наши проекты. Создаем в этой группе первый проект с именем main_config, в котором будет располагаться основной .gitlab-ci.yml. Остальные проекты будут иметь свой собственный, короткий .gitlab-ci.yml который будет ссылаться на основной в проекте main_config.
Переходим к настройке.
- Создаем группу с именем Ansible
В Gitlab переходим Groups — Create Group
Имя группы = Ansible
Уровень видимости = Internal
2. Добавляем групповые переменные
ANSIBLE_SSHKEY, Тип = переменная — приватная часть ssh ключа пользователя ansible от имени которого будем работать
3. Создаем в группе основной проект:
New Project
Указываем имя — main_config
4. Для запуска Ansbible Playbook нам потребуется Gitlab Runner, и образ Docker с установленным Ansible. Про Gitlab Runner в этой статье рассказывать не буду. Поскольку годного образа с Ansible на просторах сети я не нашел — собираем свой.
Создаем Dockerfile и наполняем:
#Download base image ubuntu 20.04
FROM ubuntu:20.04
#Configure tz-data
ENV TZ=Europe/Moscow
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Update Ubuntu Software repository
RUN apt-get -qy update
RUN apt install -qy python3 python3-pip software-properties-common git ansible
RUN pip install ansible-lint==4.0.0
CMD ["/bin/bash"]
Тут на ваше усмотрение. Можете сразу собрать образ, загрузить его в свой или публичный репозиторий, или дергать локально если потребуется. Я использовал встроенный репозиторий гитлаб, потому в конфиге будет ссылка на него. Рекомендую сохранять версионность, поскольку со временем потребуется обновить образ с выходом свежих версий Ansible и Ansible Linter
5. Создаем файлы с вашим инветарём
/inventory/test.yml — для тестового
/inventory/prod.yml — для прода
5. Добавляем .gitlab-ci.yml
для автоматизации.
---
variables:
HOSTS:
description: "указать список хостов или группу, по умолчанию all"
value: "all"
image: registry.asiacredit.ru/ansible/runner_config:1.2
stages:
- verify
- testing
- deploy
## prepare for plays
before_script:
- ansible --version
- ansible-lint --version
- mkdir secret
- echo "$ANSIBLE_SSHKEY" > secret/ansible.key ## import ansible ssh key
- chmod 400 secret/ansible.key
- export ANSIBLE_HOST_KEY_CHECKING=False
## verify syntax each commit
ansible-verify:
stage: verify
tags:
- ansible
script:
- git clone --single-branch -b new-inventory-test https://gitlab-ci-token:${CI_JOB_TOKEN}@git02.asiacredit.ru/ansible/runner_config.git inv
- ansible-lint -v *.yml
- ansible-playbook --inventory .inv/inventory/test.yml --syntax-check *.yml
allow_failure: true
## test playbook on test inventory with $TEST_INVENTORY group var
testing:
stage: testing
tags:
- ansible
script:
- git clone --single-branch -b new-inventory-test https://gitlab-ci-token:${CI_JOB_TOKEN}@git02.asiacredit.ru/ansible/runner_config.git inv
- ansible-playbook --private-key secret/ansible.key --user ansible --inventory ./inv/inventory/test.yml --limit ${HOSTS} *.yml
### deploy playbook with manual run
deploy:
stage: deploy
tags:
- ansible
script:
- git clone --single-branch -b new-inventory-test https://gitlab-ci-token:${CI_JOB_TOKEN}@git02.asiacredit.ru/ansible/runner_config.git inv
- ansible-playbook --private-key secret/ansible.key --user ansible --inventory ./inv/inventory/prod.yml --limit ${HOSTS} *.yml
when: manual
Описание по порядку:
Три стэйджа:
— проверка кода (допускается падение, потому что линтер не всегда адекватно работает)
— выполнение на тестовом стенде
— выполнение на продуктиве
Переменная HOSTS
объявленная в заголовке — принимает в качестве значение имя хоста или группы из интветаря, для которой хотите выполнить плейбук, по умолчанию выполняется для группы [all
], т.е. для всех. Если требуется заменить то во время запуска в ручную — можно указать иное значение:
Прескрипт напоминает нам о версиях Anisble и Ansible Linter, импортирует ssh ключ пользователя ansible, и отключает проверку ключей удаленных хостов.
ansible-verify
:
Запускает проверки всех плейбуков в проекте с помощью Ansible Linter, а так же ansbile-playbook с ключом syntax-check.
testing
:
Выполняет все плэйбуки с использованием тестового инвентаря
deploy
:
Выполняем всё уже с продуктивным инвентарем, запускается только по нажатию кнопки «Запуск» в Gitlab
6. В целом всё готово. Осталось добавить в группу проекты с остальными плейбуками. Для работы во всех остальных проектах группы добавляем .gitlab-ci.yml с ссылкой на основной проект:
---
include:
- project: "ansible/main_config"
file: ".gitlab-ci.yml"
На этом настройка закончена. Любой проект с .gitlab-ci.yml
из 6 шага — будет вызывать ci из основной конфигурации. И запускать ровно такой же пайплайн.
Повторюсь — данная статья это лишь моё виденье организации данного процесса и я не претендую на лучшее решение. Наоборот — буду рад обоснованной критике.
Стати по теме:
Установка Gitlab в Docker Установка Gitlab в Docker
Я правильно понимаю, что раннер гитлаба будет дергать образ ansible и в нем уже запускать playbook&
Да, всё верно)
файл ci похоже не целиком, в конце строка с git clone заканчивается на «inv» , наврено там еще что-то должно быть.
Нет, всё корректно, строка
git clone —single-branch -b new-inventory-test https://gitlab-ci-token:${CI_JOB_TOKEN}@git02.asiacredit.ru/ansible/runner_config.git inv
выполняет гит клон, только одной конкретной ветки, в каталог inv (а не в runner_config), как было бы, если бы inv был убран