diff --git a/.gitignore b/.gitignore
index f60a6ab..185c936 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,3 +66,8 @@ POSTGRES/chaos_marathon.sh
POSTGRES/test_cache_matrix.sh
POSTGRES/deploy_and_run_chaos.sh
POSTGRES/scripts/
+
+# ---- Примеры в разработке (временно скрыты) ----
+POSTGRES/
+NODEJS/
+DEVfromGround/
diff --git a/DEVfromGround/main.tf b/DEVfromGround/main.tf
deleted file mode 100644
index e17eacc..0000000
--- a/DEVfromGround/main.tf
+++ /dev/null
@@ -1,28 +0,0 @@
-// 2026-03-26 — main.tf: провайдер Nubes для DEV-стенда.
-// DEV API endpoint: https://deck-api-dev.ngcloud.ru/api/v1
-// Токен: secrets/dev.token (tazet@narod.ru)
-
-terraform {
- required_providers {
- nubes = {
- source = "terra.k8c.ru/nubes/nubes"
- version = "5.0.31"
- }
- }
-}
-
-variable "api_token" {
- type = string
- sensitive = true
- description = "Nubes API токен (DEV-стенд). Значение — в terraform.tfvars."
-}
-
-variable "resource_realm" {
- type = string
- description = "Платформа развёртывания (например k8s-3.ext.nubes.ru). Уточнить у сервис-менеджера."
-}
-
-provider "nubes" {
- api_token = var.api_token
- api_endpoint = "https://deck-api-dev.ngcloud.ru/api/v1/index.cfm"
-}
diff --git a/DEVfromGround/vc_org.tf b/DEVfromGround/vc_org.tf
deleted file mode 100644
index ee696aa..0000000
--- a/DEVfromGround/vc_org.tf
+++ /dev/null
@@ -1,34 +0,0 @@
-// 2026-03-26 — vc_org.tf: ресурс «Организация в Cloud Director» для DEV-стенда.
-// nubes_vc_org — тенант vCloud Director (organization_type = "iaas").
-// resource_realm задаётся через переменную (terraform.tfvars или -var).
-
-resource "nubes_vc_org" "dev_org" {
- resource_name = "vcOrg-2"
- resource_realm = var.resource_realm
-
- # organization_type "iaas" — единственный вариант с доступом к организации.
- # Значение по умолчанию "iaas", явно прописано для читаемости.
- organization_type = "iaas"
-
- # v_i_p_configure — JSON-список ipSpaces для операции modify.
- # При create провайдер не передаёт его в API, но требует non-null значение в плане.
- v_i_p_configure = ""
-
- # adopt_existing_on_create = true — берёт существующий инстанс (dev-org-sless-demo уже создан с null realm от предыдущей попытки).
- adopt_existing_on_create = true
-
- # suspend_on_destroy = true (по умолчанию) — при destroy инстанс уходит в Suspend, не удаляется.
- suspend_on_destroy = true
-}
-
-# ─── Outputs ─────────────────────────────────────────────────────────────────
-
-output "dev_org_id" {
- description = "ID созданной организации (используется в зависимых ресурсах)"
- value = nubes_vc_org.dev_org.id
-}
-
-output "dev_org_state_flat" {
- description = "Плоский state организации — endpoints, статусы"
- value = nubes_vc_org.dev_org.state_out_flat
-}
diff --git a/NODEJS/main.tf b/NODEJS/main.tf
deleted file mode 100644
index 442dfba..0000000
--- a/NODEJS/main.tf
+++ /dev/null
@@ -1,32 +0,0 @@
-// Создано: 2026-03-23
-// main.tf — провайдер Nubes + переменные для примера NODEJS.
-// Ресурс nubes_nodejs: managed Node.js приложение в облаке (не sless-функция).
-
-terraform {
- required_providers {
- nubes = {
- source = "terra.k8c.ru/nubes/nubes"
- version = "5.0.19"
- }
- }
-}
-
-variable "api_token" {
- type = string
- sensitive = true
-}
-
-variable "realm" {
- type = string
- description = "resource_realm — зона размещения ресурса (например: k8s-3-sandbox-nubes-ru)"
-}
-
-variable "git_path" {
- type = string
- description = "URL git-репозитория с кодом приложения"
-}
-
-provider "nubes" {
- api_token = var.api_token
- api_endpoint = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm"
-}
diff --git a/NODEJS/nodejs.tf b/NODEJS/nodejs.tf
deleted file mode 100644
index 0e1102a..0000000
--- a/NODEJS/nodejs.tf
+++ /dev/null
@@ -1,22 +0,0 @@
-# Создано: 2026-03-23
-# nodejs.tf — ресурс nubes_nodejs: managed Node.js приложение.
-# Параметры взяты из документации terra.k8c.ru/docs/nubes/nubes/5.0.19/30_registry/resources/nodejs_params_create/
-
-resource "nubes_nodejs" "app" {
- resource_name = "nodejsdemo1"
- domain = "domma"
- resource_realm = var.realm
- git_path = var.git_path
- app_version = "23"
- resource_c_p_u = 500
- resource_memory = 1024
- resource_instances = 1
- json_env = jsonencode({})
- adopt_existing_on_create = true
- # health_path не задан — используется дефолтный /
-}
-
-output "nodejs_domain" {
- description = "Домен развёрнутого Node.js приложения"
- value = nubes_nodejs.app.domain
-}
diff --git a/POSTGRES/README.md b/POSTGRES/README.md
deleted file mode 100644
index ea5d451..0000000
--- a/POSTGRES/README.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# POSTGRES — Пример: Serverless-функции с Managed PostgreSQL
-
-Демонстрирует интеграцию sless (serverless functions) с управляемым PostgreSQL (nubes_postgres).
-
-## Что делает этот пример
-
-1. **Создаёт Managed PostgreSQL** через Terraform (nubes_postgres + nubes_postgres_user + nubes_postgres_database)
-2. **Инициализирует БД**: одноразовый `sless_job` создаёт таблицу `terraform_demo_table`
-3. **Запускает 3 HTTP-сервиса**:
- - `pg-info` (Node.js 20) — версия PostgreSQL-сервера + количество строк в таблице
- - `pg-table-reader` (Python 3.11) — чтение всех строк из таблицы
- - `pg-table-writer` (Python 3.11) — добавление новой строки
-
-## Структура файлов
-
-```
-POSTGRES/
-├── main.tf # terraform + провайдеры (sless, nubes_cloud)
-├── postgres.tf # Managed PostgreSQL: DB, пользователь, locals с credentials
-├── resources.tf # Namespace и сетевые ресурсы
-├── functions.tf # sless_job (init) + 3 x sless_service
-├── terraform.tfvars # Переменные: realm, s3_uid, token
-├── stress_test.sh # Стресс-тест функций (не трогает PG lifecycle)
-├── stress_destroy_apply.sh.disabled # ОТКЛЮЧЁН — стресс-тест PG lifecycle
-├── code/
-│ ├── sql-runner/ # Python: одноразовое выполнение SQL (CREATE TABLE)
-│ ├── pg-info/ # Node.js: версия PG + строки
-│ ├── table-rw/ # Python: list_rows + add_row
-│ ├── pg-stats/ # Python: расширенная статистика PG
-│ ├── funcs-list/ # Утилита: листинг функций
-│ └── stress-*/ # Функции для стресс-тестирования
-└── scripts/ # Вспомогательные скрипты
-```
-
-## Как запустить
-
-### Предварительные требования
-
-- Terraform >= 1.3
-- Токен sless: `SLESS_TOKEN` (или в `terraform.tfvars`)
-- Токен nubes_cloud: `NUBES_TOKEN`
-- Доступ к realm (например, `ffd1f598c169b0ae`)
-
-### Запуск
-
-```bash
-# 1. Инициализация
-terraform init
-
-# 2. Проверка плана
-terraform plan
-
-# 3. Применение (создаст PG + сервисы, запустит init job)
-terraform apply
-```
-
-> Первый `apply` может занять 10–15 минут: создание PG-инстанса + kaniko-сборка образов.
-
-### Переменные (`terraform.tfvars`)
-
-```hcl
-realm = "ffd1f598c169b0ae" # Реалм (namespace в sless)
-s3_uid = "s01234" # S3 bucket для nubes_postgres бэкапов
-sless_token = "..." # Bearer-токен для sless API
-nubes_token = "..." # Bearer-токен для nubes_cloud API
-```
-
-### Вывод после apply
-
-```
-Outputs:
- table_reader_url = "https://sless.kube5s.ru/v1/namespaces/.../services/pg-table-reader/invoke"
- table_writer_url = "https://sless.kube5s.ru/v1/namespaces/.../services/pg-table-writer/invoke"
-```
-
-### Вызов функций
-
-```bash
-# Информация о PG (Node.js)
-curl https://.../services/pg-info/invoke
-
-# Список строк таблицы (Python)
-curl https://.../services/pg-table-reader/invoke
-
-# Добавить строку (Python)
-curl -X POST https://.../services/pg-table-writer/invoke \
- -H "Content-Type: application/json" \
- -d '{"title": "Hello from sless!"}'
-```
-
-## Стресс-тест
-
-`stress_test.sh` — нагружает функции HTTP-запросами. Запускать после `terraform apply`:
-
-```bash
-./stress_test.sh
-```
-
-> `stress_destroy_apply.sh.disabled` — ранний тест PG lifecycle (destroy+apply цикл).
-> **Отключён** из-за проблем с удалением postgres_user в определённых сценариях.
diff --git a/POSTGRES/code/calc-node/handler.js b/POSTGRES/code/calc-node/handler.js
deleted file mode 100644
index 29bed1f..0000000
--- a/POSTGRES/code/calc-node/handler.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Создано: 2026-04-10
-// Демо-функция: возвращает текущее время сервера.
-// Юзер меняет код под себя и перебилдит через terraform apply.
-
-'use strict';
-
-module.exports.handler = function handler(event) {
- return `Текущее время: ${new Date().toISOString()}`;
-};
diff --git a/POSTGRES/code/calc-node/package.json b/POSTGRES/code/calc-node/package.json
deleted file mode 100644
index 18a1e41..0000000
--- a/POSTGRES/code/calc-node/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "dependencies": {}
-}
diff --git a/POSTGRES/code/calc-python/handler.py b/POSTGRES/code/calc-python/handler.py
deleted file mode 100644
index f775f35..0000000
--- a/POSTGRES/code/calc-python/handler.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Создано: 2026-04-10
-# Изменено: 2026-03-23 — упрощён до поля ввода выражения (демонстрация деплоя).
-# Принимает произвольное математическое выражение: "2+2*(3-1)", "(10/3)**2" и т.д.
-# GET → HTML страница с формой; POST с {expr} → вычисление через безопасный eval.
-# Безопасность eval: __builtins__=None, только math-функции в locals.
-
-import math
-
-_PAGE = """
-
-
-
-
-Калькулятор — Python 3.11
-
-
-
-
-
Калькулятор
-
Python 3.11 · runtime: sless
-
-
-
-
-
-
-"""
-
-# Разрешённые math-функции в eval — без __builtins__ нет доступа к exec/open/etc.
-_MATH_LOCALS = {k: getattr(math, k) for k in dir(math) if not k.startswith('_')}
-
-
-def handler(event):
- if event.get('_method') == 'POST':
- expr = str(event.get('expr', '')).strip()
- return _compute(expr)
- # GET → HTML страница
- return _PAGE
-
-
-def _compute(expr):
- if not expr:
- return {'error': 'Введите выражение'}
- try:
- result = eval(expr, {'__builtins__': None}, _MATH_LOCALS) # noqa: S307
- if not isinstance(result, (int, float)):
- return {'error': 'Результат не является числом'}
- return {'expr': expr, 'result': result}
- except ZeroDivisionError:
- return {'error': 'Деление на ноль'}
- except Exception as exc:
- return {'error': f'Ошибка: {exc}'}
-
-
-def _esc(s):
- # Экранируем HTML-спецсимволы — безопасный вывод в атрибут и тело.
- return s.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
diff --git a/POSTGRES/code/calc-python/requirements.txt b/POSTGRES/code/calc-python/requirements.txt
deleted file mode 100644
index d45663c..0000000
--- a/POSTGRES/code/calc-python/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-# нет внешних зависимостей
diff --git a/POSTGRES/code/js-idempotent/js_idempotent.js b/POSTGRES/code/js-idempotent/js_idempotent.js
deleted file mode 100644
index b19d7da..0000000
--- a/POSTGRES/code/js-idempotent/js_idempotent.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 2026-03-21 — js-idempotent: INSERT с проверкой по idempotency_key.
-// Повторный вызов с тем же key НЕ создаёт дубль — возвращает существующую запись.
-// Тестирует: идемпотентность через SELECT ... FOR UPDATE + условный INSERT.
-const { Client } = require('pg');
-
-async function run(event) {
- const key = String(event.idempotency_key ?? `auto-${Date.now()}`).slice(0, 200);
- const title = String(event.title ?? key).slice(0, 255);
-
- const client = new Client({
- host: process.env.PGHOST,
- port: parseInt(process.env.PGPORT ?? '5432'),
- database: process.env.PGDATABASE,
- user: process.env.PGUSER,
- password: process.env.PGPASSWORD,
- ssl: { rejectUnauthorized: false },
- });
- await client.connect();
-
- try {
- await client.query('BEGIN');
-
- // Ищем существующую запись по title (используем как idempotency key)
- const existing = await client.query(
- 'SELECT id, title, created_at FROM terraform_demo_table WHERE title = $1 LIMIT 1 FOR UPDATE',
- [key]
- );
-
- let action, row;
- if (existing.rows.length > 0) {
- action = 'existing';
- row = existing.rows[0];
- } else {
- const ins = await client.query(
- 'INSERT INTO terraform_demo_table (title) VALUES ($1) RETURNING id, title, created_at',
- [key]
- );
- action = 'created';
- row = ins.rows[0];
- }
-
- await client.query('COMMIT');
- return {
- action,
- id: row.id,
- title: row.title,
- created_at: row.created_at,
- idempotency_key: key,
- };
- } catch (e) {
- await client.query('ROLLBACK');
- throw e;
- } finally {
- await client.end();
- }
-}
-
-module.exports = { run };
diff --git a/POSTGRES/code/js-idempotent/package.json b/POSTGRES/code/js-idempotent/package.json
deleted file mode 100644
index 1ad69de..0000000
--- a/POSTGRES/code/js-idempotent/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "js-idempotent",
- "version": "1.0.0",
- "dependencies": {
- "pg": "^8.11.3"
- }
-}
diff --git a/POSTGRES/code/pg-counter/pg_counter.py b/POSTGRES/code/pg-counter/pg_counter.py
deleted file mode 100644
index b7a7080..0000000
--- a/POSTGRES/code/pg-counter/pg_counter.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# 2026-03-21 — pg-counter: считает строки по prefix, возвращает статистику.
-# Тестирует: SELECT COUNT с WHERE LIKE, агрегация, concurrent reads.
-import os, psycopg2
-
-def count(event):
- prefix = event.get("prefix", "")
- conn = psycopg2.connect(
- host=os.environ["PGHOST"], port=int(os.environ.get("PGPORT", 5432)),
- dbname=os.environ["PGDATABASE"], user=os.environ["PGUSER"],
- password=os.environ["PGPASSWORD"], sslmode=os.environ.get("PGSSLMODE", "require"),
- )
- try:
- with conn.cursor() as cur:
- if prefix:
- cur.execute("SELECT COUNT(*) FROM terraform_demo_table WHERE title LIKE %s", (f"{prefix}%",))
- else:
- cur.execute("SELECT COUNT(*) FROM terraform_demo_table")
- total = cur.fetchone()[0]
- cur.execute("SELECT COUNT(*) FROM terraform_demo_table WHERE created_at > now() - interval '1 hour'")
- last_hour = cur.fetchone()[0]
- return {"total": total, "last_hour": last_hour, "prefix": prefix or "*"}
- finally:
- conn.close()
diff --git a/POSTGRES/code/pg-counter/requirements.txt b/POSTGRES/code/pg-counter/requirements.txt
deleted file mode 100644
index 37ec460..0000000
--- a/POSTGRES/code/pg-counter/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-psycopg2-binary
diff --git a/POSTGRES/code/pg-info/package.json b/POSTGRES/code/pg-info/package.json
deleted file mode 100644
index 5e6394d..0000000
--- a/POSTGRES/code/pg-info/package.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "pg-info",
- "version": "1.0.0",
- "description": "sless nodejs20 function: pg version + table info",
- "dependencies": {
- "pg": "8.11.0"
- }
-}
\ No newline at end of file
diff --git a/POSTGRES/code/pg-info/pg_info.js b/POSTGRES/code/pg-info/pg_info.js
deleted file mode 100644
index 9468076..0000000
--- a/POSTGRES/code/pg-info/pg_info.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// 2026-03-18
-// pg_info.js — NodeJS-функция: проверка работы JS runtime + чтение мета-данных БД.
-// Подключается к PostgreSQL через пакет pg, возвращает версию сервера и счётчик строк.
-// Демонстрирует: nodejs20 runtime, npm-зависимость (package.json), PG из JS.
-//
-// ENV (те же что у python-функций):
-// PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE
-//
-// Entrypoint: pg_info.info
-
-'use strict';
-
-const { Client } = require('pg');
-
-exports.info = async (event) => {
- const client = new Client({
- host: process.env.PGHOST,
- port: parseInt(process.env.PGPORT || '5432'),
- database: process.env.PGDATABASE,
- user: process.env.PGUSER,
- password: process.env.PGPASSWORD,
- // pg-пакет требует явного ssl-объекта; rejectUnauthorized: false — т.к.
- // self-signed cert на nubes managed PG, но канал всё равно шифруется.
- ssl: process.env.PGSSLMODE === 'require' ? { rejectUnauthorized: false } : false,
- });
-
- await client.connect();
- try {
- const [versionRes, countRes] = await Promise.all([
- client.query('SELECT version() AS v'),
- client.query('SELECT COUNT(*) AS cnt FROM terraform_demo_table'),
- ]);
-
- return {
- runtime: 'nodejs20',
- node_version: process.version,
- pg_version: versionRes.rows[0].v,
- table_rows: parseInt(countRes.rows[0].cnt, 10),
- code_version: 'v2-agent-test',
- };
- } finally {
- await client.end();
- }
-};
diff --git a/POSTGRES/code/pg-stats/pg_stats.py b/POSTGRES/code/pg-stats/pg_stats.py
deleted file mode 100644
index 225f41b..0000000
--- a/POSTGRES/code/pg-stats/pg_stats.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 2026-03-19
-# pg_stats.py — тестовая функция (Test 7): возвращает агрегированную статистику
-# по таблице terraform_demo_table: кол-во строк, дата первой и последней записи.
-# Создаётся и удаляется в рамках тестового прогона.
-#
-# Entrypoint: pg_stats.get_stats
-
-import os
-import psycopg2
-import json
-
-_CODE_VERSION = "v1-test7"
-
-
-def get_stats(event):
- conn = psycopg2.connect(
- host=os.environ["PGHOST"],
- port=int(os.environ.get("PGPORT", "5432")),
- dbname=os.environ["PGDATABASE"],
- user=os.environ["PGUSER"],
- password=os.environ["PGPASSWORD"],
- sslmode=os.environ.get("PGSSLMODE", "require"),
- )
- try:
- with conn.cursor() as cur:
- cur.execute(
- "SELECT COUNT(*) AS cnt, MIN(created_at) AS first, MAX(created_at) AS last "
- "FROM terraform_demo_table"
- )
- row = cur.fetchone()
- return {
- "version": _CODE_VERSION,
- "total_rows": row[0],
- "first_row_at": str(row[1]) if row[1] else None,
- "last_row_at": str(row[2]) if row[2] else None,
- }
- finally:
- conn.close()
diff --git a/POSTGRES/code/pg-stats/requirements.txt b/POSTGRES/code/pg-stats/requirements.txt
deleted file mode 100644
index 58ab769..0000000
--- a/POSTGRES/code/pg-stats/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-psycopg2-binary==2.9.9
diff --git a/POSTGRES/functions.tf b/POSTGRES/functions.tf
deleted file mode 100644
index 89263cf..0000000
--- a/POSTGRES/functions.tf
+++ /dev/null
@@ -1,36 +0,0 @@
-# Создано: 2026-04-10
-# functions.tf — sless_service ресурсы для примера POSTGRES.
-# Здесь: два калькуляторa — Python и Node.js.
-# sless_service = long-running Deployment + постоянный URL (в отличие от sless_function).
-
-# ─── Python-калькулятор ──────────────────────────────────────────────────────
-
-resource "sless_service" "calc_python" {
- name = "calc-python"
- runtime = "python3.11"
- entrypoint = "handler.handler"
- memory_mb = 128
- timeout_sec = 30
- source_dir = "${path.module}/code/calc-python"
-}
-
-output "calc_python_url" {
- description = "URL Python-калькулятора"
- value = sless_service.calc_python.url
-}
-
-# ─── Node.js-калькулятор ─────────────────────────────────────────────────────
-
-resource "sless_service" "calc_node" {
- name = "calc-node"
- runtime = "nodejs20"
- entrypoint = "handler.handler"
- memory_mb = 128
- timeout_sec = 30
- source_dir = "${path.module}/code/calc-node"
-}
-
-output "calc_node_url" {
- description = "URL Node.js-калькулятора"
- value = sless_service.calc_node.url
-}
diff --git a/POSTGRES/main.tf b/POSTGRES/main.tf
deleted file mode 100644
index 834387f..0000000
--- a/POSTGRES/main.tf
+++ /dev/null
@@ -1,64 +0,0 @@
-// 2026-03-17 17:05
-// main.tf — провайдеры и переменные для Nubes + sless.
-terraform {
- required_providers {
- nubes = {
- source = "terra.k8c.ru/nubes/nubes"
- version = "5.0.31"
- }
- sless = {
- source = "terra.k8c.ru/naeel/sless"
- version = "~> 0.1.19"
- }
- }
-}
-
-variable "api_token" {
- type = string
- sensitive = true
- description = "Nubes API token"
-}
-variable "s3_uid" {
- type = string
- sensitive = true
- description = "Nubes S3 UID"
-}
-variable "realm" {
- type = string
- sensitive = true
- description = "resource_realm parameter for nubes_postgres resource"
-}
-
-// 2026-03-18 — pg_user/pg_password помечены optional (default="") для сверки.
-// Реальные credentials берутся из vault_secrets через locals в resources.tf.
-variable "pg_user" {
- type = string
- sensitive = true
- default = ""
- description = "Только для сверки. Реальный username из nubes_postgres_user.pg_user.username. Должен совпадать с vault."
-}
-
-variable "pg_password" {
- type = string
- sensitive = true
- default = ""
- description = "Только для сверки. Реальный пароль из vault_secrets. Должен совпадать с tfvars."
-}
-
-# Nubes endpoints — не путать:
-# API Dashboard (для Terraform-провайдеров): https://deck-api-test.ngcloud.ru/api/v1/index.cfm
-# UI облака (только браузер, не для кода): https://deck-test.ngcloud.ru/
-# ВАЖНО: nubes и sless провайдеры требуют API endpoint, НЕ UI!
-
-provider "nubes" {
- api_token = var.api_token
- api_endpoint = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm"
-}
-
-provider "sless" {
- endpoint = "https://sless.kube5s.ru"
- token = var.api_token
- nubes_endpoint = "https://deck-api-test.ngcloud.ru/api/v1"
-}
-
-
diff --git a/POSTGRES/postgres.tf b/POSTGRES/postgres.tf
deleted file mode 100644
index 0315443..0000000
--- a/POSTGRES/postgres.tf
+++ /dev/null
@@ -1,58 +0,0 @@
-// 2026-03-20 — выделено из resources.tf: только managed PostgreSQL ресурсы.
-
-# Актуальные credentials из vault_secrets (authoritatively) — vault синхронизирован с кластером.
-# Структура vault_secrets["users"]: JSON-строка {"username": {"password": "...", "username": "..."}}
-
-locals {
- # try() нужен: vault_secrets["users"] появляется только ПОСЛЕ создания первого пользователя.
- # На первом apply ключа ещё нет → пустая map. Пароль подтянется при следующем apply.
- pg_creds_map = try(jsondecode(lookup(nubes_postgres.npg.vault_secrets, "users", "{}")), {})
- pg_username = nubes_postgres_user.pg_user.username
- pg_password = try(local.pg_creds_map[local.pg_username]["password"], "")
- pg_host = nubes_postgres.npg.state_out_flat["internalConnect.master"]
- pg_database = nubes_postgres_database.db.db_name
-}
-
-
-resource "nubes_postgres" "npg" {
- resource_name = "pg-sless-demo"
- # s3_uid = "s01325"
- s3_uid = var.s3_uid
- resource_realm = var.realm
- resource_instances = 1
- resource_memory = 512
- resource_c_p_u = 500
- resource_disk = "1"
- app_version = "17"
- json_parameters = jsonencode({
- log_connections = "off"
- log_disconnections = "off"
- })
- enable_pg_pooler_master = false
- enable_pg_pooler_slave = false
- allow_no_s_s_l = false
- auto_scale = false
- auto_scale_percentage = 10
- auto_scale_tech_window = 0
- auto_scale_quota_gb = "1"
- need_external_address_master = false
-
- # suspend_on_destroy = false
- operation_timeout = "11m"
- adopt_existing_on_create = true
-}
-
-resource "nubes_postgres_user" "pg_user" {
- postgres_id = nubes_postgres.npg.id
- username = "user0"
- role = "ddl_user"
- adopt_existing_on_create = true
-}
-
-resource "nubes_postgres_database" "db" {
- postgres_id = nubes_postgres.npg.id
- db_name = "db0"
- db_owner = nubes_postgres_user.pg_user.username
- adopt_existing_on_create = true
- # suspend_on_destroy = false
-}
diff --git a/POSTGRES/resources.tf b/POSTGRES/resources.tf
deleted file mode 100644
index cd662b8..0000000
--- a/POSTGRES/resources.tf
+++ /dev/null
@@ -1,3 +0,0 @@
-// 2026-03-20 — содержимое перенесено в два файла:
-// postgres.tf — managed PostgreSQL ресурсы (nubes_postgres, user, database, locals)
-// functions.tf — sless функции, сервисы, джобы, outputs
diff --git a/README.md b/README.md
index 96dfaae..5c9fa2a 100644
--- a/README.md
+++ b/README.md
@@ -1,75 +1,55 @@
-# Примеры использования sless
+# sless — примеры
-## Обзор платформы
-
-**sless** — система управления serverless-функциями на базе Kubernetes. Разработчик загружает код функции, платформа собирает из него Docker-образ, разворачивает его в кластере и предоставляет HTTP-эндпоинт для вызова. Всё описывается декларативно через Terraform.
-
-### Основные ресурсы провайдера
-
-| Ресурс | Назначение |
-|---|---|
-| `sless_service` | Long-running HTTP-сервис: всегда активен, отвечает на запросы. Имеет свой URL после деплоя. |
-| `sless_job` | Одноразовый запуск функции: собирает образ, выполняет код, завершается. Используется для миграций БД, batch-обработки и т.д. |
-
-Namespace функций вычисляется автоматически из JWT-токена: `sless-{sha256[:8]}`.
+**sless** — платформа для запуска serverless-функций на базе Kubernetes.
+Разработчик загружает код, платформа собирает Docker-образ и разворачивает его в кластере.
+Всё описывается декларативно через Terraform.
---
-## Требования
+## Ресурсы Terraform-провайдера
-- Terraform >= 1.3
-- JWT-токен для аутентификации в sless API
-- JWT-токен для Nubes Cloud API (если используются managed-ресурсы: PostgreSQL и т.д.)
-- Доступ к `https://sless.kube5s.ru`
+| Ресурс | Что делает |
+|---|---|
+| `sless_service` | HTTP-сервис: всегда запущен, отвечает на запросы, имеет постоянный URL |
+| `sless_job` | Разовый запуск: выполняет код один раз и завершается (установка ПО, миграции и т.д.) |
+
+---
## Конфигурация провайдера
```hcl
provider "sless" {
endpoint = "https://sless.kube5s.ru"
- token = var.sless_token
-}
-
-provider "nubes_cloud" {
- base_url = "https://deck-api-test.ngcloud.ru/api/v1"
- token = var.nubes_token
+ token = var.api_token
}
```
-> Токены задаются в `terraform.tfvars` — этот файл добавлен в `.gitignore`.
+Токен задаётся в `terraform.tfvars` (файл в `.gitignore`, не попадает в git).
---
## Примеры
-### `POSTGRES` — Serverless-функции с Managed PostgreSQL
+### [`VM/`](VM/) — Виртуальная машина в Nubes vDC
-Полный пример: managed PostgreSQL + одноразовый init-job + 3 HTTP-сервиса (чтение/запись данных и информация о PG).
+Создаёт vApp + Ubuntu 22.04 VM в облаке Nubes. После создания — автоматически устанавливает ПО (nginx, Docker, пакеты) через serverless-джобы по SSH.
-Языки: Python 3.11, Node.js 20.
-
-```bash
-cd POSTGRES
-terraform init
-terraform apply
-```
-
-Подробности: [POSTGRES/README.md](POSTGRES/README.md)
+**→ [Начать здесь](VM/README.md)**
---
## Полезные команды
```bash
-# Посмотреть состояние задеплоенных ресурсов:
+# Посмотреть состояние ресурсов:
terraform show
-# Принудительно пересобрать сервис (после изменения кода):
-terraform apply -replace=sless_service.<имя>
-
-# Повторно запустить job: увеличить run_id в .tf-файле, затем:
+# Повторно запустить job: увеличить run_id в terraform.tfvars, затем:
terraform apply
-# Удалить все ресурсы примера:
+# Принудительно пересобрать сервис после изменения кода:
+terraform apply -replace=sless_service.<имя>
+
+# Удалить все ресурсы:
terraform destroy
```