Запуск Ansible Playbooks с помощью Gitlab-CI

git+ansible

Ansible — Система управления конфигурациями, с использованием декларативного языка разметки для описания конфигураций. Написанная на Python
Gitlab — Изначально система контроля версий, в настоящее время полноценный инструмент разработки, включающий в себя множество функций, от системы контроля версий до сборочных линий, хранилища образов и прочих функций.

В данной статье опишу своё видение совместного использования этих инструментов, с целью упрощения своей работы, и работы команды в целом. Так как основная проблема командной работы — это множественные Inventory, куча одинаковых по своей сути, но разных по написанию ролей и плейбуков, Логичней в такой ситуации хранить код в системе контроля версий, например Gitlab. И уж если пользоваться им для хранения — почему бы не автоматизировать процесс.

Общая схема процесса:
В Gitlab создаем группу с именем Ansible, в ней будут располагаться все наши проекты. Создаем в этой группе первый проект с именем main_config, в котором будет располагаться основной .gitlab-ci.yml. Остальные проекты будут иметь свой собственный, короткий .gitlab-ci.yml который будет ссылаться на основной в проекте main_config.
Переходим к настройке.

  1. Создаем группу с именем 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"]
Dockerfile

Тут на ваше усмотрение. Можете сразу собрать образ, загрузить его в свой или публичный репозиторий, или дергать локально если потребуется. Я использовал встроенный репозиторий гитлаб, потому в конфиге будет ссылка на него. Рекомендую сохранять версионность, поскольку со временем потребуется обновить образ с выходом свежих версий 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
.gitlab-ci.yml

Описание по порядку:

Три стэйджа:
— проверка кода (допускается падение, потому что линтер не всегда адекватно работает)
— выполнение на тестовом стенде
— выполнение на продуктиве

Переменная 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

На этом настройка закончена. Любой проект с .gitlab-ci.yml из 6 шага — будет вызывать ci из основной конфигурации. И запускать ровно такой же пайплайн.

Повторюсь — данная статья это лишь моё виденье организации данного процесса и я не претендую на лучшее решение. Наоборот — буду рад обоснованной критике.

Стати по теме:

Установка Gitlab в Docker Установка Gitlab в Docker

4 Комментарии

    • Нет, всё корректно, строка
      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 был убран

Отправить ответ

Ваш e-mail не будет опубликован.


*