cdk-secret-manager-wrapper-layer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,102 @@
1
+ #!/bin/bash
2
+
3
+ #
4
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
+ # SPDX-License-Identifier: MIT-0
6
+ #
7
+ # This script is used to coordinate the creation of enivronmental variables by using a Golang exectutable
8
+ # that is part of the same layer. In order for this layer to operate, it must have permissiones to
9
+ # retreive data from Secrets Manager.
10
+ #
11
+ # Please note, this example uses AWS Lambda environmental varaibles. This includes the ARN of the Secret
12
+ # to use, the region to pull the Secret from, and the ARN for the role to use to retrieve the Secert.
13
+ #
14
+ # To use this script, make sure that it is wrapped in a ZIP file along with the go-retreive-secret
15
+ # Golang executable and added as a Lambda Layer. Your Lambda must reference this script by setting the
16
+ # AWS_LAMBDA_EXEC_WRAPPER environemntal variable to /opt/get-secrets-layer (the name of this shell script)
17
+ # and by referencing this layer within it's configuration.
18
+ #
19
+
20
+ # The name of this script
21
+ name=$(basename $0)
22
+
23
+ # The full path to this script
24
+ fullPath=$(dirname $(readlink -f $0))
25
+
26
+ # The path to the interpreter and all of the originally intended arguments
27
+ args=("$@")
28
+
29
+ # The name of the secret
30
+ secretArn="${SECRET_ARN}"
31
+
32
+ # The region to use for the API calls
33
+ region="${SECRET_REGION}"
34
+
35
+ # The role to use for API calls
36
+ roleName="${ASSUME_ROLE_ARN}"
37
+
38
+ # The timeout for API calls
39
+ timeout="${API_TIMEOUT}"
40
+
41
+ # Create a temp file to hold values to be exported
42
+ tempFile=$(mktemp /tmp/${name}.XXXXXXX)
43
+ last_cmd=$?
44
+ if [[ ${last_cmd} -ne 0 ]]; then
45
+ echo "Failed to create a temp file"
46
+ exit 1
47
+ fi
48
+
49
+ # Get the secret value by calling the Go executable
50
+ values=$(${fullPath}/go-retrieve-secret -r "${region}" -s "${secretArn}" -a "${roleName}" -t "${timeout}")
51
+ last_cmd=$?
52
+
53
+ # Verify that the last command was successful
54
+ if [[ ${last_cmd} -ne 0 ]]; then
55
+ echo "Failed to setup environment for Secret ${secretArn}"
56
+ exit 1
57
+ fi
58
+
59
+ # Read the data line by line and export the data as key value pairs
60
+ # and environmental variables
61
+ echo "${values}" | while read -r line; do
62
+
63
+ # Split the line into a key and value
64
+ ARRY=(${line//|/ })
65
+
66
+ # Capture the kay value
67
+ key="${ARRY[0]}"
68
+
69
+ # Since the key had been captured, no need to keep it in the array
70
+ unset ARRY[0]
71
+
72
+ # Join the other parts of the array into a single value. There is a chance that
73
+ # The split man have broken the data into multiple values. This will force the
74
+ # data to be rejoined.
75
+ value="${ARRY[@]}"
76
+
77
+ # Save as an env var to the temp file for later processing
78
+ echo "export ${key}=\"${value}\"" >> ${tempFile}
79
+ done
80
+
81
+ # Source the temp file to read in the env vars
82
+ . ${tempFile}
83
+
84
+ # Determine if AWS_LAMBDA_EXEC_WRAPPER points to this layer
85
+ # This is necessary as the Secret may have not specified a
86
+ # new layer. Without checking, the lambda layer may be
87
+ # called again.
88
+ layer_name=$(basename ${AWS_LAMBDA_EXEC_WRAPPER})
89
+
90
+ if [[ "${layer_name}" == "${name}" ]]; then
91
+ echo "No new layer was specified, unsetting AWS_LAMBDA_EXEC_WRAPPER"
92
+ unset AWS_LAMBDA_EXEC_WRAPPER
93
+ else
94
+ # Set args to include the new layer
95
+ args=("${AWS_LAMBDA_EXEC_WRAPPER}" "${args[@]}")
96
+ fi
97
+
98
+ # Remove the temp file
99
+ rm ${tempFile} > /dev/null 2>&1
100
+
101
+ # Execute the next step
102
+ exec ${args[@]}
@@ -0,0 +1,137 @@
1
+ package main
2
+
3
+ import (
4
+ "context"
5
+ "flag"
6
+ "fmt"
7
+ "time"
8
+
9
+ "encoding/json"
10
+
11
+ "github.com/aws/aws-sdk-go-v2/aws"
12
+ "github.com/aws/aws-sdk-go-v2/credentials"
13
+ "github.com/aws/aws-sdk-go-v2/service/secretsmanager"
14
+ "github.com/aws/aws-sdk-go-v2/service/sts"
15
+
16
+ "github.com/aws/aws-sdk-go-v2/aws/retry"
17
+ "github.com/aws/aws-sdk-go-v2/config"
18
+ )
19
+
20
+ // Constants for default values if none are supplied
21
+ const DEFAULT_TIMEOUT = 5000
22
+ const DEFAULT_REGION = "us-east-2"
23
+ const DEFAULT_SESSION = "param_session"
24
+
25
+ var (
26
+ region string
27
+ secretArn string
28
+ roleArn string
29
+ timeout int
30
+ sessionName string
31
+ )
32
+
33
+ // The main function will pull command line arg and retrieve the secret. The resulting
34
+ // secret will be dumped as JSON to the output
35
+ func main() {
36
+
37
+ // Get all of the command line data and perform the necessary validation
38
+ getCommandParams()
39
+
40
+ // Setup a new context to allow for limited execution time for API calls with a default of 200 milliseconds
41
+ ctx, cancel := context.WithTimeout(context.TODO(), time.Duration(timeout)*time.Millisecond)
42
+ defer cancel()
43
+
44
+ // Load the config
45
+ cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithRetryer(func() aws.Retryer {
46
+ // NopRetryer is used here in a global context to avoid retries on API calls
47
+ return retry.AddWithMaxAttempts(aws.NopRetryer{}, 1)
48
+ }))
49
+
50
+ if err != nil {
51
+ panic("configuration error " + err.Error())
52
+ }
53
+
54
+ // Assume a role to retreive the parameter
55
+ role, err := AttemptAssumeRole(ctx, cfg)
56
+
57
+ if err != nil {
58
+ panic("Failed to assume role due to error " + err.Error())
59
+ }
60
+
61
+ // Get the secret
62
+ result, err := GetSecret(ctx, cfg, role)
63
+
64
+ if err != nil {
65
+ panic("Failed to retrieve secret due to error " + err.Error())
66
+ }
67
+
68
+ // Convert the secret into JSON
69
+ var dat map[string]interface{}
70
+
71
+ // Convert the secret to JSON
72
+ if err := json.Unmarshal([]byte(*result.SecretString), &dat); err != nil {
73
+ fmt.Println("Failed to convert Secret to JSON")
74
+ fmt.Println(err)
75
+ panic(err)
76
+ }
77
+
78
+ // Get the secret value and dump the output in a manner that a shell script can read the
79
+ // data from the output
80
+ for key, value := range dat {
81
+ fmt.Printf("%s|%s\n", key, value)
82
+ }
83
+ }
84
+
85
+ func getCommandParams() {
86
+ // Setup command line args
87
+ flag.StringVar(&region, "r", DEFAULT_REGION, "The Amazon Region to use")
88
+ flag.StringVar(&secretArn, "s", "", "The ARN for the secret to access")
89
+ flag.StringVar(&roleArn, "a", "", "The ARN for the role to assume for Secret Access")
90
+ flag.IntVar(&timeout, "t", DEFAULT_TIMEOUT, "The amount of time to wait for any API call")
91
+ flag.StringVar(&sessionName, "n", DEFAULT_SESSION, "The name of the session for AWS STS")
92
+
93
+ // Parse all of the command line args into the specified vars with the defaults
94
+ flag.Parse()
95
+
96
+ // Verify that the correct number of args were supplied
97
+ if len(region) == 0 || len(secretArn) == 0 {
98
+ flag.PrintDefaults()
99
+ panic("You must supply a region and secret ARN. -r REGION -s SECRET-ARN [-a ARN for ROLE -t TIMEOUT IN MILLISECONDS -n SESSION NAME]")
100
+ }
101
+ }
102
+
103
+ // This function will attempt to assume the supplied role and return either an error or the assumed role
104
+ func AttemptAssumeRole(ctx context.Context, cfg aws.Config) (*sts.AssumeRoleOutput, error) {
105
+ if len(roleArn) <= 0 {
106
+ return nil, nil
107
+ }
108
+
109
+ client := sts.NewFromConfig(cfg)
110
+
111
+ return client.AssumeRole(ctx,
112
+ &sts.AssumeRoleInput{
113
+ RoleArn: &roleArn,
114
+ RoleSessionName: &sessionName,
115
+ },
116
+ )
117
+ }
118
+
119
+ // This function will return the descrypted version of the Secret from Secret Manager using the supplied
120
+ // assumed role to interact with Secret Manager. This function will return either an error or the
121
+ // retrieved and decrypted secret.
122
+ func GetSecret(ctx context.Context, cfg aws.Config, assumedRole *sts.AssumeRoleOutput) (*secretsmanager.GetSecretValueOutput, error) {
123
+
124
+ if assumedRole != nil {
125
+ client := secretsmanager.NewFromConfig(cfg, func(o *secretsmanager.Options) {
126
+ o.Credentials = aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(*assumedRole.Credentials.AccessKeyId, *assumedRole.Credentials.SecretAccessKey, *assumedRole.Credentials.SessionToken))
127
+ })
128
+ return client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{
129
+ SecretId: aws.String(secretArn),
130
+ })
131
+ } else {
132
+ client := secretsmanager.NewFromConfig(cfg)
133
+ return client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{
134
+ SecretId: aws.String(secretArn),
135
+ })
136
+ }
137
+ }
package/layer/go.mod ADDED
@@ -0,0 +1,13 @@
1
+ module go-retrieve-secret
2
+
3
+ go 1.15
4
+
5
+ require (
6
+ github.com/aws/aws-sdk-go v1.40.35 // indirect
7
+ github.com/aws/aws-sdk-go-v2 v1.9.0
8
+ github.com/aws/aws-sdk-go-v2/config v1.7.0 // indirect
9
+ github.com/aws/aws-sdk-go-v2/credentials v1.4.0 // indirect
10
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0 // indirect
11
+ github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0 // indirect
12
+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.0 // indirect
13
+ )
package/layer/go.sum ADDED
@@ -0,0 +1,53 @@
1
+ github.com/aws/aws-sdk-go v1.38.9 h1:eTIU8cggkcJwOT+Fb05OG8UhtSap5EWdWl0dMQFCdr8=
2
+ github.com/aws/aws-sdk-go v1.38.9/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
3
+ github.com/aws/aws-sdk-go v1.40.35 h1:ofWh1LlWaSbOpAsl8EHlg96PZXqgCGKKi8YgrdU2Z+I=
4
+ github.com/aws/aws-sdk-go v1.40.35/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
5
+ github.com/aws/aws-sdk-go-v2 v1.9.0 h1:+S+dSqQCN3MSU5vJRu1HqHrq00cJn6heIMU7X9hcsoo=
6
+ github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
7
+ github.com/aws/aws-sdk-go-v2/config v1.7.0 h1:J2cZ7qe+3IpqBEXnHUrFrOjoB9BlsXg7j53vxcl5IVg=
8
+ github.com/aws/aws-sdk-go-v2/config v1.7.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY=
9
+ github.com/aws/aws-sdk-go-v2/credentials v1.4.0 h1:kmvesfjY861FzlCU9mvAfe01D9aeXcG2ZuC+k9F2YLM=
10
+ github.com/aws/aws-sdk-go-v2/credentials v1.4.0/go.mod h1:dgGR+Qq7Wjcd4AOAW5Rf5Tnv3+x7ed6kETXyS9WCuAY=
11
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0 h1:OxTAgH8Y4BXHD6PGCJ8DHx2kaZPCQfSTqmDsdRZFezE=
12
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0/go.mod h1:CpNzHK9VEFUCknu50kkB8z58AH2B5DvPP7ea1LHve/Y=
13
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2 h1:d95cddM3yTm4qffj3P6EnP+TzX1SSkWaQypXSgT/hpA=
14
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2/go.mod h1:BQV0agm+JEhqR+2RT5e1XTFIDcAAV0eW6z2trp+iduw=
15
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0 h1:VNJ5NLBteVXEwE2F1zEXVmyIH58mZ6kIQGJoC7C+vkg=
16
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0/go.mod h1:R1KK+vY8AfalhG1AOu5e35pOD2SdoPKQCFLTvnxiohk=
17
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0 h1:3vxYnnbPWwECs3xN+cu/bRefhynMOH6elQAxuHES01Q=
18
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0/go.mod h1:B+7C5UKdVq1ylkI/A6O8wcurFtaux0R1njePNPtKwoA=
19
+ github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0 h1:kEYH8NMfMA5gC5MMcEr5gVtJxyGmaxIYJwwZ7T6ygNs=
20
+ github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0/go.mod h1:4dXS5YNqI3SNbetQ7X7vfsMlX6ZnboJA2dulBwJx7+g=
21
+ github.com/aws/aws-sdk-go-v2/service/sso v1.4.0 h1:sHXMIKYS6YiLPzmKSvDpPmOpJDHxmAUgbiF49YNVztg=
22
+ github.com/aws/aws-sdk-go-v2/service/sso v1.4.0/go.mod h1:+1fpWnL96DL23aXPpMGbsmKe8jLTEfbjuQoA4WS1VaA=
23
+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.0 h1:1at4e5P+lvHNl2nUktdM2/v+rpICg/QSEr9TO/uW9vU=
24
+ github.com/aws/aws-sdk-go-v2/service/sts v1.7.0/go.mod h1:0qcSMCyASQPN2sk/1KQLQ2Fh6yq8wm0HSDAimPhzCoM=
25
+ github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc=
26
+ github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
27
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
28
+ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
29
+ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
30
+ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
31
+ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
32
+ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
33
+ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
34
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
35
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
36
+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
37
+ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
38
+ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
39
+ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
40
+ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
41
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
42
+ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
43
+ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
44
+ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
45
+ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
46
+ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
47
+ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
48
+ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
49
+ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
50
+ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
51
+ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
52
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
53
+ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './layer';
package/lib/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./layer"), exports);
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsMENBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9sYXllcic7Il19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
4
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
5
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
6
+ const aws_secretsmanager_1 = require("aws-cdk-lib/aws-secretsmanager");
7
+ const index_1 = require("./index");
8
+ const env = {
9
+ region: process.env.CDK_DEFAULT_REGION,
10
+ account: process.env.CDK_DEFAULT_ACCOUNT,
11
+ };
12
+ const mockApp = new aws_cdk_lib_1.App();
13
+ const stack = new aws_cdk_lib_1.Stack(mockApp, 'testing-stack', { env });
14
+ /**
15
+ * Example create an Secret for testing.
16
+ */
17
+ const secret = new aws_secretsmanager_1.CfnSecret(stack, 'Mysecret', {
18
+ secretString: JSON.stringify({
19
+ KEY1: 'VALUE1',
20
+ KEY2: 'VALUE2',
21
+ KEY3: 'VALUE3',
22
+ }),
23
+ });
24
+ const layer = new index_1.SecretManagerWrapperLayer(stack, 'SecretManagerWrapperLayer');
25
+ const lambda = new aws_lambda_1.Function(stack, 'fn', {
26
+ runtime: aws_lambda_1.Runtime.PYTHON_3_9,
27
+ code: aws_lambda_1.Code.fromInline(`
28
+ import os
29
+ def hander(events, contexts):
30
+ env = {}
31
+ env['KEY1'] = os.environ.get('KEY1', 'Not Found')
32
+ env['KEY2'] = os.environ.get('KEY2', 'Not Found')
33
+ env['KEY3'] = os.environ.get('KEY3', 'Not Found')
34
+ return env
35
+ `),
36
+ handler: 'index.hander',
37
+ layers: [layer],
38
+ timeout: aws_cdk_lib_1.Duration.minutes(1),
39
+ /**
40
+ * you need to define this 4 environment various.
41
+ */
42
+ environment: {
43
+ AWS_LAMBDA_EXEC_WRAPPER: '/opt/get-secrets-layer',
44
+ SECRET_REGION: stack.region,
45
+ SECRET_ARN: secret.ref,
46
+ API_TIMEOUT: '5000',
47
+ },
48
+ });
49
+ /**
50
+ * Add Permission for lambda get secret value from secret manager.
51
+ */
52
+ lambda.role.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
53
+ effect: aws_iam_1.Effect.ALLOW,
54
+ actions: ['secretsmanager:GetSecretValue'],
55
+ // Also you can use find from context.
56
+ resources: [secret.ref],
57
+ }));
58
+ /**
59
+ * For Testing.
60
+ */
61
+ const FnUrl = lambda.addFunctionUrl({
62
+ authType: aws_lambda_1.FunctionUrlAuthType.NONE,
63
+ });
64
+ new aws_cdk_lib_1.CfnOutput(stack, 'FnUrl', {
65
+ value: FnUrl.url,
66
+ });
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWcuaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW50ZWcuaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2Q0FBOEQ7QUFDOUQsaURBQThEO0FBQzlELHVEQUFzRjtBQUN0Rix1RUFBMkQ7QUFDM0QsbUNBQW9EO0FBQ3BELE1BQU0sR0FBRyxHQUFHO0lBQ1YsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCO0lBQ3RDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQjtDQUN6QyxDQUFDO0FBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxpQkFBRyxFQUFFLENBQUM7QUFDMUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBRTNEOztHQUVHO0FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSw4QkFBUyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUU7SUFDOUMsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDM0IsSUFBSSxFQUFFLFFBQVE7UUFDZCxJQUFJLEVBQUUsUUFBUTtRQUNkLElBQUksRUFBRSxRQUFRO0tBQ2YsQ0FBQztDQUNILENBQUMsQ0FBQztBQUVILE1BQU0sS0FBSyxHQUFHLElBQUksaUNBQXlCLENBQUMsS0FBSyxFQUFFLDJCQUEyQixDQUFDLENBQUM7QUFFaEYsTUFBTSxNQUFNLEdBQUcsSUFBSSxxQkFBUSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUU7SUFDdkMsT0FBTyxFQUFFLG9CQUFPLENBQUMsVUFBVTtJQUMzQixJQUFJLEVBQUUsaUJBQUksQ0FBQyxVQUFVLENBQUM7Ozs7Ozs7O0tBUW5CLENBQUM7SUFDSixPQUFPLEVBQUUsY0FBYztJQUN2QixNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUM7SUFDZixPQUFPLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQzVCOztPQUVHO0lBQ0gsV0FBVyxFQUFFO1FBQ1gsdUJBQXVCLEVBQUUsd0JBQXdCO1FBQ2pELGFBQWEsRUFBRSxLQUFLLENBQUMsTUFBTTtRQUMzQixVQUFVLEVBQUUsTUFBTSxDQUFDLEdBQUc7UUFDdEIsV0FBVyxFQUFFLE1BQU07S0FDcEI7Q0FDRixDQUFDLENBQUM7QUFFSDs7R0FFRztBQUNILE1BQU0sQ0FBQyxJQUFLLENBQUMsb0JBQW9CLENBQy9CLElBQUkseUJBQWUsQ0FBQztJQUNsQixNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO0lBQ3BCLE9BQU8sRUFBRSxDQUFDLCtCQUErQixDQUFDO0lBQzFDLHNDQUFzQztJQUN0QyxTQUFTLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO0NBQ3hCLENBQUMsQ0FDSCxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO0lBQ2xDLFFBQVEsRUFBRSxnQ0FBbUIsQ0FBQyxJQUFJO0NBQ25DLENBQUMsQ0FBQztBQUVILElBQUksdUJBQVMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFO0lBQzVCLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRztDQUNqQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcHAsIFN0YWNrLCBDZm5PdXRwdXQsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgRWZmZWN0LCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEZ1bmN0aW9uLCBSdW50aW1lLCBDb2RlLCBGdW5jdGlvblVybEF1dGhUeXBlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBDZm5TZWNyZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXInO1xuaW1wb3J0IHsgU2VjcmV0TWFuYWdlcldyYXBwZXJMYXllciB9IGZyb20gJy4vaW5kZXgnO1xuY29uc3QgZW52ID0ge1xuICByZWdpb246IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX1JFR0lPTixcbiAgYWNjb3VudDogcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVCxcbn07XG5jb25zdCBtb2NrQXBwID0gbmV3IEFwcCgpO1xuY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sobW9ja0FwcCwgJ3Rlc3Rpbmctc3RhY2snLCB7IGVudiB9KTtcblxuLyoqXG4gKiBFeGFtcGxlIGNyZWF0ZSBhbiBTZWNyZXQgZm9yIHRlc3RpbmcuXG4gKi9cbmNvbnN0IHNlY3JldCA9IG5ldyBDZm5TZWNyZXQoc3RhY2ssICdNeXNlY3JldCcsIHtcbiAgc2VjcmV0U3RyaW5nOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgS0VZMTogJ1ZBTFVFMScsXG4gICAgS0VZMjogJ1ZBTFVFMicsXG4gICAgS0VZMzogJ1ZBTFVFMycsXG4gIH0pLFxufSk7XG5cbmNvbnN0IGxheWVyID0gbmV3IFNlY3JldE1hbmFnZXJXcmFwcGVyTGF5ZXIoc3RhY2ssICdTZWNyZXRNYW5hZ2VyV3JhcHBlckxheWVyJyk7XG5cbmNvbnN0IGxhbWJkYSA9IG5ldyBGdW5jdGlvbihzdGFjaywgJ2ZuJywge1xuICBydW50aW1lOiBSdW50aW1lLlBZVEhPTl8zXzksXG4gIGNvZGU6IENvZGUuZnJvbUlubGluZShgXG5pbXBvcnQgb3NcbmRlZiBoYW5kZXIoZXZlbnRzLCBjb250ZXh0cyk6XG4gICAgZW52ID0ge31cbiAgICBlbnZbJ0tFWTEnXSA9IG9zLmVudmlyb24uZ2V0KCdLRVkxJywgJ05vdCBGb3VuZCcpXG4gICAgZW52WydLRVkyJ10gPSBvcy5lbnZpcm9uLmdldCgnS0VZMicsICdOb3QgRm91bmQnKVxuICAgIGVudlsnS0VZMyddID0gb3MuZW52aXJvbi5nZXQoJ0tFWTMnLCAnTm90IEZvdW5kJylcbiAgICByZXR1cm4gZW52XG4gICAgYCksXG4gIGhhbmRsZXI6ICdpbmRleC5oYW5kZXInLFxuICBsYXllcnM6IFtsYXllcl0sXG4gIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMSksXG4gIC8qKlxuICAgKiB5b3UgbmVlZCB0byBkZWZpbmUgdGhpcyA0IGVudmlyb25tZW50IHZhcmlvdXMuXG4gICAqL1xuICBlbnZpcm9ubWVudDoge1xuICAgIEFXU19MQU1CREFfRVhFQ19XUkFQUEVSOiAnL29wdC9nZXQtc2VjcmV0cy1sYXllcicsXG4gICAgU0VDUkVUX1JFR0lPTjogc3RhY2sucmVnaW9uLFxuICAgIFNFQ1JFVF9BUk46IHNlY3JldC5yZWYsXG4gICAgQVBJX1RJTUVPVVQ6ICc1MDAwJyxcbiAgfSxcbn0pO1xuXG4vKipcbiAqIEFkZCBQZXJtaXNzaW9uIGZvciBsYW1iZGEgZ2V0IHNlY3JldCB2YWx1ZSBmcm9tIHNlY3JldCBtYW5hZ2VyLlxuICovXG5sYW1iZGEucm9sZSEuYWRkVG9QcmluY2lwYWxQb2xpY3koXG4gIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgIGFjdGlvbnM6IFsnc2VjcmV0c21hbmFnZXI6R2V0U2VjcmV0VmFsdWUnXSxcbiAgICAvLyBBbHNvIHlvdSBjYW4gdXNlIGZpbmQgZnJvbSBjb250ZXh0LlxuICAgIHJlc291cmNlczogW3NlY3JldC5yZWZdLFxuICB9KSxcbik7XG5cbi8qKlxuICogRm9yIFRlc3RpbmcuXG4gKi9cbmNvbnN0IEZuVXJsID0gbGFtYmRhLmFkZEZ1bmN0aW9uVXJsKHtcbiAgYXV0aFR5cGU6IEZ1bmN0aW9uVXJsQXV0aFR5cGUuTk9ORSxcbn0pO1xuXG5uZXcgQ2ZuT3V0cHV0KHN0YWNrLCAnRm5VcmwnLCB7XG4gIHZhbHVlOiBGblVybC51cmwsXG59KTsiXX0=
package/lib/layer.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
2
+ import { Construct } from 'constructs';
3
+ /**
4
+ * An AWS SecretManager Wrapper layer that includes the AWS CLI, jq etc...
5
+ */
6
+ export declare class SecretManagerWrapperLayer extends lambda.LayerVersion {
7
+ static getOrCreate(scope: Construct): SecretManagerWrapperLayer;
8
+ constructor(scope: Construct, id: string);
9
+ }
package/lib/layer.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.SecretManagerWrapperLayer = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const path = require("path");
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const lambda = require("aws-cdk-lib/aws-lambda");
9
+ /**
10
+ * An AWS SecretManager Wrapper layer that includes the AWS CLI, jq etc...
11
+ */
12
+ class SecretManagerWrapperLayer extends lambda.LayerVersion {
13
+ constructor(scope, id) {
14
+ const image = aws_cdk_lib_1.DockerImage.fromBuild(path.join(__dirname, '../layer'));
15
+ image.cp('/layer.zip', path.join(__dirname));
16
+ const props = {
17
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
18
+ code: lambda.Code.fromAsset(path.join(__dirname, 'layer.zip')),
19
+ description: 'this layer has wrapper script help you setting secret manager json string into lambda runtime',
20
+ };
21
+ super(scope, id, props);
22
+ }
23
+ static getOrCreate(scope) {
24
+ const stack = aws_cdk_lib_1.Stack.of(scope);
25
+ const id = 'DenoLayer';
26
+ const existing = stack.node.tryFindChild(id);
27
+ return existing || new SecretManagerWrapperLayer(stack, id);
28
+ }
29
+ }
30
+ exports.SecretManagerWrapperLayer = SecretManagerWrapperLayer;
31
+ _a = JSII_RTTI_SYMBOL_1;
32
+ SecretManagerWrapperLayer[_a] = { fqn: "cdk-secret-manager-wrapper-layer.SecretManagerWrapperLayer", version: "1.0.0" };
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbGF5ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsNkNBQWdFO0FBQ2hFLGlEQUFpRDtBQUlqRDs7R0FFRztBQUNILE1BQWEseUJBQTBCLFNBQVEsTUFBTSxDQUFDLFlBQVk7SUFPaEUsWUFBWSxLQUFnQixFQUFFLEVBQVU7UUFFdEMsTUFBTSxLQUFLLEdBQUcseUJBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN0RSxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFN0MsTUFBTSxLQUFLLEdBQTZCO1lBQ3RDLGFBQWEsRUFBRSwyQkFBYSxDQUFDLE9BQU87WUFDcEMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQzlELFdBQVcsRUFBRSwrRkFBK0Y7U0FDN0csQ0FBQztRQUVGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRTFCLENBQUM7SUFuQk0sTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFnQjtRQUN4QyxNQUFNLEtBQUssR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixNQUFNLEVBQUUsR0FBRyxXQUFXLENBQUM7UUFDdkIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0MsT0FBUSxRQUFzQyxJQUFJLElBQUkseUJBQXlCLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzdGLENBQUM7O0FBTkgsOERBcUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IERvY2tlckltYWdlLCBSZW1vdmFsUG9saWN5LCBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5cbi8qKlxuICogQW4gQVdTIFNlY3JldE1hbmFnZXIgV3JhcHBlciBsYXllciB0aGF0IGluY2x1ZGVzIHRoZSBBV1MgQ0xJLCBqcSBldGMuLi5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlY3JldE1hbmFnZXJXcmFwcGVyTGF5ZXIgZXh0ZW5kcyBsYW1iZGEuTGF5ZXJWZXJzaW9uIHtcbiAgcHVibGljIHN0YXRpYyBnZXRPckNyZWF0ZShzY29wZTogQ29uc3RydWN0KTogU2VjcmV0TWFuYWdlcldyYXBwZXJMYXllciB7XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZihzY29wZSk7XG4gICAgY29uc3QgaWQgPSAnRGVub0xheWVyJztcbiAgICBjb25zdCBleGlzdGluZyA9IHN0YWNrLm5vZGUudHJ5RmluZENoaWxkKGlkKTtcbiAgICByZXR1cm4gKGV4aXN0aW5nIGFzIFNlY3JldE1hbmFnZXJXcmFwcGVyTGF5ZXIpIHx8IG5ldyBTZWNyZXRNYW5hZ2VyV3JhcHBlckxheWVyKHN0YWNrLCBpZCk7XG4gIH1cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuXG4gICAgY29uc3QgaW1hZ2UgPSBEb2NrZXJJbWFnZS5mcm9tQnVpbGQocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2xheWVyJykpO1xuICAgIGltYWdlLmNwKCcvbGF5ZXIuemlwJywgcGF0aC5qb2luKF9fZGlybmFtZSkpO1xuXG4gICAgY29uc3QgcHJvcHM6IGxhbWJkYS5MYXllclZlcnNpb25Qcm9wcyA9IHtcbiAgICAgIHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGF5ZXIuemlwJykpLFxuICAgICAgZGVzY3JpcHRpb246ICd0aGlzIGxheWVyIGhhcyB3cmFwcGVyIHNjcmlwdCBoZWxwIHlvdSBzZXR0aW5nIHNlY3JldCBtYW5hZ2VyIGpzb24gc3RyaW5nIGludG8gbGFtYmRhIHJ1bnRpbWUnLFxuICAgIH07XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICB9XG59Il19
package/package.json ADDED
@@ -0,0 +1,142 @@
1
+ {
2
+ "name": "cdk-secret-manager-wrapper-layer",
3
+ "repository": {
4
+ "type": "git",
5
+ "url": "https://github.com/neilkuan/cdk-secret-manager-wrapper-layer.git"
6
+ },
7
+ "scripts": {
8
+ "build": "npx projen build",
9
+ "bump": "npx projen bump",
10
+ "clobber": "npx projen clobber",
11
+ "compat": "npx projen compat",
12
+ "compile": "npx projen compile",
13
+ "default": "npx projen default",
14
+ "docgen": "npx projen docgen",
15
+ "eject": "npx projen eject",
16
+ "eslint": "npx projen eslint",
17
+ "package": "npx projen package",
18
+ "package-all": "npx projen package-all",
19
+ "package:js": "npx projen package:js",
20
+ "package:python": "npx projen package:python",
21
+ "post-compile": "npx projen post-compile",
22
+ "post-upgrade": "npx projen post-upgrade",
23
+ "pre-compile": "npx projen pre-compile",
24
+ "release": "npx projen release",
25
+ "release:cdkv1": "npx projen release:cdkv1",
26
+ "test": "npx projen test",
27
+ "test:update": "npx projen test:update",
28
+ "test:watch": "npx projen test:watch",
29
+ "unbump": "npx projen unbump",
30
+ "upgrade": "npx projen upgrade",
31
+ "watch": "npx projen watch",
32
+ "projen": "npx projen"
33
+ },
34
+ "author": {
35
+ "name": "Neil Kuan",
36
+ "email": "guan840912@gmail.com",
37
+ "organization": false
38
+ },
39
+ "devDependencies": {
40
+ "@types/jest": "^27",
41
+ "@types/mock-fs": "^4.13.1",
42
+ "@types/node": "^14",
43
+ "@typescript-eslint/eslint-plugin": "^5",
44
+ "@typescript-eslint/parser": "^5",
45
+ "aws-cdk-lib": "2.33.0",
46
+ "constructs": "10.0.5",
47
+ "eslint": "^8",
48
+ "eslint-import-resolver-node": "^0.3.6",
49
+ "eslint-import-resolver-typescript": "^3.3.0",
50
+ "eslint-plugin-import": "^2.26.0",
51
+ "jest": "^27",
52
+ "jest-junit": "^13",
53
+ "jsii": "^1.62.0",
54
+ "jsii-diff": "^1.62.0",
55
+ "jsii-docgen": "^7.0.57",
56
+ "jsii-pacmak": "^1.62.0",
57
+ "json-schema": "^0.4.0",
58
+ "mock-fs": "^5.1.2",
59
+ "npm-check-updates": "^15",
60
+ "projen": "^0.60.5",
61
+ "standard-version": "^9",
62
+ "ts-jest": "^27",
63
+ "typescript": "4.6"
64
+ },
65
+ "peerDependencies": {
66
+ "aws-cdk-lib": "^2.33.0",
67
+ "constructs": "^10.0.5"
68
+ },
69
+ "keywords": [
70
+ "aws",
71
+ "cdk",
72
+ "lambda",
73
+ "layer",
74
+ "secret-manager"
75
+ ],
76
+ "main": "lib/index.js",
77
+ "license": "Apache-2.0",
78
+ "version": "1.0.0",
79
+ "jest": {
80
+ "testMatch": [
81
+ "<rootDir>/src/**/__tests__/**/*.ts?(x)",
82
+ "<rootDir>/(test|src)/**/*(*.)@(spec|test).ts?(x)"
83
+ ],
84
+ "clearMocks": true,
85
+ "collectCoverage": true,
86
+ "coverageReporters": [
87
+ "json",
88
+ "lcov",
89
+ "clover",
90
+ "cobertura",
91
+ "text"
92
+ ],
93
+ "coverageDirectory": "coverage",
94
+ "coveragePathIgnorePatterns": [
95
+ "/node_modules/"
96
+ ],
97
+ "testPathIgnorePatterns": [
98
+ "/node_modules/"
99
+ ],
100
+ "watchPathIgnorePatterns": [
101
+ "/node_modules/"
102
+ ],
103
+ "reporters": [
104
+ "default",
105
+ [
106
+ "jest-junit",
107
+ {
108
+ "outputDirectory": "test-reports"
109
+ }
110
+ ]
111
+ ],
112
+ "preset": "ts-jest",
113
+ "globals": {
114
+ "ts-jest": {
115
+ "tsconfig": "tsconfig.dev.json"
116
+ }
117
+ }
118
+ },
119
+ "types": "lib/index.d.ts",
120
+ "stability": "experimental",
121
+ "jsii": {
122
+ "outdir": "dist",
123
+ "targets": {
124
+ "python": {
125
+ "distName": "cdk-secret-manager-wrapper-layer",
126
+ "module": "cdk_secret_manager_wrapper_layer"
127
+ }
128
+ },
129
+ "tsc": {
130
+ "outDir": "lib",
131
+ "rootDir": "src"
132
+ }
133
+ },
134
+ "awscdkio": {
135
+ "twitter": "neil_kuan",
136
+ "announce": false
137
+ },
138
+ "resolutions": {
139
+ "@types/prettier": "2.6.0"
140
+ },
141
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
142
+ }