Terraform Provider
以基础设施即代码的方式,声明工作区、应用、变量和域名。
Cloady 的 Terraform Provider 已发布在公共 Registry 上,因此工作区、应用、环境变量和自定义域名都可以用代码声明,并像其他基础设施一样进行评审、版本管理和发布。
terraform {
required_providers {
cloady = {
source = "cloady/cloady"
version = "~> 0.1"
}
}
}
provider "cloady" {} # reads CLOADY_TOKEN
resource "cloady_app" "api" {
workspace = "acme"
name = "API"
region = "eu1"
git = { repository_url = "https://github.com/acme/api" }
}
output "url" {
value = cloady_app.api.endpoints[0].url
}terraform init 会从 Registry 安装它,无需其他设置。
身份验证
在 Account → API tokens 中创建令牌,然后导出为环境变量:
export CLOADY_TOKEN=cldy_xxxxxxxxxxxxxxxxProvider 默认读取 CLOADY_TOKEN;在 provider 块中设置 token 可以覆盖它,设置 base_url(或 CLOADY_CONTROL_PLANE_URL)则可以连接 https://cloady.com 以外的 Cloady 实例。
创建工作区和修改计费设置需要 full 权限范围的令牌;其他操作用 deploy 即可,只读操作用 read 就够了。你在工作区中的角色依然会叠加生效:在你只是 viewer 的工作区里,full 令牌也无法执行删除。
资源
| 资源 | 管理对象 |
|---|---|
cloady_app | 来自 Git 仓库或模板目录的应用 |
cloady_workspace | 工作区 |
cloady_variable | 应用的单个环境变量 |
cloady_domain | 应用上的自定义域名 |
有两个数据源只读取现有状态,而不接管它:cloady_workspace,以及列出可部署区域的 cloady_regions。无论免费还是付费,每个区域都接受来自任何工作区的应用。
完整的属性参考见 Terraform Registry。
一套完整的技术栈
data "cloady_regions" "all" {}
resource "cloady_workspace" "acme" {
slug = "acme"
name = "Acme"
}
resource "cloady_app" "db" {
workspace = cloady_workspace.acme.slug
name = "Postgres"
region = "eu1"
catalog = "postgres"
volume_sizes = { data = 20 }
lifecycle {
prevent_destroy = true
}
}
resource "cloady_app" "api" {
workspace = cloady_workspace.acme.slug
name = "API"
region = "eu1"
cpu_scale = 2
memory_scale = 2
git = {
repository_url = "https://github.com/acme/api"
branch = "main"
auto_deploy = true
}
}
resource "cloady_variable" "database_url" {
workspace = cloady_workspace.acme.slug
app = cloady_app.api.slug
region = cloady_app.api.region
key = "DATABASE_URL"
value = var.database_url
is_secret = true
}
resource "cloady_domain" "api" {
workspace = cloady_workspace.acme.slug
app = cloady_app.api.slug
region = cloady_app.api.region
host = "api.acme.com"
is_primary = true
}每个应用运行在一个区域和一个环境中,名称在所属工作区和环境内必须唯一。凡是接受 environment 的地方,它都默认为 production;如需其他环境,请设为 preview 或 development。变量名采用 SCREAMING_SNAKE_CASE 格式。
首次 apply 前必读
Terraform 的模型是“让实际状态与配置保持一致”:只要某个无法原地修改的属性发生了变化,它就会删除并重建该资源。对于存有数据的应用,重建就意味着数据丢失。
销毁应用会永久删除它的数据。它的存储卷也会一并删除,且无法撤销。请给所有保存状态的资源加上 prevent_destroy(就像上面的 Postgres 应用那样),工作区也要加上:销毁工作区会销毁其中的所有应用。
重命名是原地进行的,切勿为了重命名而销毁应用。name、branch、cpu_scale、memory_scale、volume_sizes 和 auto_deploy 都会直接在现有应用上更新。重命名唯一的代价是地址:应用的地址是 <name>-<code>-<workspace>.cloady.io,例如 my-blog-k7q2v9ze-acme.cloady.io,它会随名称变化,所以旧地址会失效。自定义域名仍然指向该应用。
- 有些属性会强制替换资源。应用创建时就确定了所在的区域、环境、工作区和来源,之后不会再变。修改
region、environment、workspace或 Git 仓库 URL,就等于先销毁再创建:数据清空、地址更换、服务中断。 - 存储卷只能扩大。调小
volume_sizes中的值会在 plan 阶段被拒绝。如需缩小,请先备份,再创建一个新应用。 - 变量的修改会在应用下次部署时生效。只改动
cloady_variable的 apply 不会重启任何东西;如果应用现在就需要新值,请接着运行cloady redeploy acme api。 - 变量值以明文形式保存在 Terraform 状态中,机密值也不例外。
is_secret只是在 Cloady 中隐藏该值,并不会加密你的状态文件。请使用支持静态加密的远程后端,并优先使用var.输入,而不是直接写字面值。 cloady_domain上只有redirect_to可以原地修改。修改host或is_primary会替换这条记录;应用会继续运行,但新主机名的 DNS 必须先指向 Cloady,HTTPS 才能在它上面生效。- apply 成功不代表应用运行正常。创建操作在部署开始后就会返回,所以
status反映的是 Cloady 在那一刻看到的状态,并不表示应用已就绪。请在控制台或通过 CLI 查看部署进度。
缩放倍数乘在应用所申请的资源上,而不是一个绝对大小:cpu_scale = 2 就是翻倍。取值范围为 0.5 到 4,步长为 0.25;工作区中运行的一切(所有区域、所有环境)都会计入工作区的费用。
只要 apply 后的整套资源不超出工作区的免费额度,就不会产生任何费用。一旦超出,apply 运行时就会从已绑定的银行卡扣取差额;如果没有绑定银行卡,或银行卡扣款被拒,Cloady 会返回 payment_required,Terraform 随即停止。由工作区所有者在 Account → Billing 中添加银行卡,然后重新运行 apply。
导入现有应用
在控制台中创建的所有资源,都可以直接纳入 Terraform 管理,无需重建。导入 ID 就是资源的地址,以斜杠分隔:
terraform import cloady_workspace.acme acme
terraform import cloady_app.api acme/api/production/eu1
terraform import cloady_variable.db acme/api/production/eu1/<variable-id>
terraform import cloady_domain.api acme/api/production/eu1/<domain-id>变量和域名的 ID 可以通过 API 中的 listVars 和 listAppDomains 获取,也可以从 CLI 获取。
与其他接口的关系
Provider 调用的 REST API,与控制台、CLI、各个 SDK 和 MCP 服务器调用的是同一套,权限范围和角色检查也完全相同。区别在于用途:CLI 和 MCP 服务器用来执行操作,而 Terraform 会收敛到声明的最终状态,并在下一次 apply 时纠正配置漂移。
因此,它不适合一次性操作。重启服务、在容器中运行命令、回滚部署或查看日志,都是没有目标状态可以收敛的操作,仍然交给 CLI 和 API 来完成。