Gitlab CI + Ansible + Alpine IaaC или как не надо делать
Или как не надо делать.
1. Заводим в Gitlab проект
2. Проект - это у нас один большой плейбук, структура моего плейбука выглядит примерно так
infra/
├── README.md
├── group_vars
│ └── all.yml
├── host_vars
│ └── specific_host.yml
├── inventory
│ └── inventory.ini
├── meta
│ └── main.yml
├── requirements.yml
├── roles
│ ├── deploy
│ │ └── tasks
│ │ ├── helloworld.yml
│ │ └── main.yml
│ ├── prepare
│ │ └── tasks
│ │ ├── apt.yml
│ │ ├── hostname.yml
│ │ └── main.yml
└── site.yml
- requirements.yml - список зависимостей, особая благодарность
geerlingguy.github-users
иgeerlingguy.security
; - Разбиваю логически этапы на единообразные роли;
- Внутри единообразных ролей main.yml делает только
include_tasks
; - Всё, что можно засунуть в Ansible Loop - оказывается в Ansible Loop;
- В inventory добавляем свои хосты
3. В разделе Settings(1), CI/CD(2), Variables(3) создаём секрет с произвольным именем, например SSH_PRIVATE_KEY
Есть два типа секретов - переменная и файл. В первом случае при вызове этой переменной возвращается её значение, а во втором - абсолютный путь до файла
Делаем её защищённой
Внутрь пишем приватную часть ssh-ключа. Не забываем про пустую строку на конце. Сохраняем.
4. Создаём .gitlab-ci.yml
---
image: alpine:latest # берём за основу последний alpine
before_script:
- 'apk add openssh-client ansible' # ставим глобально нужные пакеты
- eval $(ssh-agent -s) # используем ssh-agent для подключения
- mkdir -p ~/.ssh # готовим shh-конфиг
- echo 'StrictHostKeyChecking no' > ~/.ssh/config
- chmod 0600 ${id_rsa_path}
- ssh-add ${id_rsa_path}
stages: # разбиваем процесс на этапы тестов и деплоя.
- test
- deploy
yaml_linter: # Имя для джобы
stage: test # К какому этапу относится
script:
- apk add yamllint # ставим пакеты
- yamllint . # запускаем
ansible_linter:
stage: test
script:
- apk add ansible-lint
- ansible-lint site.yml
ansible_check_mode:
stage: test
script:
- ansible-galaxy install -r requirements.yml
- ansible-playbook --diff -i inventory/inventory.ini site.yml --check
deploy_job:
stage: deploy
script:
- ansible-galaxy install -r requirements.yml
- ansible-playbook --diff -i inventory/inventory.ini site.yml
only: # запускаем только в следующих бранчах
- main
Не забудьте положить слепок ключа в ~/.ssh/authorized_keys
.
Стремитесь к индемпотентности плейбука. Любые изменения должны накатываться один раз.
Придумай, как ты будешь бекапить состояния и артефакты.
Почему не надо делать так:
Катится при всяком коммите, нужна проверка катим ли мы на продОтсутствуют тесты- Игнорируются состояния
- Если что-то надо удалить из старого - надо удалять явно
- Всегда надо помнить про состояния
- Можно всё сломать и чинить придётся чинить руками