diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/lambdaLayerWalkthrough.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/lambdaLayerWalkthrough.ts index 9f120aa6ea3..81a09d28c50 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/lambdaLayerWalkthrough.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/lambdaLayerWalkthrough.ts @@ -113,7 +113,7 @@ export async function updateLayerWalkthrough( // select layer version if (layerHasDeployed) { - const layerCloudState = LayerCloudState.getInstance(); + const layerCloudState = LayerCloudState.getInstance(parameters.layerName); const layerVersions = await layerCloudState.getLayerVersionsFromCloud(context, parameters.layerName); const latestVersionText = 'Future layer versions'; const layerVersionChoices = [ diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeLayerWalkthrough.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeLayerWalkthrough.ts index 3230ffdaf39..51f48bd642c 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeLayerWalkthrough.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeLayerWalkthrough.ts @@ -11,7 +11,7 @@ import { updateLayerArtifacts } from '../utils/storeResources'; const removeLayerQuestion = 'Choose the Layer versions you want to remove.'; export async function removeWalkthrough(context: $TSContext, layerName: string): Promise { - const layerCloudState = LayerCloudState.getInstance(); + const layerCloudState = LayerCloudState.getInstance(layerName); const layerVersionList = await layerCloudState.getLayerVersionsFromCloud(context, layerName); // if the layer hasn't been pushed return and remove it diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/addLayerToFunctionUtils.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/addLayerToFunctionUtils.ts index b0e51fd6182..4cca83a9113 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/addLayerToFunctionUtils.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/addLayerToFunctionUtils.ts @@ -65,7 +65,7 @@ export const askLayerSelection = async ( layerSelections = layerSelections.filter(selection => selection !== provideExistingARNsPrompt); for (const layerName of layerSelections) { - const layerCloudState = LayerCloudState.getInstance(); + const layerCloudState = LayerCloudState.getInstance(layerName); const layerVersions = await layerCloudState.getLayerVersionsFromCloud(context, layerName); const layerVersionChoices = layerVersions.map(mapVersionNumberToChoice); @@ -83,10 +83,16 @@ export const askLayerSelection = async ( const previousLayerSelection = _.first(filterProjectLayers(previousSelections).filter(prev => prev.resourceName === layerName)); let defaultLayerSelection: string; + if (previousLayerSelection === undefined || previousLayerSelection.isLatestVersionSelected) { defaultLayerSelection = defaultLayerVersionPrompt; } else { - defaultLayerSelection = mapVersionNumberToChoice(_.first(layerVersions.filter(v => v.Version === previousLayerSelection.version))); + const previouslySelectedLayerVersion = _.first(layerVersions.filter(v => v.Version === previousLayerSelection.version)); + + // Fallback to defaultLayerVersionPrompt as it is possible that a function is associated with a non-existent layer version + defaultLayerSelection = previouslySelectedLayerVersion + ? mapVersionNumberToChoice(previouslySelectedLayerVersion) + : defaultLayerVersionPrompt; } const versionSelection = ( diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/lambda-layer-cloudformation-template.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/lambda-layer-cloudformation-template.ts index a6a64b37dea..53e84d3c353 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/lambda-layer-cloudformation-template.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/lambda-layer-cloudformation-template.ts @@ -24,8 +24,8 @@ export function generateLayerCfnObj(isNewVersion: boolean, parameters: LayerPara if (isNewVersion) { const [shortId] = uuid().split('-'); logicalName = `${LayerCfnLogicalNamePrefix.LambdaLayerVersion}${shortId}`; - const layerCloudState = LayerCloudState.getInstance(); - layerCloudState.latestVersionLogicalId = logicalName; // Store in singleton so it can be used in zipfile name + const layerCloudState = LayerCloudState.getInstance(parameters.layerName); + layerCloudState.latestVersionLogicalId = logicalName; // Store in the given layer's layerCloudState instance so it can be used in zipfile name versionList.unshift({ LogicalName: logicalName, legacyLayer: false }); } else { logicalName = _.first(versionList).LogicalName; diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/layerCloudState.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/layerCloudState.ts index 01c4bec8122..c45ad6ca85a 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/layerCloudState.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/layerCloudState.ts @@ -6,17 +6,17 @@ import { LegacyPermissionEnum } from './layerMigrationUtils'; import { LayerVersionMetadata, PermissionEnum } from './layerParams'; export class LayerCloudState { - private static instance: LayerCloudState; + private static instances: Record = {}; private layerVersionsMetadata: LayerVersionMetadata[]; public latestVersionLogicalId: string; private constructor() {} - static getInstance(): LayerCloudState { - if (!LayerCloudState.instance) { - LayerCloudState.instance = new LayerCloudState(); + static getInstance(layerName: string): LayerCloudState { + if (!LayerCloudState.instances[layerName]) { + LayerCloudState.instances[layerName] = new LayerCloudState(); } - return LayerCloudState.instance; + return LayerCloudState.instances[layerName]; } private async loadLayerDataFromCloud(context: $TSContext, layerName: string): Promise { diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/packageLayer.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/packageLayer.ts index 82291b51990..79989056de8 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/packageLayer.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/packageLayer.ts @@ -60,10 +60,10 @@ export const packageLayer: Packager = async (context, resource) => { await zipPackage(packageResult.zipEntries, destination); } - const layerCloudState = LayerCloudState.getInstance(); + const layerCloudState = LayerCloudState.getInstance(resource.resourceName); if (!layerCloudState.latestVersionLogicalId) { // "Should" never be reachable, but sanity check just in case - throw new Error('LogicalId missing for new layer version.'); + throw new Error(`LogicalId missing for new layer version: ${resource.resourceName}.`); } const zipFilename = createLayerZipFilename(resource.resourceName, layerCloudState.latestVersionLogicalId); @@ -112,6 +112,9 @@ export async function checkContentChanges(context: $TSContext, layerResources: A for (const layer of changedLayerResources) { let { parameters } = layer; if (!accepted) { + context.print.info(''); + context.print.info(`Change options layer: ${layer.resourceName}`); + context.print.info(''); parameters = await lambdaLayerNewVersionWalkthrough(parameters, timestampString); } else { parameters.description = `Updated layer version ${timestampString}`; diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/storeResources.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/storeResources.ts index 9e6751a031d..568ff21b958 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/storeResources.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/storeResources.ts @@ -213,14 +213,17 @@ function ensureLayerRuntimeFolder(layerDirPath: string, runtime: LayerRuntime) { } function createLayerCfnFile(parameters: LayerParameters, layerDirPath: string) { - JSONUtilities.writeJson(path.join(layerDirPath, getCfnTemplateFileName(parameters.layerName)), generateLayerCfnObj(true, parameters)); + const layerCfnObj = generateLayerCfnObj(true, parameters); + const layerCfnFilePath = path.join(layerDirPath, getCfnTemplateFileName(parameters.layerName)); + + JSONUtilities.writeJson(layerCfnFilePath, layerCfnObj); } async function updateLayerCfnFile(context: $TSContext, parameters: LayerParameters, layerDirPath: string): Promise<$TSObject> { let layerVersionList: LayerVersionMetadata[] = []; if (loadPreviousLayerHash(parameters.layerName)) { - const layerCloudState = LayerCloudState.getInstance(); + const layerCloudState = LayerCloudState.getInstance(parameters.layerName); layerVersionList = await layerCloudState.getLayerVersionsFromCloud(context, parameters.layerName); }