I've been trying de deploy a RestApiGateway with 20 lambda functions since a while now, and I keep getting the error message Subnet is out of IP addresses every time I try to deploy. Any idea why this may be happening?
Here's how my Vpc stack looks like:
this.vpc = new ec2.Vpc(this, 'vpc', {
cidr: '10.0.0.0/21',
maxAzs: this.azs,
natGateways: this.azs,
subnetConfiguration: [
{
subnetType: ec2.SubnetType.PUBLIC,
name: `${APP_PREFIX}-public-subnet`,
cidrMask: 24,
},
{
subnetType: ec2.SubnetType.PRIVATE,
name: `${APP_PREFIX}-private-subnet`,
cidrMask: 28,
},
],
});
...and here's the gateway:
const interfaceVpcEndpoint = vpc.addInterfaceEndpoint(`${APP_PREFIX}-endpoint`, {
service: ec2.InterfaceVpcEndpointAwsService.APIGATEWAY,
subnets: { subnetType: ec2.SubnetType.PRIVATE },
});
const restApiLogGroup = new logs.LogGroup(stack, `${APP_PREFIX}-log-group`, {
logGroupName: `${APP_PREFIX}-log-group`,
});
return new gateway.RestApi(stack, `${APP_PREFIX}-rest-api`, {
restApiName: `${APP_PREFIX}-rest-api`,
endpointConfiguration: {
types: [gateway.EndpointType.PRIVATE],
vpcEndpoints: [interfaceVpcEndpoint],
},
retainDeployments: true,
deployOptions: {
stageName: 'v2',
loggingLevel: gateway.MethodLoggingLevel.INFO,
dataTraceEnabled: true,
accessLogDestination: new gateway.LogGroupLogDestination(restApiLogGroup),
accessLogFormat: gateway.AccessLogFormat.jsonWithStandardFields(),
},
policy: new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.DENY,
principals: [new iam.AnyPrincipal()],
actions: ['execute-api:Invoke'],
resources: ['execute-api:/*/POST/*'],
conditions: {
StringNotEquals: {
'aws:sourceVpc': vpc.vpcId,
},
},
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [new iam.AnyPrincipal()],
actions: ['execute-api:Invoke'],
resources: ['execute-api:/*/POST/*'],
}),
],
}),
});
The idea is that the lambda functions should not be accessible from the internet, only from a Fargate service that I will deploy via another stack.
I think this is the problem:
cidrMask: 28
A /28 network allows 16 IP addresses, and AWS takes 3 of those addresses for itself.
I'm not familiar with the CDK classes to create a subnet, so can't say whether the overall approach that you're using is correct. I'm assuming that it's smart enough to break the VPC CIDR into subnet blocks based on what you provide for a mask.
I recommend giving at least a /24 allocation to each subnet; I prefer a /20. And a /16 to the VPC. Network configuration is free when you start, extremely expensive to correct later.