Teleport AWS Terraform 部署指南:从单机 Starter 集群到 HA 自动扩缩容生产集群
【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleport
本文以 Teleport 开源仓库 examples/aws/terraform 中的官方 Terraform 定义为核心,系统讲解如何用 Terraform 在 AWS 上部署两种 Teleport 集群:一台 t3.nano/t4g.micro 即可跑通的全功能单机集群(auth、proxy、node 三进程合一),以及面向生产的 HA 高可用自动扩缩容集群。读完本文,你将掌握 Teleport 预构建 AMI 的环境变量配置机制、make plan/apply/destroy的完整落地流程、全部TF_VAR_*参数的语义与默认值,以及 HA 方案中 DynamoDB、S3、SSM、Route 53 等 AWS 服务在 Teleport 架构中的真实分工。
目录速览:两种官方部署模式
该目录下包含两份相互独立的 Terraform 工程,对应两种截然不同的部署诉求:
| 工程 | 定位 | 拓扑 | 适用场景 |
|---|---|---|---|
| starter-cluster | 快速起步 | 单台 EC2 承载 auth + node + proxy | Demo、POC、学习 |
| ha-autoscale-cluster | 生产级参考 | 多 ASG 分组承载 auth / proxy / node | 生产环境、高可用 |
README 的立场非常明确:如果要参考 Terraform 示例做生产部署,应以 HA 自动扩缩容集群为准,其背后还有完整的《生产部署指南》讲解 Teleport 在生产环境中的运行细节。Starter 集群则被反复强调"不要用于生产",仅作为演示与定制起点。
前置条件
使用前建议先熟悉两类知识:Teleport 的整体架构(auth 服务、proxy 服务、node 节点的分工与通信),以及管理员日常操作指南。部署所需的本地工具链仅有两个:
- Terraform v1.0+(注意:starter-cluster 的
data.tf中声明了required_version = ">= 1.0, < 2.0.0",HA 工程也有对应的versions.tf约束) - AWS CLI v1.14+
Starter 集群:一台 EC2 跑通全功能 Teleport
Starter 工程的核心思路是:Teleport 官方 AMI 预置了完整运行环境,你只需要通过环境变量告诉它集群拓扑与外部依赖,实例启动后即可自举为完整集群。
工作原理:环境变量驱动的自举
实例的引导依赖两件事:
data.tpl生成的/etc/teleport.d/conf配置文件——data.tpl 是一个 bash 模板,启动时把 Terraform 变量渲染为TELEPORT_*环境变量写入配置目录;- 一系列 systemd 单元与 bash 脚本——位于仓库 assets/aws/files/system(systemd 单元)与 assets/aws/files/bin(引导脚本),负责把环境变量翻译成 Teleport 的实际配置文件并拉起服务。如果你需要深度定制引导逻辑,可以研究 assets/aws 下的 AMI 生成代码。
从 data.tpl 可以看到单机集群的关键环境变量组合:
TELEPORT_ROLE=auth,node,proxy # 单机三合一 TELEPORT_AUTH_SERVER_LB=localhost TELEPORT_DOMAIN_NAME=${domain_name} TELEPORT_EXTERNAL_HOSTNAME=${domain_name} TELEPORT_PROXY_SERVER_LB=${domain_name} TELEPORT_DYNAMO_TABLE_NAME=${dynamo_table_name} TELEPORT_DYNAMO_EVENTS_TABLE_NAME=${dynamo_events_table_name} TELEPORT_LOCKS_TABLE_NAME=${locks_table_name} TELEPORT_S3_BUCKET=${s3_bucket} USE_LETSENCRYPT=${use_letsencrypt} USE_ACM=${use_acm} USE_TLS_ROUTING=${use_tls_routing}其中TELEPORT_ROLE=auth,node,proxy是"all-in-one"拓扑的标志;USE_ACM=true时teleport-generate-config会自动启用 TLS routing;USE_LETSENCRYPT在启用 ACM 时会被自动关闭。
该工程会创建哪些 AWS 资源
必需资源:
- 单台 EC2(auth + node + proxy 三进程合一)
- 三张 DynamoDB 表:集群状态(cluster state)、集群事件(cluster events)、SSL 锁(ssl lock)
- 一个 S3 桶:会话录制(session recording)存储
- Route 53 A 记录
- 安全组(Security Groups)与 IAM 角色
可选资源:
- Application Load Balancer(ALB)
- ACM 证书及 Route 53 验证记录
项目布局
| 文件 | 说明 |
|---|---|
| acm.tf | ACM 证书创建与 DNS 验证记录 |
| cluster.tf | EC2 实例模板与用户数据渲染 |
| cluster_iam.tf | IAM 角色,授权实例访问 ssm/s3/dynamodb 等 |
| cluster_lb.tf | 使用 ACM 时的应用负载均衡器 |
| cluster_sg.tf | 安全组与入站规则 |
| data.tf | 数据源:VPC、子网、AMI、Route53 区、KMS 别名 |
| data.tpl | Teleport 配置模板 |
| dynamo.tf | DynamoDB 表,承载集群状态与事件 |
| outputs.tf | 输出,用于获取集群信息 |
| route53.tf | Route53 区创建(配置 SSL 需要托管区) |
| s3.tf | S3 桶,会话录制存储 |
| ssm.tf | 企业版 license 分发 |
| vars.tf | 输入变量定义 |
源码细节:实例如何被构建
在 cluster.tf 中可以看到实例的完整定义:
ami = data.aws_ami.base.id:通过 data.tf 中的aws_ami数据源按 AMI 名称过滤,most_recent = true,owners = [146628656107](Teleport 官方 AWS 账号 ID);user_data用templatefile渲染data.tpl,把所有 Terraform 变量注入引导脚本;- 默认使用默认 VPC 的第一个子网并分配公网 IP;
- 安全加固默认值:
metadata_options.http_tokens = "required"(强制 IMDSv2)、root_block_device.encrypted = true(根卷加密)。
部署完成后,outputs.tf 会输出instance_ip_public(实例公网 IP)、cluster_name、cluster_web_address(形如https://cluster.example.com,按是否启用 ACM 选择 Route 53 记录)和key_name。
变量全解析
vars.tf中声明的输入变量(对应 README 给出的TF_VAR_*环境变量用法):
| 变量 | 类型 | 默认值 | 说明 |
|---|---|---|---|
region | string | 必填 | AWS 区域,需与 AMI 发布区域匹配 |
cluster_name | string | 必填 | 集群唯一名称,不含空格与特殊字符 |
license_path | string | "" | 企业版 license 文件绝对路径,复制到 SSM 后下发到 auth 节点 |
ami_name | string | 必填 | AMI 名称,内含 Teleport 版本与 OSS/Enterprise 标识 |
route53_zone | string | 必填 | Route 53 托管区,如example.com |
route53_domain | string | 必填 | 子域,如cluster.example.com,用户访问 proxy 使用 |
add_wildcard_route53_record | bool | — | 是否添加*.cluster.example.com通配符记录,用于 Application Access |
enable_mongodb_listener | bool | false | 是否启用 MongoDB 监听(同步修改 SG、LB 端口与 Teleport 配置) |
enable_mysql_listener | bool | false | 是否启用 MySQL 监听 |
enable_postgres_listener | bool | false | 是否启用 Postgres 监听 |
s3_bucket_name | string | 必填 | 会话录制存储桶 |
email | string | 必填 | Let's Encrypt 证书注册邮箱 |
key_name | string | 必填 | 区域内存在的 AWS SSH 密钥对名 |
use_letsencrypt | bool | — | 是否使用 Let's Encrypt 签发证书 |
use_acm | bool | false | 是否使用 ACM 证书(任何 ACM 用法都必须置 true) |
use_tls_routing | bool | false | 是否启用 TLS routing,启用后关闭所有独立监听端口 |
allowed_ssh_ingress_cidr_blocks | list(any) | ["0.0.0.0/0"] | 允许访问 SSH 端口的 CIDR |
allowed_ingress_cidr_blocks | list(any) | ["0.0.0.0/0"] | 所有 Teleport 端口入站 CIDR |
allowed_egress_cidr_blocks | list(any) | ["0.0.0.0/0"] | Teleport 出站 CIDR |
kms_alias_name | string | alias/aws/ssm | SSM 加密使用的 KMS 别名 |
cluster_instance_type | string | 必填 | 实例类型 |
teleport_auth_type | string | "local" | 集群默认认证类型 |
其中teleport_auth_type的取值与版本约束需要注意:Community 版支持local或github;Enterprise 版支持local、github、oidc、saml;Enterprise FIPS 部署禁用了本地认证,应使用github、oidc或saml。该参数在 DynamoDB 中已配置 SAML/OIDC/GitHub 连接器时,可用于在 AMI 升级后保持默认认证类型不变。
使用步骤
先按需修改工程内 Makefile(或环境文件)中的变量:
# Region to run in - we currently have AMIs in the following regions: # ap-northeast-1, ap-northeast-2, ap-northeast-3, ap-south-1, ap-southeast-1, ap-southeast-2, ca-central-1, eu-central-1 # eu-north-1, eu-west-1, eu-west-2, eu-west-3, sa-east-1, us-east-1, us-east-2, us-west-1, us-west-2 TF_VAR_region ?= "us-west-2" # Cluster name is a unique cluster name to use, should be unique and not contain spaces or other special characters TF_VAR_cluster_name ?= "TeleportCluster1" # AWS SSH key pair name to provision in installed instances, must be a key pair available in the above defined region TF_VAR_key_name ?= "example" # Full absolute path to the license file, on the machine executing Terraform, for Teleport Enterprise. TF_VAR_license_path ?= "/path/to/license" # AMI name contains the version of Teleport to install, and whether to use OSS or Enterprise version # To list available AMIs: # OSS: aws ec2 describe-images --owners 146628656107 --filters 'Name=name,Values=teleport-oss-*' # Enterprise: aws ec2 describe-images --owners 146628656107 --filters 'Name=name,Values=teleport-ent-*' # FIPS images are also available for Enterprise customers, look for '-fips' on the end of the AMI's name TF_VAR_ami_name ?= "teleport-ent-18.10.0-arm64" # Route 53 hosted zone to use, must be a root zone registered in AWS, e.g. example.com TF_VAR_route53_zone ?= "example.com" # Subdomain to set up in the zone above, e.g. cluster.example.com TF_VAR_route53_domain ?= "cluster.example.com" # Set to true to add a wildcard subdomain entry to point to the proxy, e.g. *.cluster.example.com export TF_VAR_add_wildcard_route53_record="true" # Enable adding MongoDB/MySQL/Postgres listeners in Teleport proxy, load balancer ports, and security groups # These will be ignored if TF_VAR_use_tls_routing=true export TF_VAR_enable_mongodb_listener="false" export TF_VAR_enable_mysql_listener="false" export TF_VAR_enable_postgres_listener="false" # Bucket name to store Teleport session recordings. export TF_VAR_s3_bucket_name="teleport.example.com" # AWS instance type to provision for running this Teleport cluster export TF_VAR_cluster_instance_type="t4g.micro" # Email to be used for Let's Encrypt certificate registration process. export TF_VAR_email="support@example.com" # Set to true to use Let's Encrypt to provision certificates export TF_VAR_use_letsencrypt="true" # Set to true to use ACM (Amazon Certificate Manager) to provision certificates # If you wish to use a pre-existing ACM certificate, you can import it: # terraform import aws_acm_certificate.cert <certificate_arn> # Note that TLS routing is automatically enabled when using ACM with the starter-cluster Terraform, meaning: # - you must use Teleport and tsh v13+ # - you must use `tsh proxy` commands for Kubernetes/database access export TF_VAR_use_acm="false" # Set to true to use TLS routing to multiplex all Teleport traffic over one port # Setting this will disable ALL separate listener ports. # This setting is automatically set to "true" when using ACM with the starter-cluster Terraform # and will be ignored. export TF_VAR_use_tls_routing="true" # This value can be used to change the default authentication type used for the Teleport cluster. # The default is "local". # Teleport Community Edition supports "local" or "github" # Teleport Enterprise Edition supports "local", "github", "oidc", or "saml" # Teleport Enterprise FIPS deployments have local authentication disabled, so should use "github", "oidc", or "saml" export TF_VAR_teleport_auth_type="local" # plan make plan然后执行三步操作:
make plan并核对计划是否符合预期;make apply开始创建资源;make destroy删除已创建的全部资源。
实例就绪后的初始化流程:
ssh ec2-user@<cluster_domain>登录新实例;- 创建用户(同时创建 Teleport 用户并授权以本地 ec2-user 登录):
- OSS:
sudo tctl users add <username> --roles=access,editor --logins=ec2-user - Enterprise:
tctl users add --roles=access,editor <username> --logins=ec2-user
- OSS:
- 打开输出中的注册链接,设置密码并配置 2FA token;
- 至此一个功能完整的 Teleport 集群即配置完成。
HA Auto-Scaling 集群:生产级高可用参考
HA 工程是 Teleport 官方开发者推荐的生产部署模式参考,将 auth、proxy、node 拆分为独立 Auto Scaling Group,并对各类 AWS 服务进行了生产级组合。
关键设计决策
README 中明确指出了该方案的几个关键机制:
- 证书:默认使用 Let's Encrypt 证书并走 DNS-01 挑战,因此必须通过 Route 53 控制 DNS 区;ACM 可作为替代,但 Route 53 集成仍然必需;
- Join Token 分发:通过 SSM Parameter Store 分发 Teleport join token;
- 证书分发:通过加密的 S3 桶分发证书;
- 单 auth 轮换保护:利用 DynamoDB 锁保证同一时刻只有一个 auth 节点轮换 join token(该技巧可替换,不影响性能);
- 安全基线:auth 与 proxy 不以 root 运行,且只对其他组件暴露绝对最小端口集。
组件与文件
| 文件 | 职责 |
|---|---|
| auth_asg.tf / auth_iam.tf / auth_network.tf | auth 节点 ASG、IAM、网络 |
| proxy_asg.tf / proxy_iam.tf / proxy_network.tf | proxy 节点 ASG、IAM、网络 |
| node_asg.tf / node_iam.tf / node_network.tf | node 节点 ASG、IAM、网络 |
| bastion.tf | 堡垒机 |
| dynamo.tf | DynamoDB 后端表与自动扩缩容策略 |
| locks.tf | join token 轮换锁 |
| vpc.tf | 独立 VPC(默认 CIDR172.31.0.0/16) |
| network.tf | 子网、路由等网络资源 |
| route53.tf | Route 53 记录 |
| s3.tf | 证书加密存储桶 |
| ssm.tf | SSM Parameter Store(join token、license) |
| provider.tf / versions.tf | Provider 与版本约束 |
| auth-user-data.tpl / proxy-user-data.tpl / node-user-data.tpl | 各角色的用户数据模板 |
| ansible/ | 升级与访问辅助(access.yaml、upgrade.yaml 等) |
| connect.sh | 连接辅助脚本 |
以 proxy-user-data.tpl 为例,proxy 角色的引导与 starter 明显不同:TELEPORT_ROLE=proxy,需要指定TELEPORT_AUTH_SERVER_LB指向 auth 的负载均衡地址,并通过TELEPORT_PROXY_SERVER_NLB_ALIAS支持 ACM 场景下为 kubectl 等客户端准备的 NLB DNS 别名,额外把EC2_REGION、TELEPORT_DOMAIN_NAME、TELEPORT_S3_BUCKET追加写入/etc/default/teleport。
DynamoDB:状态后端与容量自动扩缩容
dynamo.tf 揭示了 HA 架构的数据面设计:
- 主表(集群状态):hash key
HashKey+ range keyFullPath,默认读写容量各 20,启用服务端加密(demo 场景未使用 CMK,代码中留有tfsec:ignore说明)、PITR 点时间恢复、TTL(Expires属性)、流(NEW_IMAGE); - 事件表:hash key
SessionID+ range keyEventIndex,并带timesearchV2全局二级索引(CreatedAtDate+CreatedAt)用于审计事件的时间检索; - 容量自动扩缩容:通过
aws_appautoscaling_target+aws_appautoscaling_policy按 DynamoDB 读写容量利用率目标跟踪伸缩,配套 IAM 角色授权 autoscaling 服务执行dynamodb:DescribeTable/UpdateTable与 CloudWatch 告警管理。
注释特别点明:"DynamoDB 仅 auth 服务器需要访问,其他组件全部无状态"——这是 HA 集群可水平扩展的关键前提。
变量与部署
完整变量清单见 vars.tf,除 starter 中的公共项外,HA 特有的关键变量包括:
| 变量 | 默认值 | 说明 |
|---|---|---|
vpc_cidr | 172.31.0.0/16 | 专用 VPC CIDR |
teleport_uid | 1007 | 主机上 teleport 用户的 UID(非 root 运行) |
auth_instance_type | m7g.large | auth ASG 实例类型,需与 AMI 架构一致(ARM/x86) |
proxy_instance_type | m7g.large | proxy ASG 实例类型 |
node_instance_type | t4g.medium | node ASG 实例类型 |
bastion_instance_type | t4g.medium | 堡垒机实例类型 |
route53_domain_acm_nlb_alias | 无 | 可选;ACM 且未启用 TLS routing 时生效,为 NLB 添加 DNS 别名,可配合tctl auth sign --user=foo --format=kubernetes --out=kubeconfig --proxy=https://cluster-nlb.example.com:3026生成 kubeconfig |
HA 工程同样以make plan起步,其 README 给出的完整变量脚本覆盖 region、cluster_name、ami_name(示例同样为teleport-ent-18.10.0-arm64)、各类实例类型、key_name、ACM/TLS routing 开关、license_path、Route 53 域名、MongoDB/MySQL/Postgres 监听开关、S3 桶名、邮箱与teleport_auth_type,完整内容可直接参考 ha-autoscale-cluster/README.md。
公共 Teleport AMI 说明
两个工程都通过ami_name变量按名称(而非硬编码 ID)选择 AMI,teleport 官方账号(owner ID146628656107)在每次发布新版本时共享公共 AMI。命名规则为teleport-{oss|ent}-{version}-{arch},企业版另有-fips后缀的 FIPS 镜像。可用如下命令枚举:
# OSS aws ec2 describe-images --owners 146628656107 --filters 'Name=name,Values=teleport-oss-*' # Enterprise aws ec2 describe-images --owners 146628656107 --filters 'Name=name,Values=teleport-ent-*'当前发布列表(以 v18.10.0 为例,各区域 arm64 与 x86_64 均有对应 ID,完整列表见 AMIS.md):
- OSS(如 us-west-2):
ami-0f4171a117a7d59b1(arm64)、ami-02d9e8fab1541553f(x86_64) - Enterprise(如 us-west-2):
ami-0d387d9ddd831728d(arm64)、ami-0615499c69008124b(x86_64) - Enterprise FIPS(如 us-west-2):
ami-0d0bb23d37cbee709(arm64)、ami-0664aee475cc5ffb2(x86_64)
覆盖区域包括 ap-northeast-1/2/3、ap-south-1、ap-southeast-1/2、ca-central-1、eu-central-1、eu-north-1、eu-west-1/2/3、sa-east-1、us-east-1/2、us-west-1/2,共 17 个区域。请注意 AMI ID 会随版本发布更新,应以 AMIS.md 或describe-images的实时结果为准。
澄清:这不是 Teleport Terraform Provider
需要明确区分:本文介绍的examples/aws/terraform是用 Terraform 在 AWS 上部署 Teleport 集群本身;而 Teleport 官方的Terraform Provider是另一种工具,用于在已存在的 Teleport 集群内部声明式管理用户、角色、认证连接器(auth connector)等资源。后者源码位于 integrations/terraform(对应仓库中的integrations/terraform目录),是典型的"基础设施即代码"(Infrastructure as Code)能力,二者职责互补、不可混用。
故障排查与支持渠道
- 部署或使用过程中遇到问题,可参考官方 GitHub Discussions 社区讨论;
- 若确认是与本目录代码相关的缺陷,可通过 GitHub Issues 提交,附上 Terraform 版本、AWS CLI 版本、
terraform plan输出与相关资源 ID,便于定位。
小结
Teleport 官方在 examples/aws/terraform 中给出了两条清晰的 AWS 落地路径:starter-cluster 用最少资源、最快速度验证 Teleport 的全部核心能力(单实例 + DynamoDB + S3 + Route 53,可选 ALB/ACM/TLS routing),适合 Demo 与 POC;ha-autoscale-cluster 则以"最小暴露端口、非 root 运行、无状态组件可扩展、加密分发与锁保护"为设计原则,将 auth/proxy/node 拆分为独立 ASG,配合 DynamoDB 自动扩缩容、SSM 分发 join token、S3 分发证书,构成可直接借鉴的生产部署蓝图。无论选择哪条路径,make plan都是开始任何变更前的第一道安全阀。
【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleport
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考