Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cdk): enable hotswap for appsync function and resolver code #26725

Closed
wants to merge 8 commits into from
5 changes: 3 additions & 2 deletions packages/aws-cdk-lib/aws-appsync/lib/appsync-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export class AppsyncFunction extends Resource implements IAppsyncFunction {
produce: () => Fn.select(3, Fn.split('/', attrs.functionArn)),
});
public readonly functionArn = attrs.functionArn;
constructor (s: Construct, i: string) {
constructor(s: Construct, i: string) {
super(s, i);
}
}
Expand Down Expand Up @@ -161,7 +161,8 @@ export class AppsyncFunction extends Resource implements IAppsyncFunction {
runtime: props.runtime?.toProperties(),
codeS3Location: code?.s3Location,
code: code?.inlineCode,
functionVersion: '2018-05-29',
// function Version should not be set when Code is provided
onlybakam marked this conversation as resolved.
Show resolved Hide resolved
functionVersion: !props.code ? '2018-05-29' : undefined,
requestMappingTemplate: props.requestMappingTemplate?.renderTemplate(),
responseMappingTemplate: props.responseMappingTemplate?.renderTemplate(),
});
Expand Down
32 changes: 23 additions & 9 deletions packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { ISDK } from '../aws-auth';
import { EvaluateCloudFormationTemplate } from '../evaluate-cloudformation-template';

export async function isHotswappableAppSyncChange(
logicalId: string, change: HotswappableChangeCandidate, evaluateCfnTemplate: EvaluateCloudFormationTemplate,
logicalId: string,
change: HotswappableChangeCandidate,
evaluateCfnTemplate: EvaluateCloudFormationTemplate,
onlybakam marked this conversation as resolved.
Show resolved Hide resolved
): Promise<ChangeHotswapResult> {
const isResolver = change.newValue.Type === 'AWS::AppSync::Resolver';
const isFunction = change.newValue.Type === 'AWS::AppSync::FunctionConfiguration';
Expand All @@ -23,7 +25,7 @@ export async function isHotswappableAppSyncChange(
return ret;
}

const classifiedChanges = classifyChanges(change, ['RequestMappingTemplate', 'ResponseMappingTemplate']);
const classifiedChanges = classifyChanges(change, ['RequestMappingTemplate', 'ResponseMappingTemplate', 'Code']);
classifiedChanges.reportNonHotswappablePropertyChanges(ret);

const namesOfHotswappableChanges = Object.keys(classifiedChanges.hotswappableProps);
Expand All @@ -47,23 +49,35 @@ export async function isHotswappableAppSyncChange(
return;
}

// copy the old properties
const sdkProperties: { [name: string]: any } = {
...change.oldValue.Properties,
requestMappingTemplate: change.newValue.Properties?.RequestMappingTemplate,
responseMappingTemplate: change.newValue.Properties?.ResponseMappingTemplate,
};

// if the code is set, make sure the `functionVersion` is not set
// otherwhise, this is a mapping template change
onlybakam marked this conversation as resolved.
Show resolved Hide resolved
if (change.newValue.Properties?.Code) {
delete sdkProperties.functionVersion;
sdkProperties.code = change.newValue.Properties?.Code;
} else {
sdkProperties.requestMappingTemplate = change.newValue.Properties?.RequestMappingTemplate;
sdkProperties.responseMappingTemplate = change.newValue.Properties?.ResponseMappingTemplate;
}
const evaluatedResourceProperties = await evaluateCfnTemplate.evaluateCfnExpression(sdkProperties);
const sdkRequestObject = transformObjectKeys(evaluatedResourceProperties, lowerCaseFirstCharacter);

if (isResolver) {
await sdk.appsync().updateResolver(sdkRequestObject).promise();
} else {
const { functions } = await sdk.appsync().listFunctions({ apiId: sdkRequestObject.apiId }).promise();
const { functionId } = functions?.find(fn => fn.name === physicalName) ?? {};
await sdk.appsync().updateFunction({
...sdkRequestObject,
functionId: functionId!,
}).promise();
const { functionId } = functions?.find((fn) => fn.name === physicalName) ?? {};
await sdk
.appsync()
.updateFunction({
...sdkRequestObject,
functionId: functionId!,
})
.promise();
onlybakam marked this conversation as resolved.
Show resolved Hide resolved
}
},
});
Expand Down
Loading