node.js - 使用 AWS-CDK 部署时无法从 Lambda 服务连接到 Elasticache Redis 集群
问题描述
在过去的几天里,我一直在尝试使用 aws-cdk(typescript) 复制我们现有的 AWS VPC,我发现从 nodejs lambda 函数连接到 Redis 很困难。我遵循了有关创建新 VPC、设置私有/公共/隔离子网以及将服务部署到各自子网的标准教程。
我用来尝试实现此目的的代码如下:
import { NodejsFunction } from "@aws-cdk/aws-lambda-nodejs";
import * as elasticache from "@aws-cdk/aws-elasticache";
import * as apiGateway from "@aws-cdk/aws-apigateway";
import * as rds from "@aws-cdk/aws-rds";
import * as iam from "@aws-cdk/aws-iam";
import * as ec2 from "@aws-cdk/aws-ec2";
import * as cdk from "@aws-cdk/core";
import * as path from "path";
import * as dotenv from "dotenv";
const some_service_path =
"/some/service/path";
const env = dotenv.config({
path: path.join(some_service_path, "env", ".production.env"),
});
export class TestStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, "VPC", {
subnetConfiguration: [
{
cidrMask: 24,
name: "ingress",
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: "application",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
},
{
cidrMask: 28,
name: "rds",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
});
const rdsSubnetIds = vpc.selectSubnets({
subnetGroupName: "rds",
}).subnetIds;
const redisClusterSubnetGroup = new elasticache.CfnSubnetGroup(
this,
"RedisClusterPrivateSubnetGroup",
{
subnetIds: rdsSubnetIds,
cacheSubnetGroupName: "cluster-subnet",
description: "Sandboxed redis cluster",
}
);
const redisReplicationGroup = new elasticache.CfnReplicationGroup(
this,
"company-redis-replication-sandbox",
{
replicasPerNodeGroup: 2,
numNodeGroups: 3,
cacheSubnetGroupName: redisClusterSubnetGroup.cacheSubnetGroupName,
replicationGroupDescription: "company Redis replication group",
replicationGroupId: "company-redis-replication-group",
securityGroupIds: [vpc.vpcDefaultSecurityGroup],
authToken: "authtoken",
cacheNodeType: "cache.t2.micro",
transitEncryptionEnabled: true,
atRestEncryptionEnabled: true,
multiAzEnabled: true,
engine: "redis",
}
);
redisReplicationGroup.addDependsOn(redisClusterSubnetGroup);
const entry = path.join(__dirname, "service", "handler.ts");
const { subnets: applicationSubnet } = vpc.selectSubnets({
subnetGroupName: "application",
});
const someServiceLambda = new NodejsFunction(this, "some-service", {
runtime: lambda.Runtime.NODEJS_14_X,
vpcSubnets: { subnets: applicationSubnet },
entry: entry,
handler: "graphqlHandler",
environment: {
...env.parsed,
REDIS_HOST: redisReplicationGroup.attrConfigurationEndPointAddress,
REDIS_PORT: redisReplicationGroup.attrConfigurationEndPointPort,
REDIS_PASSWORD: "authtoken",
REDIS_MODE: "cluster",
REDIS_USE_TLS: "true",
},
vpc,
});
new apiGateway.LambdaRestApi(this, "someServiceEndpoint", {
handler: someServiceLambda,
});
}
}
该服务是一个依赖于节点模块 IORedis 的 ApolloGQL 应用程序。当我从浏览器访问 lambda 函数时,GraphQL 游乐场正确加载;但是,当我尝试运行连接到 Redis 集群的突变时,我收到以下 IORedis 错误:
ERROR [ioredis] Unhandled error event: ClusterAllFailedError: Failed to refresh slots cache.
at tryNode (/var/task/index.js:88946:27)
at /var/task/index.js:88963:15
at Timeout.<anonymous> (/var/task/index.js:89178:20)
at Timeout.run (/var/task/index.js:84969:20)
at listOnTimeout (internal/timers.js:559:11)
at processTimers (internal/timers.js:500:7)
任何帮助将不胜感激。
解决方案
推荐阅读
- html - 为什么我的 Angular 应用程序的 html 代码中的花括号没有编译其中的内容?
- sql - 用 LAG、OVER 和未确定的偏移量填充数据集的 Null 行?
- java - 具有嵌入式十六进制编码的 Java 字符串
- c++ - grpc构建卡在虚拟机上
- python - 样式化时从数据框中删除索引和标题
- javascript - 如何强制正则表达式尽可能少地抓取?
- python - 问题制作 FizzBuzz
- azure - "message": "调用 Microsoft.Web/sites 失败。错误消息:SkuCode 'SKU' 无效。",
- mysql - 查询以不同方式显示表中的值
- python-3.x - 使用 Django Factory Boy,我如何为外键生成工厂?