# Terraform Infrastructure Infrastructure as Code для управления ресурсами Yandex Cloud и Kubernetes. ## Структура ``` terraform/ ├── infrastructure.yaml # Конфигурация всех ресурсов (единый источник правды) ├── live/ # Terragrunt конфигурации по окружениям │ ├── terragrunt.hcl # Общие настройки (backend, providers) │ └── stage/ # Stage окружение │ ├── env.hcl │ ├── namespace/ │ ├── database/ │ ├── s3/ │ └── secrets/ └── modules/ # Terraform модули ├── k8s-namespace/ # Создание Kubernetes namespaces ├── k8s-secret/ # Создание Kubernetes secrets (с зависимостями) ├── k8s-secrets/ # Простое создание secrets ├── yc-database/ # PostgreSQL users и databases в Yandex Cloud ├── yc-valkey-user/ # Valkey/Redis users в Yandex Cloud └── yc-s3/ # S3 бакеты с изолированным доступом ``` ## Принцип работы ### infrastructure.yaml Единый файл конфигурации для всех ресурсов. Структура: ```yaml environments: stage: # Имя окружения namespaces: # Kubernetes namespaces - name: pulse labels: {} annotations: {} buckets: # S3 бакеты - name: pulse-stage acl: private role: storage.uploader # опционально versioning: enabled: false cors: enabled: true allowed_methods: [GET, PUT] databases: # PostgreSQL databases - cluster_id: "xxx" database: name: mydb extensions: [pg_stat_statements] user: name: myuser password_length: 32 conn_limit: 10 valkey_users: # Valkey/Redis users - cluster_id: "xxx" host: rc1a-example.mdb.yandexcloud.net user: name: myuser permissions: patterns: allkeys pubSubChannels: allchannels secrets: # Kubernetes secrets - name: my-secret namespace: pulse type: database # database | database_url | valkey | s3 | dockerconfigjson | opaque dependencies: cluster: "xxx" db: mydb user: myuser ``` ### Terragrunt Terragrunt читает `infrastructure.yaml` и передаёт данные в модули: ```hcl locals { infra_config = yamldecode(file("${local.repo_root}/infrastructure.yaml")) env_config = local.infra_config.environments[local.env_name] } inputs = { buckets = local.env_config.buckets } ``` ### Порядок применения Модули имеют зависимости и применяются в порядке: ``` namespace → database / s3 / valkey-users → secrets ``` ## Модули ### yc-s3 Создание S3 бакетов с изолированным доступом. **Особенности:** - Каждый бакет получает отдельный Service Account - SA не имеет глобальных IAM ролей на storage на уровне folder - Доступ к бакету через IAM binding (`yandex_storage_bucket_iam_binding`) - SA может работать только со своим бакетом **Роли (Yandex Cloud IAM):** - `storage.uploader` (default) — загрузка объектов - `storage.viewer` — чтение объектов - `storage.editor` — полный доступ **Пример:** ```yaml buckets: - name: my-bucket acl: private role: storage.uploader # опционально ``` ### yc-database Создание PostgreSQL users и databases в существующем кластере. **Особенности:** - Пароль генерируется автоматически - Поддержка extensions - Поддержка permissions на другие БД - `ignore_changes` на password **Пример:** ```yaml databases: - cluster_id: "c9qa2coo5ukgcg93fldm" database: name: mydb extensions: [pg_stat_statements] user: name: myuser password_length: 32 conn_limit: 10 permissions: [other_db] ``` ### yc-valkey-user Создание Valkey/Redis users в существующем кластере Yandex Cloud. **Особенности:** - Пароль генерируется автоматически - Поддержка ACL permissions - `ignore_changes` на password **Пример:** ```yaml valkey_users: - cluster_id: "c9qa2coo5ukgcg93fldm" host: rc1a-example.mdb.yandexcloud.net port: "6380" user: name: myuser password_length: 32 permissions: patterns: allkeys pubSubChannels: allchannels categories: "+@read +@write" commands: "+GET -FLUSHALL" sanitizePayload: sanitize-payload ``` ### k8s-secret Создание Kubernetes secrets с поддержкой зависимостей. **Типы секретов:** - `database` — host, port, database, username, password, ca.crt - `database_url` — database_url в формате postgresql+asyncpg - `valkey` — cert, host, login, password, port, url - `s3` — access_key, secret_key, bucket, endpoint - `dockerconfigjson` — credentials для container registry - `opaque` — произвольные данные **Особенности:** - Автоматическое получение данных из database/s3 модулей - Поддержка `random_keys` для генерации паролей - Поддержка `custom_keys` для статических значений - `ignore_changes` для предотвращения перезаписи **Пример:** ```yaml secrets: - name: my-db-secret namespace: pulse type: database dependencies: cluster: "c9qa2coo5ukgcg93fldm" db: mydb user: myuser random_keys: session_key: length: 32 special: false lifecycle: ignore_changes: true ``` ### k8s-namespace Создание Kubernetes namespaces. **Пример:** ```yaml namespaces: - name: pulse labels: environment: stage annotations: managed-by: terraform ``` ## Использование ### Локальный запуск ```bash cd terraform/live/stage/s3 terragrunt init terragrunt plan terragrunt apply ``` ### Применение всех модулей ```bash cd terraform/live/stage terragrunt run-all plan terragrunt run-all apply ``` ### Переменные окружения ```bash export YC_TOKEN="..." # IAM токен (или YC_SERVICE_ACCOUNT_KEY_FILE) export YC_CLOUD_ID="..." export YC_FOLDER_ID="..." # Default folder export YC_STAGE_FOLDER_ID="..." # Stage folder (опционально) export KUBECONFIG="~/.kube/config" export KUBE_CONTEXT="stage" export S3_ACCESS_KEY="..." # Для terraform state export S3_SECRET_KEY="..." export DOCKER_REGISTRY_USERNAME="..." # Для dockerconfigjson secrets export DOCKER_REGISTRY_PASSWORD="..." ``` ## CI/CD Pipeline автоматически: 1. Читает изменённые файлы 2. Определяет затронутые модули 3. Запускает `terragrunt plan` / `terragrunt apply` ## Требования - Terraform >= 1.0 - Terragrunt >= 0.45 - Yandex Cloud провайдер ~> 0.100 - IAM токен с правами `storage.admin` для создания бакетов и bucket policy