-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(event-targets): workaround for CDK issue: aws/aws-cdk#17002
workaround for CDK issue: aws/aws-cdk#17002
- Loading branch information
Showing
5 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as cdk from 'aws-cdk-lib' | ||
import * as events from 'aws-cdk-lib/aws-events' | ||
import * as targets from 'aws-cdk-lib/aws-events-targets' | ||
import * as logs from 'aws-cdk-lib/aws-logs' | ||
import * as common from '../../common' | ||
|
||
/** | ||
* @stability stable | ||
* @category cdk-utils.event-taeget-manager | ||
* @subcategory Construct | ||
* @classdesc Provides operations on AWS EventBridge Targets. | ||
* - A new instance of this class is injected into {@link common.CommonConstruct} constructor. | ||
* - If a custom construct extends {@link common.CommonConstruct}, an instance is available within the context. | ||
* @example | ||
* import * as common from '@gradientedge/cdk-utils' | ||
* | ||
* class CustomConstruct extends common.common.CommonConstruct { | ||
* constructor(parent: cdk.Construct, id: string, props: common.CommonStackProps) { | ||
* super(parent, id, props) | ||
* this.props = props | ||
* this.eventTargetManager.createCloudWatchLogGroupNoPolicy('MyLogGrouptarget', this, myLogGroup) | ||
* } | ||
* } | ||
* | ||
* @see [CDK EventBridge Target Module]{@link https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_events_targets-readme.html} | ||
*/ | ||
export class EventTargetManager { | ||
/** | ||
* @summary Method to create a cloud watch log group target without a policy. | ||
* - This method is created as a workaround for cdk issue - https://github.com/aws/aws-cdk/issues/17002 | ||
* @param {string} id scoped id of the resource | ||
* @param {common.CommonConstruct} scope scope in which this resource is defined | ||
* @param {logs.ILogGroup} logGroup the log group | ||
* @param {LogGroupNoPolicyProps} props the log group target properties | ||
*/ | ||
public createCloudWatchLogGroupNoPolicy( | ||
id: string, | ||
scope: common.CommonConstruct, | ||
logGroup: logs.ILogGroup, | ||
props?: LogGroupNoPolicyProps | ||
) { | ||
return new CloudWatchLogGroupNoPolicy(logGroup, props) | ||
} | ||
} | ||
|
||
/** | ||
* Customize the CloudWatch LogGroup Event Target | ||
*/ | ||
export interface LogGroupNoPolicyProps extends targets.TargetBaseProps { | ||
/** | ||
* The event to send to the CloudWatch LogGroup | ||
* | ||
* This will be the event logged into the CloudWatch LogGroup | ||
* | ||
* @default - the entire EventBridge event | ||
*/ | ||
readonly event?: events.RuleTargetInput | ||
} | ||
|
||
/** | ||
* Use an AWS CloudWatch LogGroup as an event rule target, but don't apply a policy. | ||
*/ | ||
export class CloudWatchLogGroupNoPolicy implements events.IRuleTarget { | ||
constructor(private readonly logGroup: logs.ILogGroup, private readonly props: LogGroupNoPolicyProps = {}) {} | ||
|
||
/** | ||
* Returns a RuleTarget that can be used to log an event into a CloudWatch LogGroup | ||
*/ | ||
public bind(_rule: events.IRule, _id?: string): events.RuleTargetConfig { | ||
const logGroupStack = cdk.Stack.of(this.logGroup) | ||
|
||
return { | ||
...targets.bindBaseTargetConfig(this.props), | ||
arn: logGroupStack.formatArn({ | ||
service: 'logs', | ||
resource: 'log-group', | ||
arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, | ||
resourceName: this.logGroup.logGroupName, | ||
}), | ||
input: this.props.event, | ||
targetResource: this.logGroup, | ||
} | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import * as cdk from 'aws-cdk-lib' | ||
import { Template } from 'aws-cdk-lib/assertions' | ||
import { Construct } from 'constructs' | ||
import * as common from '../../lib/common' | ||
import * as types from '../../lib/types' | ||
|
||
interface TestStackProps extends types.CommonStackProps { | ||
testLogGroup: any | ||
} | ||
|
||
const testStackProps = { | ||
env: { | ||
account: '123456789', | ||
region: 'eu-west-1', | ||
}, | ||
name: 'test-common-stack', | ||
domainName: 'gradientedge.io', | ||
region: 'eu-west-1', | ||
stackName: 'test', | ||
stage: 'test', | ||
extraContexts: ['src/test/common/cdkConfig/logs.json'], | ||
stageContextPath: 'src/test/common/cdkEnv', | ||
} | ||
|
||
class TestCommonStack extends common.CommonStack { | ||
declare props: TestStackProps | ||
|
||
constructor(parent: cdk.App, name: string, props: cdk.StackProps) { | ||
super(parent, name, props) | ||
|
||
this.construct = new TestCommonConstruct(this, testStackProps.name, this.props) | ||
} | ||
|
||
protected determineConstructProps(props: cdk.StackProps) { | ||
return { | ||
...super.determineConstructProps(props), | ||
...{ | ||
testLogGroup: this.node.tryGetContext('testLogGroup'), | ||
}, | ||
} | ||
} | ||
} | ||
|
||
class TestCommonConstruct extends common.CommonConstruct { | ||
declare props: TestStackProps | ||
|
||
constructor(parent: Construct, name: string, props: TestStackProps) { | ||
super(parent, name, props) | ||
const testLogGroup = this.logManager.createLogGroup('test-log-group', this, this.props.testLogGroup) | ||
this.eventTargetManager.createCloudWatchLogGroupNoPolicy('test-log-group-target', this, testLogGroup) | ||
} | ||
} | ||
|
||
const app = new cdk.App({ context: testStackProps }) | ||
const commonStack = new TestCommonStack(app, 'test-common-stack', testStackProps) | ||
const template = Template.fromStack(commonStack) | ||
|
||
describe('TestEventTargetConstruct', () => { | ||
test('synthesises as expected', () => { | ||
/* test if number of resources are correctly synthesised */ | ||
template.resourceCountIs('AWS::Logs::LogGroup', 1) | ||
template.resourceCountIs('AWS::Logs::ResourcePolicy', 0) | ||
}) | ||
}) | ||
|
||
describe('TestEventTargetConstruct', () => { | ||
test('outputs as expected', () => { | ||
template.hasOutput('testLogGroupLogGroupArn', {}) | ||
}) | ||
}) | ||
|
||
describe('TestEventTargetConstruct', () => { | ||
test('provisions new log group target as expected', () => { | ||
template.hasResourceProperties('AWS::Logs::LogGroup', { | ||
LogGroupName: 'test-lg-test', | ||
}) | ||
}) | ||
}) |