Skip to content
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

Allow specifying a retention policy for lambda layers #6010

Merged
merged 2 commits into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/providers/aws/guide/layers.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ layers:
licenseInfo: GPLv3 # optional, a string specifying license information licenseInfo: GPLv3 # optional, a string specifying license information
allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer. allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer.
- '*' - '*'
retain: false # optional, false by default. If true, layer versions are not deleted as new ones are created
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add this config to the serverless.yml.md file? (the root layers definition is completely missing right now).

``` ```


You can add up to 5 layers as you want within this property. You can add up to 5 layers as you want within this property.
Expand Down
12 changes: 12 additions & 0 deletions docs/providers/aws/guide/serverless.yml.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -262,6 +262,18 @@ functions:
pool: MyUserPool pool: MyUserPool
trigger: PreSignUp trigger: PreSignUp


layers:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 thanks!

hello: # A Lambda layer
path: layer-dir # required, path to layer contents on disk
name: ${self:provider.stage}-layerName # optional, Deployed Lambda layer name
description: Description of what the lambda layer does # optional, Description to publish to AWS
compatibleRuntimes: # optional, a list of runtimes this layer is compatible with
- python3.7
licenseInfo: GPLv3 # optional, a string specifying license information
allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer.
- '*'
retain: false # optional, false by default. If true, layer versions are not deleted as new ones are created

# The "Resources" your "Functions" use. Raw AWS CloudFormation goes in here. # The "Resources" your "Functions" use. Raw AWS CloudFormation goes in here.
resources: resources:
Resources: Resources:
Expand Down
8 changes: 7 additions & 1 deletion lib/plugins/aws/package/compile/layers/index.js
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'; 'use strict';


const crypto = require('crypto');
const BbPromise = require('bluebird'); const BbPromise = require('bluebird');
const _ = require('lodash'); const _ = require('lodash');
const path = require('path'); const path = require('path');
Expand Down Expand Up @@ -49,7 +50,12 @@ class AwsCompileLayers {
newLayer.Properties.CompatibleRuntimes = layerObject.compatibleRuntimes; newLayer.Properties.CompatibleRuntimes = layerObject.compatibleRuntimes;
} }


const layerLogicalId = this.provider.naming.getLambdaLayerLogicalId(layerName); let layerLogicalId = this.provider.naming.getLambdaLayerLogicalId(layerName);
if (layerObject.retain) {
const sha = crypto.createHash('sha1').update(JSON.stringify(newLayer)).digest('hex');
layerLogicalId = `${layerLogicalId}${sha}`;
newLayer.DeletionPolicy = 'Retain';
}
const newLayerObject = { const newLayerObject = {
[layerLogicalId]: newLayer, [layerLogicalId]: newLayer,
}; };
Expand Down
43 changes: 43 additions & 0 deletions lib/plugins/aws/package/compile/layers/index.test.js
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'; 'use strict';


const crypto = require('crypto');
const path = require('path'); const path = require('path');
const chai = require('chai'); const chai = require('chai');
const AwsProvider = require('../../../provider/awsProvider'); const AwsProvider = require('../../../provider/awsProvider');
Expand Down Expand Up @@ -118,6 +119,48 @@ describe('AwsCompileLayers', () => {
}); });
}); });


it('should create a layer resource with a retention policy', () => {
const s3Folder = awsCompileLayers.serverless.service.package.artifactDirectoryName;
const s3FileName = awsCompileLayers.serverless.service.layers.test.package.artifact
.split(path.sep).pop();
awsCompileLayers.serverless.service.layers = {
test: {
path: 'layer',
retain: true,
},
};
const compiledLayer = {
Type: 'AWS::Lambda::LayerVersion',
Properties: {
Content: {
S3Bucket: { Ref: 'ServerlessDeploymentBucket' },
S3Key: `${s3Folder}/${s3FileName}`,
},
LayerName: 'test',
},
};
const sha = crypto.createHash('sha1').update(JSON.stringify(compiledLayer)).digest('hex');
compiledLayer.DeletionPolicy = 'Retain';
pmuens marked this conversation as resolved.
Show resolved Hide resolved
const compiledLayerOutput = {
Description: 'Current Lambda layer version',
Value: {
Ref: `TestLambdaLayer${sha}`,
},
};

return expect(awsCompileLayers.compileLayers()).to.be.fulfilled
.then(() => {
expect(
awsCompileLayers.serverless.service.provider.compiledCloudFormationTemplate
.Resources[`TestLambdaLayer${sha}`]
).to.deep.equal(compiledLayer);
expect(
awsCompileLayers.serverless.service.provider.compiledCloudFormationTemplate
.Outputs.TestLambdaLayerQualifiedArn
).to.deep.equal(compiledLayerOutput);
});
});

it('should create a layer resource with permissions', () => { it('should create a layer resource with permissions', () => {
const s3Folder = awsCompileLayers.serverless.service.package.artifactDirectoryName; const s3Folder = awsCompileLayers.serverless.service.package.artifactDirectoryName;
const s3FileName = awsCompileLayers.serverless.service.layers.test.package.artifact const s3FileName = awsCompileLayers.serverless.service.layers.test.package.artifact
Expand Down