Skip to content

Commit

Permalink
x86 Deployment Compatibility (#68)
Browse files Browse the repository at this point in the history
* Added Windows bundling and leader board title change

* updated base-stack with x86 bundling
  • Loading branch information
StevenAskwith authored Nov 6, 2024
1 parent f64b4ef commit f30acf8
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 118 deletions.
6 changes: 5 additions & 1 deletion lib/base-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as s3 from 'aws-cdk-lib/aws-s3';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
import { Construct } from 'constructs';
import * as os from 'os';
import { Cdn } from './constructs/cdn';
import { Eventbridge } from './constructs/eventbridge';
import { Idp } from './constructs/idp';
Expand Down Expand Up @@ -96,7 +97,10 @@ export class BaseStack extends cdk.Stack {
// Common Config
const lambda_architecture = awsLambda.Architecture.ARM_64;
const lambda_runtime = awsLambda.Runtime.PYTHON_3_11;
const lambda_bundling_image = DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.11:latest-arm64');
var lambda_bundling_image = DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.11:latest');
if (os.arch() === 'arm64') {
lambda_bundling_image = DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.11:latest-arm64');
}

// Layers
const lambdaLayers = this.lambdaLayers(stack, lambda_architecture, lambda_runtime, lambda_bundling_image);
Expand Down
230 changes: 116 additions & 114 deletions lib/constructs/standard-lambda-python-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,130 +6,132 @@ import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as logs from 'aws-cdk-lib/aws-logs';
import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
import * as os from 'os';

export interface StandardPythonFunctionProps extends lambdaPython.PythonFunctionProps {
index?: string;
handler?: string;
timeout?: Duration;
tracing?: lambda.Tracing;
memorySize?: number;
architecture?: lambda.Architecture;
bundling?: {
image: DockerImage;
};
layers?: lambda.ILayerVersion[];
environment: {
POWERTOOLS_SERVICE_NAME: string;
LOG_LEVEL?: string;
[others: string]: any;
};
logRetention?: logs.RetentionDays;
role?: iam.Role;
index?: string;
handler?: string;
timeout?: Duration;
tracing?: lambda.Tracing;
memorySize?: number;
architecture?: lambda.Architecture;
bundling?: {
image: DockerImage;
};
layers?: lambda.ILayerVersion[];
environment: {
POWERTOOLS_SERVICE_NAME: string;
LOG_LEVEL?: string;
[others: string]: any;
};
logRetention?: logs.RetentionDays;
role?: iam.Role;
}
export class StandardLambdaPythonFunction extends lambdaPython.PythonFunction {
public readonly role: iam.Role;
public readonly nodePath: string;
public readonly role: iam.Role;
public readonly nodePath: string;

constructor(scope: Construct, id: string, props: StandardPythonFunctionProps) {
const stack = cdk.Stack.of(scope);
constructor(scope: Construct, id: string, props: StandardPythonFunctionProps) {
const stack = cdk.Stack.of(scope);

var localProps = props;
var localProps = props;

// set defaults if not supplied
if (!localProps.index) {
localProps.index = 'index.py';
}
if (!localProps.handler) {
localProps.handler = 'lambda_handler';
}
if (!localProps.timeout) {
localProps.timeout = Duration.minutes(1);
}
if (!localProps.tracing) {
localProps.tracing = lambda.Tracing.ACTIVE;
}
if (!localProps.memorySize) {
localProps.memorySize = 128;
}
if (!localProps.architecture) {
localProps.architecture = lambda.Architecture.ARM_64;
}
if (!localProps.bundling) {
localProps.bundling = {
image: DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.11:latest-arm64'),
};
}
if (!localProps.layers) {
// Powertools layer
const powertoolsLambdaLayer = lambdaPython.PythonLayerVersion.fromLayerVersionArn(
scope,
`${id}-lambdaPowertoolsLambdaLayer`,
`arn:aws:lambda:${stack.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:11`
);
localProps.layers = [powertoolsLambdaLayer];
}
if (!localProps.environment.LOG_LEVEL) {
localProps.environment.LOG_LEVEL = 'INFO';
}
if (!localProps.logRetention) {
localProps.logRetention = logs.RetentionDays.SIX_MONTHS;
}
if (!localProps.role) {
localProps.role = new iam.Role(scope, `${id}-LambdaFunctionRole`, {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
description: 'IAM Role for Lambda Function',
});
}
// set defaults if not supplied
if (!localProps.index) {
localProps.index = 'index.py';
}
if (!localProps.handler) {
localProps.handler = 'lambda_handler';
}
if (!localProps.timeout) {
localProps.timeout = Duration.minutes(1);
}
if (!localProps.tracing) {
localProps.tracing = lambda.Tracing.ACTIVE;
}
if (!localProps.memorySize) {
localProps.memorySize = 128;
}
if (!localProps.architecture) {
localProps.architecture = lambda.Architecture.ARM_64;
}
if (!localProps.bundling) {
if (os.arch() === 'arm64') {
console.log('OS: ', os.arch());
localProps.bundling = {
image: DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.12:latest-arm64'),
};
} else {
localProps.bundling = {
image: DockerImage.fromRegistry('public.ecr.aws/sam/build-python3.12:latest'),
};
}
}
if (!localProps.layers) {
// Powertools layer
const powertoolsLambdaLayer = lambdaPython.PythonLayerVersion.fromLayerVersionArn(
scope,
`${id}-lambdaPowertoolsLambdaLayer`,
`arn:aws:lambda:${stack.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:11`
);
localProps.layers = [powertoolsLambdaLayer];
}
if (!localProps.environment.LOG_LEVEL) {
localProps.environment.LOG_LEVEL = 'INFO';
}
if (!localProps.logRetention) {
localProps.logRetention = logs.RetentionDays.SIX_MONTHS;
}
if (!localProps.role) {
localProps.role = new iam.Role(scope, `${id}-LambdaFunctionRole`, {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
description: 'IAM Role for Lambda Function',
});
}

super(scope, id, localProps);
super(scope, id, localProps);

const cloudWatchLogsPermissions = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
resources: [super.logGroup.logGroupArn],
});
const cloudWatchLogsPermissions = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
resources: [super.logGroup.logGroupArn],
});

localProps.role.attachInlinePolicy(
new iam.Policy(this, `${id}-CloudWatchLogs`, {
statements: [cloudWatchLogsPermissions],
})
);
this.role = localProps.role;
localProps.role.attachInlinePolicy(
new iam.Policy(this, `${id}-CloudWatchLogs`, {
statements: [cloudWatchLogsPermissions],
})
);
this.role = localProps.role;

this.nodePath = `${scope.node.path}/${id}`;
NagSuppressions.addResourceSuppressionsByPath(
stack,
`${scope.node.path}/${id}/${id}-CloudWatchLogs/Resource`,
[
{
id: 'AwsSolutions-IAM5',
reason: 'CloudWatch Logs permissions require a wildcard as streams are created dynamically.',
},
]
);
this.nodePath = `${scope.node.path}/${id}`;
NagSuppressions.addResourceSuppressionsByPath(stack, `${scope.node.path}/${id}/${id}-CloudWatchLogs/Resource`, [
{
id: 'AwsSolutions-IAM5',
reason: 'CloudWatch Logs permissions require a wildcard as streams are created dynamically.',
},
]);

NagSuppressions.addResourceSuppressions(
this.role,
[
{
id: 'AwsSolutions-IAM5',
reason: "Suppress AwsSolutions-IAM5 'xray:PutTelemetryRecords' and 'xray:PutTraceSegments' on *, which is created when CDK enables tracing",
appliesTo: ['Resource::*'],
},
],
true
);
}
public addAdditionalRolePolicy(
id: string,
PolicyStatement: iam.PolicyStatement
): { resourcePath: string } {
const suffix = '-AdditionalRolePolicy';
this.role.attachInlinePolicy(
new iam.Policy(this, id + suffix, {
statements: [PolicyStatement],
})
);
return { resourcePath: `${this.nodePath}/${id}${suffix}/Resource` };
}
NagSuppressions.addResourceSuppressions(
this.role,
[
{
id: 'AwsSolutions-IAM5',
reason:
"Suppress AwsSolutions-IAM5 'xray:PutTelemetryRecords' and 'xray:PutTraceSegments' on *, which is created when CDK enables tracing",
appliesTo: ['Resource::*'],
},
],
true
);
}
public addAdditionalRolePolicy(id: string, PolicyStatement: iam.PolicyStatement): { resourcePath: string } {
const suffix = '-AdditionalRolePolicy';
this.role.attachInlinePolicy(
new iam.Policy(this, id + suffix, {
statements: [PolicyStatement],
})
);
return { resourcePath: `${this.nodePath}/${id}${suffix}/Resource` };
}
}
6 changes: 3 additions & 3 deletions website-leaderboard/public/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"leaderboard.position": "Position",
"leaderboard.racer": "Racer",
"leaderboard.time": "Time",
"leaderboard.average": "Average Time",
"leaderboard.time": "Fastest Lap Time",
"leaderboard.average": "Average Lap Time",
"leaderboard.flag": "Flag",
"leaderboard.DNF": "DNF",
"leaderboard.summary-footer.finsiher": "NEW FINISHER",
Expand All @@ -21,4 +21,4 @@
"leaderboard.race-info-footer.best-lap": "Best Lap:",
"leaderboard.race-info-footer.current-lap": "Current Lap:",
"leaderboard.race-info-footer.best-avg": "Best AVG."
}
}

0 comments on commit f30acf8

Please sign in to comment.