Skip to content

Use ARM64 AWS Lambdas #201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 6, 2025
Merged
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
14 changes: 7 additions & 7 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,52 +26,52 @@
uses: actions/cache@v4
with:
path: node_modules
key: yarn-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
key: yarn-modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
restore-keys: |
yarn-modules-${{ runner.os }}-
yarn-modules-${{ runner.arch }}-${{ runner.os }}-

- name: Run unit testing
run: make test_unit

build:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04-arm
name: Build Application
steps:
- uses: actions/checkout@v4
env:
HUSKY: "0"

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "yarn"

- name: Restore Yarn Cache
uses: actions/cache@v4
with:
path: node_modules
key: yarn-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
key: yarn-modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
restore-keys: |
yarn-modules-${{ runner.os }}-
yarn-modules-${{ runner.arch }}-${{ runner.os }}-

- name: Run build
run: make build
env:
HUSKY: "0"
VITE_RUN_ENVIRONMENT: dev

- name: Upload Build files
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: build
path: |
.aws-sam/
dist/
dist_ui/

deploy-test-dev:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
runs-on: ubuntu-latest
permissions:
id-token: write
Expand Down Expand Up @@ -99,9 +99,9 @@
uses: actions/cache@v4
with:
path: node_modules
key: yarn-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
key: yarn-modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
restore-keys: |
yarn-modules-${{ runner.os }}-
yarn-modules-${{ runner.arch }}-${{ runner.os }}-

- name: Download Build files
uses: actions/download-artifact@v4
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Deploy all resources to DEV/PROD
run-name: DEV/PROD deploy - @${{ github.actor }}
name: Deploy all resources to PROD
run-name: PROD deploy - @${{ github.actor }}

on:
workflow_dispatch:
Expand All @@ -25,52 +25,52 @@
uses: actions/cache@v4
with:
path: node_modules
key: yarn-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
key: yarn-modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-dev
restore-keys: |
yarn-modules-${{ runner.os }}-
yarn-modules-${{ runner.arch }}-${{ runner.os }}-

- name: Run unit testing
run: make test_unit

build:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04-arm
name: Build Application
steps:
- uses: actions/checkout@v4
env:
HUSKY: "0"

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: "yarn"

- name: Restore Yarn Cache
uses: actions/cache@v4
with:
path: node_modules
key: yarn-modules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-prod
key: yarn-modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}-prod
restore-keys: |
yarn-modules-${{ runner.os }}-
yarn-modules-${{ runner.arch }}-${{ runner.os }}-

- name: Run build
run: make build
env:
HUSKY: "0"
VITE_RUN_ENVIRONMENT: prod

- name: Upload Build files
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: build-prod
path: |
.aws-sam/
dist/
dist_ui/

deploy-prod:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
runs-on: ubuntu-latest
name: Deploy to Prod and Run Health Check
concurrency:
Expand Down
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,19 @@ build: src/ cloudformation/
VITE_BUILD_HASH=$(GIT_HASH) yarn build
cp -r src/api/resources/ dist/api/resources
rm -rf dist/lambda/sqs
sam build --template-file cloudformation/main.yml --use-container
sam build --template-file cloudformation/main.yml --use-container --parallel
mkdir -p .aws-sam/build/AppApiLambdaFunction/node_modules/aws-crt/
cp -r node_modules/aws-crt/dist .aws-sam/build/AppApiLambdaFunction/node_modules/aws-crt
## IF WE EVER CHANGE THE LAMBDA ARCH, BE SURE TO CHANGE THESE ##
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/aws-crt/dist/bin/darwin*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/aws-crt/dist/bin/linux-x64*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/aws-crt/dist/bin/linux-arm64-musl
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/darwin*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/freebsd*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/linux-arm
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/linux-x64*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/win32-x64*
rm -rf .aws-sam/build/AppApiLambdaFunction/node_modules/argon2/prebuilds/linux-arm64/argon2.armv8.musl.node

local:
VITE_BUILD_HASH=$(GIT_HASH) yarn run dev
Expand Down
12 changes: 7 additions & 5 deletions cloudformation/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,23 +250,24 @@ Resources:
DependsOn:
- AppLogGroups
Properties:
Architectures: [x86_64]
Architectures: [arm64]
CodeUri: ../dist/lambda
AutoPublishAlias: live
Runtime: nodejs22.x
Description: !Sub "${ApplicationFriendlyName} API Lambda"
FunctionName: !Sub ${ApplicationPrefix}-lambda
Handler: lambda.handler
MemorySize: 768
MemorySize: 2048
Role: !GetAtt AppSecurityRoles.Outputs.MainFunctionRoleArn
Timeout: 60
Environment:
Variables:
RunEnvironment: !Ref RunEnvironment
EntraRoleArn: !GetAtt AppSecurityRoles.Outputs.EntraFunctionRoleArn
LinkryKvArn: !GetAtt LinkryRecordsCloudfrontStore.Arn
AWS_CRT_NODEJS_BINARY_RELATIVE_PATH: node_modules/aws-crt/dist/bin/linux-x64-glibc/aws-crt-nodejs.node
AWS_CRT_NODEJS_BINARY_RELATIVE_PATH: node_modules/aws-crt/dist/bin/linux-arm64-glibc/aws-crt-nodejs.node
ORIGIN_VERIFY_KEY: !Join ['-', ['secret', !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]]]
NODE_OPTIONS: --enable-source-maps
VpcConfig:
Ipv6AllowedForDualStack: !If [ShouldAttachVpc, True, !Ref AWS::NoValue]
SecurityGroupIds:
Expand All @@ -292,14 +293,14 @@ Resources:
DependsOn:
- AppLogGroups
Properties:
Architectures: [x86_64]
Architectures: [arm64]
CodeUri: ../dist/sqsConsumer
AutoPublishAlias: live
Runtime: nodejs22.x
Description: !Sub "${ApplicationFriendlyName} SQS Lambda"
FunctionName: !Sub ${ApplicationPrefix}-sqs-lambda
Handler: index.handler
MemorySize: 512
MemorySize: 2048
Role:
Fn::GetAtt: AppSecurityRoles.Outputs.SqsFunctionRoleArn
Timeout: !Ref SqsLambdaTimeout
Expand All @@ -309,6 +310,7 @@ Resources:
Variables:
RunEnvironment: !Ref RunEnvironment
EntraRoleArn: !GetAtt AppSecurityRoles.Outputs.EntraFunctionRoleArn
NODE_OPTIONS: --enable-source-maps
VpcConfig:
Ipv6AllowedForDualStack: !If [ShouldAttachVpc, True, !Ref AWS::NoValue]
SecurityGroupIds:
Expand Down
4 changes: 2 additions & 2 deletions src/api/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const commonParams = {
".json": "file",
}, // File loaders
target: "es2022", // Target ES2022
sourcemap: false,
sourcemap: true,
platform: "node",
external: ["aws-sdk", ...packagesToTransfer],
external: ["@aws-sdk/*", ...packagesToTransfer],
alias: {
"moment-timezone": resolve(
process.cwd(),
Expand Down
3 changes: 1 addition & 2 deletions src/api/createLambdaPackage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ function getPath() {
return { pathname, dirname, basename };
}
// These are packages not bundled into the JS file by esbuild
// These packages have native deps that break when bundled
export const packagesToTransfer = [
"moment-timezone",
"passkit-generator",
"fastify",
"zod",
"argon2",
"ioredis",
];
Expand Down
3 changes: 0 additions & 3 deletions src/api/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ const buildOptions = {
},
banner: {
js: `
import { fileURLToPath } from 'url';
import { createRequire as topLevelCreateRequire } from 'module';
const require = topLevelCreateRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
`.trim(),
}, // Banner for compatibility with CommonJS
plugins: [
Expand Down
6 changes: 3 additions & 3 deletions src/api/functions/apiKey.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createHash, randomBytes } from "crypto";
import * as argon2 from "argon2";
import { hash, verify } from "argon2";
import { UnauthenticatedError } from "common/errors/index.js";
import NodeCache from "node-cache";
import {
Expand Down Expand Up @@ -33,7 +33,7 @@ export const createApiKey = async () => {
const rawKey = randomBytes(32).toString("hex");
const checksum = createChecksum(rawKey);
const apiKey = `${prefix}_${rawKey}_${checksum}`;
const hashedKey = await argon2.hash(rawKey);
const hashedKey = await hash(rawKey);
return { apiKey, hashedKey, keyId };
};

Expand Down Expand Up @@ -75,7 +75,7 @@ export const verifyApiKey = async ({
if (!isChecksumValid) {
return false;
}
return await argon2.verify(hashedKey, rawKey);
return await verify(hashedKey, rawKey);
} catch (e) {
if (e instanceof UnauthenticatedError) {
return false;
Expand Down
7 changes: 1 addition & 6 deletions src/api/lambda.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import awsLambdaFastify, { LambdaResponse } from "@fastify/aws-lambda";
import awsLambdaFastify from "@fastify/aws-lambda";
import init from "./index.js";
import warmer from "lambda-warmer";
import { type APIGatewayEvent, type Context } from "aws-lambda";
import { InternalServerError, ValidationError } from "common/errors/index.js";

Expand All @@ -11,10 +10,6 @@ const realHandler = awsLambdaFastify(app, {
callbackWaitsForEmptyEventLoop: false,
});
const handler = async (event: APIGatewayEvent, context: Context) => {
// if a warming event
if (await warmer(event, { correlationId: context.awsRequestId }, context)) {
return "warmed";
}
if (process.env.ORIGIN_VERIFY_KEY) {
// check that the request has the right header (coming from cloudfront)
if (
Expand Down
3 changes: 1 addition & 2 deletions src/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"ioredis": "^5.6.1",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.2.0",
"lambda-warmer": "^2.3.0",
"moment": "^2.30.1",
"moment-timezone": "^0.6.0",
"node-cache": "^5.1.2",
Expand All @@ -71,4 +70,4 @@
"nodemon": "^3.1.10",
"pino-pretty": "^13.0.0"
}
}
}
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7041,11 +7041,6 @@ known-css-properties@^0.37.0:
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.37.0.tgz#10ebe49b9dbb6638860ff8a002fb65a053f4aec5"
integrity sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==

lambda-warmer@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/lambda-warmer/-/lambda-warmer-2.3.0.tgz#c4dcb46c73cbdf732824d3c54a99b4752c6b8a04"
integrity sha512-k3E+5tXtzXdBX2JDaL+f59CREWTch+fsNk5tyrX69TpC6FgERoFS8xG/vQ4dHR9dUgpKxRf1+y+aH8EI4oF/MQ==

language-subtag-registry@^0.3.20:
version "0.3.23"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7"
Expand Down
Loading