Skip to content

Commit

Permalink
feat(custom-resources): add custom environmentEncryption for Provider…
Browse files Browse the repository at this point in the history
… lambda functions (#26236)

The `providerFunctionEnvEncryption` property on the `Provider` class allows users to specify a custom KMS key that will be used to encrypt the environment variables of the generated lambda functions.


Closes #26197.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
lpizzinidev authored Jul 12, 2023
1 parent 1a8f5ad commit 546456a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/aws-cdk-lib/custom-resources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,27 @@ const myProvider = new cr.Provider(this, 'MyProvider', {

```

### Customizing Provider Function environment encryption key

Sometimes it may be useful to manually set a AWS KMS key for the Provider Function Lambda and therefore
be able to view, manage and audit the key usage.

```ts
declare const onEvent: lambda.Function;
declare const isComplete: lambda.Function;
declare const myRole: iam.Role;

const key = new kms.Key(this, 'MyKey');
const myProvider = new cr.Provider(this, 'MyProvider', {
onEventHandler: onEvent,
isCompleteHandler: isComplete,
logRetention: logs.RetentionDays.ONE_DAY,
role: myRole,
providerFunctionEnvEncryption: key, // Optional
});

```

## Custom Resources for AWS APIs

Sometimes a single API call can fill the gap in the CloudFormation coverage. In
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { WaiterStateMachine } from './waiter-state-machine';
import { CustomResourceProviderConfig, ICustomResourceProvider } from '../../../aws-cloudformation';
import * as ec2 from '../../../aws-ec2';
import * as iam from '../../../aws-iam';
import * as kms from '../../../aws-kms';
import * as lambda from '../../../aws-lambda';
import * as logs from '../../../aws-logs';
import { Duration } from '../../../core';
Expand Down Expand Up @@ -118,6 +119,13 @@ export interface ProviderProps {
* @default - CloudFormation default name from unique physical ID
*/
readonly providerFunctionName?: string;

/**
* AWS KMS key used to encrypt provider lambda's environment variables.
*
* @default - AWS Lambda creates and uses an AWS managed customer master key (CMK)
*/
readonly providerFunctionEnvEncryption?: kms.IKey;
}

/**
Expand Down Expand Up @@ -149,6 +157,7 @@ export class Provider extends Construct implements ICustomResourceProvider {
private readonly vpcSubnets?: ec2.SubnetSelection;
private readonly securityGroups?: ec2.ISecurityGroup[];
private readonly role?: iam.IRole;
private readonly providerFunctionEnvEncryption?: kms.IKey;

constructor(scope: Construct, id: string, props: ProviderProps) {
super(scope, id);
Expand All @@ -167,6 +176,7 @@ export class Provider extends Construct implements ICustomResourceProvider {
this.securityGroups = props.securityGroups;

this.role = props.role;
this.providerFunctionEnvEncryption = props.providerFunctionEnvEncryption;

const onEventFunction = this.createFunction(consts.FRAMEWORK_ON_EVENT_HANDLER_NAME, props.providerFunctionName);

Expand Down Expand Up @@ -216,6 +226,7 @@ export class Provider extends Construct implements ICustomResourceProvider {
securityGroups: this.securityGroups,
role: this.role,
functionName: name,
environmentEncryption: this.providerFunctionEnvEncryption,
});

fn.addEnvironment(consts.USER_ON_EVENT_FUNCTION_ARN_ENV, this.onEventHandler.functionArn);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import { Template } from '../../../assertions';
import * as ec2 from '../../../aws-ec2';
import * as iam from '../../../aws-iam';
import * as kms from '../../../aws-kms';
import * as lambda from '../../../aws-lambda';
import * as logs from '../../../aws-logs';
import { Duration, Stack } from '../../../core';
Expand Down Expand Up @@ -419,3 +420,33 @@ describe('name', () => {
});
});
});

describe('environment encryption', () => {
it('uses custom KMS key for environment encryption when present', () => {
// GIVEN
const stack = new Stack();
const key: kms.IKey = new kms.Key(stack, 'EnvVarEncryptKey', {
description: 'sample key',
});

// WHEN
new cr.Provider(stack, 'MyProvider', {
onEventHandler: new lambda.Function(stack, 'MyHandler', {
code: lambda.Code.fromAsset(path.join(__dirname, './integration-test-fixtures/s3-file-handler')),
handler: 'index.onEvent',
runtime: lambda.Runtime.NODEJS_14_X,
}),
providerFunctionEnvEncryption: key,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', {
KmsKeyArn: {
'Fn::GetAtt': [
'EnvVarEncryptKey1A7CABDB',
'Arn',
],
},
});
});
});

0 comments on commit 546456a

Please sign in to comment.