Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions examples/vpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Production-Grade VPC Infrastructure

This example provisions a complete AWS VPC with public and private subnets across multiple availability zones, ready for production workloads.

## Architecture

- **VPC** with DNS support and hostnames enabled
- **Internet Gateway** attached to the VPC for public internet access
- **NAT Gateway** with Elastic IP for private subnet outbound traffic
- **3 Public Subnets** across AZs (a, b, c) with auto-assigned public IPs
- **3 Private Subnets** across AZs (a, b, c) for internal workloads
- **Route Tables** — public routes through IGW, private routes through NAT
- **Security Groups** — public SG defaults, private SG allows all intra-VPC traffic

## Files

| File | Description |
|------|-------------|
| `main.pkl` | Entry point — wires variables into VPC class and spreads resources |
| `vars.pkl` | Configuration variables, CLI-overridable props, stack and target |
| `infrastructure/vpc.pkl` | Reusable VPC class that produces all resources |

## Usage

Ensure the formae agent is running, then:

```bash
formae apply --mode reconcile --watch examples/vpc/main.pkl
```

### CLI Overrides

Override defaults via flags:

```bash
formae apply --mode reconcile --watch examples/vpc/main.pkl \
--name my-vpc \
--region us-east-1 \
--vpc-cidr 10.0.0.0/16
```

## Default Configuration

| Variable | Default |
|----------|---------|
| `name` | `vpc-example` |
| `region` | `us-west-2` |
| `vpc-cidr` | `10.1.0.0/16` |
| Public subnets | `10.1.0.0/19`, `10.1.64.0/19`, `10.1.128.0/19` |
| Private subnets | `10.1.32.0/19`, `10.1.96.0/19`, `10.1.160.0/19` |
214 changes: 214 additions & 0 deletions examples/vpc/infrastructure/vpc.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
* © 2025 Platform Engineering Labs Inc.
*
* SPDX-License-Identifier: FSL-1.1-ALv2
*/

import "@aws/aws.pkl"
import "@aws/ec2/eip.pkl"
import "@aws/ec2/internetgateway.pkl"
import "@aws/ec2/natgateway.pkl"
import "@aws/ec2/route.pkl"
import "@aws/ec2/routetable.pkl"
import "@aws/ec2/securitygroup.pkl"
import "@aws/ec2/securitygroupingress.pkl"
import "@aws/ec2/subnet.pkl"
import "@aws/ec2/subnetroutetableassociation.pkl"
import "@aws/ec2/vpc.pkl"
import "@aws/ec2/vpcgatewayattachment.pkl"


class VPC {
name: String
region: aws.Region
cidr: String

publicZoneCidrs: Mapping<String, String>
privateZoneCidrs: Mapping<String, String>

hidden infraVpc: vpc.VPC = new {
label = "\(name)-vpc"
cidrBlock = cidr
enableDnsHostnames = true
enableDnsSupport = true
tags {
new {
key = "Name"
value = label
}
}
}

hidden natIp: eip.EIP = new {
label = name
}

hidden igw: internetgateway.InternetGateway = new {
label = name
tags {
new {
key = "Name"
value = label
}
}
}

hidden ngw: natgateway.NatGateway = new {
label = name
subnetId = publicSubnets.first.res.id
allocationId = natIp.res.id
tags {
new {
key = "Name"
value = label
}
}
}

hidden publicSubnets: Listing<subnet.Subnet> = new {
for (zone, subnet in publicZoneCidrs) {
new subnet.Subnet {
label = "\(name)-public-\(zone)"
vpcId = infraVpc.res.id
cidrBlock = subnet
availabilityZone = "\(region)\(zone)"
mapPublicIpOnLaunch = true
tags {
new {
key = "Name"
value = label
}
}
}
}
}
hidden privateSubnets: Listing<subnet.Subnet> = new {
for (zone, subnet in privateZoneCidrs) {
new subnet.Subnet {
label = "\(name)-private-\(zone)"
vpcId = infraVpc.res.id
cidrBlock = subnet
availabilityZone = "\(region)\(zone)"
mapPublicIpOnLaunch = false
tags {
new {
key = "Name"
value = label
}
}
}
}
}

hidden publicRouteTable: routetable.RouteTable = new {
label = "\(name)-public"
vpcId = infraVpc.res.id
tags {
new {
key = "Name"
value = label
}
}
}
hidden privateRouteTable: routetable.RouteTable = new {
label = "\(name)-private"
vpcId = infraVpc.res.id
tags {
new {
key = "Name"
value = label
}
}
}

hidden publicSecurityGroup: securitygroup.SecurityGroup = new {
label = "\(name)-public"
vpcId = infraVpc.res.id
groupDescription = "Default public subnet rules"

tags {
new {
key = "Name"
value = label
}
}
}

hidden privateSecurityGroup: securitygroup.SecurityGroup = new {
label = "\(name)-private"
groupDescription = "Default private subnet rules"
vpcId = infraVpc.res.id
tags {
new {
key = "Name"
value = label
}
}
}

hidden privateSecurityGroupRules: Listing = new {
new securitygroupingress.SecurityGroupIngress {
label = "\(name)-private-allow-all"
ipProtocol = "-1"
cidrIp = cidr
groupId = privateSecurityGroup.res.id
}
}

hidden resources: Listing = new {
infraVpc

igw

new vpcgatewayattachment.VPCGatewayAttachment {
label = name
vpcId = infraVpc.res.id
internetGatewayId = igw.res.id
}

...publicSubnets
...privateSubnets

natIp

ngw

publicRouteTable
privateRouteTable

publicSecurityGroup
privateSecurityGroup
...privateSecurityGroupRules

// Routes
new route.Route {
label = "\(name)-public-default"
routeTableId = publicRouteTable.res.id
destinationCidrBlock = "0.0.0.0/0"
gatewayId = igw.res.id
}

new route.Route {
label = "\(name)-private-default"
routeTableId = privateRouteTable.res.id
destinationCidrBlock = "0.0.0.0/0"
natGatewayId = ngw.res.id
}

for (subnet in publicSubnets) {
new subnetroutetableassociation.SubnetRouteTableAssociation {
label = subnet.label
subnetId = subnet.res.subnetId
routeTableId = publicRouteTable.res.routeTableId
}
}

for (subnet in privateSubnets) {
new subnetroutetableassociation.SubnetRouteTableAssociation {
label = subnet.label
subnetId = subnet.res.subnetId
routeTableId = privateRouteTable.res.routeTableId
}
}
}
}
48 changes: 48 additions & 0 deletions examples/vpc/main.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* © 2025 Platform Engineering Labs Inc.
*
* SPDX-License-Identifier: FSL-1.1-ALv2
*/

amends "@formae/forma.pkl"
import "@aws/aws.pkl"

import "./infrastructure/vpc.pkl"
import "./vars.pkl"

description {
text = """
Production-Grade VPC Infrastructure.

This forma provisions a complete AWS VPC with public and private subnets
across multiple availability zones.

This includes:
- VPC with DNS support and hostnames enabled
- Internet Gateway for public internet access
- NAT Gateway with Elastic IP for private subnet outbound traffic
- Public subnets (3 AZs) with auto-assigned public IPs
- Private subnets (3 AZs) for internal workloads
- Public and private route tables with appropriate routes
- Security groups for public and private subnets (private allows intra-VPC traffic)
- Subnet-to-route-table associations
"""
confirm = true
}

local vpcInfra = new vpc.VPC {
name = properties.name.value
region = properties.region.value as aws.Region
cidr = properties.vpcCidr.value
publicZoneCidrs = vars.publicZoneCidrs
privateZoneCidrs = vars.privateZoneCidrs
}

properties = vars.props

forma {
vars.stack
vars.target

...vpcInfra.resources
}
51 changes: 51 additions & 0 deletions examples/vpc/vars.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* © 2025 Platform Engineering Labs Inc.
*
* SPDX-License-Identifier: FSL-1.1-ALv2
*/

import "@formae/formae.pkl"
import "@aws/aws.pkl"

projectName = "vpc-example"
region = "us-west-2"
vpcCidr = "10.1.0.0/16"

publicZoneCidrs: Mapping<String, String> = new {
["a"] = "10.1.0.0/19"
["b"] = "10.1.64.0/19"
["c"] = "10.1.128.0/19"
}

privateZoneCidrs: Mapping<String, String> = new {
["a"] = "10.1.32.0/19"
["b"] = "10.1.96.0/19"
["c"] = "10.1.160.0/19"
}

props = new Dynamic {
name = new formae.Prop {
flag = "name"
default = module.projectName
}
region = new formae.Prop {
flag = "region"
default = module.region
}
vpcCidr = new formae.Prop {
flag = "vpc-cidr"
default = module.vpcCidr
}
}

stack: formae.Stack = new {
label = "vpc-example"
description = "Stack for VPC infrastructure deployment"
}

target: formae.Target = new formae.Target {
label = "aws-target"
config = new aws.Config {
region = module.props.region.value
}
}