news 2026/9/17 12:33:43

terraform-provider-aws 实战:用 OpenAPI 一键构建端到端 API Gateway REST API 示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
terraform-provider-aws 实战:用 OpenAPI 一键构建端到端 API Gateway REST API 示例

terraform-provider-aws 实战:用 OpenAPI 一键构建端到端 API Gateway REST API 示例

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

本文以 terraform-provider-aws 仓库中的 examples/api-gateway-rest-api-openapi 示例为主线,完整讲解如何用 Terraform 以 OpenAPI 配置方式声明式地创建一套端到端的 AWS API Gateway REST API:通过body内嵌 OpenAPI 3.0.1 定义实现 HTTP_PROXY 反向代理、自动创建部署与 Stage、开启 CloudWatch 指标、配置带自签名 TLS 证书的 REGIONAL 自定义域名,并输出可直接运行的curl验证命令。读完本文,你将掌握aws_api_gateway_rest_apiaws_api_gateway_deploymentaws_api_gateway_stageaws_api_gateway_method_settingsaws_api_gateway_domain_name等核心资源在真实示例中的串联用法,以及源码层面的底层实现依据。

示例概览:它做了什么

该示例(见 README.md)演示了如何创建一个完整的 AWS API Gateway REST API 环境:

  • 使用OpenAPI 配置(而非逐个声明 Method/Resource)定义 API,代理 AWS IP Address Ranges 的公开 JSON 端点;
  • 自动生成Deployment 与 Stage,并开启CloudWatch 指标
  • 配置一个REGIONAL 自定义域名,搭配自签名 TLS 证书,以贴近真实线上端点;
  • 最终通过输出的curl命令验证部署结果。

整套配置由 6 个 Terraform 文件构成,职责清晰:

文件职责
main.tfTerraform 版本与 AWS Provider 声明
rest-api.tfOpenAPI 定义的 REST API + Deployment
stage.tfStage 与方法级 CloudWatch 指标设置
domain.tf自定义域名与 Base Path Mapping
tls.tf自签名 TLS 证书(仅用于测试)
outputs.tf验证用的 curl 命令输出

如何运行这个示例

所有可变参数都集中在 variables.tf 中。官方 README 提供了两种传参方式。

方式一:使用 tfvars 文件

将模板复制为terraform.tfvars后按需修改,再执行terraform apply

cp terraform.template.tfvars terraform.tfvars # 编辑 terraform.tfvars 修改变量 terraform apply

terraform.template.tfvars 的内容如下,四个变量都有默认值,直接复制即可运行:

aws_region = "us-west-2" rest_api_domain_name = "example.com" rest_api_name = "api-gateway-rest-api-openapi-example" rest_api_path = "/path1"

方式二:命令行变量标志

也可以完全跳过 tfvars 文件,直接通过-var标志传入:

terraform apply -var="aws_region=us-west-2"

两种方式等价,未显式指定的变量会回落到 variables.tf 中声明的default值。

全部可配置变量

变量默认值说明
aws_regionus-west-2部署示例 API 的 AWS 区域
rest_api_domain_nameexample.com自定义域名,用于自签名 TLS 证书的 DNS 名称
rest_api_nameapi-gateway-rest-api-openapi-exampleREST API 名称(可用于触发重新部署)
rest_api_path/path1在 REST API 中创建的路径(可用于触发重新部署)

其中 main.tf 仅声明了 Terraform 版本下限(>= 0.12)与awsProvider 的区域配置:

terraform { required_version = ">= 0.12" } provider "aws" { region = var.aws_region }

核心一:用 OpenAPI 定义 REST API(rest-api.tf)

这是整个示例的灵魂。rest-api.tf 通过aws_api_gateway_rest_api资源的body参数,将 OpenAPI 3.0.1 文档直接内嵌进 Terraform 配置:

resource "aws_api_gateway_rest_api" "example" { body = jsonencode({ openapi = "3.0.1" info = { title = var.rest_api_name version = "1.0" } paths = { (var.rest_api_path) = { get = { x-amazon-apigateway-integration = { httpMethod = "GET" payloadFormatVersion = "1.0" type = "HTTP_PROXY" uri = "https://ip-ranges.amazonaws.com/ip-ranges.json" } } } } }) name = var.rest_api_name endpoint_configuration { types = ["REGIONAL"] } }

要点拆解:

  • jsonencode动态生成:整个 OpenAPI 文档由 HCL 对象经jsonencode序列化而成,路径${var.rest_api_path}、标题${var.rest_api_name}都是运行时插值——这正是变量描述中“可用于触发重新部署”的原因(见下文 Deployment 机制)。
  • x-amazon-apigateway-integration:OpenAPI 规范中 AWS 的扩展字段,声明该 GET 方法对接的集成。此处使用type = "HTTP_PROXY",即把请求原样转发到上游https://ip-ranges.amazonaws.com/ip-ranges.json,配合httpMethod = "GET"payloadFormatVersion = "1.0"(对应 REST API 的 HTTP 代理集成格式)。
  • endpoint_configuration.types = ["REGIONAL"]:API 端点类型为区域级(非 EDGE、非 PRIVATE),与后文自定义域名同样使用 REGIONAL 类型保持一致。

从 provider 源码看,bodyaws_api_gateway_rest_api的标准可选属性,定义于 internal/service/apigateway/rest_api.go:

"body": { Type: schema.TypeString, Optional: true, },

body变化时,资源会走 PUT 全量更新逻辑(见 rest_api.go 中d.HasChanges("body", names.AttrParameters)的分支判断),底层对应 API Gateway 的PutRestApi操作。

提示:把 OpenAPI 定义内嵌到body是“文档即配置”的推荐做法,相比逐个声明aws_api_gateway_resourceaws_api_gateway_methodaws_api_gateway_integration,它可以一次导入整个 API 定义,配置量与维护成本都显著更低。如果希望把 OpenAPI 文件独立存放,也可以使用body = file("openapi.yaml")读取外部文件。

核心二:Deployment 与"自动重新部署"触发器

REST API 定义本身并不对外提供服务,必须创建 Deployment 才能把定义发布到 Stage。rest-api.tf 中的部署资源:

resource "aws_api_gateway_deployment" "example" { rest_api_id = aws_api_gateway_rest_api.example.id triggers = { redeployment = sha1(jsonencode(aws_api_gateway_rest_api.example.body)) } lifecycle { create_before_destroy = true } }

这里有两个非常值得复用的工程技巧:

  1. triggers+sha1嗅探 API 定义变化aws_api_gateway_deployment是一个无状态资源,OpenAPI 定义更新后它不会自动重建。通过把redeployment触发器绑定为sha1(jsonencode(...body)),只要body内容发生变化,哈希值就会改变,进而强制触发新的 Deployment——这正是 variables.tf 中rest_api_namerest_api_path描述“can be used to trigger redeployments”的含义。该模式同样出现在 provider 自己的测试夹具中,例如 internal/service/apigateway/deployment_test.go:

    redeployment = sha1(jsonencode(aws_api_gateway_integration.test)) ... create_before_destroy = true
  2. create_before_destroy = true:新 Deployment 先创建、旧 Deployment 后销毁,保证更新过程中 Stage 始终有可用版本,避免因删除旧部署导致短暂的 5xx 空窗。

核心三:Stage 与 CloudWatch 指标(stage.tf)

stage.tf 把上面创建的 Deployment 挂到名为example的 Stage,并用aws_api_gateway_method_settings开启方法级 CloudWatch 指标:

resource "aws_api_gateway_stage" "example" { deployment_id = aws_api_gateway_deployment.example.id rest_api_id = aws_api_gateway_rest_api.example.id stage_name = "example" } resource "aws_api_gateway_method_settings" "example" { rest_api_id = aws_api_gateway_rest_api.example.id stage_name = aws_api_gateway_stage.example.stage_name method_path = "*/*" settings { metrics_enabled = true } }
  • stage_name = "example"决定调用 URL 中的路径段,最终调用地址形如https://<api-id>.execute-api.<region>.amazonaws.com/example/path1(见后文 outputs)。
  • method_path = "*/*"表示匹配该 Stage 下所有资源的所有 HTTP 方法,即整个 API 全量开启指标。
  • settings.metrics_enabled = true打开 CloudWatch 指标,之后可在 CloudWatch 控制台按ApiGateway命名空间查看 4xx/5xx、延迟、计数等指标,用于监控与告警。

核心四:自定义域名 + 自签名 TLS 证书(domain.tf 与 tls.tf)

为了让 API 更接近真实线上端点,示例还配置了自定义域名。domain.tf:

resource "aws_api_gateway_domain_name" "example" { domain_name = aws_acm_certificate.example.domain_name regional_certificate_arn = aws_acm_certificate.example.arn endpoint_configuration { types = ["REGIONAL"] } } resource "aws_api_gateway_base_path_mapping" "example" { api_id = aws_api_gateway_rest_api.example.id domain_name = aws_api_gateway_domain_name.example.domain_name stage_name = aws_api_gateway_stage.example.stage_name }
  • aws_api_gateway_domain_name创建 REGIONAL 类型的自定义域名,并把 ACM 证书(regional_certificate_arn)绑定到该域名。由于域名为 REGIONAL 类型,需使用regional_certificate_arn而非边缘证书参数。
  • aws_api_gateway_base_path_mapping把 REST API 的exampleStage 映射到该域名根路径,使https://<regional-domain>/<path>可以直接访问 API。

对应 provider 实现位于 internal/service/apigateway/domain_name.go 与 internal/service/apigateway/base_path_mapping.go。

自签名证书部分在 tls.tf,完全用 Terraform 生态的hashicorp/tlsProvider 本地生成,无需访问 CA:

resource "tls_private_key" "example" { algorithm = "RSA" } resource "tls_self_signed_cert" "example" { allowed_uses = [ "key_encipherment", "digital_signature", "server_auth", ] dns_names = [var.rest_api_domain_name] private_key_pem = tls_private_key.example.private_key_pem validity_period_hours = 12 subject { common_name = var.rest_api_domain_name organization = "ACME Examples, Inc" } } resource "aws_acm_certificate" "example" { certificate_body = tls_self_signed_cert.example.cert_pem private_key = tls_private_key.example.private_key_pem }

要点:

  • 证书的dns_namescommon_name都取自var.rest_api_domain_name(默认example.com);
  • allowed_uses声明了server_auth(服务器认证)等用途;
  • validity_period_hours = 12:自签名证书只有 12 小时有效期,明确是测试用途,生产中必须使用受信任 CA 签发的证书(或通过aws_acm_certificate的 DNS/Email 验证流程申请托管证书);
  • aws_acm_certificatecertificate_body+private_key方式直接导入自签名证书(不涉及 ACM 的公有验证流程),这是验证/沙箱环境的常见做法。

核心五:输出 curl 验证命令(outputs.tf)

部署完成后,outputs.tf 会直接输出两条立即可复制的curl命令:

output "curl_domain_url" { depends_on = [aws_api_gateway_base_path_mapping.example] description = "API Gateway Domain URL (self-signed certificate)" value = "curl -H 'Host: ${var.rest_api_domain_name}' https://${aws_api_gateway_domain_name.example.regional_domain_name}${var.rest_api_path} # may take a minute to become available on initial deploy" } output "curl_stage_invoke_url" { description = "API Gateway Stage Invoke URL" value = "curl ${aws_api_gateway_stage.example.invoke_url}${var.rest_api_path}" }
  • curl_stage_invoke_url:通过 API Gateway 默认的invoke_urlhttps://<api-id>.execute-api.<region>.amazonaws.com/example)直接访问,是最快的验证方式。
  • curl_domain_url:访问自定义域名的区域端点(regional_domain_name),并用-H 'Host: ...'伪造 Host 头以匹配自签名证书的 DNS 名称——这是自签名证书场景下绕过 DNS 解析的常用技巧。由于自签名证书不受信任,实际执行时通常还需要追加-k(忽略证书校验)参数;输出注释也提醒:首次部署后该域名可能需等待约一分钟才能生效。
  • 两条命令都拼接了${var.rest_api_path}(默认/path1),命中 OpenAPI 中定义的 GET 方法,最终返回 AWS IP 地址范围 JSON。

源码佐证与延伸阅读

如果想深入理解本示例所用资源的底层实现,可以继续查看 provider 源码:

  • internal/service/apigateway/rest_api.go:aws_api_gateway_rest_api的资源实现,body属性的 Schema 定义位于第 90–93 行,PutRestApi更新逻辑位于第 602 行附近;
  • internal/service/apigateway/rest_api_put.go:Framework 风格的 REST API 定义(bodytriggers等属性,见第 229、234 行),其测试夹具同样使用sha1(...)触发重新部署(rest_api_put_test.go);
  • internal/service/apigateway/deployment_test.go:Deployment 的triggers+create_before_destroy模式官方测试用例;
  • internal/service/apigateway/domain_name.go、internal/service/apigateway/base_path_mapping.go、internal/service/apigateway/stage.go、internal/service/apigateway/method_settings.go:域名、路径映射、Stage 与方法设置的实现;
  • docs/add-a-new-resource.md 与 docs/resource-name-generation.md:若你想基于该示例扩展新资源,可参考 provider 的资源开发规范。

小结

这个示例的价值在于:它用最少量的 Terraform 配置,覆盖了 API Gateway REST API 从"定义"到"可访问"的完整链路——OpenAPI 声明式定义、基于sha1的自动重新部署、Stage 挂载、CloudWatch 指标、REGIONAL 自定义域名与自签名证书、以及开箱即用的 curl 验证输出。其中的body + jsonencode + triggers + create_before_destroy组合模式,在任何"以 OpenAPI 驱动 API Gateway"的 Terraform 项目中都值得直接复用;唯一的测试性取舍是 12 小时有效期的自签名证书,生产环境请替换为 ACM 托管证书或受信任 CA 证书。

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 12:33:17

多模态Transformer融合激光雷达与视觉:Cross-Attention工程实践

简介&#xff1a;面向自动驾驶感知与多模态融合学习者的技术文档&#xff0c;共33页PDF&#xff0c;大小2.31MB&#xff0c;系统讲解Transformer架构、注意力机制、激光雷达与视觉特征提取、多模态融合算法设计及实验评估。内容覆盖摄像头/激光雷达/毫米波雷达感知原理与挑战&a…

作者头像 李华
网站建设 2026/9/17 12:31:53

波形发生器设计:DDS选型、STM32 DAC+DMA与THD杂散验证

简介&#xff1a;面向电子类课程设计与模拟电路实验的波形发生器设计报告&#xff0c;围绕方波—三角波—正弦波函数发生器的完整设计流程展开&#xff0c;适合电子信息、自动化等专业学生完成课程设计、撰写实验报告或准备电子竞赛时参考。压缩包内共1个doc文档&#xff0c;大…

作者头像 李华
网站建设 2026/9/17 12:30:57

MySQL存储过程三大循环语法详解:WHILE、REPEAT、LOOP实战指南

1. 为什么MySQL里“写循环”不是个直白操作&#xff1f;刚接触MySQL存储过程的人&#xff0c;常会下意识敲出for i in 1..10或者for (let i 0; i < 10; i)—— 然后被报错打蒙。这不是你手误&#xff0c;而是MySQL压根没提供像Python、JavaScript那样原生的for循环语法。它…

作者头像 李华
网站建设 2026/9/17 12:27:37

1.11 处理器 SOC System on Chip

1.11 处理器 SOC System on Chip1 处理器是什么&#xff1f;2 ARM的内核究竟有哪些&#xff1f;3 有哪些分类?4 其他注意事项5 参考资料1 处理器是什么&#xff1f; 首先&#xff0c;我们一般会关心它用了几个IP核(Intellectual Property core)知识产权核心&#xff0c;用的是…

作者头像 李华
网站建设 2026/9/17 12:26:52

LeetCode 题解仓库贡献指南:从文件命名到 PR 合并的完整实操规范

LeetCode 题解仓库贡献指南&#xff1a;从文件命名到 PR 合并的完整实操规范 【免费下载链接】leetcode Leetcode solutions 项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode 本篇指南以仓库根目录的 CONTRIBUTING.md 为核心&#xff0c;系统讲解向本…

作者头像 李华