Teleport 通过 Terraform 在 Azure 管理组中发现虚拟机:management-group 示例完全指南
网络安全认证鉴权运维后端【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址https://gitcode.com/gh_mirrors/tel/teleport点击查看免费下载导读在拥有大量 Azure 订阅的企业环境中逐个订阅为 Teleport 配置自动发现既繁琐又难以维护。本文以当前仓库中 Azure Discovery Terraform 模块的 management-group 示例 为主体完整讲解如何利用 Azure管理组Management Group这一层级结构一次性配置 Teleport 跨所有可见订阅自动发现并纳管虚拟机VM。读完本文你将掌握management-group 示例的完整main.tf结构与每个参数的含义、通配符订阅匹配器与租户级 allow rule 的原理、模块底层如何推导角色作用域与最小权限集以及如何用terraform plan/apply和tctl验证整个链路。一、示例要解决什么问题examples/management-group是 Azure Discovery 模块的官方示例之一另一个是 single-subscription 示例。两者的区别在于发现资源的作用域scopesingle-subscription只发现当前 Azure 订阅subscription内、符合标签条件的虚拟机management-group以管理组或 Tenant / 根管理组为作用域配合通配符订阅匹配器subscriptions [*]发现该管理组下所有可见订阅中符合条件的所有虚拟机一次性完成企业级规模化纳管。该示例的定位声明只有一句话Configure Teleport to discover resources in an Azure management group.README 首段但背后涉及 Azure 托管身份、OIDC 联合凭据、自定义角色、Teleport 动态发现配置等多层资源的编排下面逐步拆解。二、环境与版本要求示例的versions.tfexamples/management-group/versions.tf声明了运行前必须满足的版本基线组件版本要求说明terraform 1.5.7Terraform CLI 最低版本azurerm provider 4.0HashiCorp Azure 资源管理器 Providerhttp provider 3.0用于探测 Teleport Proxy 的/webapi/find接口teleport provider 18.7.6来自terraform.releases.teleport.dev/gravitational/teleport的官方 Provider注意 Teleport Provider 的source是terraform.releases.teleport.dev/gravitational/teleport与常见的registry.terraform.io不同terraform init时会从 Teleport 官方发布源拉取。另外在运行任何 Terraform 命令之前还需要两个前置条件见模块 README 的 Prerequisites 一节安装并配置 Teleport Terraform Provider确保执行环境能通过 Provider 与你的 Teleport 集群Proxy通信被发现的每台 Azure 虚拟机都必须已分配托管身份且该身份至少具备Microsoft.Compute/virtualMachines/read权限Teleport Discovery Service 才能扫描到它。三、示例 main.tf 逐段精读示例的全部逻辑集中在 examples/management-group/main.tfvariables.tf为空示例的 Inputs 声明为 No inputs所有配置都内联在main.tf中。我们按代码顺序逐段分析。3.1 公共标签与当前客户端信息locals { apply_azure_tags { origin example } apply_teleport_resource_labels { origin example } } data azurerm_client_config current {}apply_azure_tags/apply_teleport_resource_labels传递给模块给本示例创建的 Azure 资源额外打上originexample标签、给 Teleport 资源额外打上originexample标签便于识别示例产物data azurerm_client_config current读取执行 Terraform 时所用 Azure 凭证的tenant_id、subscription_id等信息。在 management-group 场景中它的tenant_id被用作azure_management_group_id即以租户根管理组为角色作用域。3.2 示例资源组resource azurerm_resource_group example { name teleport-discovery location eastus tags local.apply_azure_tags }模块创建的所有 Azure 资源托管身份、角色定义等都放入这个名为teleport-discovery、位于eastus的资源组。它由示例自行创建而模块内的azure_resource_group_name变量要求传入的是已存在的资源组名称因此示例将azurerm_resource_group.example.name传入模块。3.3 模块调用管理组作用域的核心配置module azure_discovery { source ../.. teleport_discovery_group_name cloud-discovery-group teleport_proxy_public_addr example.teleport.sh:443 azure_resource_group_name azurerm_resource_group.example.name azure_managed_identity_location azurerm_resource_group.example.location azure_management_group_id data.azurerm_client_config.current.tenant_id azure_matchers [ { types [vm] subscriptions [*] tags { TeleportEnroll [true] } } ] apply_azure_tags local.apply_azure_tags apply_teleport_resource_labels local.apply_teleport_resource_labels teleport_installer_script_name teleport_installer.example.metadata.name }这是整个示例的“题眼”几个关键点source ../..指向模块根目录 integrations/terraform-modules/teleport/discovery/azure即从示例目录上溯两级。这与 README 中 Modules 表 记录的azure_discoverySource:../..一致。teleport_discovery_group_name cloud-discovery-groupTeleport Discovery Service 的发现组名。模块 README 明确说明发现配置要生效该名称必须与至少一个 Discovery Service 实例配置的discovery_group匹配Teleport Cloud 集群必须使用cloud-discovery-group见 variables.tf 中该变量的注释。teleport_proxy_public_addr example.teleport.sh:443Proxy 公网地址格式为host:port不允许带 URL scheme。模块在main.tf中会据此拼出https://${...}并调用{proxy}/webapi/find探测集群信息见 模块 main.tf 的teleport_proxy_public_url与data.http.teleport_ping及 L35-L39。variables.tf里还内置了两条 validation禁止出现://、必须包含:。azure_management_group_id data.azurerm_client_config.current.tenant_id把**租户 IDTenant ID**当作管理组 ID 传入。示例注释说得非常清楚main.tf L26-L31传管理组 ID 或租户 ID 都可以传租户 ID 会使用根管理组作用域Root management group scope作为托管身份角色的作用域在根作用域上执行操作需要提升权限Elevated access即 Azure 的 Global Administrator 提权操作。azure_matchers使用通配符订阅subscriptions [*]表示发现该作用域下所有可见订阅中的 VM并按标签TeleportEnrolltrue过滤。这正是 management-group 场景的标志性写法——*通配符只允许单独出现在 subscriptions 列表中variables.tf 的 validation 强制了这一约束。3.4 可选把角色分配限制到子作用域示例中有一段被注释掉的配置main.tf L33-L41# azure_role_assignment_scopes [ # /providers/Microsoft.Management/managementGroups/child-mg, # /subscriptions/00000000-0000-0000-0000-000000000000, # ]它的语义是如果不希望托管身份在整棵管理组树或根作用域上都拥有角色可以显式指定角色分配的作用域列表。此时通配符订阅匹配器只会发现这些被分配作用域可见的订阅而azure_management_group_id仅用于角色定义的 assignable scope。这与模块 azure_role_definition.tf 中azure_role_assignment_scopes coalescelist(...)的推导逻辑一一对应显式 scopes 优先其次管理组作用域最后回退到按 matcher 中的订阅列表逐个推导。测试用例role_assignment_scopes_with_management_group_assignable_scopetests/main.tftest.hcl验证了这一点当azure_role_assignment_scopes指定child-mg、azure_management_group_id为parent-mg时角色定义 scope 是parent-mg但角色只分配给child-mg。3.5 自定义 Installer 脚本示例最后创建了一个teleport_installer资源main.tf L64-L103并把它的名字custom-azure-installer-example传给模块的teleport_installer_script_nameresource teleport_installer example { version v1 metadata { name custom-azure-installer-example description Example Teleport Installer labels local.apply_teleport_resource_labels } spec { script EOF #!/usr/bin/env sh set -eu INSTALL_SCRIPT_URLhttps://{{.PublicProxyAddr}}/scripts/install.sh ... sudo -E $TELEPORT_BINARY install autodiscover-node --public-proxy-addr{{.PublicProxyAddr}} --teleport-package{{.TeleportPackage}} --repo-channel{{.RepoChannel}} --auto-upgrade{{.AutomaticUpgrades}} --azure-client-id{{.AzureClientID}} $ EOF } }要点注释特别说明这个 custom 脚本其实就是默认安装脚本可用tctl get installer/default-installer查看把它复制出来改造成自定义版本是为了演示如何定制 Discovery Service 下发到 VM 的安装命令脚本中的{{.PublicProxyAddr}}、{{.TeleportPackage}}、{{.RepoChannel}}、{{.AutomaticUpgrades}}、{{.AzureClientID}}是Go 模板占位符Discovery Service 在实际下发时会替换为真实值关键动作是teleport install autodiscover-node它让被发现的 VM 以azure join 方式安装并注册为 Teleport Node模板中$${TELEPORT_INSTALL_SUFFIX:-}使用了转义的$$写法避免与 Terraform 自身的插值语法冲突。四、模块底层管理组作用域如何落地模块位于 integrations/terraform-modules/teleport/discovery/azure由 5 个资源文件组成。management-group 示例的配置会真实触发以下资源链见模块 README 的资源清单。4.1 托管身份与 OIDC 联合凭据azure_managed_identity.tfazure_managed_identity.tf 创建azurerm_user_assigned_identity.teleport_discovery_service用户分配的托管身份Discovery Service 用它认证到 Azure APIazurerm_federated_identity_credential.teleport_discovery_service联合身份凭据在 Azure 与 Teleport 集群之间建立信任——它把托管身份的信任方issuer设为 Teleport Proxy 的 OIDC 地址从teleport_proxy_public_addr推导subject 固定为teleport-azureaudience 为api://AzureADTokenExchange。这意味着托管身份可以用 Teleport Proxy 签发的 OIDC 令牌换取 Azure 访问令牌。4.2 自定义角色与按作用域分配azure_role_definition.tfazure_role_definition.tf 是 management-group 语义的“心脏”azure_management_group_scope把azure_management_group_id规范化为/providers/Microsoft.Management/managementGroups/id形式的 Azure 作用域路径若传入的已是完整路径则原样使用azure_role_assignment_scopes按“显式 scopes 管理组作用域 matcher 订阅列表”的优先级推导角色分配位置角色权限role_actions至少包含Microsoft.Resources/subscriptions/read当 matcher 类型含vm时追加 VM 相关的最小权限集如Microsoft.Compute/virtualMachines/read、runCommands/read、runCommands/write等保证 Discovery Service 既能扫描 VM 又能通过 Run Command 在 VM 上执行安装脚本一个值得注意的 precondition如果azure_role_assignment_scopes包含多个管理组作用域则必须显式设置azure_management_group_id因为角色定义的 assignable scope 只能有一个见 L60-L70。测试multiple_management_group_assignments_without_azure_management_group_id_error专门验证了这个失败路径tests/main.tftest.hcl L307-L322azurerm_role_assignment通过for_each为每个推导出的作用域执行角色分配。4.3 发现配置通配符订阅的强约束teleport_discovery_config.tfteleport_discovery_config.tf 生成 Teleport 集群内的动态资源teleport_discovery_config其中spec.azure由 matcher 转换而来每个 matcher 会被合并进install_paramsjoin_methodazure、join_token、script_name以及integration当使用 OIDC 集成时有一个针对 management-group 场景的关键 precondition使用通配符*订阅匹配器时必须设置azure_management_group_id或azure_role_assignment_scopes否则 plan 直接报错L53-L62。测试discovery_config_subscription_wildcard_missing_scopes_error验证了这一点tests/main.tftest.hcl L221-L232。这也解释了为什么示例必须传入azure_management_group_iddepends_on保证发现配置在集成资源就绪后才创建避免 Discovery Service 因权限尚未生效而空转约 5 分钟。4.4 OIDC 集成teleport_integration.tfteleport_integration.tf 创建teleport_integrationsub_kindazure-oidc把 Azure 的client_id托管身份的 client ID与tenant_id存进 Teleport 集群Discovery Service 据此代表托管身份执行 Azure OIDC 联合认证。它同样通过depends_on等待联合凭据和角色分配完成。4.5 加入令牌租户级 allow ruleteleport_provision_token.tfteleport_provision_token.tf 创建teleport_provision_tokenjoin_methodazure、roles[Node]这是被发现的 VM 加入集群的凭证。在 management-group 通配符订阅场景下其spec.azure.allow规则的生成逻辑非常关键对含*的 matcher生成按租户tenant限定的 allow rulesubscription null、tenant 当前租户 ID因为订阅不可枚举只能用租户范围约束对显式订阅的 matcher生成按 subscription可选 resource_groups限定的规则如果显式设置了teleport_provision_token_allow_rules则完全采用自定义规则。测试discovery_config_subscription_wildcardtests/main.tftest.hcl L234-L259断言management-group 模式下令牌恰好包含 1 条 allow rule 且tenant等于 mock 的租户 ID同时角色分配发生在管理组作用域。wildcard_and_subscription_matchersL405-L438则验证通配符与显式订阅混用时两条规则并存、各自限定方式正确。另一个约束当create_azure_managed_identity false使用外部托管身份且使用通配符订阅时必须显式提供teleport_provision_token_allow_rulesL60-L65因为此时模块无法获知租户 ID 来自动生成租户规则。五、从示例到落地操作步骤与验证5.1 准备与执行在示例目录 integrations/terraform-modules/teleport/discovery/azure/examples/management-group 下操作# 1. 初始化拉取 azurerm/http/teleport provider terraform init # 2. 预览将要创建的 Azure 与 Teleport 资源 terraform plan # 3. 应用 terraform apply应用前请务必确认执行 Terraform 的 Azure 身份具备在根管理组作用域执行角色分配的权限否则需要 Azure 全局管理员先做提权操作详见示例注释指向的 Azure 文档teleport_proxy_public_addr已替换为真实 Proxy 地址目标 VM 已打上TeleportEnrolltrue标签并分配了带读取权限的托管身份。5.2 用 tctl 验证结果模块的 Outputs 文档 给出了三条验证命令# 查看动态发现配置discovery_group、azure matchers 等 tctl get discovery_config/name # 查看 Azure OIDC 集成详情也可在 Web UI 的 Zero Trust Access Integrations 查看 tctl get integrations/name # 查看允许 Azure 节点加入的 provision token tctl get token/name其中资源名默认带随机后缀模块用random_id生成 4 字节 hex 后缀并追加到各类资源名后见 模块 main.tf L26-L29可通过terraform output azure_discovery拿到示例模块的所有输出示例 outputs.tf 原样透出了module.azure_discovery。如果不想用随机后缀可将各*_use_name_prefix变量设为false并使用精确名称测试name_suffix_exact验证了这一行为tests/main.tftest.hcl L531-L565。5.3 自动化测试佐证模块自带的 Terraform Test 套件 tests/main.tftest.hcl 覆盖了 management-group 模式下的核心行为可作为你修改配置后的回归验证手段create false时不创建任何资源L86-L131use_oidc_integration false时不创建联合凭据和集成且发现配置不再引用 integrationL133-L158通配符订阅缺少作用域配置时 plan 失败L221-L232多管理组作用域 显式azure_management_group_id时角色定义与分配的行为L324-L353。运行方式cd integrations/terraform-modules/teleport/discovery/azure terraform test六、常见参数速查management-group 场景结合模块 variables.tf 与示例用法将 management-group 场景最常用的参数整理如下参数类型/默认值management-group 场景建议azure_management_group_idstring默认null传管理组 ID 或租户 ID使用通配符订阅时必填之一azure_role_assignment_scopeslist(string)默认[]可选用于把角色分配收窄到子管理组/订阅设置后azure_management_group_id只作角色定义的 assignable scopeazure_matchers对象列表必填subscriptions [*]实现全订阅发现types目前仅支持vmtags默认{*[*]}即不过滤teleport_discovery_group_namestring必填Teleport Cloud 用cloud-discovery-group自建集群需与 Discovery Service 的 discovery_group 一致teleport_proxy_public_addrstring必填host:port格式禁止 URL schemeteleport_installer_script_namestring默认default-installer示例演示了自定义 installer 的接入方式create_azure_managed_identitybool默认true置false时需自备托管身份与角色且通配符订阅时必须显式传teleport_provision_token_allow_rulesuse_oidc_integrationbool默认true关闭后不创建联合凭据与集成资源七、小结examples/management-group示例展示了 Teleport Azure 自动发现最具扩展性的形态以租户/管理组为作用域、以通配符订阅匹配器为扫描范围、以租户级 allow rule 约束加入令牌配合自定义 installer 脚本下发teleport install autodiscover-node完成 VM 纳管。理解其背后的三个核心机制——作用域推导优先级显式 scopes 管理组 订阅列表、通配符订阅的强约束 precondition、租户级令牌规则自动生成——就能在企业多订阅环境中安全、可审计地规模化部署 Teleport 的 Azure 自动发现能力。进一步阅读模块 README完整输入/输出参考single-subscription 示例对比订阅级发现模块自动化测试行为契约赞分享网络安全认证鉴权运维后端【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址https://gitcode.com/gh_mirrors/tel/teleport点击查看免费下载相关推荐Watermill与Azure Management Group创建集成管理组事件配置Watermill与Azure Management Group创建集成管理组事件配置 概述 Watermill是一个用于构建事件驱动应用的Go语言框架通过消息队列后端微服务Upscheme集成实战如何在现有PHP项目中无缝接入Upscheme集成实战如何在现有PHP项目中无缝接入 Upscheme是一款强大的PHP数据库迁移工具能够轻松实现数据库模式更新和版本控制。本文将详细介绍跨平台桌面应用UI组件通过透明代理捕获虚拟机流量mitmproxy 虚拟机透明代理完整配置指南通过透明代理捕获虚拟机流量mitmproxy 虚拟机透明代理完整配置指南 本指南基于 mitmproxy 官方 howto 文档讲解如何将一台 Ubuntu网络安全网络开发工具接口测试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考