Skip to content

Commit 65b60ed

Browse files
committed
feat: add BitBake hash equivalence server on ECS Fargate
Adds a shared bitbake-hashserv running on ECS Fargate in the same VPC as CodeBuild. Uses Cloud Map service discovery (hashserv.internal:8686) and stores its database on an EFS access point. - lib/hash-equivalence-server.ts: reusable CDK construct - hashserv/: container image (python + bitbake-hashserv) - hashserv-deploy/: standalone CDK app for deployment Deployed to us-west-2 on 2026-04-01.
1 parent 6a7190f commit 65b60ed

8 files changed

Lines changed: 1044 additions & 0 deletions

File tree

hashserv-deploy/app.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env node
2+
import * as cdk from "aws-cdk-lib";
3+
import * as ec2 from "aws-cdk-lib/aws-ec2";
4+
import * as efs from "aws-cdk-lib/aws-efs";
5+
import * as ecs from "aws-cdk-lib/aws-ecs";
6+
import * as iam from "aws-cdk-lib/aws-iam";
7+
import * as logs from "aws-cdk-lib/aws-logs";
8+
import * as servicediscovery from "aws-cdk-lib/aws-servicediscovery";
9+
import { Construct } from "constructs";
10+
11+
const app = new cdk.App();
12+
13+
const env = {
14+
account: "205930633217",
15+
region: "us-west-2",
16+
};
17+
18+
/**
19+
* Standalone stack that deploys the Hash Equivalence Server
20+
* alongside the existing EmbeddedLinuxCodeBuildProject infrastructure.
21+
*/
22+
class HashEquivalenceServerStack extends cdk.Stack {
23+
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
24+
super(scope, id, props);
25+
26+
const port = 8686;
27+
28+
// Import existing resources
29+
const vpc = ec2.Vpc.fromLookup(this, "Vpc", {
30+
vpcId: "vpc-0674b335dfcb26866",
31+
});
32+
33+
const codeBuildSg = ec2.SecurityGroup.fromSecurityGroupId(
34+
this,
35+
"CodeBuildSg",
36+
"sg-0819bfca947c7c361",
37+
);
38+
39+
const sstateSg = ec2.SecurityGroup.fromSecurityGroupId(
40+
this,
41+
"SstateFsSg",
42+
"sg-03318f553912dbc34",
43+
);
44+
45+
const sstateFs = efs.FileSystem.fromFileSystemAttributes(
46+
this,
47+
"SstateFs",
48+
{
49+
fileSystemId: "fs-0e8a6bba497718a0c",
50+
securityGroup: sstateSg,
51+
},
52+
);
53+
54+
// EFS access point for hashserv database
55+
const accessPoint = new efs.AccessPoint(this, "HashServAccessPoint", {
56+
fileSystem: sstateFs,
57+
path: "/hashserv",
58+
createAcl: { ownerGid: "1000", ownerUid: "1000", permissions: "755" },
59+
posixUser: { gid: "1000", uid: "1000" },
60+
});
61+
62+
// Security group for the Fargate task
63+
const hashservSg = new ec2.SecurityGroup(this, "HashServSG", {
64+
vpc,
65+
description: "Hash Equivalence Server",
66+
});
67+
hashservSg.addIngressRule(
68+
codeBuildSg,
69+
ec2.Port.tcp(port),
70+
"CodeBuild to HashServ",
71+
);
72+
sstateSg.addIngressRule(
73+
hashservSg,
74+
ec2.Port.tcp(2049),
75+
"HashServ to EFS",
76+
);
77+
78+
// ECS Fargate
79+
const cluster = new ecs.Cluster(this, "HashEquivCluster", { vpc });
80+
81+
const taskDef = new ecs.FargateTaskDefinition(this, "HashServTask", {
82+
cpu: 256,
83+
memoryLimitMiB: 512,
84+
});
85+
86+
taskDef.addVolume({
87+
name: "hashserv-data",
88+
efsVolumeConfiguration: {
89+
fileSystemId: "fs-0e8a6bba497718a0c",
90+
transitEncryption: "ENABLED",
91+
authorizationConfig: {
92+
accessPointId: accessPoint.accessPointId,
93+
iam: "ENABLED",
94+
},
95+
},
96+
});
97+
98+
taskDef.taskRole.addToPrincipalPolicy(
99+
new iam.PolicyStatement({
100+
actions: [
101+
"elasticfilesystem:ClientMount",
102+
"elasticfilesystem:ClientWrite",
103+
],
104+
resources: [
105+
`arn:aws:elasticfilesystem:${this.region}:${this.account}:file-system/fs-0e8a6bba497718a0c`,
106+
],
107+
conditions: {
108+
StringEquals: {
109+
"elasticfilesystem:AccessPointArn": accessPoint.accessPointArn,
110+
},
111+
},
112+
}),
113+
);
114+
115+
const container = taskDef.addContainer("hashserv", {
116+
image: ecs.ContainerImage.fromAsset("../hashserv"),
117+
command: [
118+
"--bind",
119+
`0.0.0.0:${port}`,
120+
"--database",
121+
"/hashserv-data/hashserv.db",
122+
"--log",
123+
"INFO",
124+
],
125+
logging: ecs.LogDrivers.awsLogs({
126+
streamPrefix: "hashserv",
127+
logRetention: logs.RetentionDays.ONE_MONTH,
128+
}),
129+
portMappings: [{ containerPort: port }],
130+
});
131+
132+
container.addMountPoints({
133+
sourceVolume: "hashserv-data",
134+
containerPath: "/hashserv-data",
135+
readOnly: false,
136+
});
137+
138+
// Service discovery — hashserv.internal
139+
const namespace = new servicediscovery.PrivateDnsNamespace(
140+
this,
141+
"HashServNamespace",
142+
{ name: "internal", vpc },
143+
);
144+
145+
new ecs.FargateService(this, "HashServService", {
146+
cluster,
147+
taskDefinition: taskDef,
148+
desiredCount: 1,
149+
securityGroups: [hashservSg],
150+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
151+
cloudMapOptions: {
152+
cloudMapNamespace: namespace,
153+
name: "hashserv",
154+
},
155+
});
156+
157+
new cdk.CfnOutput(this, "HashServEndpoint", {
158+
value: `hashserv.internal:${port}`,
159+
description: "Hash Equivalence Server endpoint for BB_HASHSERVE",
160+
});
161+
}
162+
}
163+
164+
new HashEquivalenceServerStack(app, "HashEquivalenceServer", { env });
165+
app.synth();

hashserv-deploy/cdk.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts app.ts",
3+
"context": {
4+
"@aws-cdk/core:bootstrapQualifier": "hnb659fds"
5+
}
6+
}

0 commit comments

Comments
 (0)