Skip to content

VPCs in AWS are isolated virtual networks that provide the networking foundation for your applications. Stackattack creates VPCs with public and private subnets across multiple availability zones, internet gateways, NAT gateways, and VPC endpoints.

import * as saws from "@stackattack/aws";
const ctx = saws.context();
// NOTE: if you have multiple VPCs e.g. for different
// environments you should specify the `cidrBlock` argument,
// with non-overlapping CIDRs for each VPC
// e.g. `10.0.0.0/16` (the default), `10.1.0.0/16`, `10.2.0.0/16`, etc.
const vpc = saws.vpc(ctx);
// `vpcToIds` converts the VPC to only its serializable
// identifiers suitable for stack outputs. The full VPC
// object can be retrieved in other stacks by using
// `saws.vpcFromIds(stackRef.require('vpc'))`
export { vpc: saws.vpcToIds(vpc) };

After deploying your VPC, you’ll be able to deploy resources into it. See the Related Components for examples of how resources can be deployed into VPCs.

One important thing you’ll need to determine is how you access private resources within your VPC from your local machine—by default the only connectivity provided to private resources is SSH access to EC2 instances via EC2 Instance Connect.

Stackattack provides a few options:

  • twingate-connector - Deploys a Twingate Connector for Zero Trust access access to your resources via the Twingate client app. This is a good option: it’s very easy to set up and relatively cheap.
  • vpc - This sets up an AWS Client VPN endpoint that you can connect to via any OpenVPN client. This provides a way to provision a VPN for access to private resources without any third-party services. However, this option is quite expensive. See the costs for the VPN component for details.

VPCs provide the networking foundation for other Stackattack components:

  • cluster - Requires VPC networking for ECS instances
  • service - Runs in VPC private subnets
  • database - Deployed in VPC private subnets for security
  • load-balancer - Uses VPC public subnets for internet access
  • redis - Deployed in VPC private subnets

VPC core resources are free, but associated components incur charges:

  • VPC, subnets, route tables, security groups - No charge for the basic networking infrastructure.

  • NAT Gateway - Stackattack creates NAT Gateway(s) for private subnets (~$45/month + $0.045/GB processed apiece). This enables private subnet instances to access the internet while remaining inaccessible from the internet. If you pass nat: "multi" one NAT gateway per private subnet will be created, whereas if you pass nat: "single" only one will be created for all private subnets. Passing nat: "none" will not create a NAT gateway, but resources in your private subnets will not have access to the public internet.

  • Public IP addresses - Each public IP address costs ~$3.60/month. One public IP address is allocated per NAT gateway.

  • Internet Gateway - Free for the gateway itself, but data transfer charges apply (~$0.09/GB out to internet).

  • Instance Connect Endpoints - Stackattack creates these for secure SSH access (~$3.60/month per endpoint + $0.10/hour when in use).

  • VPC Flow Logs - If enabled, logs cost ~$0.50/GB stored in CloudWatch Logs. Can generate significant data if traffic is high.

Cost optimization strategies:

  • NAT gateways are typically the largest driver of cost (though usage-based charges can eclipse them based on usag of course). For this reason, the default is to create only a single NAT gateway for all of your private subnets. Be aware that using nat: "multi" may lead to significantly higher costs (for the benefit of higher availability).
  • Use the default flowLogs: false unless you need traffic analysis

See VPC Pricing for current rates.

Creates a complete VPC with public and private subnets across availability zones.

function vpc(ctx: Context, args?: VpcArgs): VpcOutput
  • ctx (Context) - The context for resource naming and tagging
  • args? (VpcArgs) - VPC configuration arguments
  • (VpcOutput) - Creates a complete VPC with public and private subnets across availability zones.

Get an array of availability zones based on either a number or an array of either full AZ names (us-east-1a, us-west-2b, etc.) or just a single letter (a, b, etc.). If a number is provided, it will return the first N availability zones in the current region.

function availabilityZones(zones: number | Input<string>[]): Output<string>[]
  • zones (number | Input<string>[]) -
  • (Output<string>[]) - Get an array of availability zones based on either a number or an array of either full AZ names (us-east-1a, us-west-2b, etc.) or just a single letter (a, b, etc.). If a number is provided, it will return the first N availability zones in the current region.

Create an EC2 instance connect endpoint for SSH access to instances without public IP addresses

function ec2InstanceConnectEndpoint(ctx: Context, args: EC2InstanceConnectEndpoint): InstanceConnectEndpoint
  • (InstanceConnectEndpoint) - Create an EC2 instance connect endpoint for SSH access to instances without public IP addresses

Retrieves VPC attributes from various VPC input formats.

function getVpcAttributes(input: Input<VpcInput>): Output<Vpc | GetVpcResult>
  • input (Input<VpcInput>) - VPC input in any supported format
  • (Output<Vpc | GetVpcResult>) - Retrieves VPC attributes from various VPC input formats.

Retrieves the default security group for a VPC.

function getVpcDefaultSecurityGroup(vpcId: Input<string>): Output<GetSecurityGroupResult>
  • vpcId (Input<string>) - The VPC ID to get the default security group for
  • (Output<GetSecurityGroupResult>) - Retrieves the default security group for a VPC.

Gets the VPC DNS server IP address based on the VPC CIDR block. AWS reserves the second IP address in the VPC CIDR block for the DNS server.

function getVpcDnsServer(cidrBlock: Input<string>): Output<string>
  • cidrBlock (Input<string>) - The VPC CIDR block
  • (Output<string>) - Gets the VPC DNS server IP address based on the VPC CIDR block. AWS reserves the second IP address in the VPC CIDR block for the DNS server.

Extracts the VPC ID from various VPC input formats.

function getVpcId(input: Input<VpcInput>): Output<string>
  • input (Input<VpcInput>) - VPC input in any supported format
  • (Output<string>) - Extracts the VPC ID from various VPC input formats.

Creates an Internet Gateway attached to a VPC.

function internetGateway(ctx: Context, args: InternetGatewayArgs): InternetGateway
  • ctx (Context) - The context for resource naming and tagging
  • args (InternetGatewayArgs) - Internet Gateway configuration arguments
  • (InternetGateway) - Creates an Internet Gateway attached to a VPC.

Create an S3 Gateway VPC endpoint to connect to S3 within a VPC without going through the public internet

function s3GatewayEndpoint(ctx: Context, args: S3GatewayEndpointArgs): VpcEndpoint
  • (VpcEndpoint) - Create an S3 Gateway VPC endpoint to connect to S3 within a VPC without going through the public internet

Creates public and private subnets across multiple availability zones.

function subnets(ctx: Context, args: SubnetsArgs): { privateSubnetIds: Output<string>[]; publicSubnetIds: Output<string>[] }
  • ctx (Context) - The context for resource naming and tagging
  • args (SubnetsArgs) - Subnet configuration arguments
  • ({ privateSubnetIds: Output<string>[]; publicSubnetIds: Output<string>[] }) - Creates public and private subnets across multiple availability zones.

Creates VPC Flow Logs with associated log group and IAM role.

function vpcFlowLogs(ctx: Context, args: VPCFlowLogsArgs): FlowLog
  • ctx (Context) - The context for resource naming and tagging
  • args (VPCFlowLogsArgs) - VPC Flow Logs configuration arguments
  • (FlowLog) - Creates VPC Flow Logs with associated log group and IAM role.

Creates an IAM role for VPC Flow Logs with appropriate permissions.

function vpcFlowLogsRole(ctx: Context, args: VPCFlowLogsRoleArgs): Role
  • ctx (Context) - The context for resource naming and tagging
  • args (VPCFlowLogsRoleArgs) - VPC Flow Logs role configuration arguments
  • (Role) - Creates an IAM role for VPC Flow Logs with appropriate permissions.

Reconstructs a VPC output from serialized VPC IDs.

function vpcFromIds(vpcInput: Input<VpcIds>, increment?: number): { cidrAllocator: CidrAllocator; network: (type: NetworkType, azs?: number) => { subnetIds: Output<Output<string>[]>; vpc: Output<Vpc | GetVpcResult> }; privateSubnetIds: Output<Output<string>[]>; publicSubnetIds: Output<Output<string>[]>; vpc: Output<Vpc | GetVpcResult> }
  • vpcInput (Input<VpcIds>) - The VPC IDs input to reconstruct from
  • increment? (number) - Optional increment to add to the CIDR counter
  • ({ cidrAllocator: CidrAllocator; network: (type: NetworkType, azs?: number) => { subnetIds: Output<Output<string>[]>; vpc: Output<Vpc | GetVpcResult> }; privateSubnetIds: Output<Output<string>[]>; publicSubnetIds: Output<Output<string>[]>; vpc: Output<Vpc | GetVpcResult> }) - Reconstructs a VPC output from serialized VPC IDs.

Converts a VPC output to a serializable VPC IDs format.

function vpcToIds(vpc: VpcOutput): VpcIds
  • vpc (VpcOutput) - The VPC output to convert
  • (VpcIds) - Converts a VPC output to a serializable VPC IDs format.

Interface for allocating CIDR blocks within a VPC.

  • allocate ((netmask: number) => Output<string>) - Allocates a subnet with the specified netmask within the VPC CIDR block
  • counter (() => OutputInstance<number>) - Returns the current allocation counter

Input parameters for ec2InstanceConnectEndpoint

  • noPrefix? (boolean) - Do not add a prefix to the context
  • subnetId (Input<string>) - ID of the private subnet to associate the endpoint with. You will still be able to access resources in other subnets (so long as your other configuration allows it; it does by default if you used Stackattack components to create your vpc)

Arguments for creating an Internet Gateway.

  • noPrefix? (boolean) - Whether to skip adding prefix to the resource name
  • vpc (Input<VpcInput>) - The VPC to attach the Internet Gateway to

Represents a network configuration with VPC and subnets.

  • subnetIds (Output<string>[]) - Array of subnet IDs in the network
  • vpc (Vpc) - The VPC resource

Input type for network configuration.

  • subnetIds (Input<Input<string>[]>) - Array of subnet ID inputs
  • vpc (Input<VpcInput>) - The VPC input

Input parameters for s3GatewayEndpoint

  • noPrefix? (boolean) - Do not add a prefix to the context
  • privateRouteTableId (Input<string>) - ID of the private route table to associate the endpoint with
  • vpc (Input<VpcInput>) - The target VPC to create subnets in
  • availabilityZones? (number | Input<string>[]) - Availability zone input; see availabilityZones for details on behavior
  • cidrAllocator (CidrAllocator) - CIDR allocator for getting new cidrs
  • nat? ("single" | "none" | "multi") - Whether to create a NAT gateway or not; single (the default) creates a single NAT gateway in the first subnet in your VPC. multi creates a NAT gateway per subnet for high availability. none does not create any NAT gateways.
  • noPrefix? (boolean) - Do not add a prefix to the context
  • noS3Endpoints? (boolean) - By default, s3 gateway endpoint(s) will be created for internal access to S3. Passing true disables this behavior. Otherwise, one S3 endpoint will be created per private route table—so one if you’re using nat: "single" or nat: "none" (default), or one per AZ if you’re using nat: "multi"
  • subnetMask? (number) - Indicate the netmask to use for subnets, which defines how many IP addresses are available. Defaults to 20 (4096 IP addresses available per subnet)
  • vpc (Input<VpcInput>) - The target VPC to create subnets in

Input properties for the vpc component

  • availabilityZones? (number | Input<string>[]) - Availability zone input; see availabilityZones for details on behavior
  • cidrBlock? (Input<string>) - Provide a CIDR block that defines the range of addresses for your VPC. Defaults to 10.0.0.0/16 if not provided. See https://docs.aws.amazon.com/vpc/latest/userguide/vpc-cidr-blocks.html for details
  • flowLogs? (boolean) - Indicate whether VPC Flow Logs should be enabled
  • nat? ("single" | "none" | "multi") - Whether to create a NAT gateway or not; single (the default) creates a single NAT gateway in the first subnet in your VPC. multi creates a NAT gateway per subnet for high availability. none does not create any NAT gateways.
  • noInstanceConnectEndpoint? (boolean) - By default, an EC2 Instance Connect endpoint will be created for SSH access to EC2 instances without a public IP address. Passing true disables this behavior.
  • noPrefix? (boolean) - Do not add a name prefix to the context
  • noProtect? (boolean) - By default, VPCs are created with protect: true, which prevent accidental deletion. To disable this behavior, pass true.
  • noS3Endpoints? (boolean) - By default, s3 gateway endpoint(s) will be created for internal access to S3. Passing true disables this behavior. Otherwise, one S3 endpoint will be created per private route table—so one if you’re using nat: "single" or nat: "none" (default), or one per AZ if you’re using nat: "multi"
  • subnetMask? (number) - Indicate the netmask to use for subnets, which defines how many IP addresses are available. Defaults to 20 (4096 IP addresses available per subnet)

Arguments for creating VPC Flow Logs.

  • noPrefix? (boolean) - Whether to skip adding prefix to the resource name
  • vpc (VpcInput) - The VPC to enable flow logs for

Arguments for creating a VPC Flow Logs IAM role.

  • logGroup (LogGroupInput) - The log group where flow logs will be written
  • noPrefix? (boolean) - Whether to skip adding prefix to the resource name

Interface representing VPC resources as IDs for serialization.

  • counter (OutputInstance<number>) - CIDR allocation counter
  • privateSubnetIds (Output<string>[]) - Array of private subnet IDs
  • publicSubnetIds (Output<string>[]) - Array of public subnet IDs
  • vpc (Output<string>) - The VPC ID
  • cidrAllocator (CidrAllocator) - The cidrAllocator provides a way to allocate new CIDR blocks within the vpc for subnets or other purposes, given a netmask.
  • network ((type: NetworkType, azs?: number) => Network) - Method to get a Network, which is a VPC and a set of subnets. type should be “public” to choose public subnet IDs, and “private” to choose private ones. You can optionally pass a number of azs to limit the number of availability zones that you want to include subnets from
  • privateSubnetIds (Output<string>[]) - The private subnet IDs created in the VPC
  • publicSubnetIds (Output<string>[]) - The public subnet IDs created in the VPC
  • vpc (Vpc) - The created VPC object

Type representing network visibility - either public or private.

type NetworkType = "public" | "private"

Union type representing various VPC input formats. Accepts VPC ID string, VPC resource, VPC result, or VPC output.

type VpcInput = string | aws.ec2.Vpc | aws.ec2.GetVpcResult | VpcOutput