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_api、aws_api_gateway_deployment、aws_api_gateway_stage、aws_api_gateway_method_settings、aws_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 Deploymentstage.tfStage 与方法级 CloudWatch 指标设置domain.tf自定义域名与 Base Path Mappingtls.tf自签名 TLS 证书仅用于测试outputs.tf验证用的 curl 命令输出如何运行这个示例所有可变参数都集中在 variables.tf 中。官方 README 提供了两种传参方式。方式一使用 tfvars 文件将模板复制为terraform.tfvars后按需修改再执行terraform applycp terraform.template.tfvars terraform.tfvars # 编辑 terraform.tfvars 修改变量 terraform applyterraform.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 -varaws_regionus-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 APIrest-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-integrationOpenAPI 规范中 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 源码看body是aws_api_gateway_rest_api的标准可选属性定义于 internal/service/apigateway/rest_api.gobody: { Type: schema.TypeString, Optional: true, },当body变化时资源会走 PUT 全量更新逻辑见 rest_api.go 中d.HasChanges(body, names.AttrParameters)的分支判断底层对应 API Gateway 的PutRestApi操作。提示把 OpenAPI 定义内嵌到body是“文档即配置”的推荐做法相比逐个声明aws_api_gateway_resource、aws_api_gateway_method、aws_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 } }这里有两个非常值得复用的工程技巧用triggerssha1嗅探 API 定义变化aws_api_gateway_deployment是一个无状态资源OpenAPI 定义更新后它不会自动重建。通过把redeployment触发器绑定为sha1(jsonencode(...body))只要body内容发生变化哈希值就会改变进而强制触发新的 Deployment——这正是 variables.tf 中rest_api_name与rest_api_path描述“can be used to trigger redeployments”的含义。该模式同样出现在 provider 自己的测试夹具中例如 internal/service/apigateway/deployment_test.goredeployment sha1(jsonencode(aws_api_gateway_integration.test)) ... create_before_destroy truecreate_before_destroy true新 Deployment 先创建、旧 Deployment 后销毁保证更新过程中 Stage 始终有可用版本避免因删除旧部署导致短暂的 5xx 空窗。核心三Stage 与 CloudWatch 指标stage.tfstage.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.tfresource 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 本地生成无需访问 CAresource 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_names与common_name都取自var.rest_api_domain_name默认example.comallowed_uses声明了server_auth服务器认证等用途validity_period_hours 12自签名证书只有 12 小时有效期明确是测试用途生产中必须使用受信任 CA 签发的证书或通过aws_acm_certificate的 DNS/Email 验证流程申请托管证书aws_acm_certificate以certificate_bodyprivate_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.goaws_api_gateway_rest_api的资源实现body属性的 Schema 定义位于第 90–93 行PutRestApi更新逻辑位于第 602 行附近internal/service/apigateway/rest_api_put.goFramework 风格的 REST API 定义body、triggers等属性见第 229、234 行其测试夹具同样使用sha1(...)触发重新部署rest_api_put_test.gointernal/service/apigateway/deployment_test.goDeployment 的triggerscreate_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),仅供参考