Skip to content

FileSystem

Source: src/AWS/EFS/FileSystem.ts

An Amazon EFS file system — serverless, elastic, shared POSIX storage.

The file system is created encrypted by default with a deterministic creation token derived from the app, stage, and logical ID, so retried creates are idempotent. Mount it into compute with MountTarget (per-subnet network endpoints) and AccessPoint (application-specific POSIX entry points — required for Lambda mounts).

Default file system (encrypted, general purpose)

import * as AWS from "alchemy/AWS";
const files = yield* AWS.EFS.FileSystem("Files");

Elastic throughput

const files = yield* AWS.EFS.FileSystem("Files", {
throughputMode: "elastic",
});
const files = yield* AWS.EFS.FileSystem("Files", {
lifecyclePolicies: [
{ transitionToIA: "AFTER_30_DAYS" },
{ transitionToPrimaryStorageClass: "AFTER_1_ACCESS" },
],
});

Enable AWS Backup automatic backups

const files = yield* AWS.EFS.FileSystem("Files", {
backup: true,
});

Allow the file system to be a replication destination

const files = yield* AWS.EFS.FileSystem("Files", {
replicationOverwriteProtection: "DISABLED",
});
const files = yield* AWS.EFS.FileSystem("Files", {
policy: {
Version: "2012-10-17",
Statement: [
{
Sid: "DenyUnencryptedTransport",
Effect: "Deny",
Principal: { AWS: "*" },
Action: ["elasticfilesystem:ClientMount"],
Condition: { Bool: { "aws:SecureTransport": "false" } },
},
],
},
});

Lambda mounts EFS through an access point; the function must be attached to a VPC that can reach a mount target.

File system + mount target + access point + Lambda

const files = yield* AWS.EFS.FileSystem("Files");
const target = yield* AWS.EFS.MountTarget("FilesTarget", {
fileSystemId: files.fileSystemId,
subnetId,
});
const accessPoint = yield* AWS.EFS.AccessPoint("FilesAccess", {
fileSystemId: files.fileSystemId,
posixUser: { uid: 1000, gid: 1000 },
rootDirectory: {
path: "/lambda",
creationInfo: { ownerUid: 1000, ownerGid: 1000, permissions: "750" },
},
});
const fn = yield* AWS.Lambda.Function("Api", {
main: "./src/handler.ts",
vpc: { subnetIds: [subnetId], securityGroupIds: [securityGroupId] },
fileSystemConfigs: [
// pass the AccessPoint resource itself (or its ARN)
{ accessPoint, localMountPath: "/mnt/files" },
],
// depend on the mount target so the function is created only after
// the network endpoint is available
env: { EFS_MOUNT_TARGET: target.mountTargetId },
});

Host-agnostic mount binding (Lambda or ECS)

EFS.mount wires the mount config + least-privilege IAM through the host’s binding channel — the same code works inside a Lambda Function or an ECS Task body (provide AWS.EFS.MountLive on the host Effect).

export default class Api extends AWS.Lambda.Function<Api>()(
"Api",
{ main: import.meta.url, vpc: { subnetIds, securityGroupIds } },
Effect.gen(function* () {
const files = yield* AWS.EFS.mount(accessPoint, { path: "/mnt/files" });
return Effect.fn(function* (event: unknown) {
// read/write under files.path at runtime
return { mountedAt: files.path };
});
}).pipe(Effect.provide(AWS.EFS.MountLive)),
) {}