Skip to content

Commit df24d22

Browse files
authored
feat(schedule-alpha): support customer managed KMS keys (#27609)
Allows to specify a customer-managed KMS key for encryption. Example: ```ts declare const key: kms.Key; declare const fn: lambda.Function; const target = new targets.LambdaInvoke(fn, { input: ScheduleTargetInput.fromObject({ "payload": "useful", }), }); const schedule = new Schedule(this, 'Schedule', { schedule: ScheduleExpression.rate(Duration.minutes(10)), target, key, }); ``` Closes #27543. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent a1ad28b commit df24d22

11 files changed

+359
-11
lines changed

packages/@aws-cdk/aws-scheduler-alpha/README.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,31 @@ Executing cross-account and cross-region targets are not supported yet.
201201

202202
### Specifying Encryption key
203203

204-
TODO: Not yet implemented. See section in [L2 Event Bridge Scheduler RFC](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0474-event-bridge-scheduler-l2.md)
204+
EventBridge Scheduler integrates with AWS Key Management Service (AWS KMS) to encrypt and decrypt your data using an AWS KMS key.
205+
EventBridge Scheduler supports two types of KMS keys: AWS owned keys, and customer managed keys.
206+
207+
By default, all events in Scheduler are encrypted with a key that AWS owns and manages.
208+
If you wish you can also provide a customer managed key to encrypt and decrypt the payload that your schedule delivers to its target using the `key` property.
209+
Target classes will automatically add AWS KMS Decrypt permission to your schedule's execution role permissions policy.
210+
211+
```ts
212+
declare const key: kms.Key;
213+
declare const fn: lambda.Function;
214+
215+
const target = new targets.LambdaInvoke(fn, {
216+
input: ScheduleTargetInput.fromObject({
217+
payload: 'useful',
218+
}),
219+
});
220+
221+
const schedule = new Schedule(this, 'Schedule', {
222+
schedule: ScheduleExpression.rate(Duration.minutes(10)),
223+
target,
224+
key,
225+
});
226+
```
227+
228+
> Visit [Data protection in Amazon EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/data-protection.html) for more details.
205229
206230
## Error-handling
207231

packages/@aws-cdk/aws-scheduler-alpha/lib/schedule.ts

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { IResource, Resource } from 'aws-cdk-lib';
22
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
3+
import * as kms from 'aws-cdk-lib/aws-kms';
34
import { CfnSchedule } from 'aws-cdk-lib/aws-scheduler';
45
import { Construct } from 'constructs';
56
import { IGroup } from './group';
@@ -22,6 +23,11 @@ export interface ISchedule extends IResource {
2223
* The arn of the schedule.
2324
*/
2425
readonly scheduleArn: string;
26+
27+
/**
28+
* The customer managed KMS key that EventBridge Scheduler will use to encrypt and decrypt your data.
29+
*/
30+
readonly key?: kms.IKey;
2531
}
2632

2733
/**
@@ -67,6 +73,13 @@ export interface ScheduleProps {
6773
* @default true
6874
*/
6975
readonly enabled?: boolean;
76+
77+
/**
78+
* The customer managed KMS key that EventBridge Scheduler will use to encrypt and decrypt your data.
79+
*
80+
* @default - All events in Scheduler are encrypted with a key that AWS owns and manages.
81+
*/
82+
readonly key?: kms.IKey;
7083
}
7184

7285
/**
@@ -179,6 +192,11 @@ export class Schedule extends Resource implements ISchedule {
179192
*/
180193
public readonly scheduleName: string;
181194

195+
/**
196+
* The customer managed KMS key that EventBridge Scheduler will use to encrypt and decrypt your data.
197+
*/
198+
readonly key?: kms.IKey;
199+
182200
constructor(scope: Construct, id: string, props: ScheduleProps) {
183201
super(scope, id, {
184202
physicalName: props.scheduleName,
@@ -188,13 +206,19 @@ export class Schedule extends Resource implements ISchedule {
188206

189207
const targetConfig = props.target.bind(this);
190208

209+
this.key = props.key;
210+
if (this.key) {
211+
this.key.grantEncryptDecrypt(targetConfig.role);
212+
}
213+
191214
const resource = new CfnSchedule(this, 'Resource', {
192215
name: this.physicalName,
193216
flexibleTimeWindow: { mode: 'OFF' },
194217
scheduleExpression: props.schedule.expressionString,
195218
scheduleExpressionTimezone: props.schedule.timeZone?.timezoneName,
196219
groupName: this.group?.groupName,
197220
state: (props.enabled ?? true) ? 'ENABLED' : 'DISABLED',
221+
kmsKeyArn: this.key?.keyArn,
198222
target: {
199223
arn: targetConfig.arn,
200224
roleArn: targetConfig.role.roleArn,

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.assets.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/aws-cdk-scheduler-schedule.template.json

+97
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,37 @@
6767
}
6868
}
6969
},
70+
"RoleDefaultPolicy5FFB7DAB": {
71+
"Type": "AWS::IAM::Policy",
72+
"Properties": {
73+
"PolicyDocument": {
74+
"Statement": [
75+
{
76+
"Action": [
77+
"kms:Decrypt",
78+
"kms:Encrypt",
79+
"kms:GenerateDataKey*",
80+
"kms:ReEncrypt*"
81+
],
82+
"Effect": "Allow",
83+
"Resource": {
84+
"Fn::GetAtt": [
85+
"ScheduleKey7E6B3A92",
86+
"Arn"
87+
]
88+
}
89+
}
90+
],
91+
"Version": "2012-10-17"
92+
},
93+
"PolicyName": "RoleDefaultPolicy5FFB7DAB",
94+
"Roles": [
95+
{
96+
"Ref": "Role1ABCC5F0"
97+
}
98+
]
99+
}
100+
},
70101
"DefaultSchedule597B0B2C": {
71102
"Type": "AWS::Scheduler::Schedule",
72103
"Properties": {
@@ -128,6 +159,72 @@
128159
"Statistic": "Sum",
129160
"Threshold": 1
130161
}
162+
},
163+
"ScheduleKey7E6B3A92": {
164+
"Type": "AWS::KMS::Key",
165+
"Properties": {
166+
"KeyPolicy": {
167+
"Statement": [
168+
{
169+
"Action": "kms:*",
170+
"Effect": "Allow",
171+
"Principal": {
172+
"AWS": {
173+
"Fn::Join": [
174+
"",
175+
[
176+
"arn:",
177+
{
178+
"Ref": "AWS::Partition"
179+
},
180+
":iam::",
181+
{
182+
"Ref": "AWS::AccountId"
183+
},
184+
":root"
185+
]
186+
]
187+
}
188+
},
189+
"Resource": "*"
190+
}
191+
],
192+
"Version": "2012-10-17"
193+
}
194+
},
195+
"UpdateReplacePolicy": "Retain",
196+
"DeletionPolicy": "Retain"
197+
},
198+
"CustomerKmsSchedule12B1FEFE": {
199+
"Type": "AWS::Scheduler::Schedule",
200+
"Properties": {
201+
"FlexibleTimeWindow": {
202+
"Mode": "OFF"
203+
},
204+
"KmsKeyArn": {
205+
"Fn::GetAtt": [
206+
"ScheduleKey7E6B3A92",
207+
"Arn"
208+
]
209+
},
210+
"ScheduleExpression": "rate(12 hours)",
211+
"ScheduleExpressionTimezone": "Etc/UTC",
212+
"State": "ENABLED",
213+
"Target": {
214+
"Arn": {
215+
"Fn::GetAtt": [
216+
"Function76856677",
217+
"Arn"
218+
]
219+
},
220+
"RoleArn": {
221+
"Fn::GetAtt": [
222+
"Role1ABCC5F0",
223+
"Arn"
224+
]
225+
}
226+
}
227+
}
131228
}
132229
},
133230
"Parameters": {

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/integtestscheduleDefaultTestDeployAssert24CB3896.assets.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-scheduler-alpha/test/integ.schedule.js.snapshot/manifest.json

+20-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)