Промты для DevOps: как я поднял CI/CD, Terraform и Kubernetes-кластер, почти не открывая документацию
Полтора года назад я потратил почти три дня на одну задачу: настроить multi-stage сборку Docker-образа так, чтобы кэш работал, секреты не попадали в слои, а финальный образ весил меньше 100 МБ. Три дня. Не на архитектуру, не на отладку продакшена — на рутину, которую любой опытный инженер делает за час. Проблема была не в сложности, а в переключении контекста: документация Docker, гайды по BuildKit, Stack Overflow, снова документация.
Сейчас я работаю иначе. Я всё ещё читаю официальные доки (например, docs.docker.com/build или kubernetes.io/docs), но делаю это точечно — когда нужно понять концепцию. А всю рутинную генерацию артефактов я делегирую LLM. Промт — это не «магия, которая всё сделает за тебя». Это способ зафиксировать контекст: версию, среду, ограничения — и получить черновик, который остаётся только проверить и запустить.
Ниже — подборка промтов, отсортированных по сложности: от базовых (Dockerfile, Compose) до продвинутых (Terraform-модули, Helm-чарты, GitLab CI) и экспертных (RBAC, admission-политики, GitOps). Каждый промт я привожу в том виде, в котором реально его использую, с примером результата. Важная оговорка: любой сгенерированный манифест нужно валидировать — через terraform validate, kubectl apply --dry-run=server, hadolint или kubeconform.
Базовый уровень: Docker и локальная среда
1. Multi-stage Dockerfile с кэш-маунтами
Задача: получить воспроизводимый образ для Python/Node-приложения с разделением build- и runtime-стадий.
Промт:
Ты senior DevOps. Напиши multi-stage Dockerfile для FastAPI-приложения (Python 3.12).
Требования: базовый образ python:3.12-slim, зависимости в отдельном слое для кэша,
запуск от non-root пользователя, HEALTHCHECK через /health, финальный образ минимальный.
Используй BuildKit cache mount для pip. Приведи команду сборки с --cache-to/--cache-from.
Пример результата:
# syntax=docker/dockerfile:1.7
FROM python:3.12-slim AS builder
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --prefix=/install -r requirements.txt
FROM python:3.12-slim
RUN useradd -m appuser
COPY --from=builder /install /usr/local
COPY . /app
WORKDIR /app
USER appuser
HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Проверяйте через hadolint Dockerfile — линтер поймает проблемы вроде отсутствия --no-install-recommends или непиннованных версий.
2. Docker Compose для локальной разработки
Задача: поднять приложение + Postgres + Redis одной командой.
Промт:
Сгенерируй docker-compose.yml для локальной разработки: app (build из ./),
postgres:16, redis:7. Используй healthcheck, depends_on с condition: service_healthy,
именованные volume для данных Postgres, .env-файл для переменных.
Пример результата:
services:
db:
image: postgres:16
env_file: .env
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
interval: 5s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
app:
build: .
depends_on:
db:
condition: service_healthy
ports: ["8000:8000"]
volumes:
pgdata:
3. Разбор ошибки сборки
Задача: LLM как «резиновый утёнок» для отладки.
Промт:
Сборка падает с ошибкой: <вставить лог целиком>.
Вот мой Dockerfile: <вставить>.
Объясни причину, предложи минимальный фикс и покажи diff.
Не переписывай файл целиком.
Ключевой приём — требовать diff, а не полный файл. Так вы видите, что именно меняется, и не теряете свои правки.
Продвинутый уровень: CI/CD и IaC
4. GitHub Actions workflow с матрицей
Задача: тесты + сборка образа + пуш в registry.
Промт:
Напиши GitHub Actions workflow. Триггеры: push в main, pull_request.
Джобы: lint (ruff), test (pytest с матрицей Python 3.11/3.12), build-and-push
(только на main, через docker/build-push-action с кэшем gha).
Пиновать actions по SHA. Добавить concurrency для отмены устаревших запусков.
Пример результата (фрагмент):
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
strategy:
matrix: { python: ["3.11", "3.12"] }
steps:
- uses: actions/checkout@<sha>
- uses: actions/setup-python@<sha>
with: { python-version: ${{ matrix.python }} }
5. Terraform-модуль для VPC
Задача: сеть с публичными и приватными подсетями.
Промт:
Сгенерируй Terraform-модуль vpc для AWS (провайдер ~> 5.0).
Входные переменные: cidr_block, az_count, name. Выходные: vpc_id, public_subnet_ids,
private_subnet_ids. Подсети распредели через cidrsubnet(). Добавь variables.tf,
outputs.tf, main.tf и пример вызова в README.
Пример результата:
resource "aws_subnet" "public" {
count = var.az_count
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
}
cidrsubnet("10.0.0.0/16", 8, 0) вернёт 10.0.0.0/24 — функция из Terraform docs.
6. Рефакторинг Terraform state
Задача: перенести ресурс в модуль без пересоздания.
Промт:
У меня ресурс aws_s3_bucket.logs в корне. Переношу его в модуль s3 (module.s3.aws_s3_bucket.logs).
Дай точные команды terraform state mv и объясни, как проверить план до применения.
Пример результата:
terraform state mv aws_s3_bucket.logs module.s3.aws_s3_bucket.logs
terraform plan # должно быть "No changes"
7. Helm-чарт с values-схемой
Промт:
Создай структуру Helm-чарта для stateless-сервиса: Chart.yaml (apiVersion v2),
values.yaml, templates/deployment.yaml, service.yaml, ingress.yaml, _helpers.tpl.
Добавь values.schema.json для валидации обязательных полей (image.tag, replicas).
Пример результата:
# values.schema.json (фрагмент)
{"properties": {"replicas": {"type": "integer", "minimum": 1}},
"required": ["image", "replicas"]}
8. GitLab CI с кэшем и артефактами
Промт:
Напиши .gitlab-ci.yml: стадии build/test/deploy. Кэш по ключу на основе lock-файла,
artifacts с expire_in: 1 week, rules вместо only/except, окружения staging/prod
с manual-джобой для prod.
Пример результата:
build:
stage: build
script: ["make build"]
cache:
key:
files: ["package-lock.json"]
paths: [".npm/"]
artifacts:
paths: ["dist/"]
expire_in: 1 week
9. Kubernetes Deployment с probes
Задача: корректные liveness/readiness/startup probes.
Промт:
Напиши Deployment для приложения, которое стартует 40 секунд.
Добавь startupProbe (failureThreshold 30, periodSeconds 2), readinessProbe,
livenessProbe, resource requests/limits, securityContext (runAsNonRoot, readOnlyRootFilesystem).
Пример результата:
startupProbe:
httpGet: { path: /health, port: 8000 }
failureThreshold: 30
periodSeconds: 2
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 512Mi }
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
Экспертный уровень: безопасность и эксплуатация
10. RBAC-роль с минимальными правами
Промт:
Сгенерируй Role и RoleBinding для CI-раннера в namespace ci:
только get/list/watch pods, create/delete jobs. Объясни, почему cluster-admin тут не нужен.
11. NetworkPolicy по принципу deny-all
Промт:
Напиши NetworkPolicy: default deny ingress+egress в namespace app,
затем разреши ingress от namespace ingress-nginx на порт 8000
и egress к DNS (kube-system, порт 53).
Пример результата:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: default-deny, namespace: app }
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
12. Валидация манифестов через kubeconform
Задача: проверять YAML на соответствие схеме перед деплоем.
Промт:
Покажи, как встроить kubeconform в CI: команду с -strict -summary,
как указать версию Kubernetes (-kubernetes-version 1.30.0) и
где взять кастомные схемы для CRD.
Пример результата:
kubeconform -strict -summary -kubernetes-version 1.30.0 ./manifests/
13. GitOps через Argo CD
Промт:
Опиши Application-манифест для Argo CD: source — Helm-чарт из Git-репозитория,
syncPolicy с automated, prune, selfHeal. Добавь ignoreDifferences для поля,
которое меняет оператор.
14. Admission-политика на Kyverno
Промт:
Напиши ClusterPolicy Kyverno: запретить контейнеры без requests/limits
и с тегом latest. Для каждого правила — сообщение об ошибке
и режим audit для начала.
15. Terraform + проверка через tflint и checkov
Промт:
Как настроить pre-commit хуки для Terraform: terraform fmt, tflint, checkov.
Дай .pre-commit-config.yaml и объясни, какие проверки checkov ловит
(например, публичный S3 bucket).
16. Диагностика CrashLoopBackOff
Промт:
Под CrashLoopBackOff. Вот вывод: kubectl describe pod <name>,
kubectl logs <name> --previous. Помоги составить пошаговое дерево диагностики:
проверка exit code, ресурсов, probe, монтирования ConfigMap.
17. Оптимизация стоимости кластера
Промт:
Проанализируй: у меня 12 нод, средняя загрузка CPU 15%.
Предложи шаги по снижению стоимости: rightsizing requests,
HPA, cluster-autoscaler, spot-инстансы. Для каждого шага — риски.
18. Промт-шаблон с фиксацией контекста
Задача: сделать любой из промтов воспроизводимым.
Контекст: <облако/версия K8s/провайдер Terraform>
Ограничения: <security, cost, compliance>
Формат ответа: <YAML/HCL/bash + объяснение>
Критерии приёмки: <что проверю>
Последний пункт важнее всех остальных: LLM без контекста даёт «средний по интернету» ответ. С контекстом — черновик, который экономит часы.
Что это даёт на практике
Я не считаю, что LLM заменяет инженера. Он заменяет переключение контекста. Вместо «открыть доки → найти пример → адаптировать» вы делаете «сформулировать ограничения → получить черновик → валидировать». По моему опыту, это экономит значительную часть времени на рутинных задачах, но не отменяет ревью: terraform plan, --dry-run=server, hadolint, kubeconform — обязательная часть процесса. Если хотите системно прокачать этот навык — попробуйте формулировать промты как техзадание с критериями приёмки, а не как вопрос. Начните с одного промта из списка и доведите его до рабочего состояния в своём репозитории.
Comments