nwarila-platform/github-terraform-framework
GitHub: nwarila-platform/github-terraform-framework
基于 Terraform 的 GitHub 仓库治理框架,通过声明式 YAML 和安全基线矩阵实现仓库、规则集和安全默认值的统一管理与合规验证。
Stars: 0 | Forks: 0
# github-terraform-framework
用于管理 GitHub 仓库、规则集、安全默认值以及共享账户级治理即代码的 Terraform 框架。
此框架是一个由 [github-terraform-runner](../github-terraform-runner) 使用的**根模块**。Runner 会将此仓库物化到其 `_workspace/` 目录中,通过 `backend_override.tf` 覆盖后端配置,并运行 `terraform init && terraform apply`。
## 版本控制与 CLI 锁定契约
此框架通过 [terraform/00-providers.tf](terraform/00-providers.tf) 中的 `required_version` 锁定一个**精确的** Terraform CLI 版本。下游消费者必须:
1. **通过 commit SHA 锁定框架**,而不是通过分支或标签。分支锁定会使得未审查的框架更改无声息地进入消费者端。
2. **在针对消费仓库的 PR 中审查框架更改**。当框架更新时(包括对 `required_version` 的任何更改),消费者需发起一个 PR 以更新锁定的 SHA。消费者端的 CI 将针对新的 SHA 运行。
3. **在本地和 CI 中匹配锁定的 Terraform CLI 版本**。框架仅针对一个 CLI 版本进行测试。版本不一致是一个错误,而不是警告。
如果 `required_version` 发生更改,框架侧的提交信息必须明确标记,以便下游 PR 能够捕获此 CLI 升级。
## 仓库 YAML schema
仓库定义存放于 `terraform/repos/public/*.yml` 和 `terraform/repos/private/*.yml` 中。允许的顶层键声明在 `local.allowed_repo_keys` ([terraform/30-locals.tf](terraform/30-locals.tf)) 中;未知的键(包括嵌套级别的键)会通过 `terraform_data.framework_validation` 导致 plan 失败。
### 约束
- **种子内容是分支管理所必需的。** 如果仓库设置了 `auto_init: false`,则它还必须配置 `template` 或 `fork` 源。否则,`github_branch_default` 将在 apply 阶段失败并出现 provider 级别的错误,因为没有可供重命名的默认分支。框架不会对此进行预验证——provider 报错即已足够。
- **不支持 `allow_forking`。** 该键在未知顶层键校验阶段就会被拒绝。该设置仅属于组织级别,且此框架目前未通过任何 provider 支持的资源对其进行管理;接受它将导致一个无声的空操作,这比拒绝它更糟。如果框架发展出明确的组织级别管理功能,则需重新审视此项。
- **`require_code_owner_review` 需要一个有效的 CODEOWNERS 来源。** 需在 YAML 中按仓库设置 `codeowners: |`(org 模式下必需),或者设置 `var.repo_default_codeowners`,亦或在个人账户模式(`github_is_organization = false`)下运行,以便框架自动合成 `* @`。CODEOWNERS 文件会被置备在默认分支上,并且规则集依赖于它先被成功应用。
## 认证模式
`github` provider 支持两种认证模式,通过 `var.github_auth_mode` 进行选择:
- `app` — GitHub App 安装。推荐用于企业级自动化。需要 `var.github_app_auth = { id, installation_id, pem_file }`。
- `token` — 经典或细粒度 PAT。仅用于紧急突破 / 初始化引导。需要 `var.github_token`。
`github_token` 和 `github_app_auth` 中必须且只能设置一个。配置错误会在任何资源被触及之前被 `terraform_data.framework_validation` 捕获。
有关**细粒度 PAT 权限矩阵**(每个受管资源所需的权限、环境上的 GET/PUT 不对称性,以及轮换流程),请参阅 [`docs/reference/github-pat-permissions.md`](docs/reference/github-pat-permissions.md) 和 [`docs/how-to/setup-github-pat.md`](docs/how-to/setup-github-pat.md)。
## 文档
本仓库遵循 [Diátaxis](https://diataxis.fr) 框架,该框架由 [ADR-0002](docs/decision-records/org/0002-adopt-diataxis-documentation-framework.md) 在全组织范围内采用。长篇文档位于 [`docs/`](docs/) 下,分为参考、指南和解释四个象限。ADR 位于 [`docs/decision-records/`](docs/decision-records/),遵循 [ADR-0001](docs/decision-records/org/0001-use-architecture-decision-records.md),分为 `org/`(nwariliaplatform 基线的镜像)和 `repo/`(特定于仓库,当前为空)。
请从 [`docs/README.md`](docs/README.md) 开始查看索引。当前的 `DESIGN.md` 早于 ADR-0002,并被推迟至后续的分类重新归档阶段处理。
## 安全基线
该框架将 GitHub 安全特性建模为针对**预期基线**的**按可见性划分的能力矩阵**:
- `var.github_security_capabilities` — 所有者计划支持的功能,按可见性(`public`、`private`、`internal`)声明。完全必填:每种可见性都必须包含每一项功能。默认与 GitHub Free 匹配。
- `var.security_baseline` — 框架期望按可见性启用的功能。默认为带有倾向性的企业级基线。
- `var.security_baseline_mode` — `strict` 模式会在基线要求某项功能但能力不支持时导致 plan 失败;`compatibility` 模式会通过 `check` 块发出建议性预览,并保持不受支持的功能处于非托管状态。默认值为 `compatibility`,以实现无破坏性的推广。在修复任何预览警告后,在下一个标记版本中切换为 `strict`。
这两个变量均遵循 Packer-coherence 风格:完全类型化、完全必需、零 `optional()`。
## 回归测试
该框架附带位于 [terraform/tests/](terraform/tests/) 的 `terraform test` 测试套件,可针对一组 fixture YAML 目录执行验证层测试。测试通过 `mock_provider` 块脱机运行——无需真实的 GitHub API 调用,也无真实状态。
**运行测试套件:**
```
cd terraform
terraform init -backend=false
terraform test
```
**测试套件覆盖范围:**
- **正向用例:** `good-minimal` — 断言干净 YAML fixture 的 `output.validation_errors` 为空。
- **未知键拒绝:** 顶层拼写错误(`descripton`)、嵌套拼写错误(`actions.enable`)以及被故意拒绝的 `allow_forking`。
- **重复的仓库键:** 在 `public/` 和 `private/` 中声明相同仓库名称必须导致 plan 失败,而不是无声地折叠。
- **不支持的推送规则集:** 公共仓库上的推送目标规则(或在 `github_supports_push_rulesets=false` 时的任何可见性)必须导致 plan 失败。
- **认证配置:** 未提供 token 的 token 模式、未提供 app_auth 的 app 模式,以及同时设置两种来源,均必须失败。
- **安全基线:**
- 具有能力差距的严格模式会导致 plan 失败。
- 具有相同差距的兼容性模式不会导致 plan 失败,但会填充 `output.security_capability_gap_preview`,以便操作员了解切换到严格模式会破坏什么。
**添加新用例:**
1. 在 `terraform/tests/fixtures//` 下创建一个新的 fixture 目录,并包含带有 YAML 文件的 `public/` 和/或 `private/` 子目录。
2. 向 [terraform/tests/validation.tftest.hcl](terraform/tests/validation.tftest.hcl) 添加一个 `run` 块,设置 `repo_yaml_path = "tests/fixtures/"`,并断言 `output.validation_errors`(正向用例),或使用 `expect_failures = [terraform_data.framework_validation]`(针对全局错误的反向用例)/ 特定的资源地址(针对每个资源前置条件的反向用例)。
3. 运行 `terraform test` 以验证新用例通过。
由于 fixture 路径是通过 `var.repo_yaml_path` 选择的(默认为 `repos`),生产代码路径保持不变——测试仅仅是替换了该变量。
## 验证分层
- **全局不变量**(重复的仓库键、未知的嵌套 YAML 键、不支持的推送规则集、认证配置、严格模式下的能力差距)聚合到 `local.global_validation_errors` 中,并由 `terraform_data.framework_validation` 上的单一前置条件强制执行。
- **每个资源的不变量**(可见性枚举、规则集强制执行、env wait_timer、actions allowed_actions 枚举、需要时存在的 CODEOWNERS)作为 `lifecycle.precondition` 块位于相关资源上,因此错误消息会指向特定的资源地址。
- **一个有意的建议性例外:** `check "security_baseline_preview"` 在兼容模式下发出列举能力差距的警告。这是严格模式切换前的预览,而不是一个强制执行点。
标签:DNS解析, ECS, GitOps, HCL, IT基础设施, Terraform, 代码治理, 共享治理, 合规管理, 存储库管理, 安全可观测性, 安全默认配置, 开源项目, 版本控制, 特权提升, 自动化运维, 自动化部署, 规则集管理