{"id":50559806,"url":"https://github.com/lexfrei/terraform-provider-cozystack","last_synced_at":"2026-06-04T11:01:33.371Z","repository":{"id":361944611,"uuid":"1256320165","full_name":"lexfrei/terraform-provider-cozystack","owner":"lexfrei","description":"Terraform/OpenTofu provider for managing Cozystack applications via the apps.cozystack.io aggregated API","archived":false,"fork":false,"pushed_at":"2026-06-02T00:02:35.000Z","size":215,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-02T00:21:23.115Z","etag":null,"topics":["cozystack","kubernetes","opentofu","terraform","terraform-provider"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lexfrei.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-01T17:03:05.000Z","updated_at":"2026-06-02T00:02:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lexfrei/terraform-provider-cozystack","commit_stats":null,"previous_names":["lexfrei/terraform-provider-cozystack"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/lexfrei/terraform-provider-cozystack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexfrei%2Fterraform-provider-cozystack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexfrei%2Fterraform-provider-cozystack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexfrei%2Fterraform-provider-cozystack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexfrei%2Fterraform-provider-cozystack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lexfrei","download_url":"https://codeload.github.com/lexfrei/terraform-provider-cozystack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lexfrei%2Fterraform-provider-cozystack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33901305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cozystack","kubernetes","opentofu","terraform","terraform-provider"],"created_at":"2026-06-04T11:01:32.591Z","updated_at":"2026-06-04T11:01:33.361Z","avatar_url":"https://github.com/lexfrei.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-provider-cozystack\n\nA Terraform / OpenTofu provider for [Cozystack](https://cozystack.io). It manages Cozystack applications through the aggregated Kubernetes API (`apps.cozystack.io`), so a Cozystack platform can be driven as Infrastructure as Code with the same kubeconfig you already use.\n\n## Supported resources\n\nEvery kind is served by the same aggregated API, so the provider is built to grow one kind at a time. Adding a kind is a typed model, a schema, and a one-line resource descriptor — the create/read/update/delete/import/wait logic is shared.\n\n| Kind | Resource | Data source |\n| --- | --- | --- |\n| Tenant — isolated namespace under a parent tenant | [`cozystack_tenant`](docs/resources/tenant.md) | [`cozystack_tenant`](docs/data-sources/tenant.md) |\n| Managed Redis | [`cozystack_redis`](docs/resources/redis.md) | [`cozystack_redis`](docs/data-sources/redis.md) |\n| Managed Qdrant (vector database) | [`cozystack_qdrant`](docs/resources/qdrant.md) | [`cozystack_qdrant`](docs/data-sources/qdrant.md) |\n| S3-compatible bucket | [`cozystack_bucket`](docs/resources/bucket.md) | [`cozystack_bucket`](docs/data-sources/bucket.md) |\n| Managed OpenBAO (Vault-compatible) | [`cozystack_openbao`](docs/resources/openbao.md) | [`cozystack_openbao`](docs/data-sources/openbao.md) |\n| VPN server | [`cozystack_vpn`](docs/resources/vpn.md) | [`cozystack_vpn`](docs/data-sources/vpn.md) |\n| Managed RabbitMQ | [`cozystack_rabbitmq`](docs/resources/rabbitmq.md) | [`cozystack_rabbitmq`](docs/data-sources/rabbitmq.md) |\n| Managed MariaDB | [`cozystack_mariadb`](docs/resources/mariadb.md) | [`cozystack_mariadb`](docs/data-sources/mariadb.md) |\n| Managed MongoDB | [`cozystack_mongodb`](docs/resources/mongodb.md) | [`cozystack_mongodb`](docs/data-sources/mongodb.md) |\n| Managed ClickHouse | [`cozystack_clickhouse`](docs/resources/clickhouse.md) | [`cozystack_clickhouse`](docs/data-sources/clickhouse.md) |\n| Managed NATS | [`cozystack_nats`](docs/resources/nats.md) | [`cozystack_nats`](docs/data-sources/nats.md) |\n| Managed OpenSearch | [`cozystack_opensearch`](docs/resources/opensearch.md) | [`cozystack_opensearch`](docs/data-sources/opensearch.md) |\n| Managed PostgreSQL | [`cozystack_postgres`](docs/resources/postgres.md) | [`cozystack_postgres`](docs/data-sources/postgres.md) |\n| HTTP cache | [`cozystack_httpcache`](docs/resources/httpcache.md) | [`cozystack_httpcache`](docs/data-sources/httpcache.md) |\n| TCP load balancer | [`cozystack_tcpbalancer`](docs/resources/tcpbalancer.md) | [`cozystack_tcpbalancer`](docs/data-sources/tcpbalancer.md) |\n| Harbor registry | [`cozystack_harbor`](docs/resources/harbor.md) | [`cozystack_harbor`](docs/data-sources/harbor.md) |\n| Virtual private cloud | [`cozystack_vpc`](docs/resources/vpc.md) | [`cozystack_vpc`](docs/data-sources/vpc.md) |\n| Virtual machine disk | [`cozystack_vmdisk`](docs/resources/vmdisk.md) | [`cozystack_vmdisk`](docs/data-sources/vmdisk.md) |\n| Managed Kafka | [`cozystack_kafka`](docs/resources/kafka.md) | [`cozystack_kafka`](docs/data-sources/kafka.md) |\n| Managed FoundationDB | [`cozystack_foundationdb`](docs/resources/foundationdb.md) | [`cozystack_foundationdb`](docs/data-sources/foundationdb.md) |\n| Virtual machine instance | [`cozystack_vminstance`](docs/resources/vminstance.md) | [`cozystack_vminstance`](docs/data-sources/vminstance.md) |\n| Managed Kubernetes | [`cozystack_kubernetes`](docs/resources/kubernetes.md) | [`cozystack_kubernetes`](docs/data-sources/kubernetes.md) |\n\nEvery kind served by the aggregated `apps.cozystack.io` API is now covered.\n\n## Platform resources (`cozystack.io` group)\n\nBeyond the namespaced tenant apps, the provider also manages the cluster-scoped platform resources in the `cozystack.io` group — useful for platform-as-code:\n\n| Kind | Resource | Data source |\n| --- | --- | --- |\n| Package — install a package variant | [`cozystack_package`](docs/resources/package.md) | [`cozystack_package`](docs/data-sources/package.md) |\n| PackageSource — where packages come from | [`cozystack_package_source`](docs/resources/package_source.md) | [`cozystack_package_source`](docs/data-sources/package_source.md) |\n| ApplicationDefinition — register an app kind | [`cozystack_application_definition`](docs/resources/application_definition.md) | [`cozystack_application_definition`](docs/data-sources/application_definition.md) |\n| SchedulingClass — named placement policy | [`cozystack_scheduling_class`](docs/resources/scheduling_class.md) | [`cozystack_scheduling_class`](docs/data-sources/scheduling_class.md) |\n\nThese are cluster-scoped (imported by name, no namespace). `cozystack_package` is fully typed (`variant`, `ignore_dependencies`, per-component overrides). The other three are platform-definition documents whose deeply-nested, version-coupled specs are surfaced as a single normalized-JSON `spec` attribute (write with `jsonencode`, read back with `jsondecode`) rather than brittle per-field modeling.\n\n### Backups and dashboard\n\nThe same JSON-spec passthrough also covers the backup framework and dashboard panels:\n\n| Kind | Resource | Data source |\n| --- | --- | --- |\n| Plan (typed) | [`cozystack_backup_plan`](docs/resources/backup_plan.md) | [`cozystack_backup_plan`](docs/data-sources/backup_plan.md) |\n| RestoreJob (typed) | [`cozystack_restore_job`](docs/resources/restore_job.md) | [`cozystack_restore_job`](docs/data-sources/restore_job.md) |\n| BackupClass | [`cozystack_backup_class`](docs/resources/backup_class.md) | [`cozystack_backup_class`](docs/data-sources/backup_class.md) |\n| Backup | [`cozystack_backup`](docs/resources/backup.md) | [`cozystack_backup`](docs/data-sources/backup.md) |\n| BackupJob | [`cozystack_backup_job`](docs/resources/backup_job.md) | [`cozystack_backup_job`](docs/data-sources/backup_job.md) |\n| MarketplacePanel | [`cozystack_marketplace_panel`](docs/resources/marketplace_panel.md) | [`cozystack_marketplace_panel`](docs/data-sources/marketplace_panel.md) |\n\n`backup_plan` (schedule a backup) and `restore_job` (restore a backup) are user-authored, so they are fully typed (`application_ref`, `backup_class_name`, `schedule` / `backup_name`, `target_application_ref`, `options`). The remaining backups kinds are records or driver config and stay JSON-spec.\n\n### Tenant core resources (`core.cozystack.io`)\n\nThese do not follow the spec pattern, so they have purpose-built models:\n\n| Kind | Resource | Shape |\n| --- | --- | --- |\n| TenantSecret | [`cozystack_tenant_secret`](docs/resources/tenant_secret.md) | Secret-shaped: `type` + `data` (plaintext in, stored base64) |\n| TenantModule | [`cozystack_tenant_module`](docs/resources/tenant_module.md) | namespaced marker (existence enables the module) |\n| TenantNamespace | [`cozystack_tenant_namespace`](docs/resources/tenant_namespace.md) | cluster-scoped marker |\n\nDeliberately not exposed: the `strategy.backups.cozystack.io` per-engine backup strategies and the `dashboard.cozystack.io` UI-customization CRDs (Sidebar, Navigation, Factory, …) — platform internals shipped and reconciled by Cozystack itself, with no Infrastructure-as-Code use case.\n\nAuthentication mirrors the official kubernetes provider: `config_path`/`config_context`, `host`/`token`, `cluster_ca_certificate`, `client_certificate`/`client_key`, an `in_cluster` toggle, and an `exec {}` credential-plugin block for OIDC login helpers (`kubectl oidc-login`). OIDC via a kubeconfig already works through `config_path` with no extra configuration.\n\n## Referencing outputs\n\nThe aggregated API is write-oriented: it takes a spec and returns a thin status. The connection details you actually want to reference — endpoints, credentials, a child cluster's kubeconfig, a VM's IP — are materialised by the underlying charts as Secrets, Services, and KubeVirt status. The provider reads those and exposes them as computed (sensitive where appropriate) attributes:\n\n- `cozystack_kubernetes.\u003cx\u003e.kubeconfig` — admin kubeconfig of the provisioned cluster, for chaining the `kubernetes`/`helm` providers into it.\n- `cozystack_postgres.\u003cx\u003e.endpoints` — `{ host, read_host, port }` from the CNPG `rw`/`ro` Services.\n- `cozystack_bucket.\u003cx\u003e.credentials[\"\u003cuser\u003e\"]` — `{ endpoint, bucket_name, region, access_key, secret_key }` per user.\n- `cozystack_vminstance.\u003cx\u003e.ip_address` / `.ip_addresses` — guest addresses from the backing VirtualMachineInstance.\n\nThese are populated asynchronously, after the application is ready. Set `wait_for_ready = true` on the resource you consume so they are available on first apply rather than on a later refresh.\n\n### Keeping secrets out of state\n\nTo avoid persisting secrets in state, the provider offers modern Terraform secret handling:\n\n- **Ephemeral resources** (`ephemeral \"cozystack_kubernetes\"`, `ephemeral \"cozystack_tenant_secret\"`) fetch a cluster kubeconfig or a tenant secret at apply time, usable to configure downstream providers, without ever writing the value to state.\n- **Write-only inputs** — `cozystack_tenant_secret` accepts `data_wo` (write-only, sent on apply but never stored; bump `data_wo_version` to push changes) alongside the state-persisted `data`.\n\n```hcl\nresource \"cozystack_kubernetes\" \"app\" {\n  name           = \"app\"\n  namespace      = \"tenant-root\"\n  node_groups    = { md0 = { min_replicas = 1, max_replicas = 3 } }\n  wait_for_ready = true\n}\n\nprovider \"kubernetes\" {\n  alias = \"app\"\n  # chain straight into the cluster this provider just created\n  # (parse cozystack_kubernetes.app.kubeconfig with the helm/kubernetes provider's\n  #  config_path written from it, or your preferred kubeconfig wiring)\n}\n```\n\nThe names of these backing Secrets/Services are chart conventions (`postgres-\u003cname\u003e-rw`, `bucket-\u003cname\u003e-\u003cuser\u003e`, `kubernetes-\u003cname\u003e-admin-kubeconfig`), pinned to the supported Cozystack version — not part of the stable aggregated-API contract.\n\n## Requirements\n\n- Terraform \u003e= 1.0 or OpenTofu \u003e= 1.6\n- A running Cozystack cluster and a kubeconfig (or bearer token) that can reach its API\n\n## Usage\n\n```terraform\nterraform {\n  required_providers {\n    cozystack = {\n      source = \"lexfrei/cozystack\"\n    }\n  }\n}\n\nprovider \"cozystack\" {\n  config_path    = \"~/.kube/config\"\n  config_context = \"my-cozystack-cluster\"\n}\n\nresource \"cozystack_tenant\" \"team_a\" {\n  name      = \"team-a\"\n  namespace = \"tenant-root\"\n\n  monitoring = true\n  ingress    = true\n}\n\nresource \"cozystack_redis\" \"cache\" {\n  name      = \"cache\"\n  namespace = cozystack_tenant.team_a.status_namespace\n\n  replicas = 2\n  version  = \"v8\"\n}\n```\n\nResources are namespaced by tenant, so other applications reference a tenant's `status_namespace` to deploy inside it.\n\n## Authentication\n\nConnection settings mirror the official `kubernetes` provider, so existing kubeconfig and environment conventions transfer directly. Every provider attribute is optional and falls back to a `KUBE_*` environment variable: `config_path` (`KUBE_CONFIG_PATH`, then `KUBECONFIG`), `config_context` (`KUBE_CTX`), `host` (`KUBE_HOST`), `token` (`KUBE_TOKEN`), `cluster_ca_certificate` (`KUBE_CLUSTER_CA_CERT_DATA`), and `insecure` (`KUBE_INSECURE`). Set `in_cluster = true` to use a pod's service account instead of a kubeconfig.\n\n## Local install\n\nUntil a release is published to the registry, build the provider and point Terraform/OpenTofu at it with a dev override:\n\n```sh\nmake install   # go install into $GOBIN\n```\n\n```hcl\n# ~/.terraformrc  (or a file referenced by TF_CLI_CONFIG_FILE)\nprovider_installation {\n  dev_overrides {\n    \"registry.terraform.io/lexfrei/cozystack\" = \"/path/to/your/gobin\"\n  }\n  direct {}\n}\n```\n\n## Development\n\n```sh\nmake build   # build the provider binary\nmake test    # unit tests with the race detector\nmake lint    # golangci-lint\nmake docs    # regenerate docs/ with tfplugindocs\n```\n\nAcceptance tests create and destroy real applications and need a reachable Cozystack cluster:\n\n```sh\nKUBECONFIG=/path/to/kubeconfig KUBE_CTX=my-context make testacc\n```\n\nThe acceptance harness drives the Terraform CLI; the `testacc` target points `TF_ACC_TERRAFORM_PATH` at `tofu` automatically so it runs against OpenTofu when Terraform is not installed.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow and [SECURITY.md](SECURITY.md) for vulnerability reporting and credential-handling guidance.\n\n## License\n\n[BSD-3-Clause](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flexfrei%2Fterraform-provider-cozystack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flexfrei%2Fterraform-provider-cozystack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flexfrei%2Fterraform-provider-cozystack/lists"}