UNPKG

serverless

Version:

Serverless Framework - Build web, mobile and IoT applications with serverless architectures using AWS Lambda, Azure Functions, Google CloudFunctions & more

724 lines (672 loc) • 26.1 kB
'use strict'; const _ = require('lodash'); const crypto = require('crypto'); /** * A centralized naming object that provides naming standards for the AWS provider plugin. The * intent is for this to enable naming standards to be configured using a custom naming plugin or * a naming configuration feature, based on which of those is determined to in the best approach. * * There are two main concepts: * 1. normalization - normalization of a name comprises removing any unacceptable characters and * changing the name to comply with capitalization expectations. * 2. logicalization - logicalization of a name comprises preparing it for use as an attribute name * for a resource within the Service's CloudFormation Template. Notably, a suffix or prefix should * be added to the name of resources. These help to disambiguate attributes identifying or * declaring different aspects or data about the same resource. (e.g. MyFuncLambdaFunction vs. * MyFuncLambdaFunctionArn) Generally, normalization of the name also occurs. * * Sometimes, it is important to deconstruct the names that are created via this centralized * utility. As a result, the regular expressions used for identifying specific resource types using * their names or the logic to extract a name components from a logical name are things that must * also be centralized so that they co-occur and are more correlated spatially within the code base. * That is to say that they are easier to change together. */ module.exports = { // General normalizeName(name) { return `${_.upperFirst(name)}`; }, normalizeNameToAlphaNumericOnly(name) { return this.normalizeName(name.replace(/[^0-9A-Za-z]/g, '')); }, toStartCase(name) { return _.startCase(name).replace(/\s+/g, ''); }, normalizePathPart(rawPath) { return _.upperFirst( _.capitalize(rawPath) .replace(/-/g, 'Dash') .replace(/\{(.*)\}/g, '$1Var') .replace(/[^0-9A-Za-z]/g, '') ); }, getServiceEndpointRegex() { return /^(ServiceEndpoint|HttpApiUrl)/; }, // Stack getStackName() { if ( this.provider.serverless.service.provider.stackName && typeof this.provider.serverless.service.provider.stackName === 'string' ) { return this.provider.serverless.service.provider.stackName; } return `${this.provider.serverless.service.service}-${this.provider.getStage()}`; }, getStackChangeSetName() { return `${this.getStackName()}-change-set`; }, getServiceArtifactName() { return `${this.provider.serverless.service.service}.zip`; }, getFunctionArtifactName(functionName) { return `${functionName}.zip`; }, getLayerArtifactName(layerName) { return `${layerName}.zip`; }, getServiceStateFileName() { return 'serverless-state.json'; }, getCompiledTemplateFileName() { return 'cloudformation-template-update-stack.json'; }, getCompiledTemplateS3Suffix() { return 'compiled-cloudformation-template.json'; }, getCoreTemplateFileName() { return 'cloudformation-template-create-stack.json'; }, // Role getRolePath() { const customRolePath = _.get(this.provider, 'serverless.service.provider.iam.role.path'); return customRolePath || '/'; }, getRoleName() { const customRoleName = _.get(this.provider, 'serverless.service.provider.iam.role.name'); return ( customRoleName || { 'Fn::Join': [ '-', [ this.provider.serverless.service.service, this.provider.getStage(), { Ref: 'AWS::Region' }, 'lambdaRole', ], ], } ); }, getRoleLogicalId() { return 'IamRoleLambdaExecution'; }, // Policy getPolicyName() { return { 'Fn::Join': [ '-', [this.provider.serverless.service.service, this.provider.getStage(), 'lambda'], ], }; }, // Log Group getLogGroupLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LogGroup`; }, getLogGroupName(functionName) { return `/aws/lambda/${functionName}`; }, // Lambda getNormalizedFunctionName(functionName) { return this.getNormalizedResourceName(functionName); }, extractLambdaNameFromArn(functionArn) { return functionArn.substring(functionArn.lastIndexOf(':') + 1); }, extractAuthorizerNameFromArn(functionArn) { const splitArn = functionArn.split(':'); // TODO the following two lines assumes default function naming? Is there a better way? // TODO (see ~/lib/classes/service.js:~155) const splitName = splitArn[splitArn.length - 1].split('-'); return splitName[splitName.length - 1]; }, getLambdaLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaFunction`; }, getLambdaFunctionUrlLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaFunctionUrl`; }, getLambdaEventConfigLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaEvConf`; }, getLambdaLayerLogicalId(layerName) { return `${this.getNormalizedFunctionName(layerName)}LambdaLayer`; }, getLambdaLayerPermissionLogicalId(layerName, account) { return `${this.getNormalizedFunctionName(layerName)}${account.replace( '*', 'Wild' )}LambdaLayerPermission`; }, getLambdaLogicalIdRegex() { return /LambdaFunction$/; }, getLambdaVersionLogicalId(functionName, sha) { return `${this.getNormalizedFunctionName(functionName)}LambdaVersion${sha.replace( /[^0-9a-z]/gi, '' )}`; }, getCodeDeployApplicationLogicalId() { return 'CodeDeployApplication'; }, getCodeDeployDeploymentGroupLogicalId() { return 'CodeDeployDeploymentGroup'; }, getCodeDeployRoleLogicalId() { return 'CodeDeployRole'; }, getLambdaProvisionedConcurrencyAliasLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}ProvConcLambdaAlias`; }, getLambdaProvisionedConcurrencyAliasName() { return 'provisioned'; }, getLambdaFunctionUrlOutputLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaFunctionUrl`; }, getLambdaVersionOutputLogicalId(functionName) { return `${this.getLambdaLogicalId(functionName)}QualifiedArn`; }, getLambdaLayerOutputLogicalId(layerName) { return `${this.getLambdaLayerLogicalId(layerName)}QualifiedArn`; }, getLambdaLayerHashOutputLogicalId(layerName) { return `${this.getLambdaLayerLogicalId(layerName)}Hash`; }, getLambdaLayerS3KeyOutputLogicalId(layerName) { return `${this.getLambdaLayerLogicalId(layerName)}S3Key`; }, // Websockets API getWebsocketsApiName() { if ( this.provider.serverless.service.provider.websocketsApiName && typeof this.provider.serverless.service.provider.websocketsApiName === 'string' ) { return `${this.provider.serverless.service.provider.websocketsApiName}`; } return `${this.provider.getStage()}-${this.provider.serverless.service.service}-websockets`; }, getWebsocketsApiLogicalId() { return 'WebsocketsApi'; }, getWebsocketsIntegrationLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}WebsocketsIntegration`; }, getLambdaWebsocketsPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionWebsockets`; }, getNormalizedWebsocketsRouteKey(route) { return route .replace(/\$/g, 'S') // dollar sign .replace(/\//g, 'Slash') .replace(/-/g, 'Dash') .replace(/_/g, 'Underscore') .replace(/\./g, 'Period'); }, getWebsocketsRouteLogicalId(route) { return `${this.getNormalizedWebsocketsRouteKey(route)}WebsocketsRoute`; }, getWebsocketsDeploymentLogicalId(sha) { return `WebsocketsDeployment${sha.replace(/[^0-9a-z]/gi, '')}`; }, getWebsocketsRouteResponseLogicalId(route) { return `${this.getWebsocketsRouteLogicalId(route)}Response`; }, getWebsocketsStageLogicalId() { return 'WebsocketsDeploymentStage'; }, getWebsocketsAuthorizerLogicalId(functionName) { return `${this.getNormalizedAuthorizerName(functionName)}WebsocketsAuthorizer`; }, getWebsocketsLogGroupLogicalId() { return 'WebsocketsLogGroup'; }, // API Gateway getApiGatewayName() { if (this.provider.serverless.service.provider.apiName) { return `${this.provider.serverless.service.provider.apiName}`; } return _.get(this.provider.serverless.service.provider.apiGateway, 'shouldStartNameWithService') ? `${this.provider.serverless.service.service}-${this.provider.getStage()}` : `${this.provider.getStage()}-${this.provider.serverless.service.service}`; }, generateApiGatewayDeploymentLogicalId(id) { return `ApiGatewayDeployment${id}`; }, getRestApiLogicalId() { return 'ApiGatewayRestApi'; }, getNormalizedAuthorizerName(functionName) { return this.getNormalizedFunctionName(functionName); }, getAuthorizerLogicalId(functionName) { return `${this.getNormalizedAuthorizerName(functionName)}ApiGatewayAuthorizer`; }, normalizePath(resourcePath) { return resourcePath.split('/').map(this.normalizePathPart.bind(this)).join(''); }, getResourceLogicalId(resourcePath) { return `ApiGatewayResource${this.normalizePath(resourcePath)}`; }, extractResourceId(resourceLogicalId) { return resourceLogicalId.match(/ApiGatewayResource(.*)/)[1]; }, normalizeMethodName(methodName) { return this.normalizeName(methodName.toLowerCase()); }, getMethodLogicalId(resourceId, methodName) { return `ApiGatewayMethod${resourceId}${this.normalizeMethodName(methodName)}`; }, getValidatorLogicalId() { return `ApiGateway${this.normalizeNameToAlphaNumericOnly( this.provider.serverless.service.service )}RequestValidator`; }, getModelLogicalId(schemaId) { return `ApiGateway${_.upperFirst(_.camelCase(schemaId))}Model`; }, getEndpointModelLogicalId(resourceId, methodName, contentType) { return `${this.getMethodLogicalId(resourceId, methodName)}${_.startCase(contentType).replace( / /g, '' )}Model`; }, getApiKeyLogicalId(apiKeyNumber, apiKeyName) { if (apiKeyName) { return `ApiGatewayApiKey${this.normalizeName(apiKeyName)}${apiKeyNumber}`; } return `ApiGatewayApiKey${apiKeyNumber}`; }, getApiKeyLogicalIdRegex() { return /^ApiGatewayApiKey/; }, getUsagePlanLogicalId(name) { if (name) { return `ApiGatewayUsagePlan${this.normalizeName(name)}`; } return 'ApiGatewayUsagePlan'; }, getUsagePlanKeyLogicalId(usagePlanKeyNumber, usagePlanKeyName) { if (usagePlanKeyName) { return `ApiGatewayUsagePlanKey${this.normalizeName(usagePlanKeyName)}${usagePlanKeyNumber}`; } return `ApiGatewayUsagePlanKey${usagePlanKeyNumber}`; }, getStageLogicalId() { return 'ApiGatewayStage'; }, getApiGatewayLogGroupLogicalId() { return 'ApiGatewayLogGroup'; }, // S3 getDeploymentBucketLogicalId() { return 'ServerlessDeploymentBucket'; }, getDeploymentBucketOutputLogicalId() { return 'ServerlessDeploymentBucketName'; }, getDeploymentBucketPolicyLogicalId() { return 'ServerlessDeploymentBucketPolicy'; }, normalizeBucketName(bucketName) { return this.normalizeNameToAlphaNumericOnly(bucketName); }, getBucketLogicalId(bucketName) { return `S3Bucket${this.normalizeBucketName(bucketName)}`; }, // SNS normalizeTopicName(topicName) { return this.normalizeNameToAlphaNumericOnly(topicName); }, getTopicLogicalId(topicName) { return `SNSTopic${this.normalizeTopicName(topicName)}`; }, getTopicDLQPolicyLogicalId(functionName, topicName) { return `${this.normalizeTopicName(topicName)}To${this.getNormalizedFunctionName( functionName )}DLQPolicy`; }, // Schedule getScheduleId(functionName) { return `${functionName}Schedule`; }, getScheduleLogicalId(functionName, scheduleIndex) { return `${this.getNormalizedFunctionName(functionName)}EventsRuleSchedule${scheduleIndex}`; }, // Stream getStreamLogicalId(functionName, streamType, streamName) { return `${this.getNormalizedFunctionName(functionName)}EventSourceMapping${this.normalizeName( streamType )}${this.normalizeNameToAlphaNumericOnly(streamName)}`; }, getStreamConsumerName(functionName, streamName) { return `${functionName}${streamName}Consumer`; }, getStreamConsumerLogicalId(streamConsumerName) { return `${this.getNormalizedFunctionName(streamConsumerName)}StreamConsumer`; }, // IoT getIotLogicalId(functionName, iotIndex) { return `${this.getNormalizedFunctionName(functionName)}IotTopicRule${iotIndex}`; }, getLambdaIotPermissionLogicalId(functionName, iotIndex) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionIotTopicRule${iotIndex}`; }, // IoT Fleet Provisioning getIotFleetProvisioningLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}IotProvisioningTemplate`; }, getLambdaIotFleetProvisioningPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionIotProvisioningTemplate`; }, // CloudWatch Event getCloudWatchEventId(functionName) { return `${functionName}CloudWatchEvent`; }, getCloudWatchEventLogicalId(functionName, cloudWatchIndex) { return `${this.getNormalizedFunctionName( functionName )}EventsRuleCloudWatchEvent${cloudWatchIndex}`; }, // CloudWatch Log getCloudWatchLogLogicalId(functionName, logsIndex) { return `${this.getNormalizedFunctionName( functionName )}LogsSubscriptionFilterCloudWatchLog${logsIndex}`; }, // Cognito User Pool getCognitoUserPoolLogicalId(poolId) { return `CognitoUserPool${this.normalizeNameToAlphaNumericOnly(poolId)}`; }, // SQS getQueueLogicalId(functionName, queueName) { return `${this.getNormalizedFunctionName( functionName )}EventSourceMappingSQS${this.normalizeNameToAlphaNumericOnly(queueName)}`; }, // MSK getMSKEventLogicalId(functionName, clusterName, topicName) { const normalizedFunctionName = this.getNormalizedFunctionName(functionName); // Both clusterName and topicName are trimmed to 79 chars to avoid going over 255 character limit const normalizedClusterName = this.normalizeNameToAlphaNumericOnly(clusterName).slice(0, 79); const normalizedTopicName = this.normalizeNameToAlphaNumericOnly(topicName).slice(0, 79); return `${normalizedFunctionName}EventSourceMappingMSK${normalizedClusterName}${normalizedTopicName}`; }, // Kafka getKafkaEventLogicalId(functionName, topicName) { const normalizedFunctionName = this.getNormalizedFunctionName(functionName); // TopicName is trimmed to 158 chars to avoid going over 255 character limit const normalizedTopicName = this.normalizeNameToAlphaNumericOnly(topicName).slice(0, 158); return `${normalizedFunctionName}EventSourceMappingKafka${normalizedTopicName}`; }, // ActiveMQ getActiveMQEventLogicalId(functionName, queueName) { const normalizedFunctionName = this.getNormalizedFunctionName(functionName); // QueueName is trimmed to 150 chars to avoid going over 255 character limit const normalizedQueueName = this.normalizeNameToAlphaNumericOnly(queueName).slice(0, 150); return `${normalizedFunctionName}EventSourceMappingActiveMQ${normalizedQueueName}`; }, // RabbitMQ getRabbitMQEventLogicalId(functionName, queueName) { const normalizedFunctionName = this.getNormalizedFunctionName(functionName); // QueueName is trimmed to 150 chars to avoid going over 255 character limit const normalizedQueueName = this.normalizeNameToAlphaNumericOnly(queueName).slice(0, 150); return `${normalizedFunctionName}EventSourceMappingRabbitMQ${normalizedQueueName}`; }, // ALB getAlbTargetGroupLogicalId(functionName, albId, multiValueHeaders) { return `${this.getNormalizedFunctionName(functionName)}Alb${ multiValueHeaders ? 'MultiValue' : '' }TargetGroup${albId}`; }, getAlbTargetGroupNameTagValue(functionName, albId, multiValueHeaders) { return `${this.provider.serverless.service.service}-${functionName}-${albId}-${ multiValueHeaders ? 'multi-value-' : '' }${this.provider.getStage()}`; }, generateAlbTargetGroupName(functionName, albId, multiValueHeaders) { const hash = crypto .createHash('md5') .update(this.getAlbTargetGroupNameTagValue(functionName, albId, multiValueHeaders)) .digest('hex'); const albTargetGroupName = this.provider.getAlbTargetGroupPrefix() + hash; return albTargetGroupName.slice(0, 32); }, getAlbListenerRuleLogicalId(functionName, idx) { return `${this.getNormalizedFunctionName(functionName)}AlbListenerRule${idx}`; }, // Permissions getLambdaS3PermissionLogicalId(functionName, bucketName) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermission${this.normalizeBucketName(bucketName)}S3`; }, getLambdaSnsPermissionLogicalId(functionName, topicName) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermission${this.normalizeTopicName(topicName)}SNS`; }, getLambdaSnsSubscriptionLogicalId(functionName, topicName) { return `${this.getNormalizedFunctionName(functionName)}SnsSubscription${this.normalizeTopicName( topicName )}`; }, getLambdaSchedulePermissionLogicalId(functionName, scheduleIndex) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermissionEventsRuleSchedule${scheduleIndex}`; }, getLambdaCloudWatchEventPermissionLogicalId(functionName, cloudWatchIndex) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermissionEventsRuleCloudWatchEvent${cloudWatchIndex}`; }, getLambdaApiGatewayPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionApiGateway`; }, getLambdaHttpApiPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionHttpApi`; }, getLambdaFnUrlPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionFnUrl`; }, getLambdaAuthorizerHttpApiPermissionLogicalId(authorizerName) { return `${this.getNormalizedResourceName(authorizerName)}LambdaAuthorizerPermissionHttpApi`; }, getLambdaAlexaSkillPermissionLogicalId(functionName, alexaSkillIndex) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlexaSkill${ alexaSkillIndex || '0' }`; }, getLambdaAlexaSmartHomePermissionLogicalId(functionName, alexaSmartHomeIndex) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermissionAlexaSmartHome${alexaSmartHomeIndex}`; }, getLambdaCloudWatchLogPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermissionLogsSubscriptionFilterCloudWatchLog`; }, getLambdaCognitoUserPoolPermissionLogicalId(functionName, poolId, triggerSource) { return `${this.getNormalizedFunctionName( functionName )}LambdaPermissionCognitoUserPool${this.normalizeNameToAlphaNumericOnly( poolId )}TriggerSource${this.normalizeNameToAlphaNumericOnly(triggerSource)}`; }, getLambdaAlbPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlb`; }, getLambdaRegisterTargetPermissionLogicalId(functionName) { return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionRegisterTarget`; }, // Custom Resources getCustomResourcesArtifactName() { return 'custom-resources.zip'; }, getCustomResourcesRoleLogicalId() { return 'IamRoleCustomResourcesLambdaExecution'; }, // S3 getCustomResourceS3HandlerFunctionName() { return 'custom-resource-existing-s3'; }, getCustomResourceS3HandlerFunctionLogicalId() { return this.getLambdaLogicalId( `${this.getNormalizedFunctionName(this.getCustomResourceS3HandlerFunctionName())}` ); }, getCustomResourceS3ResourceLogicalId(functionName) { // NOTE: we have to keep the 1 at the end to ensure backwards compatibility // previously we've used an index to allow the creation of multiple custom S3 resources // we're now using one resource to handle multiple S3 event definitions return `${this.getNormalizedFunctionName(functionName)}CustomS31`; }, // Cognito User Pool getCustomResourceCognitoUserPoolHandlerFunctionName() { return 'custom-resource-existing-cup'; }, getCustomResourceCognitoUserPoolHandlerFunctionLogicalId() { return this.getLambdaLogicalId( `${this.getNormalizedFunctionName( this.getCustomResourceCognitoUserPoolHandlerFunctionName() )}` ); }, getCustomResourceCognitoUserPoolResourceLogicalId(functionName) { // NOTE: we have to keep the 1 at the end to ensure backwards compatibility // previously we've used an index to allow the creation of multiple custom // Cognito User Pool resources // we're now using one resource to handle multiple Cognito User Pool event definitions return `${this.getNormalizedFunctionName(functionName)}CustomCognitoUserPool1`; }, // Event Bridge getCustomResourceEventBridgeHandlerFunctionName() { return 'custom-resource-event-bridge'; }, getCustomResourceEventBridgeHandlerFunctionLogicalId() { return this.getLambdaLogicalId( `${this.getNormalizedFunctionName(this.getCustomResourceEventBridgeHandlerFunctionName())}` ); }, getCustomResourceEventBridgeResourceLogicalId(functionName, idx) { return `${this.getNormalizedFunctionName(functionName)}CustomEventBridge${idx}`; }, getNormalizedResourceName(resourceName) { return this.normalizeName(resourceName.replace(/-/g, 'Dash').replace(/_/g, 'Underscore')); }, getEventBridgeEventBusLogicalId(eventBusName) { return `${this.getNormalizedResourceName(eventBusName)}EventBridgeEventBus`; }, getEventBridgeRuleLogicalId(ruleName) { return `${this.normalizeNameToAlphaNumericOnly(ruleName)}EventBridgeRule`; }, getEventBridgeLambdaPermissionLogicalId(functionName, idx) { return `${this.getNormalizedFunctionName(functionName)}EventBridgeLambdaPermission${idx}`; }, // API Gateway Account Logs Write Role getCustomResourceApiGatewayAccountCloudWatchRoleHandlerFunctionName() { return 'custom-resource-apigw-cw-role'; }, getCustomResourceApiGatewayAccountCloudWatchRoleHandlerFunctionLogicalId() { return this.getLambdaLogicalId( `${this.getNormalizedFunctionName( this.getCustomResourceApiGatewayAccountCloudWatchRoleHandlerFunctionName() )}` ); }, getCustomResourceApiGatewayAccountCloudWatchRoleResourceLogicalId() { return 'CustomApiGatewayAccountCloudWatchRole'; }, // CloudFront getCloudFrontDistributionLogicalId() { return 'CloudFrontDistribution'; }, getCloudFrontDistributionDomainNameLogicalId() { return 'CloudFrontDistributionDomainName'; }, getLambdaAtEdgeInvokePermissionLogicalId(functionName) { return `${this.getLambdaLogicalId(functionName)}InvokePermission`; }, getCloudFrontOriginId(originObj) { const isS3Origin = Boolean(originObj.S3OriginConfig); const domain = originObj.DomainName; const originPath = originObj.OriginPath; let originId = isS3Origin ? 's3' : 'custom'; const domainName = typeof domain === 'string' ? domain : this.normalizeNameToAlphaNumericOnly(JSON.stringify(domain)); originId = `${originId}/${domainName}`; if (originPath) { originId = `${originId}${originPath}`; } return originId; }, getCloudFrontCachePolicyLogicalId(cachePolicyName) { return `CloudFrontCachePolicy${this.getNormalizedFunctionName(cachePolicyName)}`; }, getCloudFrontCachePolicyName(cachePolicyName) { const serviceName = this.provider.serverless.service.getServiceName(); const stage = this.provider.getStage(); return `${serviceName}-${stage}-${cachePolicyName}`; }, // HTTP API getHttpApiName() { if ( this.provider.serverless.service.provider.httpApi && this.provider.serverless.service.provider.httpApi.name ) { return `${String(this.provider.serverless.service.provider.httpApi.name)}`; } return _.get(this.provider.serverless.service.provider.httpApi, 'shouldStartNameWithService') ? `${this.provider.serverless.service.service}-${this.provider.getStage()}` : `${this.provider.getStage()}-${this.provider.serverless.service.service}`; }, getHttpApiLogicalId() { return 'HttpApi'; }, getHttpApiStageLogicalId() { return 'HttpApiStage'; }, getHttpApiIntegrationLogicalId(functionName) { return `HttpApiIntegration${this.getNormalizedFunctionName(functionName)}`; }, getHttpApiRouteLogicalId(routeKey) { if (routeKey === '*') return 'HttpApiRouteDefault'; return `HttpApiRoute${this.normalizePath(routeKey)}`; }, getHttpApiAuthorizerLogicalId(authorizerName) { return `HttpApiAuthorizer${this.getNormalizedFunctionName(authorizerName)}`; }, getHttpApiLogGroupLogicalId() { return 'HttpApiLogGroup'; }, getHttpApiLogGroupName() { return `/aws/http-api/${this.getStackName()}`; }, getEcrRepositoryName() { const serviceName = this.provider.serverless.service.getServiceName(); const stage = this.provider.getStage(); // Ensure no consecutive dashes are present and that there is to trailing slash left // TODO: Remove that with next major, assuming that issue #7056 (https://github.com/serverless/serverless/issues/7056) has been addressed return `serverless-${serviceName}-${stage}`.toLowerCase().replace(/-+/g, '-').replace(/-$/, ''); }, // Console getConsoleExtensionLayerLogicalId() { return 'SlsConsoleOtelExtension'; }, };