Package: aws-prototyping-sdk.cdk-graph
CDK Graph (@aws-prototyping-sdk/cdk-graph)More comprehensive documentation to come as this package stabilizesThis package is the core framework for supporting additional cdk based automation and tooling, such as diagraming, cost modeling, security and compliance, in a holistic and comprehensive way.This package provides the following functionality:Synthesizes a serialized graph (nodes and edges) from CDK source code.Provides runtime interface for interacting with the graph (in-memory database-like graph store).Provides plugin framework for additional tooling to utilize and extend the graph.The goal of this framework is to enable bespoke tooling to be built without having to first traverse the CDK Tree and Metadata to build a graph. Projects likecdk-diagenerate a bespoke in-memory graph that is then utilized to generate diagrams; while the diagram generation is the core value it must first have a graph to act upon and currently is required to generate this undifferentiated graph to provide its diagrams. By standardizing on the graph interface necessary to build complex tooling, we can more rapidly build new tooling that focuses on its core value.Available PluginsNameDescriptionScreenshotLinksDiagramGenerate cloud infrastructure diagrams from cdk graphQuick StartInstrument CDK App with CdkGraph#!/usr/bin/env nodeimport*ascdkfrom"aws-cdk-lib";import{MyStack}from"../lib/my-stack";import{CdkGraph}from"@aws-prototyping-sdk/cdk-graph";constapp=newcdk.App();newMyStack(app,"MyStack");//AddCdkGraphafterotherconstructaddedtoappnewCdkGraph(app);Using Plugins#!/usr/bin/env nodeimport*ascdkfrom"aws-cdk-lib";import{MyStack}from"../lib/my-stack";import{CdkGraph}from"@aws-prototyping-sdk/cdk-graph";import{ExamplePlugin}from"@aws-prototyping-sdk/cdk-graph-plugin-example";//doesnotexist,justexampleconstapp=newcdk.App();newMyStack(app,"MyStack");//AddCdkGraphafterotherconstructaddedtoappnewCdkGraph(app,{plugins:[newExamplePlugin()],});ConfigConfiguration is supported through the.cdkgraphrc.jsand depending on the plugin, through passing config to the plugin instance.Config precedence follows 1) defaults, 2) cdkgraphrc, 3) instance.// .cdkgraphrc.jsmodule.exports={// Defaults to "<cdk.out>/cdkgraph"outdir:"reports/graph",// plugin configurationexample:{verbose:true,reportType:"csv",},};#!/usr/bin/env nodeimport*ascdkfrom"aws-cdk-lib";import{MyStack}from"../lib/my-stack";import{CdkGraph}from"@aws-prototyping-sdk/cdk-graph";import{ExamplePlugin}from"@aws-prototyping-sdk/cdk-graph-plugin-example";//doesnotexist,justexampleconstapp=newcdk.App();newMyStack(app,"MyStack");//AddCdkGraphafterotherconstructaddedtoappnewCdkGraph(app,{plugins:[newExamplePlugin({//Willoverride.cdkgraphrc.jsvalueverbose:false,}),],});Plugin Interface/**CdkGraph**Plugin**interface*/exportinterfaceICdkGraphPlugin{/**Uniqueidentifierforthisplugin*/readonlyid:string;/**Pluginversion*/readonlyversion:Version;/**Listofpluginsthisplugindependson,includingoptionalsemverversion(eg:["foo","bar@1.2"])*/readonlydependencies?:string[];/***BindstheplugintotheCdkGraphinstance.Enablespluginstoreceivebaseconfigs.*/bind:IGraphPluginBindCallback;/***Nodevisitorcallbackforconstructtreetraversal.ThisfollowsIAspect.visitpattern,buttheorder*ofvisitortraversalinmanagedbytheCdkGraph.*/inspect?:IGraphVisitorCallback;/***CalledduringCDKsynthesizetogeneratesynchronousartifactsbasedonthein-memorygraphpassed*totheplugin.Thisiscalledinfifoorderofplugins.*/synthesize?:IGraphSynthesizeCallback;/***Generateasynchronousreportsbasedonthegraph.ThisisnotautomaticallycalledwhensynthesizingCDK.*Developermustexplicitlyadd`awaitgraphInstance.report()`totheCDKbinorinvokethisoutside*oftheCDKsynth.Ineithercase,thepluginreceivesthein-memorygraphinterfacewheninvoked,asthe*CdkGraphwilldeserializethegraphpriortoinvokingthepluginreport.*/report?:IGraphReportCallback;}Plugin operations are automatically invoked by CdkGraph in the order they are defined in thepluginsproperty. The invocation flow of plugins follows: 1)bind, 2)inspect, 3)synthesize, 4)async report.Asynchronous PluginsSome plugins may requiring performing asynchronous requests, or may make expensive operations that are best left outside of the synthesis process.CdkGraph support asynchronous operations through theasync report()method of plugins. However, since CDK does not support asynchronous operations during synthesis, this must be wired up a bit differently.#!/usr/bin/env nodeimport*ascdkfrom"aws-cdk-lib";import{MyStack}from"../lib/my-stack";import{CdkGraph}from"@aws-prototyping-sdk/cdk-graph";import{ExampleAsyncPlugin}from"@aws-prototyping-sdk/cdk-graph-plugin-async-example";//doesnotexist,justexample(async()=>{constapp=newcdk.App();newMyStack(app,"MyStack");//AddCdkGraphafterotherconstructaddedtoappconstgraph=newCdkGraph(app,{plugins:[newExampleAsyncPlugin()],});//invokesallplugin`report()`operationsasynchronously(inordertheyaredefinedin`plugins`property)awaitgraph.report();})();Example Plugin ImplementationVery basic example of implementing a plugin. Once the first actual plugins have been published this will be updated to reference those as examples.import{CdkGraph,CdkGraphContext,ICdkGraphPlugin,}from"@aws-prototyping-sdk/cdk-graph";exportclassCdkGraphExamplePluginimplementsICdkGraphPlugin{staticreadonlyARTIFACT_NS="EXAMPLE";staticreadonlyID="example";staticreadonlyVERSION="0.0.0";getid():string{returnCdkGraphDiagramPlugin.ID;}getversion():string{returnCdkGraphDiagramPlugin.VERSION;}readonlydependencies?:string[]=[];/**@internal*/private_graph?:CdkGraph;bind(graph:CdkGraph):void{this._graph=graph;}synthesize(context:CdkGraphContext):void{constpluginConfig=this.configasRequired<IPluginConfig>;//GetcountsofallresourcesconstcfnResourceCounts=context.store.counts.cfnResources;//Writepluginartifactcontext.writeArtifact(this,"EXAMPLE","example.json",JSON.stringify(cfnResourceCounts,null,2));}asyncreport(context:CdkGraphContext):void{//performasyncoperationhereutilizinggraphstoreconstcfnResourceCounts=context.store.counts.cfnResources;constfetchedData=awaitfetch("https://example.com/data",{method:"POST",body:JSON.stringify(cfnResourceCounts),});//Writepluginartifactforfetcheddatacontext.writeArtifact(this,"EXAMPLE:FETCHED","example-fetched.json",JSON.stringify(fetchedData,null,2));}}Path to StabilityThe below is a rough checklist of task necessary to elevate this from experimental to stable.Dynamic versioning and Semver enforcement (store, plugins, etc)Support runningasync report()method outside of CDK synthesis processFind alternative synthesis solution that doesn't utilize CDK internalsSupport custom Nodes and EdgesImprove logging, bookkeeping, and debuggingImplement store upgrade solutionBattle test the implementation against several pluginsBattle test the implementation in all target languages (currently tested in Typescript, but vended in all PDK supported languages)Receive community feedback to validate approach