Last active
July 29, 2023 23:17
-
-
Save braska/6f622fdac92d8c66d9d69300d480fbed to your computer and use it in GitHub Desktop.
Cross-stage Cloudwatch dashboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ApplicationStackProps extends StackProps { | |
dashboardStack: DashboardStack; | |
} | |
export class ApplicationStack extends Stack { | |
constructor(scope: Construct, id: string, props: ApplicationStackProps) { | |
super(scope, id, props); | |
const myFunction = new NodejsFunction(this, 'MyFunction', { | |
functionName: PhysicalName.GENERATE_IF_NEEDED, | |
// ... other attrs goes here | |
}); | |
props.dashboardStack.createLambdaObservability('MyFunction', myFunction); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class DashboardDeploymentStage extends Stage { | |
readonly dashboardStack; | |
constructor(scope: Construct, id: string, props?: StageProps) { | |
super(scope, id, props); | |
this.dashboardStack = new DashboardStack(this, 'dashboard'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class DashboardStack extends Stack { | |
readonly dashboard: Dashboard; | |
readonly widgets: Record<string, cloudwatch.GraphWidget> = {}; | |
constructor(scope: Construct, id: string, props: DashboardProps) { | |
super(scope, id, props); | |
this.dashboard = new cloudwatch.Dashboard(this, 'dashboard'); | |
} | |
createLambdaObservability(name: string, lambdaToMonitor: IFunction) { | |
let errorsWidget = this.widgets[`${name} Errors`]; | |
const widgetsToAdd: IWidget[] = []; | |
if (!errorsWidget) { | |
errorsWidget = new cloudwatch.GraphWidget({ | |
title: `${name} Errors`, | |
leftYAxis: { | |
showUnits: true, | |
}, | |
height: 6, | |
width: 6, | |
}); | |
this.widgets[`${name} Errors`] = errorsWidget; | |
widgetsToAdd.push(errorsWidget as IWidget); | |
} | |
errorsWidget.addLeftMetric( | |
lambdaToMonitor.metricErrors({ | |
label: lambdaToMonitor.env.region, | |
}) | |
); | |
let throttlesWidget = this.widgets[`${name} Throttles`]; | |
if (!throttlesWidget) { | |
throttlesWidget = new cloudwatch.GraphWidget({ | |
title: `${name} Throttles`, | |
leftYAxis: { | |
showUnits: true, | |
}, | |
height: 6, | |
width: 6, | |
}); | |
this.widgets[`${name} Throttles`] = throttlesWidget; | |
widgetsToAdd.push(throttlesWidget as IWidget); | |
} | |
throttlesWidget.addLeftMetric( | |
lambdaToMonitor.metricThrottles({ | |
label: lambdaToMonitor.env.region, | |
}) | |
); | |
let invocationsWidget = this.widgets[`${name} Invocations`]; | |
if (!invocationsWidget) { | |
invocationsWidget = new cloudwatch.GraphWidget({ | |
title: `${name} Invocations`, | |
leftYAxis: { | |
showUnits: true, | |
}, | |
height: 6, | |
width: 6, | |
}); | |
this.widgets[`${name} Invocations`] = invocationsWidget; | |
widgetsToAdd.push(invocationsWidget as IWidget); | |
} | |
invocationsWidget.addLeftMetric( | |
lambdaToMonitor.metricInvocations({ | |
label: lambdaToMonitor.env.region, | |
}) | |
); | |
let durationsWidget = this.widgets[`${name} Durations`]; | |
if (!durationsWidget) { | |
durationsWidget = new cloudwatch.GraphWidget({ | |
title: `${name} Durations`, | |
leftYAxis: { | |
showUnits: true, | |
}, | |
height: 6, | |
width: 6, | |
}); | |
this.widgets[`${name} Durations`] = durationsWidget; | |
widgetsToAdd.push(durationsWidget as IWidget); | |
} | |
durationsWidget.addLeftMetric( | |
lambdaToMonitor.metricDuration({ | |
label: lambdaToMonitor.env.region, | |
}) | |
); | |
if (widgetsToAdd.length > 0) { | |
this.dashboard.addWidgets(...widgetsToAdd); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface DeploymentStageProps extends StageProps { | |
dashboardStack: DashboardStack; | |
} | |
export class DeploymentStage extends Stage { | |
constructor(scope: Construct, id: string, props: DeploymentStageProps) { | |
super(scope, id, props); | |
new ApplicationStack(this, "ApplicationStack", { dashboardStack: props.dashboardStack }); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class PipelineStack extends Stack { | |
constructor(scope: Construct, id: string, props?: StackProps) { | |
super(scope, id, props); | |
const source = CodePipelineSource.connection(`${GITHUB_ORGANIZATION}/${GITHUB_REPOSITORY}`, 'main', { | |
connectionArn: '...', | |
}); | |
const pipeline = new CodePipeline(this, "Pipeline", { | |
crossAccountKeys: true, | |
synth: new CodeBuildStep(this, "SynthStep", { | |
input: source, | |
installCommands: ["n auto", "corepack enable", "pnpm install"], | |
commands: ['pnpm cdk synth'], | |
}), | |
}); | |
const dashboardDeploymentStage = new DashboardDeploymentStage(pipelineStack, "dashboard", { | |
env: { account: '123456789', region: "us-west-2" }, | |
}); | |
const caDeploymentStage = new DeploymentStage(pipelineStack, "ca", { | |
env: { account: '123456789', region: "ca-central-1" }, | |
dashboardStack: dashboardDeploymentStage.dashboardStack, | |
}); | |
const usDeploymentStage = new DeploymentStage(pipelineStack, "ca", { | |
env: { account: '123456789', region: "us-east-1" }, | |
dashboardStack: dashboardDeploymentStage.dashboardStack, | |
}); | |
dashboardDeploymentStage.synth(); | |
const production = pipeline.addWave("production"); | |
production.addStage(caDeploymentStage); | |
production.addStage(usDeploymentStage); | |
pipeline.addStage(dashboardDeploymentStage); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment