Skip to content

Commit 62d7bf8

Browse files
authored
feat(custom-resource): allow AwsCustomResource to be placed in vpc (#21357)
This will allow for users with a need for all Lambda functions to be placed in a VPC to more easily adopt the use of `AwsCustomResource`. This is implemented by accepting a `vpc` and `vpcSubnets` property and passing those up to the created `SingletonFunction`. Then tests are added to ensure that it builds correctly and that errors are thrown in the expected circumstances (in the same situations that `lambda.Function` does). This mimics the setup already used by `Provider` in the same package. ---- ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 5549f16 commit 62d7bf8

File tree

14 files changed

+2416
-2
lines changed

14 files changed

+2416
-2
lines changed

packages/@aws-cdk/custom-resources/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,26 @@ new cr.AwsCustomResource(this, 'Customized', {
533533
});
534534
```
535535

536+
Additionally, the Lambda function can be placed in a private VPC by using the `vpc`
537+
and `vpcSubnets` properties.
538+
539+
```ts
540+
declare const myVpc: ec2.Vpc;
541+
new cr.AwsCustomResource(this, 'CustomizedInVpc', {
542+
vpc,
543+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_NAT },
544+
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
545+
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
546+
}
547+
})
548+
```
549+
550+
Note that Lambda functions in a VPC
551+
[require Network Address Translation (NAT) in order to access the internet][vpc-internet].
552+
The subnets specified in `vpcSubnets` must be private subnets.
553+
554+
[vpc-internet]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-internet
555+
536556
### Restricting the output of the Custom Resource
537557
538558
CloudFormation imposes a hard limit of 4096 bytes for custom resources response

packages/@aws-cdk/custom-resources/lib/aws-custom-resource/aws-custom-resource.ts

+20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
3+
import * as ec2 from '@aws-cdk/aws-ec2';
34
import * as iam from '@aws-cdk/aws-iam';
45
import * as lambda from '@aws-cdk/aws-lambda';
56
import * as logs from '@aws-cdk/aws-logs';
@@ -314,6 +315,23 @@ export interface AwsCustomResourceProps {
314315
* ID for the function's name. For more information, see Name Type.
315316
*/
316317
readonly functionName?: string;
318+
319+
/**
320+
* The vpc to provision the lambda function in.
321+
*
322+
* @default - the function is not provisioned inside a vpc.
323+
*/
324+
readonly vpc?: ec2.IVpc;
325+
326+
/**
327+
* Which subnets from the VPC to place the lambda function in.
328+
*
329+
* Only used if 'vpc' is supplied. Note: internet access for Lambdas
330+
* requires a NAT gateway, so picking Public subnets is not allowed.
331+
*
332+
* @default - the Vpc default strategy if not specified
333+
*/
334+
readonly vpcSubnets?: ec2.SubnetSelection;
317335
}
318336

319337
/**
@@ -384,6 +402,8 @@ export class AwsCustomResource extends Construct implements iam.IGrantable {
384402
role: props.role,
385403
logRetention: props.logRetention,
386404
functionName: props.functionName,
405+
vpc: props.vpc,
406+
vpcSubnets: props.vpcSubnets,
387407
});
388408
this.grantPrincipal = provider.grantPrincipal;
389409

packages/@aws-cdk/custom-resources/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"@aws-cdk/aws-ssm": "0.0.0",
8787
"@aws-cdk/cdk-build-tools": "0.0.0",
8888
"@aws-cdk/integ-runner": "0.0.0",
89+
"@aws-cdk/integ-tests": "0.0.0",
8990
"@aws-cdk/cfn2ts": "0.0.0",
9091
"@aws-cdk/pkglint": "0.0.0",
9192
"@types/aws-lambda": "^8.10.102",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "21.0.0",
3+
"files": {
4+
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
5+
"source": {
6+
"path": "CustomResourceVpcDefaultTestDeployAssert5F9D2F88.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"Parameters": {
3+
"BootstrapVersion": {
4+
"Type": "AWS::SSM::Parameter::Value<String>",
5+
"Default": "/cdk-bootstrap/hnb659fds/version",
6+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
7+
}
8+
},
9+
"Rules": {
10+
"CheckBootstrapVersion": {
11+
"Assertions": [
12+
{
13+
"Assert": {
14+
"Fn::Not": [
15+
{
16+
"Fn::Contains": [
17+
[
18+
"1",
19+
"2",
20+
"3",
21+
"4",
22+
"5"
23+
],
24+
{
25+
"Ref": "BootstrapVersion"
26+
}
27+
]
28+
}
29+
]
30+
},
31+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
32+
}
33+
]
34+
}
35+
}
36+
}

packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource-vpc.integ.snapshot/asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286/index.js

+252
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"version": "21.0.0",
3+
"files": {
4+
"105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286": {
5+
"source": {
6+
"path": "asset.105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286",
7+
"packaging": "zip"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "105b4f39ae68785e705640aa91919e412fcba2dd454aca53412747be8d955286.zip",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
},
17+
"22efa0d4a96b66c40920e49bb4682abcbc095c711aa828b6004b1dc95b97775c": {
18+
"source": {
19+
"path": "aws-cdk-customresources-vpc.template.json",
20+
"packaging": "file"
21+
},
22+
"destinations": {
23+
"current_account-current_region": {
24+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
25+
"objectKey": "22efa0d4a96b66c40920e49bb4682abcbc095c711aa828b6004b1dc95b97775c.json",
26+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
27+
}
28+
}
29+
}
30+
},
31+
"dockerImages": {}
32+
}

0 commit comments

Comments
 (0)