Merge pull request #7045 from serverless/lambda-provisioned-concurrency

Fix lambda provisioned concurrency setup
This commit is contained in:
Mariusz Nowak 2019-12-04 12:17:11 +01:00 committed by GitHub
commit 0bc5014045
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 58 deletions

View File

@ -409,21 +409,18 @@ class AwsCompileFunctions {
}
}
if (functionObject.provisionedConcurrency) {
const provisionedConcurrency = _.parseInt(functionObject.provisionedConcurrency);
const versionFunction =
functionObject.versionFunction != null
? functionObject.versionFunction
: this.serverless.service.provider.versionFunctions;
if (_.isInteger(provisionedConcurrency)) {
newFunction.Properties.ProvisionedConcurrencyConfig = {
ProvisionedConcurrentExecutions: provisionedConcurrency,
};
} else {
return BbPromise.reject(
new this.serverless.classes.Error(
'You should use integer as provisionedConcurrency value on function: ' +
`${newFunction.Properties.FunctionName}`
)
);
}
if (functionObject.provisionedConcurrency && !versionFunction) {
return BbPromise.reject(
new this.serverless.classes.Error(
'Cannot setup provisioned conncurrency with lambda versioning disabled on function: ' +
`${newFunction.Properties.FunctionName}`
)
);
}
newFunction.DependsOn = [this.provider.naming.getLogGroupLogicalId(functionName)].concat(
@ -449,8 +446,6 @@ class AwsCompileFunctions {
newFunctionObject
);
const newVersion = this.cfLambdaVersionTemplate();
// Create hashes for the artifact and the logical id of the version resource
// The one for the version resource must include the function configuration
// to make sure that a new version is created on configuration changes and
@ -490,12 +485,31 @@ class AwsCompileFunctions {
const fileDigest = fileHash.read();
const versionDigest = versionHash.read();
if (!versionFunction) return;
const newVersion = this.cfLambdaVersionTemplate();
newVersion.Properties.CodeSha256 = fileDigest;
newVersion.Properties.FunctionName = { Ref: functionLogicalId };
if (functionObject.description) {
newVersion.Properties.Description = functionObject.description;
}
if (functionObject.provisionedConcurrency) {
const provisionedConcurrency = _.parseInt(functionObject.provisionedConcurrency);
if (_.isInteger(provisionedConcurrency)) {
newVersion.Properties.ProvisionedConcurrencyConfig = {
ProvisionedConcurrentExecutions: provisionedConcurrency,
};
} else {
throw new this.serverless.classes.Error(
'You should use integer as provisionedConcurrency value on function: ' +
`${newFunction.Properties.FunctionName}`
);
}
}
// use the version SHA in the logical resource ID of the version because
// AWS::Lambda::Version resource will not support updates
const versionLogicalId = this.provider.naming.getLambdaVersionLogicalId(
@ -506,17 +520,10 @@ class AwsCompileFunctions {
[versionLogicalId]: newVersion,
};
const versionFunction =
functionObject.versionFunction != null
? functionObject.versionFunction
: this.serverless.service.provider.versionFunctions;
if (versionFunction) {
_.merge(
this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
newVersionObject
);
}
_.merge(
this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
newVersionObject
);
// Add function versions to Outputs section
const functionVersionOutputLogicalId = this.provider.naming.getLambdaVersionOutputLogicalId(
@ -526,13 +533,9 @@ class AwsCompileFunctions {
newVersionOutput.Value = { Ref: versionLogicalId };
if (versionFunction) {
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Outputs, {
[functionVersionOutputLogicalId]: newVersionOutput,
});
}
return BbPromise.resolve();
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Outputs, {
[functionVersionOutputLogicalId]: newVersionOutput,
});
});
}

View File

@ -2201,10 +2201,6 @@ describe('AwsCompileFunctions', () => {
});
it('should set function declared provisioned concurrency limit', () => {
const s3Folder = awsCompileFunctions.serverless.service.package.artifactDirectoryName;
const s3FileName = awsCompileFunctions.serverless.service.package.artifact
.split(path.sep)
.pop();
awsCompileFunctions.serverless.service.functions = {
func: {
handler: 'func.function.handler',
@ -2212,29 +2208,16 @@ describe('AwsCompileFunctions', () => {
provisionedConcurrency: 5,
},
};
const compiledFunction = {
Type: 'AWS::Lambda::Function',
DependsOn: ['FuncLogGroup', 'IamRoleLambdaExecution'],
Properties: {
Code: {
S3Key: `${s3Folder}/${s3FileName}`,
S3Bucket: { Ref: 'ServerlessDeploymentBucket' },
},
FunctionName: 'new-service-dev-func',
Handler: 'func.function.handler',
MemorySize: 1024,
ProvisionedConcurrencyConfig: { ProvisionedConcurrentExecutions: 5 },
Role: { 'Fn::GetAtt': ['IamRoleLambdaExecution', 'Arn'] },
Runtime: 'nodejs12.x',
Timeout: 6,
},
};
return expect(awsCompileFunctions.compileFunctions()).to.be.fulfilled.then(() => {
const resourceId =
awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate.Outputs
.FuncLambdaFunctionQualifiedArn.Value.Ref;
expect(
awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate.Resources
.FuncLambdaFunction
).to.deep.equal(compiledFunction);
awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate.Resources[
resourceId
].Properties.ProvisionedConcurrencyConfig
).to.deep.equal({ ProvisionedConcurrentExecutions: 5 });
});
});