Skip to main content

Overview

The ComputeFactory is Fjall’s pattern for creating compute resources. It provides a unified interface to deploy different compute types including ECS containers, EC2 instances, and Lambda functions.

Basic Usage

Compute Types

ECS (Elastic Container Service)

Deploy containerised applications with three variants:

Fargate Spot (Cost Savings)

EC2-backed ECS

Lambda Functions

Deploy serverless functions with code deployment:
With container images:
Container-based Lambdas require an ECR repository. The ecrRepository parameter is required when deployment: "container". When using Fjall’s App scaffolding, ECR repositories are created automatically.

EC2 Instances

Deploy traditional virtual machines:

Configuration Parameters

Common Parameters

Connection Syntax

Connect compute resources to databases, storage, and queues:

ECS Parameters

Service Configuration

Each service in the services array:

Container Configuration

Each container in the containers array:

Routing Configuration

Scaling Configuration

scalingType takes the ScalingType enum, not a string. Import it from @fjall/components-infrastructure:

ECS Cluster Configuration

Configure the ECS cluster at the root level of the ComputeFactory:

Load Balancer Options

Custom Domain Configuration

EC2 Capacity Provider Configuration

When using capacityProvider: "EC2", additional EC2-specific options are available:
The service-level cpu and memoryLimitMiB fields are Fargate only. On an EC2 service, size the container with ec2Config.memoryLimitMiB instead — from 4.2.0, setting either on EC2 capacity is rejected at synth.

Upgrading to 4.2.0 or later

Before 4.2.0 a service-level cpu or memoryLimitMiB on an EC2 service was silently ignored. A service whose config reads memoryLimitMiB: 2048 has in fact been running on ec2Config.memoryLimitMiB — or, where that was unset, on the 1024 MiB default. 4.2.0 rejects the ambiguous config at synth instead, with an error naming the field and the service. A service-level memoryLimitMiB that already matches ec2Config.memoryLimitMiB is accepted, so a redundant but consistent config needs no change. Check what the container is actually running before you move a value across. Copying memoryLimitMiB: 2048 into an ec2Config that had no memoryLimitMiB doubles the real memory limit at the next deploy — that may be what you wanted, but it is a change to a running workload, not a no-op config tidy. Deleting the ignored field instead leaves the deployed size exactly as it is.

Upgrading to 5.0.0 — services that share an Auto Scaling group

Two EC2 services in the same cluster share one Auto Scaling group when their ec2Config agrees on instanceType, amiHardwareType, warmPool, persistentDataVolume and availabilityZones. Those five fields are the sharing key. Every other ec2Config field — minCapacity, maxCapacity, desiredCapacity, instanceMonitoring, associatePublicIpAddress, machineImage, userData, blockDevices and tags — is read only when the group is first created. Before 5.0.0 the second service’s values for those fields were silently discarded, so it ran on whichever sizing the first service happened to declare. From 5.0.0 a mismatch is rejected at synth, naming both services and every field that differs. As with the memory guard, this is a narrowing: a config that synthesised on 4.x can fail on 5.0.0.
There are two cures, and they mean different things:
  • Equalise the values if the services were always meant to share capacity. The group already runs on the first service’s numbers, so copying those onto the second is the no-op — copying the second service’s numbers onto the first resizes a running group.
  • Diverge one of the five keyed fields (a different instanceType, say) if the services were meant to scale independently. That gives each its own group, which is a new instance and a real cost change.
machineImage, userData and blockDevices are compared on presence only — set-versus-unset — because CDK gives them no cheap structural identity. Two services that each supply their own equivalent userData are accepted.

Upgrading to 12.0.0 — the EC2 default instance type and the memory-fit guard

Two related changes land in 12.0.0:
  • The default ec2Config.instanceType is now t4g.small (previously t4g.micro). The old default could never place a task: a micro registers roughly 896 MiB with ECS, below the 1024 MiB default container limit. A service that omitted instanceType gets its instances replaced on the next deploy — since that shape could never start a task before, no working workload is affected. Pin instanceType explicitly to opt out.
  • The synth-time memory-fit guard now applies to defaulted instance types too. If the sum of container hard memory limits reaches the instance type’s nominal memory, synth fails — whether the type was set explicitly or defaulted. On 11.x the defaulted shape only warned.
Explicit t4g.micro remains fully supported (it is what the free-tier Tinkerer preset pins, with memoryLimitMiB: 400): keep the container limits under roughly 896 MiB total and the guard stays quiet.

Multi-Container Service Example

Lambda Parameters

architecture takes the Architecture enum from aws-cdk-lib/aws-lambda, not a string. Use Architecture.ARM_64 or Architecture.X86_64.

EC2 Parameters

Database Connections

Connect compute resources to databases:

Lambda Function URLs

Make Lambda functions publicly accessible:

Auto-Scaling

ECS services support auto-scaling:

Custom Domains

Configure custom domains for ECS services:

Cost Optimisation

Development Environments

Use Fargate Spot for cost savings:

Production Environments

Right-size resources:

Next Steps

Storage Factory

Create S3 buckets and storage resources.

Database Factory

Provision Aurora, RDS, DynamoDB, and ClickHouse databases.

Standard Pattern

Compose full applications from these factories.

ECS Cluster Resources

Configure ECS clusters for advanced workloads.