OneUptime Terraform Provider 实战示例指南:用 HCL 管理监控、状态页与事件响应资源
2026/9/17 23:32:05 网站建设 项目流程

OneUptime Terraform Provider 实战示例指南:用 HCL 管理监控、状态页与事件响应资源

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

本指南以 OneUptime 官方 Terraform Provider 示例文档(App/FeatureSet/Docs/Content/de/terraform/examples.md,与 英文版示例 同源)为骨架,系统讲解用 HCL 声明式管理 OneUptime 最常见资源的完整写法:从 Label、Monitor(HTTP/Ping/Manual)、带自定义域名的 Status Page,到 Team、On-Call 策略、Scheduled Maintenance、Incident 与自定义 Probe。文中的每一段配置都对应仓库内 E2E 测试套件(E2E/Terraform/e2e-tests)中的真实 fixture,保证属性真实、可直接复制应用。读完你将能基于这些模板快速搭建一套「监控 → 状态页 → 告警升级 → 事件管理」的完整 IaC 工作流。

一、前置条件:Provider 基础配置

所有示例都依赖以下 Provider 声明。这是从 Terraform Registry 拉取oneuptime/oneuptime提供者的标准写法,~> 11.0表示允许 11.x 范围内的兼容升级:

terraform { required_providers { oneuptime = { source = "oneuptime/oneuptime" version = "~> 11.0" } } } provider "oneuptime" { # api_key from ONEUPTIME_API_KEY; oneuptime_url only needed when self-hosted. }

两点说明:

  • 认证api_key从环境变量ONEUPTIME_API_KEY读取,无需在 HCL 中硬编码密钥;
  • 自托管:仅当使用自托管 OneUptime 实例时,才需要显式传入oneuptime_url(云版默认可省略)。更多自托管接入细节可参考 self-hosted.md。

需要指出的是,OneUptime 的 Terraform Provider 并非手工维护,而是由仓库中的 TerraformProviderGenerator 等生成器基于 OneUptime 的 OpenAPI 定义自动生成(见 Scripts/TerraformProvider 目录),因此资源的属性结构天然与 OneUptime REST API 一一对应。

二、Labels:最基础的构建块

Label 是成本最低的构建单元——先创建它,再通过labels = [...](一个无序的 label ID 集合)挂到几乎任何资源上,用于组织、过滤和展示。

resource "oneuptime_label" "production" { name = "production" description = "Production infrastructure" color = "#FF5733" }

在 E2E 测试中,Label 经常作为其他资源的附属依赖出现,例如维护事件、On-Call 策略、Incident、Probe 都可以挂 Label(参见 30-scheduled-maintenance-crud/main.tf、31-on-call-duty-policy-crud/main.tf 中的oneuptime_label用法)。

三、Monitor:三种典型形态

3.1 HTTP Monitor 与显式检查项

Website类型 Monitor 让你完整控制「检查什么」以及「何时判定为 up/down」。核心在于monitor_steps这个 JSON 结构,逐行讲解参见 Monitor Steps 文档。

先定义两个 Monitor 状态(status):一个「Operational」(绿色),一个「Offline」(红色)。is_operational_state决定了该状态是否被视为「可用」:

resource "oneuptime_monitor_status" "operational" { name = "Operational" description = "Monitor is operational" color = "#2ecc71" priority = 1 is_operational_state = true } resource "oneuptime_monitor_status" "offline" { name = "Offline" description = "Monitor is offline" color = "#e74c3c" priority = 3 is_operational_state = false } resource "oneuptime_monitor" "website" { name = "Website" description = "Homepage availability and status code check" monitor_type = "Website" monitor_steps = jsonencode({ _type = "MonitorSteps" value = { monitorStepsInstanceArray = [ { _type = "MonitorStep" value = { id = "step-website-1" monitorDestination = { _type = "URL" value = "https://example.com" } requestType = "GET" monitorCriteria = { _type = "MonitorCriteria" value = { monitorCriteriaInstanceArray = [ { _type = "MonitorCriteriaInstance" value = { id = "criteria-online" name = "Online" description = "Website responds with 200" filterCondition = "All" changeMonitorStatus = true createIncidents = false createAlerts = false monitorStatusId = oneuptime_monitor_status.operational.id filters = [ { _type = "CriteriaFilter" value = { checkOn = "Is Online" filterType = "True" } }, { _type = "CriteriaFilter" value = { checkOn = "Response Status Code" filterType = "Equal To" value = "200" } } ] incidents = [] alerts = [] } }, { _type = "MonitorCriteriaInstance" value = { id = "criteria-offline" name = "Offline" description = "Website is unreachable" filterCondition = "Any" changeMonitorStatus = true createIncidents = false createAlerts = false monitorStatusId = oneuptime_monitor_status.offline.id filters = [ { _type = "CriteriaFilter" value = { checkOn = "Is Online" filterType = "False" } } ] incidents = [] alerts = [] } } ] } } } } ] } }) }

这段配置的逻辑非常清晰:criteria(判定条件)是 monitor_steps 的核心,它由多条MonitorCriteriaInstance组成,每条实例通过monitorStatusId绑定到前面定义的 Monitor 状态,并通过一组filters描述具体判定规则:

  • filterCondition = "All":所有 filter 同时满足才命中该条件;"Any"则任一满足即命中;
  • 上方 Online 条件要求「在线为真」且「状态码等于 200」同时成立才切到 Operational;
  • 下方 Offline 条件只需「在线为假」即切到 Offline(filterCondition = "Any");
  • createIncidents/createAlerts控制状态切换时是否自动创建事件与告警(此处均关闭)。

(此例改编自 E2E 测试35-monitor-with-steps,对应 fixture 见 tests/35-monitor-with-steps/main.tf。)

3.2 Ping Monitor

Ping Monitor 的区别仅在于目的地(destination)使用Hostname(或IP)而不是 URL:

resource "oneuptime_monitor" "ping" { name = "Gateway Ping" description = "ICMP reachability of the gateway host" monitor_type = "Ping" monitor_steps = jsonencode({ _type = "MonitorSteps" value = { monitorStepsInstanceArray = [ { _type = "MonitorStep" value = { id = "step-ping-1" monitorDestination = { _type = "Hostname" value = "gateway.example.com" } requestType = "GET" monitorCriteria = { _type = "MonitorCriteria" value = { monitorCriteriaInstanceArray = [ { _type = "MonitorCriteriaInstance" value = { id = "criteria-ping-online" name = "Reachable" description = "Host responds to ping" filterCondition = "All" changeMonitorStatus = true createIncidents = false createAlerts = false monitorStatusId = oneuptime_monitor_status.operational.id filters = [ { _type = "CriteriaFilter" value = { checkOn = "Is Online" filterType = "True" } } ] incidents = [] alerts = [] } } ] } } } } ] } }) }

(此例同样改编自 E2E 测试35-monitor-with-steps。)

3.3 Manual Monitor(手动监控)

Manual Monitor 没有主动检查,状态由人工或自动化流程手动设置,因此完全不需要monitor_steps

resource "oneuptime_monitor" "third_party" { name = "Payment Provider (manual)" description = "Tracked manually during vendor incidents" monitor_type = "Manual" monitoring_interval = "Every 5 minutes" }

(改编自 E2E 测试26-monitor-steps-basic,该 fixture 还展示了「只给 name、连 steps 都不写」的最简 Manual Monitor 写法,见 tests/26-monitor-steps-basic/main.tf。)

其他同样用法的合法monitor_type取值包括:"API""Port""IP""SSL Certificate""Incoming Request""Server"。其中ServerIncoming Request类型的 Monitor 会由服务端计算生成密钥属性(server_monitor_secret_keyincoming_request_secret_key),供对应 Agent 接入使用。

3.4 进阶:monitor_steps 的两种书写形式

从源码 fixture 看,monitor_steps存在两种等价写法:

  • 本指南示例的jsonencode+_type/value信封结构:与服务端 API 的序列化格式一致,直观反映内部数据结构;
  • 类型化嵌套属性(typed nested attribute):E2E 测试中更新的写法——直接写monitor_steps = [{ monitor_destination = ..., monitor_destination_type = "URL", request_type = "GET", criteria = [...] }],无需jsonencode、无需手写 step/criteria 的id(由服务端生成),见 tests/35-monitor-with-steps/main.tf 与 tests/26-monitor-steps-basic/main.tf 的注释说明。生产环境建议优先采用类型化嵌套属性。

此外,E2E fixture 中反复出现disable_active_monitoring = true有两个实战含义:其一是在测试中避免活动 Probe 在 destroy 期间把currentMonitorStatusId写回 Monitor 造成竞态;其二是它本身就是可用的属性——如果你希望先声明资源、稍后再开启真实探测,可以在创建阶段用它。另外注意monitor_statuspriority在服务端是「INSERT 槽位」语义:创建后不可更新,且密集的低位 priority 会与项目默认状态冲突、在 Terraform 并行创建下产生竞态——实战建议使用高位且留有空隙的 priority(如 101/102/103),并用depends_on串行创建(见 tests/35-monitor-with-steps/main.tf 顶部注释)。

四、带自定义域名的 Status Page

三个资源协同工作:一个已验证的项目domainstatus_page本身、以及把二者关联起来的status_page_domain。其中full_domaincname_verification_token由服务端计算得出——不要手动设置它们

resource "oneuptime_domain" "company" { domain = "example.com" } resource "oneuptime_status_page" "public" { name = "Public Status" description = "Customer-facing status page" page_title = "System Status" page_description = "Check our system status and incident history" is_public_status_page = true enable_email_subscribers = true enable_sms_subscribers = false } resource "oneuptime_status_page_domain" "status" { domain_id = oneuptime_domain.company.id status_page_id = oneuptime_status_page.public.id subdomain = "status" } output "status_domain" { # Computed by the server: subdomain + domain, e.g. status.example.com value = oneuptime_status_page_domain.status.full_domain }

output "status_domain"展示了如何把服务端计算的full_domain(例如status.example.com)暴露给上层调用方。

(改编自 E2E 测试25-status-page-with-domain12-status-page-domain。注意:新域名必须先通过 DNS 验证,status_page_domain 才会真正生效。)

从源码 fixture 可以进一步确认该组合的完整行为(见 tests/25-status-page-with-domain/main.tf):

  • oneuptime_domain支持is_verified属性直接声明域名已通过验证(E2E 中置为true);
  • 同一个域名可挂到多个状态页、同一个状态页也可挂多个域名(fixture 中同时演示了statusapi-statusinternal三个子域的组合);
  • downtime_monitor_statusesslug等服务端注入的默认值不会引发 plan 漂移(对应 Issue #2232 的修复验证);
  • full_domaincname_verification_token作为计算字段由 provider 回读(对应 Issue #2236 的修复验证)。

五、Team 与成员

resource "oneuptime_team" "sre" { name = "SRE" description = "Site reliability engineering" } resource "oneuptime_team_member" "alice" { team_id = oneuptime_team.sre.id user_id = "5f8a1b2c3d4e5f6a7b8c9d0e" # user's id — visible in the dashboard URL on their profile }

(Team 部分改编自 E2E 测试33-team-crud。两点约束:被引用的user_id必须已经是该项目的一员;成员资格需在该用户接受邀请后才最终确认。)

六、带升级(Escalation)的 On-Call 策略

一个 On-Call 策略 + 一条「5 分钟未确认即升级」的升级规则:

resource "oneuptime_on_call_policy" "primary" { name = "Primary On-Call" description = "First line for production incidents" repeat_policy_if_no_one_acknowledges = true } resource "oneuptime_escalation_rule" "first_line" { on_call_duty_policy_id = oneuptime_on_call_policy.primary.id name = "First line" description = "Page the on-call engineer immediately" order = 1 escalate_after_in_minutes = 5 }

(策略部分改编自 E2E 测试31-on-call-duty-policy-crud。)

要点解读:

  • repeat_policy_if_no_one_acknowledges控制「无人确认时是否重复执行本轮升级」;
  • escalation_rule通过on_call_duty_policy_id挂到策略下,order决定升级层级顺序,escalate_after_in_minutes = 5表示超时 5 分钟未确认就升级到下一层;
  • 若需要把规则绑定到具体值班人员/调度表,可进一步参考 E2E 中的39-escalation-rule40-on-call-schedule测试目录。

七、Scheduled Maintenance(计划维护)

resource "oneuptime_scheduled_maintenance_event" "db_upgrade" { title = "Database maintenance" description = "Planned PostgreSQL upgrade — writes paused briefly" starts_at = "2026-08-01T02:00:00Z" ends_at = "2026-08-01T04:00:00Z" is_visible_on_status_page = true }

(改编自 E2E 测试30-scheduled-maintenance-crud。)

实战注意点(均有 E2E 佐证,见 tests/30-scheduled-maintenance-crud/main.tf):

  • 时间戳采用RFC3339格式;provider 实现了「语义化日期相等」判断,因此相同时刻的不同记法(如带不带毫秒、时区表示差异)不会引发 plan 漂移——fixture 特意使用固定的未来时间戳(如2030-06-01T10:00:00.000Z)来回归验证这一点;
  • 维护事件同样支持labels关联与should_status_page_subscribers_be_notified_on_event_created等订阅者通知开关;
  • 服务端会生成slugcreated_at等计算字段,provider 会正确回读,避免二次 plan 出现 diff。

八、Incident 严重级别与状态

自定义事件分类法:severity(严重级别)用来衡量影响程度,state(状态)用来建模生命周期,order控制展示位置:

resource "oneuptime_incident_severity" "sev1" { name = "SEV-1" description = "Full outage, all hands" color = "#e74c3c" order = 1 } resource "oneuptime_incident_state" "mitigated" { name = "Mitigated" description = "Impact contained, fix in progress" color = "#f39c12" order = 3 }

(改编自 E2E 测试03-incident-severity04-incident-stateoneuptime_alert_severityoneuptime_alert_state对告警(Alert)完全同理。)

8.1 从 Terraform 直接声明 Incident

Incident 通常由 Monitor 自动创建,但它本质上也是普通资源——非常适合故障演练(game days)等场景:

resource "oneuptime_incident" "drill" { title = "DR drill" description = "Disaster recovery exercise" incident_severity_id = oneuptime_incident_severity.sev1.id current_incident_state_id = oneuptime_incident_state.mitigated.id }

(改编自 E2E 测试28-incident-crud。)

从 tests/28-incident-crud/main.tf 可以看到该资源更完整的可选属性:root_cause(根因分析)、is_visible_on_status_pageshould_status_page_subscribers_be_notified_on_incident_createdlabels等。

九、自定义 Probe(探针)

自定义 Probe 让你从自己的基础设施发起监控检查(例如覆盖私有网络或特定区域):

resource "oneuptime_probe" "eu_west" { key = "probe-eu-west-1" name = "EU West Probe" description = "Probe running in eu-west-1" probe_version = "1.0.0" should_auto_enable_probe_on_new_monitors = true }

(改编自 E2E 测试23-probe-crud。)

实现细节(见 tests/23-probe-crud/main.tf):

  • key是 Probe 的稳定标识(fixture 中通常拼接随机后缀避免碰撞);
  • probe_version早期曾以{"_type":"Version","value":"9.3.19"}的 JSON 对象形式返回,现已修复为直接回读纯版本字符串(对应 Issue #2228);
  • should_auto_enable_probe_on_new_monitors = true表示新建 Monitor 时自动启用该 Probe;
  • Probe 同样支持labels

十、源码级佐证:E2E 测试如何保证这些示例真实可用

本指南的所有示例都宣称「可直接复制」,依据在于仓库内的 Terraform Provider E2E 测试套件(E2E/Terraform/e2e-tests/README.md),它同时驱动Terraform 与 OpenTofu双引擎验证。每个测试目录(tests/XX-resource-name/)由main.tfvariables.tfverify.sh组成,覆盖了示例中提到的全部资源类型(如03-incident-severity04-incident-state12-status-page-domain23-probe-crud25-status-page-with-domain26-monitor-steps-basic28-incident-crud30-scheduled-maintenance-crud31-on-call-duty-policy-crud33-team-crud35-monitor-with-steps等)。

每个测试统一经历以下阶段:

  1. Init:预置 provider(使用 dev_override);
  2. Plan + Apply:创建资源;
  3. verify.sh:通过 API 校验资源真实存在且字段正确;
  4. 漂移闸门(drift gate)terraform plan -detailed-exitcode必须返回 0,确保二次 plan 无 diff;
  5. Update 阶段:若目录含update.tf,覆盖main.tf重新 apply 并再次校验无漂移;
  6. Import 往返terraform state rm后按 IDterraform import,再要求 plan 干净;
  7. Destroy + 删除校验:通过 API 确认资源确实被删除。

Fixtures 遵循两条硬性规则,也值得在你自己写配置时借鉴:

  • 使用静态名称,绝不用timestamp()/formatdate()作为资源参数(那会必然导致后续 plan 变脏);
  • 不用lifecycle { ignore_changes = [...] }掩盖漂移,服务端归一化的日期字段用固定的未来 RFC3339 时间戳,从而真正回归 provider 的语义日期相等逻辑。

此外,scripts/coverage-report.sh会对比生成 provider 声明的资源类型与实际测试覆盖的类型,并以 scripts/coverage-baseline.txt 作为下限门槛——覆盖率只能上升不能下降,这从流程上保证了文档示例对应的每个资源类型都有真实测试兜底。

十一、继续深入

  • Monitor Steps——monitor_steps完整 schema、criteria filter 语义与常见误区;
  • Importing Resources——把控制台(dashboard)里已创建的资源导入到这些 Terraform 模式中;
  • 各资源属性的完整字段参考:Terraform Registry 上oneuptime/oneuptimeProvider 的最新文档。

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询