Skip to content

Commit

Permalink
feat: adding support for provisioned concurrency (#1284) (#1285)
Browse files Browse the repository at this point in the history
  • Loading branch information
praneetap authored Dec 3, 2019
1 parent 69822c1 commit 818b4ef
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 18 deletions.
17 changes: 17 additions & 0 deletions examples/2016-10-31/lambda_edge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ LambdaEdgeFunctionSample:
AutoPublishAlias: live
```
This also uses `ProvisionedConcurrencyConfig` setting on the lambda function Alias created by AutoPublishAlias:

```yaml
LambdaEdgeFunctionSample:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Runtime: nodejs6.10
Handler: index.handler
Role: !GetAtt LambdaEdgeFunctionRole.Arn
Timeout: 5
# More info at https://github.com/awslabs/serverless-application-model/blob/master/docs/safe_lambda_deployments.rst
AutoPublishAlias: live
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: !If [AliasProvisionedConcurrencyEnabled, !Ref ProvisionedConcurrency, !Ref 'AWS::NoValue']
```

We must also create a custom IAM Role which allows `lambda.amazonaws.com` and `edgelambda.amazonaws.com` services to assume the role and execute the function.

```yaml
Expand Down
18 changes: 18 additions & 0 deletions examples/2016-10-31/lambda_edge/template.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM configuration for Lambda@Edge to ease deployment and further updates
Parameters:

ProvisionedConcurrency:
Type: String
Default: 10
EnableAliasProvisionedConcurrency:
Type: String
AllowedValues:
- true
- false
Default: true

Globals:

Function:
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: !If [AliasProvisionedConcurrencyEnabled, !Ref ProvisionedConcurrency, !Ref 'AWS::NoValue']

Resources:

CFDistribution:
Expand Down
2 changes: 1 addition & 1 deletion samtranslator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.17.0'
__version__ = '1.18.0'
3 changes: 2 additions & 1 deletion samtranslator/model/lambda_.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class LambdaAlias(Resource):
'Description': PropertyType(False, is_str()),
'Name': PropertyType(False, is_str()),
'FunctionName': PropertyType(True, one_of(is_str(), is_type(dict))),
'FunctionVersion': PropertyType(True, one_of(is_str(), is_type(dict)))
'FunctionVersion': PropertyType(True, one_of(is_str(), is_type(dict))),
'ProvisionedConcurrencyConfig': PropertyType(False, is_type(dict))
}

runtime_attrs = {
Expand Down
10 changes: 9 additions & 1 deletion samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class SamFunction(SamResourceMacro):

# Intrinsic functions in value of Alias property are not supported, yet
'AutoPublishAlias': PropertyType(False, one_of(is_str())),
'VersionDescription': PropertyType(False, is_str())
'VersionDescription': PropertyType(False, is_str()),
'ProvisionedConcurrencyConfig': PropertyType(False, is_type(dict)),
}
event_resolver = ResourceTypeResolver(samtranslator.model.eventsources, samtranslator.model.eventsources.pull,
samtranslator.model.eventsources.push,
Expand Down Expand Up @@ -96,6 +97,11 @@ def to_cloudformation(self, **kwargs):
lambda_function = self._construct_lambda_function()
resources.append(lambda_function)

if self.ProvisionedConcurrencyConfig:
if not self.AutoPublishAlias:
raise InvalidResourceException(self.logical_id, "To set ProvisionedConcurrencyConfig "
"AutoPublishALias must be defined on the function")

lambda_alias = None
if self.AutoPublishAlias:
alias_name = self._get_resolved_alias_name("AutoPublishAlias", self.AutoPublishAlias, intrinsics_resolver)
Expand Down Expand Up @@ -415,6 +421,8 @@ def _construct_alias(self, name, function, version):
alias.Name = name
alias.FunctionName = function.get_runtime_attr('name')
alias.FunctionVersion = version.get_runtime_attr("version")
if self.ProvisionedConcurrencyConfig:
alias.ProvisionedConcurrencyConfig = self.ProvisionedConcurrencyConfig

return alias

Expand Down
3 changes: 2 additions & 1 deletion samtranslator/plugins/globals/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class Globals(object):
"Layers",
"DeploymentPreference",
"PermissionsBoundary",
"ReservedConcurrentExecutions"
"ReservedConcurrentExecutions",
"ProvisionedConcurrencyConfig"
],

# Everything except
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Parameters:
FnName:
Type: String
ProvisionedConcurrency:
Type: String
Default: 10
EnableAliasProvisionedConcurrency:
Type: String
AllowedValues:
- true
- false
Default: true
Conditions:
AliasProvisionedConcurrencyEnabled: !Equals [!Ref EnableAliasProvisionedConcurrency, true]
Resources:
MinimalFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: s3://sam-demo-bucket/hello.zip
Handler: hello.handler
Runtime: python2.7
DeploymentPreference:
Type: Linear10PercentEvery3Minutes
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: !If [AliasProvisionedConcurrencyEnabled, ProvisionedConcurrentExecutions: !Ref ProvisionedConcurrency, !Ref 'AWS::NoValue']
18 changes: 17 additions & 1 deletion tests/translator/input/function_with_deployment_preference.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
Parameters:
FnName:
Type: String
ProvisionedConcurrency:
Type: String
Default: 10
EnableAliasProvisionedConcurrency:
Type: String
AllowedValues:
- true
- false
Default: true
Conditions:
AliasProvisionedConcurrencyEnabled: !Equals [!Ref EnableAliasProvisionedConcurrency, true]
Resources:
MinimalFunction:
Type: 'AWS::Serverless::Function'
Expand All @@ -7,4 +21,6 @@ Resources:
Runtime: python2.7
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery3Minutes
Type: Linear10PercentEvery3Minutes
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: !If [AliasProvisionedConcurrencyEnabled, !Ref ProvisionedConcurrency, !Ref 'AWS::NoValue']
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
{
"Conditions": {
"AliasProvisionedConcurrencyEnabled": {
"Fn::Equals": [
{
"Ref": "EnableAliasProvisionedConcurrency"
},
true
]
}
},
"Parameters": {
"EnableAliasProvisionedConcurrency": {
"Default": true,
"Type": "String",
"AllowedValues": [
true,
false
]
},
"FnName": {
"Type": "String"
},
"ProvisionedConcurrency": {
"Default": 10,
"Type": "String"
}
},
"Resources": {
"MinimalFunctionDeploymentGroup": {
"Type": "AWS::CodeDeploy::DeploymentGroup",
Expand Down Expand Up @@ -61,11 +88,11 @@
"MinimalFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "hello.handler",
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "hello.zip"
},
"Handler": "hello.handler",
"Role": {
"Fn::GetAtt": [
"MinimalFunctionRole",
Expand Down Expand Up @@ -133,17 +160,30 @@
}
},
"Properties": {
"Name": "live",
"FunctionVersion": {
"Fn::GetAtt": [
"MinimalFunctionVersion640128d35d",
"Version"
]
},
"ProvisionedConcurrencyConfig": {
"ProvisionedConcurrentExecutions": {
"Fn::If": [
"AliasProvisionedConcurrencyEnabled",
{
"Ref": "ProvisionedConcurrency"
},
{
"Ref": "AWS::NoValue"
}
]
}
},
"FunctionName": {
"Ref": "MinimalFunction"
},
"Name": "live"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
{
"Conditions": {
"AliasProvisionedConcurrencyEnabled": {
"Fn::Equals": [
{
"Ref": "EnableAliasProvisionedConcurrency"
},
true
]
}
},
"Parameters": {
"EnableAliasProvisionedConcurrency": {
"Default": true,
"Type": "String",
"AllowedValues": [
true,
false
]
},
"FnName": {
"Type": "String"
},
"ProvisionedConcurrency": {
"Default": 10,
"Type": "String"
}
},
"Resources": {
"MinimalFunctionDeploymentGroup": {
"Type": "AWS::CodeDeploy::DeploymentGroup",
Expand Down Expand Up @@ -61,11 +88,11 @@
"MinimalFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "hello.handler",
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "hello.zip"
},
"Handler": "hello.handler",
"Role": {
"Fn::GetAtt": [
"MinimalFunctionRole",
Expand Down Expand Up @@ -133,16 +160,29 @@
}
},
"Properties": {
"Name": "live",
"FunctionVersion": {
"Fn::GetAtt": [
"MinimalFunctionVersion640128d35d",
"Version"
]
},
"ProvisionedConcurrencyConfig": {
"ProvisionedConcurrentExecutions": {
"Fn::If": [
"AliasProvisionedConcurrencyEnabled",
{
"Ref": "ProvisionedConcurrency"
},
{
"Ref": "AWS::NoValue"
}
]
}
},
"FunctionName": {
"Ref": "MinimalFunction"
},
"Name": "live"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"errors": [
{
"errorMessage": "Resource with id [MinimalFunction] is invalid. To set ProvisionedConcurrencyConfig AutoPublishALias must be defined on the function"
}
],
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MinimalFunction] is invalid. To set ProvisionedConcurrencyConfig AutoPublishALias must be defined on the function"
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"errors": [
{
"errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions']"
"errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig']"
}
],
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions']"
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig']"
}
Loading

0 comments on commit 818b4ef

Please sign in to comment.