Skip to content

Commit

Permalink
Merge pull request #96 from fourTheorem/cdk-test
Browse files Browse the repository at this point in the history
Add CDK Test Project to test Macro
  • Loading branch information
eoinsha committed Oct 10, 2022
2 parents 20fad99 + fc46e30 commit 27810ec
Show file tree
Hide file tree
Showing 22 changed files with 7,426 additions and 1,482 deletions.
3 changes: 1 addition & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ module.exports = {
ecmaVersion: 12,
sourceType: 'module'
},
rules: {
}
rules: {}
}
118 changes: 87 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,21 @@
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)


**SLIC Watch** creates instant, best-practice CloudWatch **Dashboards** and **Alarms** for your AWS applications. The supported AWS services are:
Automatic, best-practice CloudWatch **Dashboards** and **Alarms** for your SAM, CloudFormation, CDK and Serverless Framework applications.

1. AWS Lambda
2. API Gateway
3. DynamoDB
4. Kinesis Data Streams
5. SQS Queues
6. Step Functions
7. ECS (Fargate or EC2)
8. SNS
9. EventBridge

SLIC Watch is available for ⚡️ **Serverless Framework**, 🐿 **AWS SAM** and ☁️ **CloudFormation**.
SLIC Watch supports: _AWS Lambda, API Gateway, DynamoDB, Kinesis Data Streams, SQS Queues, Step Functions, ECS (Fargate or EC2), SNS and EventBridge._ ⚡️ **Serverless Framework**, 🐿 **AWS SAM**, **AWS CDK** and ☁️ **CloudFormation**.

* Serverless Framework v2 and v3 are supported in the _SLIC Watch Serverless Plugin_.
* SLIC Watch is available as a _CloudFormation Macro_ published in the Serverless Application Repository (SAR). This allows you to add SLIC Watch to SAM or CloudFormation templates by simply adding a `Transform` to your template.

<!-- TOC -->
* SLIC Watch is available as a _CloudFormation Macro_ published in the Serverless Application Repository (SAR). This allows you to add SLIC Watch to SAM, CDK or CloudFormation templates by simply adding a `Transform` to your template.

## Contents
- [slic-watch](#slic-watch)
- [Contents](#contents)
- [Getting Started with Serverless Framework](#getting-started-with-serverless-framework)
- [Getting Started with AWS SAM or CloudFormation](#getting-started-with-aws-sam-or-cloudformation)
- [Getting Started with AWS SAM, CDK or CloudFormation](#getting-started-with-aws-sam-cdk-or-cloudformation)
- [Deploying the SLIC Watch Macro](#deploying-the-slic-watch-macro)
- [Adding the SLIC Watch Transform](#adding-the-slic-watch-transform)
- [Adding the SLIC Watch Transform to SAM or CloudFormation templates](#adding-the-slic-watch-transform-to-sam-or-cloudformation-templates)
- [Adding the SLIC Watch Transform to CDK Apps](#adding-the-slic-watch-transform-to-cdk-apps)
- [Features](#features)
- [Lambda Functions](#lambda-functions)
- [API Gateway](#api-gateway)
Expand All @@ -46,32 +37,30 @@ SLIC Watch is available for ⚡️ **Serverless Framework**, 🐿 **AWS SAM** an
- [Function-level configuration](#function-level-configuration)
- [Serverless Framework function-level configuration](#serverless-framework-function-level-configuration)
- [SAM/CloudFormation function-level configuration](#samcloudformation-function-level-configuration)
- [CDK function-level configuration](#cdk-function-level-configuration)
- [A note on CloudWatch cost](#a-note-on-cloudwatch-cost)
- [References](#references)
- [Other Projects](#other-projects)
- [Reading](#reading)
- [LICENSE](#license)

<!-- /TOC -->
## Getting Started with Serverless Framework

_If you are using AWS SAM or CloudFormation, skip to the section below._

1. 📦 Install the plugin:
```
```bash
npm install serverless-slic-watch-plugin --save-dev
```
2. 🖋️ Add the plugin to the `plugins` section of `serverless.yml`:
```
```yaml
plugins:
- serverless-slic-watch-plugin
```

3. 🪛 _Optionally_, add some configuration for the plugin to the `custom -> slicWatch` section of `serverless.yml`.
Here, you can specify a reference to the SNS topic for alarms. This is optional, but it's usually something you want
so you can receive alarm notifications via email, Slack, etc.

```
```yaml
custom:
slicWatch:
topicArn: {'Fn::Ref': myTopic}
Expand All @@ -86,8 +75,9 @@ sls deploy
5. 👀 Head to the CloudWatch section of the AWS Console to check out your new dashboards 📊 and alarms ⏰ !


## Getting Started with AWS SAM or CloudFormation
ℹ️ **IMPORTANT**: If you are using AWS SAM, or just plain CloudFormation, the most important thing to know is that your AWS account/region should have the **SLIC Watch Macro** deployed before you do anything. Once that's done, it is very simple to add this macro as a transform to your SAM or CloudFormation template.
## Getting Started with AWS SAM, CDK or CloudFormation

ℹ️ **IMPORTANT**: If you are using AWS SAM, CDK, or just plain CloudFormation, the most important thing to know is that your AWS account/region should have the **SLIC Watch Macro** deployed before you do anything. Once that's done, it is very simple to add this macro as a transform to your SAM or CloudFormation template.

### Deploying the SLIC Watch Macro
It would be nice if CloudFormation allowed us to publicly publish a macro so you don't need this step, but for now, you can deploy the SLIC Watch Macro using any of the following options. We have made the macro available as a _Serverless Application Repository (SAR)_ app. This SAR app is used in Options 1 and 2 below. Option 3 is a manual option where you deploy the macro from this repository directly without using SAR.
Expand All @@ -106,25 +96,25 @@ The snippet of CloudFormation is as follows.
SemanticVersion: <enter latest version>
```
- **Option 3** (manual Macro deployment using SAM directly from source):
```
```bash
npm install
sam build --base-dir . --template-file cf-macro/template.yaml
sam deploy --guided
```
### Adding the SLIC Watch Transform
### Adding the SLIC Watch Transform to SAM or CloudFormation templates
Once you have deployed the macro, you can start using SLIC Watch in SAM or CloudFormation templates by adding this to the **Transform** section:

```
```yaml
Transform:
- ...
- SlicWatch-v2
```

3. 🪛 _Optionally_, add some configuration for the plugin to the `Metadata -> slicWatch` section of `template.yml`.
🪛 _Optionally_, add some configuration for the plugin to the `Metadata -> slicWatch` section of `template.yml`.
Here, you can specify a reference to the SNS topic for alarms. This is optional, but it's usually something you want
so you can receive alarm notifications via email, Slack, etc.

```
```yaml
Metadata:
slicWatch:
enabled: true
Expand All @@ -134,6 +124,46 @@ See the [Configuration](#configuration) section below for more detailed instruct

If you want to override the default alarm and dashboard settings for each Lambda Functino resource, add the `slicWatch` property to the `Metadata` section.

### Adding the SLIC Watch Transform to CDK Apps
Once you have deployed the macro, add it to CDK Stack in the constructor of the class that extends Stack. It should be done for every Stack in the CDK App.

```javascript
// JavaScript/TypeScript:
export class MyStack extends cdk.Stack {
constructor (scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props)

this.addTransform('SlicWatch-v2')
...
}
}
```

```python
# Python:
self.add_transform("SlicWatch-v2")
```
```csharp
// C#:
this.AddTransform("SlicWatch-v2")
```

```java
// Java:
this.addTransform("SlicWatch-v2");
```

🪛 _Optionally_, add some configuration for the plugin as below:

```javascript
this.templateOptions.metadata = {
slicWatch: {
enabled: true,
topicArn: "arn:aws:sns:eu-west-1:xxxxxxx:topic",
}
}
```

## Features

CloudWatch Alarms and Dashboard widgets are created for all supported resources in the CloudFormation stack generated by The Serverless Framework. This includes generated resources as well as resources specifed explicitly in the `resources` section.
Expand Down Expand Up @@ -282,6 +312,16 @@ Metadata:
...
```

- For *CDK Stacks, the top-level SLIC Watch configuration can be set as follows.
```typescript
this.templateOptions.metadata = {
slicWatch: {
enabled: true,
....
}
}
```

- The `topicArn` may be optionally provided as an SNS Topic destination for all alarms. If you omit the topic, alarms are still created but are not sent to any destination.
- Alarms or dashboards can be disabled at any level in the configuration by adding `enabled: false`. You can even disable all plugin functionality by specifying `enabled: false` at the top-level plugin configuration.

Expand Down Expand Up @@ -353,14 +393,30 @@ Resources:
Lambda:
enabled: false
```
#### CDK function-level configuration
```typescript
const hello: lambda.Function;
const cfnFuncHello = hello.node.defaultChild as CfnResource;
cfnFuncHello.cfnOptions.metadata = {
slicWatch: {
alarms: {
Lambda: {
Invocations: {
Threshold: 2
}
}
}
}
}
```

## A note on CloudWatch cost

This plugin creates additional CloudWatch resources that, apart from a limited free tier, have an associated cost.
Depending on what you enable, SLIC Watch creates one dashboard and multiple alarms. The number of each depend on the number of resources in your stack and the number of stacks you have.

Check out the AWS [CloudWatch Pricing](https://aws.amazon.com/cloudwatch/pricing/) page to understand the cost impact of creating CloudWatch resources.


## References

### Other Projects
Expand Down
3 changes: 3 additions & 0 deletions cdk-test-project/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
cdk.out
20 changes: 20 additions & 0 deletions cdk-test-project/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
root: true,
env: {
node: true
},
plugins: [
'@typescript-eslint'
],
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
ecmaVersion: 2018
},
rules: {
'no-new': 0
},
extends: [
'standard-with-typescript'
]
}
7 changes: 7 additions & 0 deletions cdk-test-project/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out
6 changes: 6 additions & 0 deletions cdk-test-project/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.ts
!*.d.ts

# CDK asset staging directory
.cdk.staging
cdk.out
23 changes: 23 additions & 0 deletions cdk-test-project/bin/cdk-test-project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib'
import { CdkTestGeneralStack } from '../source/general-stack'
import { CdkSFNStack } from '../source/sfn-stack'
import { CdkECSStack } from '../source/ecs-stack'

const app = new cdk.App()

new CdkTestGeneralStack(app, 'CdkGeneralStackTest-Europe', {
env: { region: 'eu-west-1' }
})

new CdkECSStack(app, 'CdkECSStackTest-Europe', {
env: { region: 'eu-west-1' }
})

new CdkSFNStack(app, 'CdkSFNStackTest-Europe', {
env: { region: 'eu-west-1' }
})

new CdkTestGeneralStack(app, 'CdkGeneralStackTest-US', {
env: { region: 'us-east-1' }
})
40 changes: 40 additions & 0 deletions cdk-test-project/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"app": "npx ts-node --prefer-ts-exts bin/cdk-test-project.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:stackRelativeExports": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
]
}
}
8 changes: 8 additions & 0 deletions cdk-test-project/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
}
8 changes: 8 additions & 0 deletions cdk-test-project/lambda/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.handler = async function (event) {
console.log('request:', JSON.stringify(event, undefined, 2))
return {
statusCode: 200,
headers: { 'Content-Type': 'text/plain' },
body: `Hello good day, CDK! You've hit ${event.path}\n`
}
}
27 changes: 27 additions & 0 deletions cdk-test-project/lambda/stream-test-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict'

const Kinesis = require('aws-sdk/clients/kinesis')
const kin = new Kinesis()

const { STREAM_NAME } = process.env

async function handleDrive (event) {
console.log(`Sending events to ${STREAM_NAME}`)
const items = [...new Array(500)].map((_, index) => ({
index,
createdAt: new Date().toISOString(),
...event // Propagate event so the received can behave in required ways
}))
await kin.putRecords({
Records: items.map(item => ({
Data: JSON.stringify(item),
PartitionKey: 'a'
})),
StreamName: STREAM_NAME
}).promise()
console.log('Sent events')
}

module.exports = {
handleDrive
}
Loading

0 comments on commit 27810ec

Please sign in to comment.