diff --git a/lib/base-stack.ts b/lib/base-stack.ts index 57a2f0ff..3befa5cb 100644 --- a/lib/base-stack.ts +++ b/lib/base-stack.ts @@ -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'; @@ -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); diff --git a/lib/constructs/standard-lambda-python-function.ts b/lib/constructs/standard-lambda-python-function.ts index 37acc0db..4913122e 100644 --- a/lib/constructs/standard-lambda-python-function.ts +++ b/lib/constructs/standard-lambda-python-function.ts @@ -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` }; + } } diff --git a/website-leaderboard/public/locales/en/translation.json b/website-leaderboard/public/locales/en/translation.json index 0e765e7c..5ac7af30 100644 --- a/website-leaderboard/public/locales/en/translation.json +++ b/website-leaderboard/public/locales/en/translation.json @@ -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", @@ -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." -} \ No newline at end of file +}