Skip to content

aws-lambda-secretsmanager #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
74d0436
docs: added README.md and architecture.png
allen-moheimani-aws Mar 24, 2021
f5e2d17
feat(aws-lambda-secretsmanager): Updated documentation with code revi…
danielmatuki Mar 30, 2021
a0c446f
feat(aws-lambda-secretsmanager): Updated documentation with code revi…
danielmatuki Mar 30, 2021
9b27790
feat(aws-lambda-secretsmanager): Created core helpers to provision se…
danielmatuki Apr 3, 2021
fc593fe
feat(aws-lambda-secretsmanager): Fixed double quotes in import
danielmatuki Apr 5, 2021
227258f
feat(aws-lambda-secretsmanager): Fixed double quotes in import
danielmatuki Apr 5, 2021
76c64b9
Merge pull request #1 from ammoheim/aws-lambda-secrets-manager-daniel
danielmatuki Apr 5, 2021
b607c2b
implemented lib/index.ts; added ignore files; added package.json
allen-moheimani-aws Apr 13, 2021
aff559e
Merge branch 'allen/aws-lambda-secrets-manager' of github.com:ammohei…
allen-moheimani-aws Apr 13, 2021
a6ee8c5
fixed naming
allen-moheimani-aws Apr 13, 2021
507fb4e
feat(aws-lambda-secretsmanager): Implementation changes, integration …
danielmatuki Apr 15, 2021
cae6e1b
feat(aws-lambda-secretsmanager): Added missing snapshot
danielmatuki Apr 15, 2021
89abf9b
Merge branch 'master' into allen/aws-lambda-secrets-manager
danielmatuki Apr 15, 2021
74ce19e
Merge branch 'main' into allen/aws-lambda-secrets-manager
danielmatuki Apr 21, 2021
44a3439
feat(aws-lambda-secretsmanager): Updated documentation and test snaps…
danielmatuki Apr 21, 2021
a067ec6
feat(aws-lambda-secretsmanager): Updated documentation and test snaps…
danielmatuki Apr 22, 2021
9ae1aec
Merge branch 'main' into allen/aws-lambda-secrets-manager
danielmatuki Apr 22, 2021
62cc689
suppressed warning on build
allen-moheimani-aws Apr 24, 2021
1975482
docs: added README.md and architecture.png
allen-moheimani-aws Mar 24, 2021
ba72fd8
implemented lib/index.ts; added ignore files; added package.json
allen-moheimani-aws Apr 13, 2021
b703f12
feat(aws-lambda-secretsmanager): Updated documentation with code revi…
danielmatuki Mar 30, 2021
712622a
feat(aws-lambda-secretsmanager): Created core helpers to provision se…
danielmatuki Apr 3, 2021
9207ba5
feat(aws-lambda-secretsmanager): Fixed double quotes in import
danielmatuki Apr 5, 2021
b4a61ab
feat(aws-lambda-secretsmanager): Fixed double quotes in import
danielmatuki Apr 5, 2021
69699d9
fixed naming
allen-moheimani-aws Apr 13, 2021
c74574b
feat(aws-lambda-secretsmanager): Implementation changes, integration …
danielmatuki Apr 15, 2021
3b95ed2
feat(aws-lambda-secretsmanager): Added missing snapshot
danielmatuki Apr 15, 2021
04ea64d
feat(aws-lambda-secretsmanager): Updated documentation and test snaps…
danielmatuki Apr 21, 2021
1e44b74
feat(aws-lambda-secretsmanager): Updated documentation and test snaps…
danielmatuki Apr 22, 2021
fc8d288
suppressed warning on build
allen-moheimani-aws Apr 24, 2021
ca6a781
Merge branch 'allen/aws-lambda-secrets-manager' of github.com:ammohei…
allen-moheimani-aws Apr 26, 2021
afaf9a3
feedback from PR
allen-moheimani-aws Apr 26, 2021
8e66733
fixed failing test
allen-moheimani-aws Apr 26, 2021
5dff62f
feat(aws-lambda-secretsmanager): code review fixes.
danielmatuki Apr 28, 2021
658710d
feat(aws-lambda-secretsmanager): unit test code review fixes.
danielmatuki Apr 30, 2021
38ad126
updated removal policy for tests to destroy the secret upon stack del…
allen-moheimani-aws May 3, 2021
0170268
feat(aws-lambda-secretsmanager): Updated unit tests snapshot
danielmatuki May 4, 2021
546f6d0
feat(aws-lambda-secretsmanager): Updates to utilize secret ARN instea…
danielmatuki May 4, 2021
b8033aa
Merge branch 'main' into allen/aws-lambda-secrets-manager
hnishar May 5, 2021
7282f96
feat(aws-lambda-secretsmanager): Included unit test to override the s…
danielmatuki May 6, 2021
3dce4c4
Merge branch 'allen/aws-lambda-secrets-manager' of github.com:ammohei…
danielmatuki May 6, 2021
4e56276
feat(aws-lambda-secretsmanager): Included viper light ignore for unit…
danielmatuki May 6, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .viperlightignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ source/patterns/@aws-solutions-constructs/core/test/cloudfront-distribution-s3-h
source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/test.s3-sqs.test.ts:251
source/use_cases/aws-custom-glue-etl/stream-producer/generate_data.py:86
source/use_cases/aws-custom-glue-etl/stream-producer/generate_data.py:87
source/patterns/@aws-solutions-constructs/aws-lambda-secretsmanager/test/lambda-secretsmanager.test.ts:481
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lib/*.js
test/*.js
*.d.ts
coverage
test/lambda/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lib/*.js
test/*.js
*.js.map
*.d.ts
node_modules
*.generated.ts
dist
.jsii

.LAST_BUILD
.nyc_output
coverage
.nycrc
.LAST_PACKAGE
*.snk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Exclude typescript source and config
*.ts
tsconfig.json
coverage
.nyc_output
*.tgz
*.snk
*.tsbuildinfo

# Include javascript files and typescript declarations
!*.js
!*.d.ts

# Exclude jsii outdir
dist

# Include .jsii
!.jsii

# Include .jsii
!.jsii
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# aws-lambda-secretsmanager module
<!--BEGIN STABILITY BANNER-->

---

![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge)

> All classes are under active development and subject to non-backward compatible changes or removal in any
> future version. These are not subject to the [Semantic Versioning](https://semver.org/) model.
> This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.

---
<!--END STABILITY BANNER-->

| **Reference Documentation**:| <span style="font-weight: normal">https://docs.aws.amazon.com/solutions/latest/constructs/</span>|
|:-------------|:-------------|
<div style="height:8px"></div>

| **Language** | **Package** |
|:-------------|-----------------|
|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_lambda_secretsmanager`|
|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-lambda-secretsmanager`|
|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.lambdasecretsmanager`|

This AWS Solutions Construct implements the AWS Lambda function and AWS Secrets Manager secret with the least privileged permissions.

Here is a minimal deployable pattern definition in Typescript:

``` javascript
const { LambdaToSecretsmanagerProps, LambdaToSecretsmanager } from '@aws-solutions-constructs/aws-lambda-secretsmanager';

const props: LambdaToSecretsmanagerProps = {
lambdaFunctionProps: {
runtime: lambda.Runtime.NODEJS_14_X,
// This assumes a handler function in lib/lambda/index.js
code: lambda.Code.fromAsset(`${__dirname}/lambda`),
handler: 'index.handler'
},
};

new LambdaToSecretsmanager(this, 'test-lambda-secretsmanager-stack', props);

```

## Initializer

``` text
new LambdaToSecretsmanager(scope: Construct, id: string, props: LambdaToSecretsmanagerProps);
```

_Parameters_

* scope [`Construct`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.Construct.html)
* id `string`
* props [`LambdaToSecretsmanagerProps`](#pattern-construct-props)

## Pattern Construct Props

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|existingLambdaObj?|[`lambda.Function`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.Function.html)|Existing instance of Lambda Function object, if this is set then the lambdaFunctionProps is ignored.|
|lambdaFunctionProps?|[`lambda.FunctionProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.FunctionProps.html)|User provided props to override the default props for the Lambda function.|
|secretProps?|[`secretsmanager.SecretProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.SecretProps.html)|Optional user provided props to override the default props for Secrets Manager|
|existingSecretObj?|[`secretsmanager.Secret`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.Secret.html)|Existing instance of Secrets Manager Secret object, If this is set then the secretProps is ignored|
|grantWriteAccess?|`boolean`|Optional write access to the Secret for the Lambda function (Read-Only by default)
|secretEnvironmentVariableName?|`string`|Optional Name for the Secrets Manager secret environment variable set for the Lambda function.|
|existingVpc?|[`ec2.IVpc`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.IVpc.html)|An optional, existing VPC into which this pattern should be deployed. When deployed in a VPC, the Lambda function will use ENIs in the VPC to access network resources and an Interface Endpoint will be created in the VPC for AWS Secrets Manager. If an existing VPC is provided, the `deployVpc` property cannot be `true`. This uses `ec2.IVpc` to allow clients to supply VPCs that exist outside the stack using the [`ec2.Vpc.fromLookup()`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options) method.|
|vpcProps?|[`ec2.VpcProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.VpcProps.html)|Optional user-provided properties to override the default properties for the new VPC. `enableDnsHostnames`, `enableDnsSupport`, `natGateways` and `subnetConfiguration` are set by the pattern, so any values for those properties supplied here will be overrriden. If `deployVpc` is not `true` then this property will be ignored.|
|deployVpc?|`boolean`|Whether to create a new VPC based on `vpcProps` into which to deploy this pattern. Setting this to true will deploy the minimal, most private VPC to run the pattern:<ul><li> One isolated subnet in each Availability Zone used by the CDK program</li><li>`enableDnsHostnames` and `enableDnsSupport` will both be set to true</li></ul>If this property is `true` then `existingVpc` cannot be specified. Defaults to `false`.|

## Pattern Properties

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|lambdaFunction|[`lambda.Function`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-lambda.Function.html)|Returns an instance of lambda.Function created by the construct|
|secret|[`secretsmanager.Secret`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.Secret.html)|Returns an instance of secretsmanager.Secret created by the construct|
|vpc?|[`ec2.IVpc`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.IVpc.html)|Returns an interface on the VPC used by the pattern (if any). This may be a VPC created by the pattern or the VPC supplied to the pattern constructor.|

## Default settings

Out of the box implementation of the Construct without any override will set the following defaults:

### AWS Lambda Function
* Configure limited privilege access IAM role for Lambda function
* Enable reusing connections with Keep-Alive for NodeJs Lambda function
* Enable X-Ray Tracing
* Set Environment Variables
* (default) SECRET_ARN containing the ARN of the secret as return by CDK [secretArn property](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-secretsmanager.Secret.html#secretarn).
* AWS_NODEJS_CONNECTION_REUSE_ENABLED (for Node 10.x and higher functions)

### Amazon SecretsManager Secret
* Enable read-only access for the associated AWS Lambda Function
* Enable server-side encryption using a default KMS key for the account and region
* Creates a new Secret
* (default) random name
* (default) random value
* Retain the Secret when deleting the CloudFormation stack

## Architecture
![Architecture Diagram](architecture.png)

***
&copy; Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

// Imports
import * as defaults from "@aws-solutions-constructs/core";
import * as lambda from "@aws-cdk/aws-lambda";
import * as secretsmanager from "@aws-cdk/aws-secretsmanager";
import * as ec2 from "@aws-cdk/aws-ec2";
import { Construct } from "@aws-cdk/core";

/**
* @summary The properties for the LambdaToSecretsmanager class.
*/
export interface LambdaToSecretsmanagerProps {
/**
* Existing instance of Lambda Function object, if this is set then the lambdaFunctionProps is ignored.
*
* @default - None
*/
readonly existingLambdaObj?: lambda.Function;
/**
* User provided props to override the default props for the Lambda function.
*
* @default - Default properties are used.
*/
readonly lambdaFunctionProps?: lambda.FunctionProps;
/**
* Existing instance of Secret object, if this is set then secretProps is ignored.
*
* @default - Default props are used
*/
readonly existingSecretObj?: secretsmanager.Secret;
/**
* Optional user-provided props to override the default props for the Secret.
*
* @default - Default props are used
*/
readonly secretProps?: secretsmanager.SecretProps;
/**
* An existing VPC for the construct to use (construct will NOT create a new VPC in this case)
*/
readonly existingVpc?: ec2.IVpc;
/**
* Properties to override default properties if deployVpc is true
*/
readonly vpcProps?: ec2.VpcProps;
/**
* Whether to deploy a new VPC
*
* @default - false
*/
readonly deployVpc?: boolean;
/**
* Optional Name for the Secret environment variable set for the Lambda function.
*
* @default - SECRET_NAME
*/
readonly secretEnvironmentVariableName?: string;
/**
* Optional secret permissions to grant to the Lambda function.
* One of the following may be specified: "Read" or "ReadWrite".
*
* @default - Read only acess is given to the Lambda function if no value is specified.
*/
readonly grantWriteAccess?: string;
}

/**
* @summary The LambdaToSecretsmanager class.
*/
export class LambdaToSecretsmanager extends Construct {
public readonly lambdaFunction: lambda.Function;
public readonly secret: secretsmanager.Secret;
public readonly vpc?: ec2.IVpc;

/**
* @summary Constructs a new instance of the LambdaToSecretsmanager class.
* @param {cdk.App} scope - represents the scope for all the resources.
* @param {string} id - this is a a scope-unique id.
* @param {LambdaToSecretsmanagerProps} props - user provided props for the construct.
* @access public
*/
constructor(scope: Construct, id: string, props: LambdaToSecretsmanagerProps) {
super(scope, id);

if (props.deployVpc || props.existingVpc) {
if (props.deployVpc && props.existingVpc) {
throw new Error("More than 1 VPC specified in the properties");
}

this.vpc = defaults.buildVpc(scope, {
defaultVpcProps: defaults.DefaultIsolatedVpcProps(),
existingVpc: props.existingVpc,
userVpcProps: props.vpcProps,
constructVpcProps: {
enableDnsHostnames: true,
enableDnsSupport: true,
},
});

defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.SECRETS_MANAGER);
}

// Setup the Lambda function
this.lambdaFunction = defaults.buildLambdaFunction(this, {
existingLambdaObj: props.existingLambdaObj,
lambdaFunctionProps: props.lambdaFunctionProps,
vpc: this.vpc,
});

// Setup the Secret
if (props.existingSecretObj) {
this.secret = props.existingSecretObj;
} else {
this.secret = defaults.buildSecretsManagerSecret(this, 'secret', props.secretProps);
}

// Configure environment variables
const secretEnvironmentVariableName = props.secretEnvironmentVariableName || 'SECRET_ARN';
this.lambdaFunction.addEnvironment(secretEnvironmentVariableName, this.secret.secretArn);

// Enable read permissions for the Lambda function by default
this.secret.grantRead(this.lambdaFunction);

if (props.grantWriteAccess === 'ReadWrite') {
this.secret.grantWrite(this.lambdaFunction);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"name": "@aws-solutions-constructs/aws-lambda-secretsmanager",
"version": "0.0.0",
"description": "CDK constructs for defining an interaction between an AWS Lambda function and AWS Secrets Manager.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
"directory": "source/patterns/@aws-solutions-constructs/aws-lambda-secretsmanager"
},
"author": {
"name": "Amazon Web Services",
"url": "https://aws.amazon.com",
"organization": true
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc -b .",
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
"test": "jest --coverage",
"clean": "tsc -b --clean",
"watch": "tsc -b -w",
"integ": "cdk-integ",
"integ-assert": "cdk-integ-assert",
"integ-no-clean": "cdk-integ --no-clean",
"jsii": "jsii",
"jsii-pacmak": "jsii-pacmak",
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
},
"jsii": {
"outdir": "dist",
"targets": {
"java": {
"package": "software.amazon.awsconstructs.services.lambdasecretsmanager",
"maven": {
"groupId": "software.amazon.awsconstructs",
"artifactId": "lambdasecretsmanager"
}
},
"dotnet": {
"namespace": "Amazon.Constructs.AWS.LambdaSecretsManager",
"packageId": "Amazon.Constructs.AWS.LambdaSecretsManager",
"signAssembly": true,
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
},
"python": {
"distName": "aws-solutions-constructs.aws-lambda-secretsmanager",
"module": "aws_solutions_constructs.aws_lambda_secretsmanager"
}
}
},
"dependencies": {
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-secretsmanager": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"constructs": "^3.2.0"
},
"devDependencies": {
"@aws-cdk/assert": "0.0.0",
"@types/jest": "^24.0.23",
"@types/node": "^10.3.0"
},
"jest": {
"moduleFileExtensions": [
"js"
]
},
"peerDependencies": {
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-secretsmanager": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"constructs": "^3.2.0"
}
}
Loading