如何将私有AWS AppSync GraphQL API注册到Cloud Map自定义命名空间并规避SSL问题
私有AppSync API注册到Cloud Map的解决方案
问题概述
要将私有AWS AppSync GraphQL API注册到Cloud Map自定义命名空间,实现ECS服务通过内部服务发现安全HTTPS调用,但遇到两个核心问题:
- 使用AppSync默认域名注册Cloud Map实例:DNS解析正常,但SSL证书(
*.appsync-api.<region>.amazonaws.com)与Cloud Map自定义域名不匹配,导致握手失败。 - 使用匹配Cloud Map命名空间的自定义域名注册:DNS解析失败,无法通过服务发现访问API。
可行性结论
完全可以实现,核心是通过以下两种方案对齐域名与SSL证书,或调整服务发现配置规避证书不匹配问题。
方案一:使用AppSync默认域名,规避SSL验证错误
核心思路
让Cloud Map返回AppSync默认域名的DNS记录,ECS服务直接使用该默认域名发起请求,确保SSL证书完全匹配。
具体操作
- 修改Cloud Map实例配置,直接注册AppSync默认域名作为CNAME记录。
- ECS服务通过服务发现获取默认域名后,直接用该域名调用API,无需使用Cloud Map自定义服务域名。
CDK代码调整
// 在AppSync CDK代码中,替换Cloud Map注册逻辑 const service = new servicediscovery.Service(this, 'GraphCloudMapService', { namespace: this.cloudMapNamespace, name: 'mygraph-local', dnsRecordType: servicediscovery.DnsRecordType.CNAME, // 可选:配置健康检查,目标为AppSync默认域名的/graphql路径 healthCheck: { resourcePath: '/graphql', type: servicediscovery.HealthCheckType.HTTPS, }, }) // 注册AppSync默认域名作为实例CNAME service.registerCnameInstance('GraphInstance', { instanceCname: api.graphqlUrl.replace('https://', ''), // 提取默认域名(如xxxx.appsync-api.us-east-1.amazonaws.com) })
优势
- 无需额外配置自定义域名和证书,快速解决SSL验证问题。
- 依赖AWS原生域名,稳定性高。
方案二:修复自定义域名解析问题,实现域名与证书对齐
核心思路
确保AppSync自定义域名与Cloud Map服务域名的SSL证书覆盖范围一致,同时解决VPC内的DNS解析问题。
关键步骤
- 对齐域名与证书
- 若使用单域名证书:将Cloud Map服务名与AppSync自定义域名前缀保持一致(如AppSync自定义域名为
mygraph.mydomain.com,Cloud Map服务名设为mygraph,则服务域名为mygraph.mydomain.com),确保证书覆盖该域名。 - 若使用通配符证书:申请
*.mydomain.com证书,覆盖所有Cloud Map服务域名。
- 若使用单域名证书:将Cloud Map服务名与AppSync自定义域名前缀保持一致(如AppSync自定义域名为
- 确保自定义域名在VPC内可解析
- 在与Cloud Map同VPC的私有Route53区域中,创建CNAME记录,将
mygraph.mydomain.com指向AppSync自定义域名对应的CloudFront分布域名。 - 配置CloudFront私有访问:创建CloudFront VPC端点(PrivateLink),确保VPC安全组允许ECS服务和Cloud Map健康检查访问该端点。
- 在与Cloud Map同VPC的私有Route53区域中,创建CNAME记录,将
- 修复Cloud Map健康检查
- 确保健康检查的目标
mygraph.mydomain.com/graphql在VPC内可访问,检查安全组、NACL是否允许443端口流量。
- 确保健康检查的目标
CDK代码调整
// AppSync配置:使用匹配Cloud Map命名空间的自定义域名 const api = new appsync.GraphqlApi(this, 'MyGraph', { // ...其他配置 visibility: appsync.Visibility.PRIVATE, domainName: { certificate: this.certificate, // 证书为*.mydomain.com或mygraph.mydomain.com domainName: 'mygraph.mydomain.com', }, }) // Cloud Map服务名与AppSync自定义域名前缀一致 const service = new servicediscovery.Service(this, 'GraphCloudMapService', { namespace: this.cloudMapNamespace, name: 'mygraph', // 服务域名:mygraph.mydomain.com,与AppSync自定义域名完全匹配 dnsRecordType: servicediscovery.DnsRecordType.CNAME, healthCheck: { resourcePath: '/graphql', type: servicediscovery.HealthCheckType.HTTPS, port: 443, }, }) // 注册AppSync自定义域名作为实例CNAME service.registerCnameInstance('GraphInstance', { instanceCname: 'mygraph.mydomain.com', })
验证步骤
- 在VPC内的EC2实例执行
nslookup mygraph.mydomain.com,确认返回正确的CNAME记录。 - 执行
curl -v https://mygraph.mydomain.com/graphql,验证SSL握手和API访问是否正常。
额外注意事项
- 私有AppSync API需配合AppSync VPC端点使用,确保ECS服务所在VPC已关联该端点。
- 若使用方案二,CloudFront分布需配置Origin Access Control(OAC),确保仅允许通过CloudFront访问AppSync API。
内容的提问来源于stack exchange,提问作者user3067870
相关产品推荐
相关产品推荐

