【AWS CDK v2】创建固定IP的Lambda方法
在某些需要从Lambda访问受IP限制的服务器的情况下,或者在需要Lambda IP固定化的时候,在AWS CDK v2中如何实现。
组成
创建VPC,在其中将Lambda和EIP绑定以固定IP,并配置以访问互联网。
Lambda主体用TypeScript编写,利用axios执行API。
环境
cdk --version
2.21.1 (build a6ee543)
node_modules/.bin/tsc --v
Version 4.8.3
完整的工作
import { Duration, Stack, StackProps } from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";
export class VpcLambdaStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, "vpc", {
maxAzs: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: "PublicSubnet",
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: "PrivateSubnet",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
},
],
});
// セキュリティグループの作成
const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
vpc: vpc,
allowAllOutbound: true,
});
// Lambdaの作成
new nodejs.NodejsFunction(this, "VpcLambdaFunction", {
entry: "src/api-test/handler/handler.ts",
runtime: lambda.Runtime.NODEJS_16_X,
timeout: Duration.seconds(10),
vpc: vpc,
securityGroups: [securityGroup],
vpcSubnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
}),
allowPublicSubnet: true,
});
}
}
虚拟私有云
首先,我们将创建一个作为基础的VPC(请参考官方参考文档)。
在创建该VPC时,您还可以一并创建相关联的子网和EIP等资源。
在这里,除了默认的资源外,通过使用选项,我们分别对两个可用区创建了公共子网和私有子网。
const vpc = new ec2.Vpc(this, "vpc", {
maxAzs: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: "PublicSubnet",
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: "PrivateSubnet",
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
},
],
});
安全组
创建一个与Lambda相关联的安全组(官方参考文档在此)。
将安全组的vpc指定为刚刚创建的那个。
// セキュリティグループの作成
const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
vpc: vpc,
allowAllOutbound: true,
});
Lambda – fā yā
最后创建将放置在VPC中的Lambda(可参考官方参考资料)。
将先前创建的安全组传递给securityGroups,将subnetType设置为PRIVATE_WITH_NAT的子网传递给vpcSubnets,通过vpc的selectSubnets方法。由于Lambda函数需要访问互联网,还需要将allowPublicSubnet设置为true。
// Lambdaの作成
new nodejs.NodejsFunction(this, "VpcLambdaFunction", {
entry: "src/api-test/handler/handler.ts",
runtime: lambda.Runtime.NODEJS_16_X,
timeout: Duration.seconds(10),
vpc: vpc,
securityGroups: [securityGroup],
vpcSubnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
}),
allowPublicSubnet: true,
});
}
请确认固定IP是否已设定。
您可以在AWS控制台的EC2 -> 网络和安全 -> 弹性IP下找到已创建的EIP。
由于此次将maxAzs设置为2,因此将创建两个EIP。如果需要访问具有访问限制的服务器等,请确保允许此IP地址。
请注意:默认情况下,每个AWS账户在每个区域只能创建最多5个弹性IP地址。参考:弹性IP地址
总结
设置VPC以固定Lambda的IP地址,感觉需要进行详细的配置。但事实上,VPC会很好地创建所需的资源,所以实现起来意外地简单。
请注意,每个账户最多只能创建5个EIP,因此如果要使用多个环境,可能需要为每个环境分别设立账户来进行相应的处理。
我认为受到IP限制的访问很常见,如果这篇文章能对您有所帮助,我将感到幸运。
请查阅相关资料。
使用AWS CDK时尝试设置Lambda函数URL(函数URL)。(使用L1 Constract)从VPC关联给Lambda添加固定IP。
额外的东西
Lambda的实现细节
Lambda的实现是通过TypeScript,并使用axios来执行API。
以下示例可发送简单的POST请求。
import { APIGatewayProxyEvent } from "aws-lambda";
import axios from "axios";
import * as log from "lambda-log";
/**
* apiを実行するLambda
* @param event
* @returns
*/
export const handler = async (event: APIGatewayProxyEvent) => {
log.info("event row data", { event });
const endpoint = "https://example.com/";
const headers = {
"Content-Type": "application/json",
};
const body = {
id: "XXXXXXXXXX",
};
// APIを実行
try {
return await axios
.post(endpoint, body, {
headers: headers,
})
.then((response) => {
log.info("raw response data", { data: response.data });
})
.catch(async (reason) => {
log.error("Executing api failed.", { reason });
throw reason;
});
} catch (e) {
log.error(`Error executing api, reason=${(e as Error).message}`);
}
};