> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fjall.io/llms.txt
> Use this file to discover all available pages before exploring further.

# VPC

> Create an isolated AWS VPC with Fjall, including multi-AZ subnets, NAT gateways, flow logs, IPAM allocation, and VPC endpoints.

## Overview

The Fjall `Vpc` construct extends the AWS CDK `ec2.Vpc` with sensible defaults for network isolation. It creates public and private subnets across multiple availability zones, configures NAT gateways, enables flow logs, allocates IP ranges from IPAM, and provisions VPC endpoints, all through one set of Fjall props.

Because `Vpc` extends `ec2.Vpc`, every standard CDK VPC property remains available alongside the Fjall additions.

## Import

```typescript theme={null}
import { Vpc } from "@fjall/components-infrastructure/lib/resources/aws/networking/vpc";
```

## Basic Usage

```typescript theme={null}
const vpc = new Vpc(this, "AppVpc", {
  maxAzs: 2,
  natGatewayConfig: { count: 1 },
});
```

## Configuration Options

### Core Properties

| Property            | Type                          | Description                            | Default                          |
| ------------------- | ----------------------------- | -------------------------------------- | -------------------------------- |
| `vpcName`           | `string`                      | VPC name tag                           | The construct id                 |
| `maxAzs`            | `number`                      | Maximum availability zones             | `3`                              |
| `availabilityZones` | `string[]`                    | Specific AZs to use                    | First `maxAzs` AZs in the region |
| `natGatewayConfig`  | `{ count?: number } \| false` | NAT gateway count, or `false` for none | CDK default                      |

`natGatewayConfig` resolves to a NAT gateway count: an object uses `count` (default `1`), and `false` disables NAT gateways. The raw CDK `natGateways` number remains available as an `ec2.VpcProps` pass-through, but prefer `natGatewayConfig` so the construct can apply its own resolution.

### Flow Log Properties

| Property                      | Type                            | Description                                                          | Default                      |
| ----------------------------- | ------------------------------- | -------------------------------------------------------------------- | ---------------------------- |
| `flowLogConfig`               | `VpcFlowLogConfig \| false`     | Flow log destination, retention, traffic type, or `false` to disable | Auto when `accountId` is set |
| `flowLogConfig.destination`   | `"cloudwatch" \| "s3"`          | Where logs are written                                               | `"cloudwatch"`               |
| `flowLogConfig.retentionDays` | `number`                        | CloudWatch log retention in days                                     | `14`                         |
| `flowLogConfig.trafficType`   | `"ALL" \| "ACCEPT" \| "REJECT"` | Traffic captured                                                     | `"ALL"`                      |

### IPAM Properties

| Property         | Type     | Description                                       | Default |
| ---------------- | -------- | ------------------------------------------------- | ------- |
| `accountId`      | `string` | Account ID, required to enable flow logs and IPAM | -       |
| `ipv4IpamPoolId` | `string` | IPAM pool ID for IP allocation                    | -       |
| `vpcCidrMask`    | `number` | Netmask length for the IPAM-allocated VPC CIDR    | `20`    |
| `subnetCidrMask` | `number` | Default subnet netmask length under IPAM          | `23`    |

### VPC Endpoint Properties

| Property                    | Type                                                                    | Description         | Default                 |
| --------------------------- | ----------------------------------------------------------------------- | ------------------- | ----------------------- |
| `endpointsConfig.gateway`   | `{ s3?, dynamodb? } \| false`                                           | Gateway endpoints   | S3 and DynamoDB enabled |
| `endpointsConfig.interface` | `{ ecr?, secretsManager?, kms?, cloudwatchLogs?, ssm?, sts? } \| false` | Interface endpoints | Off unless requested    |

### Additional Properties

All standard CDK `ec2.VpcProps` are supported through the extending class, including `subnetConfiguration`, `ipAddresses`, and `natGatewayProvider`.

## Default Configuration

With no props, the construct creates:

* **3 availability zones** for high availability
* **Public and private-with-egress subnets**, one of each per AZ
* **An internet gateway** plus NAT gateways per the CDK default
* **Gateway endpoints** for S3 and DynamoDB

Flow logs and IPAM allocation activate only when you supply `accountId` (and `ipv4IpamPoolId` for IPAM).

## NAT Gateway Configuration

```typescript theme={null}
// Single NAT gateway (lower cost)
const devVpc = new Vpc(this, "DevVpc", {
  natGatewayConfig: { count: 1 },
});

// No NAT gateway (lowest cost)
const isolatedVpc = new Vpc(this, "IsolatedVpc", {
  natGatewayConfig: false,
});
```

When NAT gateways are disabled, the construct places interface endpoints in `PRIVATE_ISOLATED` subnets so private workloads can still reach AWS services.

## Flow Logs

Flow logs turn on automatically once `accountId` is set. They write to a CloudWatch log group at `/vpc/flowlogs/vpc-${id}/`.

```typescript theme={null}
// CloudWatch flow logs (automatic when accountId is provided)
const monitoredVpc = new Vpc(this, "MonitoredVpc", {
  accountId: "123456789012",
});

// S3 flow logs with 30-day retention
const archivedVpc = new Vpc(this, "ArchivedVpc", {
  accountId: "123456789012",
  flowLogConfig: {
    destination: "s3",
    retentionDays: 30,
    trafficType: "REJECT",
  },
});
```

Set `flowLogConfig: false` to disable flow logs even when `accountId` is present.

## IPAM Integration

When you supply both `accountId` and `ipv4IpamPoolId`, the construct allocates the VPC CIDR from your IPAM pool.

```typescript theme={null}
const ipamVpc = new Vpc(this, "IpamVpc", {
  accountId: "123456789012",
  ipv4IpamPoolId: "ipam-pool-1234567890abcdef0",
});
```

IPAM allocation defaults to a `/20` VPC CIDR and `/23` subnet masks. Override them with `vpcCidrMask` and `subnetCidrMask`.

## VPC Endpoints

Gateway endpoints (S3, DynamoDB) are on by default. Request interface endpoints individually.

```typescript theme={null}
const endpointVpc = new Vpc(this, "EndpointVpc", {
  natGatewayConfig: false,
  endpointsConfig: {
    gateway: { s3: true, dynamodb: false },
    interface: {
      ecr: true,
      secretsManager: true,
      cloudwatchLogs: true,
    },
  },
});
```

Interface endpoint keys: `ecr`, `secretsManager`, `kms`, `cloudwatchLogs`, `ssm`, `sts`. Enabling `ecr` provisions both the ECR API and ECR Docker endpoints. Enabling `ssm` provisions SSM, SSM Messages, and EC2 Messages.

## Custom Subnets

Pass standard CDK `subnetConfiguration` for a multi-tier layout.

```typescript theme={null}
const vpc = new Vpc(this, "MultiTierVpc", {
  maxAzs: 2,
  subnetConfiguration: [
    { name: "web", subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24 },
    {
      name: "app",
      subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
      cidrMask: 23,
    },
    { name: "data", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24 },
  ],
});
```

## Factory and StackBuilder Patterns

### Network Factory

The canonical way to add a VPC inside a Fjall app is `NetworkFactory.build` passed to `app.addNetwork`. The factory wires account, region, and IPAM context automatically.

```typescript theme={null}
import { NetworkFactory } from "@fjall/components-infrastructure";

const isolatedVpc = app.addNetwork(
  NetworkFactory.build("IsolatedVpc", {
    maxAzs: 2,
    natGateways: false,
    flowLogs: {},
    vpcEndpoints: { interface: { ecr: true } },
  }),
);
```

`NetworkFactory` props use `natGateways`, `flowLogs`, `vpcEndpoints`, and `subnets`, which it maps onto the construct's `natGatewayConfig`, `flowLogConfig`, and `endpointsConfig`. See the [Network Factory pattern](/patterns/network-factory) for the full prop reference.

### StackBuilder

```typescript theme={null}
const vpc = Vpc.build("NetworkVpc", {
  maxAzs: 3,
})(stackBuilder);
```

### Import an Existing VPC

```typescript theme={null}
const importedVpc = Vpc.import(
  "ImportedVpc",
  "existing-stack-name",
)(stackBuilder);
```

## Static Helpers

The construct exposes the helpers it uses internally, so you can compute the same values in custom code.

```typescript theme={null}
// First `maxAzs` AZs in the region
const azs = Vpc.availabilityZones(this, 3);

// CloudWatch or S3 flow log options
const flowLogs = Vpc.flowLogs(this, "MyVpc", { accountId: "123456789012" });

// IPAM-backed ipAddresses provider
const ipConfig = Vpc.ipAddresses(this, "MyVpc", {
  accountId: "123456789012",
  ipv4IpamPoolId: "ipam-pool-1234567890abcdef0",
});
```

## Complete Example

```typescript theme={null}
import { Vpc } from "@fjall/components-infrastructure/lib/resources/aws/networking/vpc";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import { CfnOutput } from "aws-cdk-lib";

const prodVpc = new Vpc(this, "ProductionVpc", {
  maxAzs: 3,
  natGatewayConfig: { count: 2 },
  accountId: this.account,
  ipv4IpamPoolId: props.ipamPoolId,
  endpointsConfig: {
    interface: { ecr: true, secretsManager: true },
  },
  subnetConfiguration: [
    { name: "web", subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24 },
    {
      name: "app",
      subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
      cidrMask: 23,
    },
    { name: "data", subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24 },
  ],
});

// Pass prodVpc to downstream constructs:
//   ECS Cluster  -> /resources/compute/ecs-cluster
//   RDS Aurora   -> /resources/database/rds-aurora

new CfnOutput(this, "VpcId", {
  value: prodVpc.vpcId,
  description: "VPC ID",
});
```

## Cost Considerations

| Resource            | Cost                   | Optimisation                                          |
| ------------------- | ---------------------- | ----------------------------------------------------- |
| NAT gateway         | \~\$45/month plus data | Use a single NAT gateway or `natGatewayConfig: false` |
| Interface endpoints | \~\$7/month per AZ     | Saves on NAT data transfer for AWS-service traffic    |
| Flow logs           | Storage costs          | Use S3 for cheaper long-term storage                  |

## Troubleshooting

| Issue                                       | Check                                                                  |
| ------------------------------------------- | ---------------------------------------------------------------------- |
| CIDR conflicts                              | Plan IP ranges across accounts before deploying                        |
| Private workloads cannot reach AWS services | Enable the matching interface endpoints when `natGatewayConfig: false` |
| Flow logs missing                           | Confirm `accountId` is set and `flowLogConfig` is not `false`          |

```bash theme={null}
# Describe the VPC
aws ec2 describe-vpcs --vpc-ids vpc-12345

# Check route tables
aws ec2 describe-route-tables --filters "Name=vpc-id,Values=vpc-12345"
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Network Factory" icon="diagram-project" href="/patterns/network-factory">
    Compose VPCs declaratively with NetworkFactory props.
  </Card>

  <Card title="Security Group" icon="shield-halved" href="/resources/networking/security-group">
    Control inbound and outbound traffic for VPC resources.
  </Card>

  <Card title="ECS Cluster" icon="server" href="/resources/compute/ecs-cluster">
    Run containers inside your VPC's private subnets.
  </Card>

  <Card title="RDS Aurora" icon="database" href="/resources/database/rds-aurora">
    Deploy a managed database into VPC subnets.
  </Card>
</CardGroup>
