Skip to content

Instantly share code, notes, and snippets.

@orangain
Created October 21, 2023 12:03
Show Gist options
  • Save orangain/569b8df21cbce82057d606459fc44701 to your computer and use it in GitHub Desktop.
Save orangain/569b8df21cbce82057d606459fc44701 to your computer and use it in GitHub Desktop.
cdk-auto-mapper.ts: Deno script to fill CDK's import mapping file using result of `aws cloudformation list-stack-resources`
if (Deno.args.length !== 2) {
console.error(
"Usage: deno run --allow-read cdk-auto-mapper.ts <resource-file-path> <mapping-file-path>"
);
Deno.exit(1);
}
const [resourcePath, mappingPath] = Deno.args;
const resourceFileContent = await Deno.readTextFile(resourcePath);
const mappingFileContent = await Deno.readTextFile(mappingPath);
type Resources = {
StackResourceSummaries: ResourceSummary[];
};
type ResourceSummary = {
LogicalResourceId: string;
PhysicalResourceId: string;
ResourceType: string;
};
type Mapping = Record<string, Record<string, string>>;
const resources = JSON.parse(resourceFileContent) as Resources;
const mapping = JSON.parse(mappingFileContent) as Mapping;
const resourceMap = resources.StackResourceSummaries.reduce((acc, resource) => {
acc[resource.LogicalResourceId] = resource;
return acc;
}, {} as Record<string, ResourceSummary>);
Object.entries(mapping).forEach(([logicalId, attributes]) => {
const resource = resourceMap[logicalId];
if (!resource) {
throw new Error(`Resource ${logicalId} not found`);
}
const attributesResolver = getAttributesResolver(resource.ResourceType);
if (attributesResolver !== null) {
const physicalId = resource.PhysicalResourceId;
const resolvedAttributes = attributesResolver(physicalId);
Object.assign(attributes, resolvedAttributes);
} else {
Object.keys(attributes).forEach((attribute) => {
attributes[attribute] = resource.PhysicalResourceId;
});
}
});
console.log(JSON.stringify(mapping, null, 2));
type AttributesResolver = (physicalId: string) => Record<string, string>;
function getAttributesResolver(
resourceType: string
): AttributesResolver | null {
const attributesResolvers: Record<string, AttributesResolver> = {
"AWS::EC2::EIP": (physicalId) => {
return {
PublicIp: physicalId,
};
},
"AWS::EC2::Route": (physicalId) => {
const [routeTableId, destinationCidrBlock] = physicalId.split("|");
return {
RouteTableId: routeTableId,
CidrBlock: destinationCidrBlock,
};
},
};
return attributesResolvers[resourceType] ?? null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment