Настройка CI/CD с помощью пользовательских конвейеров
Введен ие
Один из основных принципов dbt заключается в том, что аналитический код должен быть под версионным контролем. Это приносит вашей организации множество преимуществ в плане сотрудничества, согласованности кода, стабильности и возможности отката к предыдущей версии. Существует дополнительное преимущество, предоставляемое вашей платформой хостинга кода, которое часто упускается из виду или недооценивается. Некоторые из вас могут иметь опыт использования вебхуков dbt Cloud для запуска задания при создании PR. Это замечательная возможность, и она удовлетворяет большинство случаев использования для тестирования вашего кода перед слиянием в продакшн. Однако бывают случаи, когда организации требуется дополнительная функциональность, например, запуск рабочих процессов при каждом коммите (линтинг) или запуск рабочих процессов после завершения слияния. В этой статье мы покажем вам, как настроить пользовательские ко нвейеры для линтинга вашего проекта и запуска задания dbt Cloud через API.
Примечание о терминологии в этой статье, так как каждая платформа хостинга кода использует разные термины для схожих концепций. Термины pull request
(PR) и merge request
(MR) используются взаимозаменяемо, чтобы обозначить процесс слияния одной ветки с другой.
Что такое конвейеры?
Конвейеры (которые известны под многими именами, такими как рабочие процессы, действия или шаги сборки) — это серия предопределенных заданий, которые запускаются определенными событиями в вашем репозитории (создание PR, отправка коммита, слияние ветки и т.д.). Эти задания могут выполнять практически все, что вы пожелаете, при условии, что у вас есть соответствующий доступ к безопасности и навыки программирования.
Задания выполняются на раннерах, которые являются виртуальными с ерверами. Раннеры предварительно настроены с Ubuntu Linux, macOS или Windows. Это означает, что команды, которые вы выполняете, определяются операционной системой вашего раннера. Вы увидите, как это будет использоваться позже в настройке, но пока просто помните, что ваш код выполняется на виртуальных серверах, которые, как правило, размещаются платформой хостинга кода.
Обратите внимание, что раннеры, размещенные вашей платформой хостинга кода, предоставляют определенное количество бесплатного времени. После этого могут применяться платежные сборы в зависимости от того, как настроена ваша учетная запись. Вы также можете разместить свои собственные раннеры. Это выходит за рамки данной статьи, но ознакомьтесь с приведенными ниже ссылками, если вам интересно настроить это:
- Информация о биллинге для раннеров, размещенных в репозитории:
- Информация о самостоятелных раннерах:
Кроме того, если вы используете бесплатный тарифный план GitLab, вы все равно можете следовать этому руководству, но вас могут попросить предоставить кредитную карту для подтверждения вашей учетной записи. Вы увидите что-то подобное, когда впервые попытаетесь запустить конвейер:
Как настроить конвейеры
Это руководство предоставляет подробности для нескольких платформ хостинга кода. Где шаги уникальны, они представлены без опции выбора. Если код специфичен для платформы (например, GitHub, GitLab, Bitbucket), вы увидите опцию выбора для каждой.
Конвейеры могут быть запущены различными событиями. Процесс вебхука dbt Cloud уже запускает выполнение, если вы хотите запускать свои задания на запрос слияния, поэтому это руководство сосредоточено на запуске конвейеров для каждого пуша и при слиянии PR. Поскольку пуши происходят часто в проекте, мы сделаем это задание супер простым и быстрым, используя линтинг с SQLFluff. Конвейер, который запускается на запросах слияния, будет запускаться реже и может быть использован для вызова API dbt Cloud для запуска конкретного задания. Это может быть полезно, если у вас есть специфические требования, которые должны выполняться при обновлении кода в продакшене, например, выполнение --full-refresh
на всех затронутых инкрементальных моделях.
Вот краткий обзор того, что этот конвейер будет выполнять:
Запуск задания dbt Cloud при слиянии
Это задание потребует немного больше настройки, но является хорошим примером того, как вызвать API dbt Cloud из конвейера CI/CD. Представленные здесь концепции могут быть обобщены и использованы в любом виде, который лучше всего подходит для вашего случая использования.
Если ваш поставщик Git имеет нативную интеграцию с dbt Cloud, вы можете воспользоваться настройкой Merge jobs в интерфейсе.
Настройка ниже показывает, как вызвать API dbt Cloud для запуска задания каждый раз, когда происходит пуш в вашу основную ветку (ветка, в которую обычно сливаются pull requests. Обычно называется основной, первичной или мастер-веткой, но может быть названа иначе).
1. Получите ваш API-ключ dbt Cloud
При запуске конвейера CI/CD вы захотите использовать сервисный токен вместо API-ключа любого отдельного пользователя. Существуют подроб ные документы на эту тему, но ниже приведен краткий обзор (это должен выполнить администратор учетной записи):
- Войдите в свою учетную запись dbt Cloud
- В левом верхнем углу нажмите кнопку меню, затем Настройки учетной записи
- Нажмите Сервисные токены слева
- Нажмите Новый токен, чтобы создать новый токен специально для вызовов API CI/CD
- Назовите ваш токен, например, “CICD Token”
- Нажмите кнопку +Добавить в разделе Доступ и предоставьте этому токену разрешение Администратор заданий
- Нажмите Сохранить, и вы увидите серую рамку с вашим токеном. Скопируйте его и сохраните в безопасном месте (это пароль, и с ним следует обращаться соответствующим образом).
Вот видео, показывающее эти шаги:
2. Поместите ваш API-ключ dbt Cloud в ваш репозиторий
Следующая часть будет происходить на вашей платформе хостинга кода. Нам нужно сохранить ваш API-ключ из предыдущего шага в секрет репозитория, чтобы задание, которое мы создаем, могло получить к нему доступ. Не рекомендуется когда-либо сохранять пароли или API-ключи в вашем коде, поэтому этот шаг гарантирует, что ваш ключ останется безопасным, но все еще будет доступен для ваших конвейеров.
- GitHub
- GitLab
- Azure DevOps
- Bitbucket
- Откройте ваш репозиторий, в котором вы хотите запустить конвейер (тот же, в котором находится ваш проект dbt)
- Нажмите Настройки, чтобы открыть параметры репозитория
- Слева нажмите на раскрывающееся меню Секреты и переменные в разделе Безопасность
- Из этого списка выберите Действия
- В середине экрана нажмите кнопку Новый секрет репозитория
- Вас попросят ввести имя, поэтому давайте назовем его
DBT_API_KEY
- Очень важно, чтобы вы скопировали/вставили это имя точно, так как оно используется в скриптах ниже.
- В разделе Секрет вставьте ключ, который вы скопировали из dbt Cloud
- Нажмите Добавить секрет, и все готово!
** Быстрая заметка о безопасности: хотя использование секрета репозитория является самым простым способом наст ройки этого секрета, в GitHub доступны и другие опции. Они выходят за рамки этого руководства, но могут быть полезны, если вам нужно создать более безопасную среду для выполнения действий. Ознакомьтесь с документацией GitHub о секретах здесь.*
Вот видео, показывающее эти шаги:
-
Откройте ваш репозиторий, в котором вы хотите запустить конвейер (тот же, в котором находится ваш проект dbt)
-
Нажмите Настройки > CI/CD
-
В разделе Переменные нажмите Развернуть, затем нажмите Добавить переменную
-
Вас попросят ввести имя, поэтому давайте назовем его
DBT_API_KEY
- Очень важно, чтобы вы скопировали/вставили это имя точно, так как оно используется в скриптах ниже.
-
В разделе Значение вставьте ключ, который вы скопировали из dbt Cloud
-
Убедитесь, что флажок рядом с Защитить переменную не установлен, а флажок рядом с Маскировать переменную установлен (см. ниже)
- "Защищенный" означает, что переменная доступна только в конвейерах, которые запускаются на защищенных ветках или защищенных тегах - это не подойдет нам, потому что мы хотим запускать этот конвейер на нескольких ветках. "Маскированный" означает, что он будет доступен вашему раннеру конвейера, но будет замаскирован в логах.
Вот видео, показывающее эти шаги:
В Azure:
- Откройте ваш проект Azure DevOps, в котором вы хотите запустить конвейер (тот же, в котором находится ваш проект dbt)
- Нажмите на Конвейеры и затем Создать конвейер
- Выберите, где находится ваш код git. Это должно быть Azure Repos Git
- Выберите ваш git-репозиторий из списка
- Выберите Стартовый конвейер (это будет обновлено позже на Шаге 4)
- Нажмите на Переменные и затем Новая переменная
- В поле Имя введите
DBT_API_KEY
- Очень важно, чтобы вы скопировали/вставили это имя точно, так как оно используется в скриптах ниже.
- В разделе Значение вставьте ключ, который вы скопировали из dbt Cloud
- Убедитесь, что флажок рядом с Сохранить это значение в секрете установлен. Это замаскирует значение в логах, и вы не сможете увидеть значение переменной в интерфейсе.
- Нажмите ОК и затем Сохранить, чтобы сохранить переменную
- Сохраните ваш новый конвейер Azure
В Bitbucket:
-
Откройте ваш репозиторий, в котором вы хотите запустить конвейер (тот же, в котором находится ваш проект dbt)
-
В левом меню нажмите Настройки репозитория
-
Прокрутите до конца левого меню и выберите Переменные репозитория
-
В поле Имя введите
DBT_API_KEY
- Очень важно, чтобы вы скопировали/вставили это имя точно, так как оно используется в скриптах ниже.
-
В разделе Значение вставьте ключ, который вы скопировали из dbt Cloud
-
Убедитесь, что флажок рядом с Защищено установлен. Это замаскирует значение в логах, и вы не сможете увидеть значение переменной в интерфейсе.
-
Нажмите Добавить, чтобы сохранить переменную
Вот видео, показывающее эти шаги:
3. Создайте скрипт для запуска задания dbt Cloud через вызов API
В вашем проекте dbt Cloud создайте новую папку на корневом уровне с именем python
. В этой папке создайте файл с именем run_and_monitor_dbt_job.py
. Вы скопируете/вставите содержимое из этого gist в этот файл.
my_awesome_project
├── python
│ └── run_and_monitor_dbt_job.py
Этот файл Python содержит все, что вам нужно для вызова API dbt Cloud, но требует нескольких входных данных (см. фрагмент ниже). Эти входные данные передаются этому скрипту через переменные окружения, которые будут определены на следующем шаге.
#------------------------------------------------------------------------------
# получение переменных окружения
#------------------------------------------------------------------------------
api_base = os.getenv('DBT_URL', 'https://cloud.getdbt.com/') # по умолчанию используется URL многопользовательской версии
job_cause = os.getenv('DBT_JOB_CAUSE', 'API-triggered job') # по умолчанию используется общее сообщение
git_branch = os.getenv('DBT_JOB_BRANCH', None) # по умолчанию None
schema_override = os.getenv('DBT_JOB_SCHEMA_OVERRIDE', None) # по умолчанию None
api_key = os.environ['DBT_API_KEY'] # здесь нет значения по умолчанию, просто выбросьте ошибку, если ключ не предоставлен
account_id = os.environ['DBT_ACCOUNT_ID'] # здесь нет значения по умолчанию, просто выбросьте ошибку, если id не предоставлен
project_id = os.environ['DBT_PROJECT_ID'] # здесь нет значения по умолчанию, просто выбросьте ошибку, если id не предоставлен
job_id = os.environ['DBT_PR_JOB_ID'] # здесь нет значени я по умолчанию, просто выбросьте ошибку, если id не предоставлен
Требуемый ввод:
Для вызова API dbt Cloud скрипту необходимо несколько данных. Самый простой способ получить эти значения — открыть задание, которое вы хотите запустить в dbt Cloud. URL, когда вы находитесь внутри задания, содержит все необходимые значения:
DBT_ACCOUNT_ID
- это число сразу послеaccounts/
в URLDBT_PROJECT_ID
- это число сразу послеprojects/
в URLDBT_PR_JOB_ID
- это число сразу послеjobs/
в URL