-
Clayton, Brandon Scott authoredClayton, Brandon Scott authored
update-proxy.ts 2.60 KiB
import {
aws_ssm as ssm,
CfnDeletionPolicy,
CfnResource,
custom_resources as cr,
CustomResource,
RemovalPolicy,
Stack,
} from 'aws-cdk-lib';
import {Construct} from 'constructs';
import * as fs from 'fs';
import * as path from 'path';
/**
* SNS message contents.
*/
export interface Message {
/** Configuration files */
files?: ProxyFile[];
/** Stack name */
stackName?: string;
}
/**
* Reverse proxy file info.
*/
export interface ProxyFile {
/** File content */
content: string;
/** Filename */
filename: string;
}
/**
* Update proxy properties.
*/
export interface UpdateProxyProps {
/** Resource id */
id: string;
/** Path to configuration files */
paths: string[];
/** Current scope */
scope: Construct;
/** SSM parameter name for reverse proxy topic arn */
topicArnSsmName: string;
}
/**
* Read in reverse proxy configuration files from given path and publish SNS
* message with contents.
*
* @param props Properties
*/
export function updateProxy(props: UpdateProxyProps): cr.AwsCustomResource {
const files: ProxyFile[] = props.paths.map(filePath => {
const content = fs.readFileSync(filePath, {
encoding: 'utf-8',
});
return {
filename: path.basename(filePath),
content,
};
});
const topicArn = ssm.StringParameter.valueFromLookup(
props.scope,
props.topicArnSsmName
);
const {stackName} = Stack.of(props.scope);
const message: Message = {
files,
stackName,
};
const sdkCall: cr.AwsSdkCall = {
action: 'publish',
service: 'SNS',
parameters: {
Message: JSON.stringify(message),
TopicArn: topicArn,
},
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
};
const onDeleteMessage: Message = {
stackName,
};
const onDeleteSdkCall: cr.AwsSdkCall = {
...sdkCall,
parameters: {
...sdkCall.parameters,
Message: JSON.stringify(onDeleteMessage),
},
};
const customResource = new cr.AwsCustomResource(
props.scope,
`${props.id}SnsReverseProxy`,
{
onCreate: sdkCall,
onDelete: onDeleteSdkCall,
onUpdate: sdkCall,
removalPolicy: RemovalPolicy.RETAIN,
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
}),
}
);
const cfnResource = (
customResource.node.defaultChild as CustomResource | undefined
)?.node.defaultChild as CfnResource | undefined;
// Update deletion policy
if (cfnResource instanceof CfnResource) {
cfnResource.addOverride('DeletionPolicy', CfnDeletionPolicy.DELETE);
}
return customResource;
}