in packages/@aws-cdk/toolkit-lib/lib/api/hotswap/lambda-functions.ts [164:242]
async function evaluateLambdaFunctionProps(
hotswappablePropChanges: Record<string, PropertyDifference<any>>,
runtime: string,
evaluateCfnTemplate: EvaluateCloudFormationTemplate,
): Promise<LambdaFunctionChange | undefined> {
/*
* At first glance, we would want to initialize these using the "previous" values (change.oldValue),
* in case only one of them changed, like the key, and the Bucket stayed the same.
* However, that actually fails for old-style synthesis, which uses CFN Parameters!
* Because the names of the Parameters depend on the hash of the Asset,
* the Parameters used for the "old" values no longer exist in `assetParams` at this point,
* which means we don't have the correct values available to evaluate the CFN expression with.
* Fortunately, the diff will always include both the s3Bucket and s3Key parts of the Lambda's Code property,
* even if only one of them was actually changed,
* which means we don't need the "old" values at all, and we can safely initialize these with just `''`.
*/
let code: LambdaFunctionCode | undefined = undefined;
let description: string | undefined = undefined;
let environment: { [key: string]: string } | undefined = undefined;
for (const updatedPropName in hotswappablePropChanges) {
const updatedProp = hotswappablePropChanges[updatedPropName];
switch (updatedPropName) {
case 'Code':
let s3Bucket, s3Key, s3ObjectVersion, imageUri, functionCodeZip;
for (const newPropName in updatedProp.newValue) {
switch (newPropName) {
case 'S3Bucket':
s3Bucket = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
break;
case 'S3Key':
s3Key = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
break;
case 'S3ObjectVersion':
s3ObjectVersion = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
break;
case 'ImageUri':
imageUri = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
break;
case 'ZipFile':
// We must create a zip package containing a file with the inline code
const functionCode = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
const functionRuntime = await evaluateCfnTemplate.evaluateCfnExpression(runtime);
if (!functionRuntime) {
return undefined;
}
// file extension must be chosen depending on the runtime
const codeFileExt = determineCodeFileExtFromRuntime(functionRuntime);
functionCodeZip = await zipString(`index.${codeFileExt}`, functionCode);
break;
}
}
code = {
s3Bucket,
s3Key,
s3ObjectVersion,
imageUri,
functionCodeZip,
};
break;
case 'Description':
description = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue);
break;
case 'Environment':
environment = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue);
break;
default:
// we will never get here, but just in case we do throw an error
throw new ToolkitError(
'while apply()ing, found a property that cannot be hotswapped. Please report this at github.com/aws/aws-cdk/issues/new/choose',
);
}
}
const configurations = description || environment ? { description, environment } : undefined;
return code || configurations ? { code, configurations } : undefined;
}