ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

使用 Terraform 在 AWS ECS 上部署 Teleport 服务:container-service/aws 模块实战指南

使用 Terraform 在 AWS ECS 上部署 Teleport 服务:container-service/aws 模块实战指南 使用 Terraform 在 AWS ECS 上部署 Teleport 服务container-service/aws 模块实战指南【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleport导读本指南围绕 Teleport 官方 Terraform 模块integrations/terraform-modules/teleport/container-service/aws展开讲解如何通过纯 Terraform 声明式配置将 Teleport 各类服务如 Database Service、SSH 代理等以 Fargate 任务的形式部署到 AWS ECS并借助 IAM Join Token 安全接入既有 Teleport 集群。读完本文你将掌握该模块的全部输入参数、底层资源编排逻辑、Managed Updates 版本管理机制以及一个可复制运行的完整数据库服务部署示例。模块概览与适用场景该模块位于仓库 integrations/terraform-modules/teleport/container-service/aws定位非常明确在 AWS ECSFargate上运行一个 Teleport agent 容器。Teleport 本身是一个统一基础设施访问平台其各类 agentSSH、数据库、Kubernetes、应用等以容器方式运行时天然适合交给 ECS 托管借助 Fargate 免去对底层 EC2 的管理。典型使用场景包括在 AWS 账户内运行Database Service让数据库访问流量统一经过 Teleport 网关模块自带的示例正是这种用法运行其他 Teleport 服务如 SSH Service、Discovery Service 等只需调整teleport_config中的*_service开关通过assign_public_ip控制任务出网方式公网子网经 Internet Gateway私有子网经 NAT Gateway。模块在create true时一次性创建 ECS 集群、ECS 服务、ECS 任务定义、CloudWatch 日志组、安全组、执行角色与任务角色等全部资源并且所有资源均支持通过create false一键跳过创建便于在条件化场景中复用。前提条件在开始之前需要完成两项基础设施准备原文档明确列出配置 Teleport Terraform Provider用于在目标 Teleport 集群中创建 IAM Join Token 等资源官方文档见 Teleport 的 Terraform Provider 配置说明配置 AWS Terraform Provider用于在 AWS 侧创建 ECS 相关资源。同时模块自身对 Terraform 与 Provider 版本有硬性要求见 versions.tf名称最低版本要求terraform 1.5.7aws 6.0http 3.0random 3.0其中httpProvider 用于运行时从 Teleport 集群拉取 Managed Updates 版本信息randomProvider 用于生成资源名后缀。模块创建的 AWS 资源全景从 aws_ecs_cluster.tf、aws_ecs_service.tf 等源码看模块在 AWS 侧编排的资源包括资源类型作用aws_ecs_cluster.teleport_agentresource承载 Teleport 任务的 ECS 集群默认名teleport支持名称前缀aws_ecs_service.teleport_agentresourceFargate 启动类型的 ECS 服务控制期望任务数、网络配置aws_ecs_task_definition.teleport_agentresource任务定义含容器镜像、启动命令、资源配额、日志配置aws_cloudwatch_log_group.thisresource任务日志的 CloudWatch 日志组默认名ecs-teleport保留 30 天aws_security_group.teleport_agentresource任务安全组默认放行全部出站流量aws_vpc_security_group_egress_rule.allow_all_outbound_from_teleport_agentresource上述安全组的出站规则0.0.0.0/0全协议aws_iam_role.ecs_executionresource执行角色供 ECS 拉取镜像、写日志aws_iam_role.ecs_taskresource任务角色供容器内 Teleport 进程调用 AWS API如 IAM Joinaws_iam_role_policy.ecs_execution / ecs_taskresource上述两个角色的内联策略random_string.name_suffixresource为集群、任务定义、日志组等生成随机名称后缀模块还声明了多个 data source 用于推导环境信息aws_caller_identity当前账户、aws_region当前区域、aws_partition如aws、aws-cn、aws_subnet校验子网归属、aws_iam_policy_document拼装策略 JSON以及http_http.managed_updates查询 Managed Updates 端点。输入参数详解必填参数参数类型说明ecs_service_subnetslist(string)Teleport 任务所在的子网 ID 列表。若assign_public_ip true必须是可路由到 Internet Gateway 的公网子网否则必须是可路由到 NAT Gateway 的私有子网vpc_idstringTeleport 任务部署所在的 VPC IDteleport_configanyTeleport 配置使用原生 Terraform 语法书写。注意任务定义中会以明文保存该配置任何能读取任务定义的人都能看到其中的敏感数据如静态 Join Token切勿在其中放置未加密的长期凭据可选参数含默认值全局开关与标签参数默认值说明createtrue是否创建全部资源设为false可跳过create_security_grouptrue是否为任务创建安全组apply_aws_tags{}附加到所有 AWS 资源的额外标签类型 map(string)security_group_ids[]额外附加到任务的安全组 ID 列表ECS 集群与服务参数默认值说明ecs_cluster_nameteleportECS 集群名称ecs_cluster_use_name_prefixtrue是否将集群名作为前缀拼接随机后缀避免重名冲突ecs_service_nameteleportECS 服务名称ecs_task_desired_count2期望运行的任务数生产环境建议 ≥ 2 保障可用性ecs_task_force_new_deploymentfalse设为true可在无配置变更时强制 ECS 重新部署任务assign_public_ipfalse是否为任务分配公网 IP需与子网类型匹配任务定义与资源配额参数默认值说明ecs_task_definition_nameteleport任务定义名称ecs_task_definition_use_name_prefixtrue是否使用名称前缀ecs_task_cpu2048CPU 单位数Fargate 下 2048 对应 2 vCPUecs_task_memory4096内存MiBFargate 下需与 CPU 成合法组合teleport_container_imagepublic.ecr.aws/gravitational/teleport-ent-distroless容器镜像默认企业版 distroless 镜像可替换为 OSS 版teleport_version19.0.0-prealpha.2部署的 Teleport 版本。原文档特别说明版本通常应跟随模块自身版本控制该变量仅供开发调试使用CloudWatch 日志组参数默认值说明ecs_task_cloudwatch_log_group_nameecs-teleport日志组名称ecs_task_cloudwatch_log_group_use_name_prefixtrue是否使用名称前缀ecs_task_cloudwatch_log_group_regionnull日志组所在区域默认跟随 AWS Provider 区域ecs_task_cloudwatch_log_group_kms_key_idnull用于加密日志的 KMS Key ID 或 ARNnull时使用 CloudWatch 默认加密ecs_task_cloudwatch_log_group_retention_days30日志保留天数ecs_task_cloudwatch_log_group_skip_destroyfalse销毁时是否保留日志组true则只从 Terraform 状态中移除不删除日志IAM 角色参数默认值说明ecs_task_role_inline_policynull要合并进任务角色内联策略的 JSON 策略文档ecs_task_role_self_assumption_allowedtrue是否允许任务角色自假设sts:AssumeRole到自身容器运行时参数默认值说明environment_vars{}设置到 Teleport 容器上的环境变量map(string)Managed Updates参数默认值说明managed_updates_enabledtrue是否在 apply 时从 Managed Updates 端点解析 Teleport 版本managed_updates_groupdefault通过 v2 Managed Updates 端点查询的更新组名称子网与公网 IP 的约束assign_public_ip与子网类型必须严格匹配模块通过 data.tf 中的aws_subnetdata source 读取每个子网的归属 VPC并在 aws_ecs_service.tf 中以precondition做三层校验至少提供一个子网length(var.ecs_service_subnets) 0至少存在一个可用安全组create_security_group true或提供了security_group_ids所有子网必须属于配置的vpc_id否则 apply 直接报错Each Teleport agent subnet must belong to the configured vpc_id.任务定义内部实现Teleport 是如何被启动的aws_ecs_task_definition.tf 揭示了容器启动的核心逻辑这是本模块最有价值的实现细节command [ # 将 SIGTERM(15) 重写为 SIGQUIT(3)使 ECS 停止信号触发 Teleport 优雅退出 --rewrite, 15:3, --, teleport, start, --config-string, base64encode(yamlencode(var.teleport_config)), ] entryPoint [/usr/bin/dumb-init]几个关键点配置以 base64 编码的 YAML 注入teleport_config先被yamlencode序列化为 YAML再base64encode后通过--config-string传给teleport start。这意味着你在 Terraform 中书写的是 HCL 语法最终会转成 Teleport 原生 YAML 配置dumb-init 作为入口点容器以dumb-init为 PID 1负责正确转发信号、回收僵尸进程SIGTERM 重写为 SIGQUITECS 停止任务时发送 SIGTERM(15)但 Teleport 的优雅关闭依赖 SIGQUIT(3)因此用--rewrite 15:3做信号转换保证 agent 下线前能优雅释放连接与状态日志走 awslogs日志驱动为awslogs日志组、区域来自模块创建的 CloudWatch 日志组流前缀为{cluster-name}-{service-name}网络模式 awsvpc FARGATE任务直接获得 ENI安全组与子网由 ECS Service 的网络配置注入。镜像标签${var.teleport_container_image}:${local.teleport_version}中local.teleport_version的解析优先级是Managed Updates 端点返回的版本 var.teleport_version见下文。Managed Updates自动解析 Teleport 版本模块内置了 Teleport Managed Updates 集成data.tf。当managed_updates_enabled true时apply阶段会发起一次 HTTP 请求url format( https://%v/webapi/find?group%v, local.managed_updates_proxy_addr, urlencode(coalesce(var.managed_updates_group, default)), )其中local.managed_updates_proxy_addr取自teleport_config.teleport.proxy_server并会剥离 URL scheme如https://。响应体中的auto_update.agent_version即成为本次部署的 Teleport 版本。模块通过precondition与postcondition双重校验保证该流程的可靠性启用 Managed Updates 时teleport_config中必须配置teleport.proxy_server否则报错Managed Updates require teleport.proxy_server in teleport_config.端点必须返回 HTTP 200且auto_update.agent_version必须匹配^v?[0-9]\.[0-9]\.[0-9].*的合法版本格式否则 apply 失败并提示检查集群是否支持 Managed Updates 及更新组是否存在。任务定义中版本的最终计算方式为aws_ecs_task_definition.tfteleport_version trimprefix( trimspace( coalesce(local.managed_updates_version, var.teleport_version), ), v, )即Managed Updates 返回值优先未启用或查询失败时回退到var.teleport_version。IAM 角色设计执行角色与任务角色模块创建两个职责分离的 IAM 角色aws_task_execution_role.tf 与 aws_task_role.tf执行角色ecs_execution供 ECS 控制面使用负责拉取 ECR 镜像、向 CloudWatch 写日志任务角色ecs_task附加到容器内进程Teleport agent 通过它调用 AWS API例如 IAM Join 时的sts:AssumeRole与身份验证。任务角色的信任策略值得注意aws_task_role.tf允许ecs-tasks.amazonaws.com服务主体担任并用aws:SourceAccount与aws:SourceArn条件收紧防范 confused deputy 攻击当ecs_task_role_self_assumption_allowed true默认时额外增加一条“自假设”信任语句允许角色假设自身 ARN这是 IAM Join 流程中 Teleport 使用 AWS 身份的前提之一内联策略可通过ecs_task_role_inline_policy合并自定义 JSON也可通过ecs_task_role_self_assumption_allowed控制是否注入sts:AssumeRole自假设权限。输出让 Join Token 与 ECS 任务精确匹配模块在 outputs.tf 中暴露了 12 个输出除集群、服务、任务定义、日志组、安全组、两个角色的 ARN/名称外最值得一提的是teleport_provision_token_allow_aws_arn该输出生成形如arn:{partition}:sts::{account_id}:assumed-role/{task_role_name}/*的 ARN直接用于 Teleport IAM Join Token 的allow.aws_arn字段让 ECS 任务得以用 IAM 身份加入 Teleport 集群。这在示例中体现得淋漓尽致见下文teleport_config输出则回显模块实际使用的 Teleport 配置便于审计。完整示例将 Teleport Database Service 部署到 ECS示例位于 examples/db-service完整演示了“VPC ECS 模块 IAM Join Token”三件套目录下包含main.tf、providers.tf、variables.tf、outputs.tf等完整文件。Provider 配置providers.tfprovider aws { region us-east-1 default_tags { tags { env example } } } provider teleport { addr var.teleport_proxy_addr profile_name replace(var.teleport_proxy_addr, /:[0-9].*/, ) }注意 Teleport Provider 的profile_name通过正则从代理地址中剥离端口号得到示例所需输入仅一个teleport_proxy_addrhost:port形式的代理地址。核心编排main.tf示例先创建一个 3 AZ 的 VPC含公网/私有子网再引用模块module teleport_database_service { source ../.. # 启用 Managed Updates更新组使用默认组 managed_updates_enabled true managed_updates_group default apply_aws_tags { example true } assign_public_ip true # 使用公网子网时必须为 true ecs_cluster_name ${local.namespace}-cluster ecs_service_name ${local.namespace}-svc ecs_service_subnets module.vpc.public_subnets ecs_task_desired_count 1 environment_vars { EXAMPLE_VAR EXAMPLE_VALUE } vpc_id module.vpc.vpc_id teleport_config { version v3 teleport { join_params { token_name ${local.namespace}-iam method iam } proxy_server var.teleport_proxy_addr log { severity DEBUG } } auth_service { enabled no } proxy_service { enabled no } ssh_service { enabled no } discovery_service { enabled no } db_service { enabled yes resources [ { labels { env example } } ] } } }该teleport_config是一份典型的Teleport Database Service 纯 agent 配置join_params声明使用iam方式加入token 名为example-iamproxy_server指向 Teleport 代理地址同时也是 Managed Updates 查询地址除db_service外的所有服务auth、proxy、ssh、discovery均enabled nodb_service开启并通过resources[].labels指定要代理的数据库标签选择器env example。IAM Join Tokenmain.tf 续resource teleport_provision_token iam { metadata { name ${local.namespace}-iam description Allow the Teleport ECS agent to join the cluster using AWS IAM credentials. } spec { allow [{ aws_arn module.teleport_database_service.teleport_provision_token_allow_aws_arn }] join_method iam roles [Db] } version v2 }teleport_provision_token_allow_aws_arn输出与 token 的allow.aws_arn直接对接token 授予Db角色并通过iam方式加入——这就打通了“ECS 任务以 IAM 身份加入 Teleport 集群、成为数据库代理”的完整链路。运行方式在示例目录下依次执行terraform init terraform plan -var teleport_proxy_addryour-proxy.example.com:443 terraform apply -var teleport_proxy_addryour-proxy.example.com:443示例的版本要求为terraform 1.5.7、aws ~ 6.0、http ~ 3.0、teleport ~ 18.5。常见问题与故障排查Managed Updates require teleport.proxy_server in teleport_config.启用了managed_updates_enabled但teleport_config未设置teleport.proxy_server。要么补充proxy_server要么将managed_updates_enabled设为falseManaged Updates endpoint must return HTTP 200 and a valid Teleport version.集群不支持 Managed Updates或指定的managed_updates_group不存在。确认代理地址可访问且更新组名称正确Each Teleport agent subnet must belong to the configured vpc_id.ecs_service_subnets中混入了不属于vpc_id的子网At least one security group is required.将create_security_group与security_group_ids同时关闭/置空二者至少保留其一容器一直重启查看 CloudWatch 日志组默认ecs-teleport-*中teleport容器的 stdout/stderr确认teleport_config语法与 Join 是否成功敏感信息提醒teleport_config以明文写入任务定义静态 Join Token 等敏感值会暴露给可读任务定义的任何人。生产环境应优先使用 IAM Join 等免静态凭据的方式或结合 AWS Secrets Manager 注入。小结container-service/aws模块把 Teleport agent 上云的过程收敛为三个必填变量加若干可调参数vpc_id、ecs_service_subnets与teleport_config。底层它替你完成了 ECS 集群/服务/任务定义、日志、网络、IAM 全套资源的编排并通过 Managed Updates 保证镜像版本与集群策略一致通过teleport_provision_token_allow_aws_arn输出打通 IAM Join。对于希望以基础设施即代码方式在 AWS 上规模化运行 Teleport 服务的团队这是一个开箱即用的参考实现。【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleport创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表