TGViewer
Сочный DevOps Сочный DevOps @andtree_sec · 420 subscribers
Post #156 138
Динамический сиай в gitlab-ci

У меня структура проекта с ansible выглядит вот так:
Ansible # Группа в gitlab.
Roles # Группа внутри Ansible, в которой проекты по названию роли.
Playbooks # Проект с файликами playbook-ов.
Inventory # Проект с инвентарем. Тут происходит все управление за счет переменных.


Для реализации сиай мы приходим к модели, где любая роль может быть раскатана с теми или иными значениями и поведением за счет управления ее из инвентори, следовательно инвентори это то место, где должна быть реализована сиай.

Есть только один нюанс, с такой точки зрения инвентарь по-сути - это монорепа. Для удобства сделаем сиай динамическим:
default:
tags: [ <tags> ]

include:
- project: "<project_path"
ref: <ci_version>
file:
- "<template_file>"

git:get:diff:
stage: .pre
extends: [".ansible_git_diff"]
image: <ansible_image>
artifacts:
reports:
dotenv: deploy_var.env
expire_in: 24 hours
paths:
- changed_inventories.json
expire_in: 24 hours

create:deploy:pipeline:
stage: render
needs: ["git:get:diff"]
image: <gomplate_image>
script:
- .gitlab/scripts/render.sh
variables:
TEMPLATE_FILE: ".gitlab/templates/deploy.yml.tmpl"
RENDERED_FILE: ".gitlab/dynamic/deploy.yml"
COLLAPSE_NAME: "Deploy job template"
COLLAPSE_CAT_FILE: ".gitlab/dynamic/deploy.yml"
artifacts:
paths:
- .gitlab/dynamic
expire_in: 24 hours

deploy:trigger:
stage: prepare
needs: ["git:get:diff", "create:deploy:pipeline"]
trigger:
include:
- artifact: .gitlab/dynamic/deploy.yml
job: create:deploy:pipeline


Это основной .gitlab-ci.yml в корне инвенторя. Сами темплейты в удаленной репе показаны не будут, они не влезут да и тут только общий подход в конечном проекте.
В джобе create:deploy:pipeline мы рендерим с помощью gomplate вот такой шаблон:
default:
tags: [ <tags> ]

include:
- project: "<project_path>"
ref: <ci_version>
file:
- "<template_file>"

{{- if (eq (env.Getenv "SKIP_DEPLOY") "true") }}
nothing:to:deploy:
stage: deploy
script:
- echo "No inventory found for deploy"
{{- else }}
{{- $inventory_dirs := (datasource "inventory_dirs" "changed_inventories.json") }}
{{- range $path := $inventory_dirs }}
deploy:{{ $path | strings.ReplaceAll "/" "-" }}:
stage: deploy
extends: [".ansible_run_playbook"]
image: <ansible_image>
variables:
INVENTORY_PATH: {{ $path }}
PLAYBOOK: {{ index (strings.Split "/" (print $path)) 0 }}.yml
{{- end }}
{{- end }}


Переменную SKIP_DEPLOY мы получали на шаге git:get:diff, как и changed_inventories.json (в нем сравнение изменений по git).
В этой модели предполагается, что директории в инвенторе и имена плэйбуков одинаковы. Это видно по переменным в шаблонной джобе.
Скрипт для рендера выглядит так:
#!/bin/bash

TEMPLATE_DIR="."

function collapse () {
echo -e "\e[0Ksection_start:`date +%s`:templates[collapsed=true]\r\e[0K$1"
cat $2
echo -e "\e[0Ksection_end:`date +%s`:templates\r\e[0K"
}

gomplate -f $TEMPLATE_FILE -o $RENDERED_FILE -d inventory_dirs=$TEMPLATE_DIR
collapse "${COLLAPSE_NAME}" "${COLLAPSE_CAT_FILE}"


Ну и последним шагом deploy:trigger просто вызываем отрендеренный ранее шаблон через trigger job.
В итоге за счет шаблонизации мы получаем динамически создаваемое кол-во джобов в зависимости от изменений в inventory.

#gitlab
  • 👍 1
More from @andtree_sec
  1. Sep 7, 2026Давненько не было сообщений. Скорее всего в будущем они уйдут в telegraf, который я еще не…
  2. Jul 6, 2026Последнее время на работе часто приходится работать с apache flink и даже что-то писать на…
  3. Jun 4, 2026Немножко про молекула тесты... У нас принято использовать в переменных lookup плагин для д…
  4. May 20, 2026Очередной небольшой проект. Веб-приложение, которое агрегирует через стандартный механиз g…
  5. May 15, 2026Включаем профилирование в ansible Профилирование, это вывод даты, времени запуска и итогов…
  6. Apr 17, 2026Так выглядит общий dashbord работы с инцидентами.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →