Files
tf_provider/devops/ARCHITECTURE.md
T

132 lines
4.7 KiB
Markdown

# Provider Architecture (Source of Truth)
This document defines the project-wide architecture and rules for generation,
provider behavior, and documentation. It is the single source of truth for
implementation and DevOps workflow.
## Core Principles
1) YAML per service is generated ONLY from API data.
2) The provider core is universal and must not contain service-specific logic.
3) Service-specific Go code is fully generated from YAML. No manual edits.
4) Documentation is generated from the same YAML.
5) Build artifacts for 3 OS targets are published to the registry, and docs are
published to the website.
## Service Selection
- The inclusion list is defined by: `devops/config/services_list.txt` (repo-relative path)
- Each line starts with service_id, followed by service name/alias.
- Operation timeouts source is defined by: `devops/config/operation_timeouts.json`.
## Unified YAML (Per Service)
One YAML file per service. This is the only input for:
- Provider code generation
- Documentation generation
- Validation rules
Required top-level fields:
- name
- service_id
- service_display_name
- service_short_name
- lifecycle
- outputs
- operations
- service_man
### Operations: Kinds and Rules
Each operation has a kind:
- kind: instance (CRUD for the service instance, plus suspend/resume)
- kind: subresource (CRUD for objects inside the service, e.g. users/databases)
- kind: action (one-shot operations, e.g. restart/recovery/redeploy)
### Idempotency Rules
- instance CRUD is idempotent via standard Terraform behavior.
- subresource CRUD is idempotent by resource identity.
- action operations are idempotent via a trigger field (e.g. run_id/nonce).
If the trigger does not change, the action is not re-run.
### Lifecycle Behavior
- For `instance` resources with `suspend`/`resume`, use explicit flags:
`adopt_existing_on_create` (default `false`) and `suspend_on_destroy` (default `true`).
- Apply decision matrix for suspend-capable services:
- cloud status `missing` or `deleted` -> `create`
- `suspend` + `adopt_existing_on_create=true` + key params match -> `resume` + `adopt`
- `suspend` + `adopt_existing_on_create=false` -> error (explicitly require flag for resume/adopt)
- `suspend` + key params mismatch -> error
- `running` + `adopt_existing_on_create=true` -> adopt/import behavior
- `running` + `adopt_existing_on_create=false` -> error
- `not created` -> error, no auto-adopt/create
- `creating`/`pending`/`failed` -> error
- Conflict diagnostics requirement:
- When `resource_name` already exists and `adopt_existing_on_create=false`, diagnostics must explicitly offer two choices:
1) change `resource_name` to create a new resource;
2) import/adopt existing one by setting `adopt_existing_on_create=true` and re-running `apply`.
- Destroy behavior for suspend-capable services:
- `suspend_on_destroy=true` -> call `suspend`
- `suspend_on_destroy=false` -> remove from Terraform state only (no API call)
### Diagnostics Format
- Lifecycle diagnostics for plan/apply must be multiline and human-readable.
- Include decision reason and controlling flag in message body.
- Print details as separate lines: `resource_name`, `service_id`, `instance_uid`,
`status`, `status_raw`, `operation_pending`, `operation_in_progress`.
## Provider Model
- Core is universal: no service-specific logic inside the core.
- Generated service resources contain only schema/params and references.
### Subresource Resources
Subresource operations are exposed as standard resources.
Example mapping:
- create_user/delete_user/modify_user => nubes_<service>_user
- create_database/delete_database => nubes_<service>_database
Example HCL:
resource "nubes_postgres_user" "user1" {
postgres_id = nubes_postgres.db.id
username = "app_user"
role = "app_user"
}
### Action Resources
Action operations are exposed as action resources with a trigger field.
Example HCL:
resource "nubes_postgres_restart" "restart1" {
postgres_id = nubes_postgres.db.id
run_id = "2026-02-20-001"
}
## Documentation Model
From the unified YAML, generate:
- Resource page: CRUD params, outputs, lifecycle defaults, operations summary
- MAN page: service_man + parameter man blocks
- Resources index: each resource links to its page and its MAN page
## Pipeline Overview (DevOps)
1) Generate unified YAML from API for services_list.txt.
2) Generate provider code from YAML.
3) Generate documentation from YAML.
4) Build provider for linux/windows/darwin.
5) Upload provider artifacts to registry.
6) Build and publish docs to site.
## Non-Negotiable Rules
- No manual edits to generated YAML or generated Go code.
- Any change must come from API or generator logic updates.
- The generator must enforce these rules and fail fast on drift.