Плагины
TerraCi построен как plugin-first система. Каждая функция — генерация пайплайнов, оценка стоимости, проверка политик, MR-комментарии — это плагин. Вы можете добавлять свои плагины для интеграции с любыми инструментами и сервисами.
Что могут плагины?
| Тип плагина | Что добавляет | Примеры |
|---|---|---|
| CLI-команда | Новая субкоманда terraci <command> | Slack-уведомления, отчёты, аудит |
| Шаг пайплайна | Джобы/шаги в генерируемые CI-пайплайны | Сканирование безопасности, гейты согласования |
| CI-провайдер | Поддержка новой CI-системы | Bitbucket Pipelines, Jenkins, CircleCI |
| Поле в мастере | Поля конфигурации в terraci init TUI | Настройки плагина, корпоративные дефолты |
Быстрый старт
Соберите кастомный TerraCi с вашим плагином за 3 шага:
# 1. Напишите плагин (см. гайды ниже)
# 2. Соберите бинарник
xterraci build --with github.com/your-org/terraci-plugin-slack
# 3. Используйте
./terraci slack --channel #deploysАрхитектура
┌──────────────────────────┐
│ Ядро TerraCi │
│ │
│ discovery → parser → │
│ graph → pipeline IR │
└──────────┬───────────────┘
│
┌────────────────┼────────────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ Встроенные │ │ Встроенные │ │ Ваш │
│ плагины │ │ плагины │ │ плагин │
│ │ │ │ │ │
│ gitlab │ │ cost │ │ slack │
│ github │ │ policy │ │ jira │
│ git │ │ summary │ │ vault │
│ │ │ tfupdate │ │ ... │
└────────────┘ └────────────┘ └───────────┘Плагины компилируются в бинарник. Нет рантайм-загрузки — нулевой overhead и полная типобезопасность.
Гайды
CLI-команда
Добавьте новую terraci <command>. Самый распространённый тип — идеален для уведомлений, отчётов, интеграций.
Шаг пайплайна
Внедрите кастомные джобы или шаги в генерируемые CI-пайплайны. Для сканирования безопасности, гейтов согласования или post-deploy хуков.
CI-провайдер
Добавьте поддержку новой CI-системы. Реализуйте генерацию пайплайна, определение окружения и MR/PR-комментарии.
Поле в мастере
Добавьте поля конфигурации в интерактивный мастер terraci init. Пользователи настроят ваш плагин через TUI-форму.
Встроенные плагины
| Плагин | Возможности | Конфигурация |
|---|---|---|
| git | ChangeDetection, Preflight | Всегда активен |
| gitlab | Generator, EnvDetector, Comments, Preflight, Init | config/gitlab |
| github | Generator, EnvDetector, Comments, Preflight, Init | config/github |
| summary | Command, Pipeline, Init | Включён по умолчанию |
| cost | Command, Pipeline, Runtime, Preflight, Init | config/cost |
| policy | Command, Pipeline, Runtime, Preflight, Version, Init | config/policy |
| tfupdate | Command, Pipeline, Runtime, Preflight, Init | config/tfupdate |
Основы
Регистрация
Каждый плагин регистрируется в init():
package myplugin
import (
"github.com/edelwud/terraci/pkg/plugin"
"github.com/edelwud/terraci/pkg/plugin/registry"
)
func init() {
registry.RegisterFactory(func() plugin.Plugin {
return &Plugin{
BasePlugin: plugin.BasePlugin[*Config]{
PluginName: "myplugin",
PluginDesc: "Что делает мой плагин",
EnableMode: plugin.EnabledExplicitly,
DefaultCfg: func() *Config { return &Config{} },
IsEnabledFn: func(cfg *Config) bool {
return cfg != nil && cfg.Enabled
},
},
}
})
}
type Plugin struct {
plugin.BasePlugin[*Config]
}
type Config struct {
Enabled bool `yaml:"enabled"`
}
func (c *Config) Clone() *Config {
if c == nil {
return nil
}
out := *c
return &out
}Пользователи настраивают плагин в .terraci.yaml:
extensions:
myplugin:
enabled: trueПолитики активации
| Политика | Поведение | Используют |
|---|---|---|
EnabledAlways | Всегда активен, конфиг не нужен | git |
EnabledWhenConfigured | Активен при наличии секции конфига | gitlab, github |
EnabledByDefault | Активен пока не enabled: false | summary, diskblob, inmemcache |
EnabledExplicitly | Требует явного opt-in | cost, policy, tfupdate |
Жизненный цикл
Register → Configure → Preflight → Bind → ExecuteКонтрактные тесты SDK
Для проверки поведения SDK используйте публичные test kits вместо ручного дублирования framework-логики:
pkg/plugin/plugintest:AssertBaseConfigPlugin,AssertCommandBinding,AssertRequireEnabled,AssertRuntimeBuilder,AssertPipelineContributor,AssertPreflightable,AssertInitContributor,AssertVersionProvider,AssertKVCacheProvider,AssertBlobStoreProvider,AssertChangeDetector,AssertCIProvider.pkg/ci/citest:AssertRenderedReportContract,AssertPublishArtifactsContractи builders для rendered reports.
Локальные тесты плагина должны фокусироваться на доменной логике, API и собственном rendering. Контрактные helpers проверяют, что плагин следует тем же правилам immutable config, command binding, report contract и artifact lifecycle, что и built-in плагины.
AppContext
Каждая возможность получает *plugin.AppContext:
ctx.WorkDir() // корневая директория проекта
ctx.ServiceDir() // абсолютный путь к .terraci
ctx.Config() // immutable config.Snapshot; используйте accessors вроде ServiceDir()
ctx.Version() // строка версии TerraCi
ctx.Reports() // shared ci.ReportStore для plugin artifacts и отчётов
ctx.CIResolver() // резолвер CI-провайдера — никогда не nil
ctx.ChangeDetectorResolver() // резолвер ChangeDetector — никогда не nil
ctx.KVCacheResolver() // резолвер KV cache backend — никогда не nil
ctx.BlobStoreResolver() // резолвер blob backend — никогда не nilКонтекст конструируется фреймворком один раз через plugin.NewAppContext(plugin.AppContextOptions{...}) и привязывается на время выполнения команды. Плагины получают уже готовый контекст.
Capability resolvers
Используйте узкий accessor для той capability, которая нужна плагину:
ctx.CIResolver().ResolveCIProvider()
ctx.ChangeDetectorResolver().ResolveChangeDetector()
ctx.KVCacheResolver().ResolveKVCacheProvider(name)
ctx.BlobStoreResolver().ResolveBlobStoreProvider(name)Resolver accessors никогда не nil — если контекст не привязан к реестру (тестовое окружение), возвращается no-op-резолвер с sentinel-ошибками вместо nil-разыменования. Framework lifecycle enumeration вроде preflight и pipeline contribution collection принадлежит CLI runflow, не plugin-коду.
Сборка
# Из опубликованного модуля
xterraci build --with github.com/your-org/terraci-plugin-slack
# Из локальной директории при разработке
xterraci build --with github.com/your-org/plugin=./my-plugin
# Исключить ненужные встроенные плагины
xterraci build --without cost --without policyСм. также
- examples/external-plugin — рабочий пример
- Система плагинов — архитектурный обзор