serverless-vpc-plugin
![npm downloads](https://img.shields.io/npm/dt/serverless-vpc-plugin.svg?style=flat)
Automatically creates an AWS Virtual Private Cloud (VPC) using all available Availability Zones (AZ) in a region.
This plugin provisions the following resources:
AWS::EC2::VPC
AWS::EC2::InternetGateway
(for outbound internet access from "Public" subnet)AWS::EC2::VPCGatewayAttachment
(to attach the InternetGateway
to the VPC)AWS::EC2::SecurityGroup
(to execute Lambda functions [AppSecurityGroup
])
If the VPC is allocated a /16 subnet, each availability zone within the region will be allocated a /20 subnet. Within each availability zone, this plugin will further divide the subnets:
AWS::EC2::Subnet
"Public" (/22) - default route set to the InternetGateway
AWS::EC2::Subnet
"Application" (/21) - no default route set (can be set to either a NatGateway
or NatInstance
)AWS::EC2::Subnet
"Database" (/22) - no default route set
The subnetting layout was heavily inspired by the now shutdown Skyliner platform. 😞
Optionally, this plugin can also create AWS::EC2::NatGateway
instances in each availability zone which requires provisioning AWS::EC2::EIP
resources (AWS limits you to 5 per VPC, so if you want to provision your VPC across all 6 us-east availability zones, you'll need to request an VPC EIP limit increase from AWS).
Instead of using the managed AWS::EC2::NatGateway
instances, this plugin can also provision a single t2.micro
NAT instance in PublicSubnet1
which will allow HTTP/HTTPS traffic from the "Application" subnets to reach the Internet.
Lambda functions will execute within the "Application" subnet and only be able to access:
- S3 (via an S3 VPC endpoint)
- DynamoDB (via an DynamoDB VPC endpoint)
- RDS instances (provisioned within the "DB" subnet)
- ElastiCache instances (provisioned within the "DB" subnet)
- RedShift (provisioned within the "DB" subnet),
- DAX clusters (provisioned within the "DB" subnet)
- Neptune clusters (provisioned with the "DB" subnet)
- Internet Access (if using a
NatGateway
or a NatInstance
)
If your Lambda functions need to access the internet, then you MUST provision NatGateway
resources or a NAT instance.
By default, AWS::EC2::VPCEndpoint
"Gateway" endpoints for S3 and DynamoDB will be provisioned within each availability zone to provide internal access to these services (there is no additional charge for using Gateway Type VPC endpoints). You can selectively control which AWS::EC2::VPCEndpoint
"Interface" endpoints are available within your VPC using the services
configuration option below. Not all AWS services are available in every region, so the plugin will query AWS to validate the services you have selected and notify you if any changes are required (there is an additional charge for using Interface Type VPC endpoints).
If you specify more then one availability zone, this plugin will also provision the following database-related resources (controlled using the subnetGroups
plugin option):
AWS::RDS::DBSubnetGroup
AWS::ElastiCache::SubnetGroup
AWS::Redshift::ClusterSubnetGroup
AWS::DAX::SubnetGroup
to make it easier to create these resources across all of the availability zones.
Installation
$ npx sls plugin install -n serverless-vpc-plugin
Configuration
- All
vpcConfig
configuration parameters are optional
plugins:
- serverless-vpc-plugin
provider:
vpc:
securityGroupIds:
-
subnetIds:
-
custom:
vpcConfig:
enabled: true
cidrBlock: '10.0.0.0/16'
createNatGateway: 2
createNetworkAcl: false
createDbSubnet: true
createFlowLogs: false
createBastionHost: false
bastionHostKeyName: MyKey
createNatInstance: false
createParameters: false
zones:
- us-east-1a
- us-east-1b
- us-east-1c
services:
- kms
- secretsmanager
subnetGroups:
- rds
exportOutputs: false
CloudFormation Outputs
After executing serverless deploy
, the following CloudFormation Stack Outputs will be provided:
VPC
: VPC logical resource IDAppSecurityGroup
: Security Group ID that the applications use when executing within the VPCLambdaExecutionSecurityGroupId
: DEPRECATED - Please use AppSecurityGroupId insteadBastionSSHUser
: SSH username to access the bastion host, if provisionedBastionEIP
: Elastic IP address associated to the bastion host, if provisionedRDSSubnetGroup
: SubnetGroup associated to RDS, if provisionedElastiCacheSubnetGroup
: SubnetGroup associated to ElastiCache, if provisionedRedshiftSubnetGroup
: SubnetGroup associated to Redshift, if provisionedDAXSubnetGroup
: SubnetGroup associated to DAX, if provisionedAppSubnet{i}
: Each of the generated "Application" Subnets, where i is a 1 based index
Exporting CloudFormation Outputs
Setting exportOutputs: true
will export stack outputs. The name of the exported value will be prefixed by the cloud formation stack name (AWS::StackName
). For example, the value of the VPC
output of a stack named foo-prod
will be exported as foo-prod-VPC
.
SSM Parameters
Setting createParameters: true
will create the below parameters in the AWS Systems Manager (SSM) Parameter Store:
/SLS/${AWS::StackName}/VPC
: VPC logical resource ID/SLS/${AWS::StackName}/AppSecurityGroup
: Security Group ID that the applications use when executing within the VPC/SLS/${AWS::StackName}/RDSSubnetGroup
: SubnetGroup associated to RDS, if provisioned/SLS/${AWS::StackName}/ElastiCacheSubnetGroup
: SubnetGroup associated to ElastiCache, if provisioned/SLS/${AWS::StackName}/RedshiftSubnetGroup
: SubnetGroup associated to Redshift, if provisioned/SLS/${AWS::StackName}/DAXSubnetGroup
: SubnetGroup associated to DAX, if provisioned/SLS/${AWS::StackName}/PublicSubnets
: Subnet ID's for the "Public" subnets/SLS/${AWS::StackName}/AppSubnets
: Subnet ID's for the "Application" subnets/SLS/${AWS::StackName}/DBSubnets
: Subnet ID's for the "Database" subnets
As an example, if the stack name you want to reference is new-service-dev
, you can then use Serverless' built-in support for reading from SSM:
vpc:
securityGroupIds:
- ${ssm:/SLS/new-service-dev/AppSecurityGroup}
subnetIds: ${ssm:/SLS/new-service-dev/AppSubnets~split}
(Note the usage of ~split
to split the SSM StringList
parameter type and return an array of values)