Teleport Terraform Provider:从源码构建、测试到以基础设施即代码管理 Teleport 资源的完整指南
网络安全认证鉴权运维后端【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址https://gitcode.com/gh_mirrors/tel/teleport点击查看免费下载Teleport Terraform Provider 是 Teleport 官方提供的基础设施即代码IaC方案它让 Terraform 用户可以通过声明式的.tf文件创建、更新、导入和删除 Teleport 中的动态资源用户、角色、访问列表、数据库、Kubernetes 集群、加入令牌等。本文以仓库中 integrations/terraform/README.md 为骨架结合 provider 源码、构建脚本 与测试套件完整讲解环境准备、插件编译安装、测试运行、Schema 再生成、本地示例演练以及 Provider 内部架构读完你可以独立完成 Provider 的开发环境搭建、本地端到端验证与二次开发。Terraform Provider 在 Teleport 中的定位Teleport 允许管理员通过动态资源dynamic resources管理集群配置而 Terraform Provider 正是这套机制的 IaC 前端它在 Terraform 与 Teleport Auth/Proxy 服务之间建立一条经过认证的通道把teleport_*资源转换为 Teleport API 调用。从 provider/provider.go 的资源注册表可以看到当前 Provider 同时提供资源resource与数据源data source两类入口例如teleport_user、teleport_role、teleport_app、teleport_database、teleport_kube_cluster、teleport_provision_token、teleport_access_list、teleport_lock、teleport_login_rule等数据源用于从 Teleport 读取信息资源用于在 Teleport 中创建与维护对象。Provider 要求目标集群版本不低于15.0.0-0见 provider.go 中的minServerVersion常量并在Configure阶段通过client.Ping校验版本兼容性。开发环境准备按照 integrations/terraform/README.md 的 Development 一节搭建开发环境需要两个前置依赖protobuf 编译器用于从.proto文件生成 Terraform schema 代码。官方安装指引为grpc.io/docs/protoc-installation/编译器的存在是make gen-tfschema能够运行的前提。Terraform CLI v1.1.0Provider 的测试与本地演练都会调用terraform命令因此要求本机安装可用的 Terraform。也可以使用版本管理器tfenv安装指定版本在 Apple M1arm64上需要通过环境变量指定架构例如TFENV_ARCHarm64 tfenv install 1.1.6除此之外源码编译本身还需要 Go 工具链与仓库go.mod声明的版本一致以及make。编译时使用CGO_ENABLED0静态编译这一点在 Makefile 中有明确注释HashiCorp Cloud 不支持运行依赖 CGO 的 Provider因此产物是纯静态二进制。构建并安装 Provider 插件在 integrations/terraform 目录下执行make install该目标依赖build与install两个动作。build使用GOWORKoff关闭 workspace 模式、通过 build tagterraformprovider编译出terraform-provider-teleport可执行文件install则由 install.mk 负责把它安装到 Terraform 的本地插件目录~/.terraform.d/plugins/terraform.releases.teleport.dev/gravitational/teleport/$(VERSION)/$(TERRAFORM_ARCH)/其中VERSION由 install.mk 通过go run ../hack/get-version/get-version.go自动从仓库版本推导TERRAFORM_ARCH形如linux_amd64、darwin_arm64。这个目录结构是 Terraform 从terraform.releases.teleport.dev/gravitational/teleport源解析 Provider 时必须遵循的布局因此make install之后配置了相同source的 Terraform 工程即可直接使用本地构建版本。运行测试套件make testmake test会先执行install然后通过gotestsum运行 testlib 下的全套测试并把 JUnit 报告写到test-logs/目录。执行前会检查本机是否存在 Terraform v1.4不存在时给出提示Makefile 中的检查逻辑。测试以资源为单位组织例如 user_test.go、role_test.go、provision_token_test.go、access_list_test.go每个资源的测试都搭配testlib/fixtures/下的.tffixture 文件如user_0_create.tf、user_1_update.tf等以创建 → 更新 → 校验 plan 稳定 → 导入 → 数据源读取 → 删除的完整生命周期验证资源行为。测试入口分为 OSS 与 Scoped Resources 两种模式见 terraform_oss_test.go其中TestTerraformOSSWithCache会以开启缓存CacheEnabled的 AuthServer 运行用于验证 Provider 对 Teleport 端缓存读一致性的适配。需要聚焦单个用例时可以通过TEST_ARGS指定make test TEST_ARGS-run TestTerraformOSS/TestAppProvider 内部架构架构设计详见 integrations/terraform/ARCHITECTURE.md。Provider 基于 HashiCorp 的 Terraform Plugin Framework 实现核心思想是把可复用的 Terraform 生命周期机制与资源相关的 Teleport API 调用分离从而让新增资源只需少量手写代码。主要目标包括让所有资源的 Terraform 生命周期行为保持一致复用 integrations/terraform/tfschema 中由代码生成的 schema 与转换函数隔离 Teleport API 细节与 Terraform Framework 细节允许传统生成式资源与新的通用驱动generic driver资源在迁移期间共存。代码包布局provider/provider.goProvider 入口负责解析配置、创建认证的 Teleport API 客户端、暴露重试参数并注册资源与数据源。GetResources/GetDataSources以legacy.ResourceTypes()为底再插入通用驱动资源这样被迁移的资源可以覆盖旧注册而不改变对外暴露的 Terraform 资源名。provider/internal/tfdriver通用资源/数据源驱动是生命周期机制的实现地包含ResourceType[T, I]、DataSourceType[T, I]、ResourceClient[T, I]Get/Create/Upsert/Delete、DataSourceClient[T, I]Get、ResourceCodec[T]、IdentifierPolicy[T, I]、ResourceNormalizer[T]等类型。provider/internal/resources资源描述符把 tfschema 生成的 schema、API 客户端、标识符策略、normalizer 与 revision 提取函数绑定在一起。provider/internal/teleport把*client.Client适配为tfdriver接口的薄封装层只关心 Teleport API 调用不感知 Terraform 的 plan/state/schema。provider/internal/legacy早于通用驱动的一批生成式资源实现及其注册表。integrations/terraform/tfschema由protoc-gen-terraform生成的 schema 与拷贝函数新旧两类资源共用。驱动层统一的资源生命周期从 resource.go 可以看到通用驱动把以下行为固化为模板Create 前置检查创建前先按标识符Get若资源已存在于 Teleport 且非单例资源则报错并提示要么用tctl rm删除要么用terraform import导入现有状态Create/Update 前的规范化调用资源的 Normalizer例如CheckAndSetDefaults、ForceKind实现见 normalize.go在调用 API 前补齐默认值、强制 kind 等不变量创建后的最终一致性重试写入后用指数退避轮询Get直到资源可读更新后的 revision 收敛当资源描述符提供ResourceRevision一般取metadata.revision时Update 会持续轮询直到远端 revision 发生变化从而保证 Terraform 的写入真正生效对关闭了 Auth 缓存、读最终一致的部署尤其重要Read 的远端已删除则移除状态Get返回 NotFound 时调用resp.State.RemoveResourceImport 状态解析与填充通过IdentifierPolicy.FromImportID解析导入 ID 并回填状态统一的诊断封装通过provider/internal/tfdiag输出一致的错误信息。标识符体系资源唯一标识符定义在 identifier.go它决定 Terraform 资源如何映射到 Teleport 集群中的对象同时决定terraform import时使用的 ID 格式NameIdentifier大多数以metadata.name唯一标识的资源导入 ID 即资源名ScopeQualifiedNameIdentifier以(name, scope)唯一标识的作用域资源导入 ID 为scope::nameCompositeIdentifier由两部分标识的资源导入 ID 形如prefix/name例如 Access List 的成员 Access List 名 成员名SingletonIdentifier固定标识的集群单例资源如 Auth 偏好、集群网络配置。更新 Provider重新生成 Schema当 Teleport 的 API 定义.proto文件发生变化时需要重新生成 Terraform schema 与 Provider 代码。在 integrations/terraform 目录执行make gen-tfschema该目标会调用protoc逐个读取 Makefile 中列出的protoc-gen-terraform-*.yaml配置把../../api/proto下的 proto 文件例如teleport/legacy/types/types.proto、teleport/accesslist/v1/accesslist.proto、teleport/workloadidentity/v1/resource.proto、teleport/loginrule/v1/loginrule.proto等转换为tfschema下的*_terraform.go文件随后用go run ./gen/main.go重新生成 legacy 代码。每个protoc-gen-terraform-*.yaml都是 schema 生成规则的配置源以 protoc-gen-terraform-example.yaml 为例它声明了types要导出为 Terraform 的顶层类型injected_fields注入id计算字段供集成测试使用Provider 本身不用exclude_fields排除的字段如metadata.id、metadata.namespace、metadata.revision资源以 name 作为唯一标识computed_fields/required_fields标记 Computed 与 Required 的字段plan_modifiers例如Metadata.name上挂RequiresReplace()资源名变更时强制重建custom_types时间戳、Duration 等自定义类型映射validators例如Metadata.expires必须指向未来时间。若 schema 发生变化导致公开文档需要同步还需重新渲染文档make docsmake docs的实现见 gen/docs.sh它在临时目录用terraform providers schema -json导出 Provider schema调用定制版tfplugindocs渲染 Markdown再转换为.mdx并复制到 docs/pages/reference/infrastructure-as-code/terraform-provider。渲染模板位于 templates如 resources.md.tmpl默认模板会尝试包含examples/resources/teleport_资源名/resource.tf示例文件。本地端到端演练README 提供了完整的最小闭环演练流程以下按步骤展开全部命令在 integrations/terraform 目录下执行。1. 启动 Teleportteleport start本地启动一个 Teleport Auth Proxy 组合实例作为 Provider 的接入目标。2. 创建 Terraform 用户与角色tctl create example/terraform.yaml tctl auth sign --formatfile --userterraform --out/tmp/terraform-identity --ttl10h第一步创建名为terraform的用户及其角色第二步以tctl auth sign签发出有效期 10 小时的身份文件identity file到/tmp/terraform-identity。身份文件是 Provider 推荐的连接凭据形态它同时支持经 Proxy Service443/3080 端口与 Auth Service3025 端口连接。注意仓库当前示例目录 examples/provider 提供的是 Provider 声明示例provider.tf 面向自托管、provider-cloud.tf 面向 Teleport Enterprise 托管租户以及 scoped 场景的角色模板 scoped-provider-role.yaml。README 中提到的example/terraform.yaml需结合你所用的 Teleport 版本按需准备其作用等价于为该用户授予管理动态资源的角色权限。3. 准备main.tfcp example/main.tf.example example/main.tfREADME 指出上一步导出的身份文件路径为/tmp/terraform-identity若你选择了其他位置需要同步修改main.tf。典型的最小配置形如terraform { required_providers { teleport { source terraform.releases.teleport.dev/gravitational/teleport version ~ 15.0 } } } provider teleport { addr proxy.example.com:443 # 或 auth.example.com:3025 identity_file_path terraform-identity/identity }Provider 的可用配置项在 provider.go 的GetSchema中定义除addr与identity_file_path外还包括cert_path/cert_base64、key_path/key_base64、root_ca_path/root_ca_base64TLS 密钥直连 Auth 方式、profile_name/profile_dir复用 tsh profile、identity_file/identity_file_base64、insecure跳过代理证书校验不推荐生产使用、retry_base_duration默认1s、retry_cap_duration默认5s、retry_max_tries默认10、dial_timeout_duration默认30s以及原生 MachineID 接入所需的join_method、join_token、audience_tag、gitlab_id_token_env_var、kubernetes_token_path、scoped。每个配置项都可以通过同名环境变量覆盖例如TELEPORT_ADDR、TELEPORT_IDENTITY_FILE等常量定义见api/constants包。addr必须是host:port格式否则 Provider 会直接报错validateAddr。4. 复制示例资源定义cp example/user.tf.example example/user.tf cp example/role.tf.example example/role.tf cp example/provision_token.tf.example example/provision_token.tf这些示例资源的字段结构与仓库测试夹具一致可以参考 testlib/fixtures 下的真实用例例如 user_0_create.tfresource teleport_user test { version v2 metadata { name test expires 2035-10-12T07:20:50Z labels { example yes } } spec { roles [terraform-provider] traits { logins1 [example] logins2 [example] } oidc_identities [{ connector_id oidc username example }] github_identities [{ connector_id github username example }] saml_identities [{ connector_id saml username example }] } }role_0_create.tf 展示了角色资源的最小形态resource teleport_role test { version v8 metadata { name test } spec { allow { logins [anonymous] } } }provision_token_0_create.tf 则展示了加入令牌资源resource teleport_provision_token test { version v2 metadata { name test expires 2038-01-01T00:00:00Z labels { example yes } } spec { roles [Node, Auth] } }README 特别提醒部分资源需要前置步骤才能生效例如 Provision Token 的 IAM 变体、Kubernetes 集群、集成类资源等首次演练建议从用户、角色这类无外部依赖的资源开始。5. 应用变更make applymake apply见 Makefile等价于terraform -chdirexample init terraform -chdirexample apply -auto-approveinit会从本地插件目录解析terraform.releases.teleport.dev/gravitational/teleport源apply -auto-approve免确认执行。若此前执行过make install且main.tf的版本约束与本地一致Terraform 会直接命中本地构建的插件。6. 修改并重新应用make reapply修改任意.tf文件后执行。reapply只执行terraform apply不重新 init保留交互确认Terraform 会计算 plan 并只对变更字段下发Upsert。得益于驱动层基于metadata.revision的收敛轮询见上文更新后的 revision 收敛apply会一直等到 Teleport 侧真正应用变更后才把新状态写入 state。7. 清理make destroy等价于terraform destroy -auto-approve删除 Terraform 管理的全部资源并清理 state。如何为 Provider 贡献新资源新资源开发建议直接使用通用驱动legacy 生成器已弃用待存量资源全部迁移后移除完整流程见 integrations/terraform/CONTRIBUTING.md要点如下生成 schema 代码若 tfschema 中已有所需 schema 则直接复用否则新增/修改protoc-gen-terraform-*.yaml、在Makefile的gen-tfschema中补充protoc调用然后运行make gen-tfschema。编写 API 适配层在provider/internal/teleport/resource.go中实现tfdriver.ResourceClient[T, I]Get/Create/Upsert/Delete或DataSourceClient[T, I]Get该层只做 Teleport API 调用不感知 Terraform 概念若更新需要保留服务端自有字段可实现tfdriver.UpdatePreparer[T]。编写资源描述符在provider/internal/resources/resource.go中把 API 适配层、schema/转换函数、标识符策略、normalizer如CheckAndSetDefaults、ForceKind与ResourceRevision组合成ResourceType[T, I]。标识符策略需按资源特性选择按名导入用NameIdentifierPolicy作用域资源用ScopeQualifiedNameIdentifierPolicy双段 ID 用CompositeIdentifierPolicy单例用SingletonIdentifierPolicy。注册资源在 provider.go 的GetResources/GetDataSources的 generic 映射中加入teleport_name: resources.NewXxxResourceType()注意资源只允许在一个地方注册generic 映射或 legacy 注册表。补充测试与夹具在testlib/fixtures/添加resource_0_create.tf、resource_1_update.tf必要时加resource_data_source.tf在testlib/resource_test.go中覆盖 create/read/update/delete、plan 稳定性、import、data source 与敏感字段不泄漏到 state 等行为。更新文档涉及公开 surface 变化时运行make docs。若需要为某资源定制文档可将 templates/resources.md.tmpl 复制为templates/resources/resource_name.md.tmpl用tffile函数引用示例文件并追加自定义说明。对于存量 legacy 资源的迁移CONTRIBUTING.md 强调兼容性优先先记录现有资源名、schema 路径与 Required/Computed/Sensitive 标记、导入 ID 格式、create/update 方法选择、默认值与强制 kind 行为、secret 字段处理、重试行为等再迁移注册、保持公开 Terraform 类型名不变并围绕旧导入 ID 可导入、旧 fixture 应用不触发意外替换、plan-only 检查等场景强化测试。RFD 153 类资源还需遵循 rfd/0153-resource-guidelines.md 的资源规范。结语Teleport Terraform Provider 通过生成式 schema 通用驱动的双层设计把 Terraform 生命周期的一致性与 Teleport API 的多样性解耦日常使用者只需要make install后按 README 的七步走完本地闭环即可上手管理动态资源开发者则可以从 ARCHITECTURE.md 理解驱动边界按 CONTRIBUTING.md 的六步流程低门槛地贡献新资源。本文涉及的关键文件都保留在当前仓库中可继续深入阅读构建与安装integrations/terraform/Makefile、integrations/terraform/install.mkProvider 入口与配置项integrations/terraform/provider/provider.go生命周期驱动integrations/terraform/provider/internal/tfdriver/resource.go标识符体系integrations/terraform/provider/internal/tfdriver/identifier.goSchema 生成配置示例integrations/terraform/protoc-gen-terraform-example.yaml测试夹具integrations/terraform/testlib/fixtures文档生成integrations/terraform/gen/docs.sh 与 integrations/terraform/templates赞分享网络安全认证鉴权运维后端【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址https://gitcode.com/gh_mirrors/tel/teleport点击查看免费下载相关推荐yajl-objc vs 原生JSON库为什么它是Objective-C项目的最佳选择yajl objc vs 原生JSON库为什么它是Objective C项目的最佳选择 在Objective C开发中JSON处理是日常任务的重要组成部分IGLDropDownMenu与CocoaPods集成从安装到部署的完整流程IGLDropDownMenu与CocoaPods集成从安装到部署的完整流程 IGLDropDownMenu是一款为iOS应用开发的下拉菜单组件以其精美的动移动开发UI库/组件Terraform完整指南如何用基础设施即代码快速管理云资源Terraform完整指南如何用基础设施即代码快速管理云资源 Terraform是一款流行的开源工具用于构建、变更和版本化云基础架构。作为基础设施即代码IIaCCLI基础设施云原生DevOps创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考