A few month ago, AWS introduced Provisioned Concurrency for Lambda Functions. This is a great addition for .NET Core Lambda since it eliminates the cold-start penalty.
Unfortunately, to use provisioned concurrency in CloudFormation, we have to use
AWS::Lambda::Version, which is an immutable resource. Meaning, once it has been created, it cannot be modified. That's a problem if you want to be able to set the provisioned concurrency using a CloudFormation parameter.
Something like the following CloudFormation template will work the first time the stack is created and then never again, because none of the properties of
MyLambadVersion can be modified after creation:
Parameters: ProvisionedConcurrency: Type: Number Default: 0 MinValue: 0 Resources: MyLambdaVersion: Type: AWS::Lambda::Version Properties: FunctionName: !Ref MyLambda ProvisionedConcurrencyConfig: ProvisionedConcurrentExecutions: !Ref ProvisionedConcurrency
AWS::Lambda::Function definition omitted for brevity.
The trick is to be able to get rid of the
MyLambdaVersion resource. We can achieve that by making it a conditional resource and using as condition that
ProvisionedConcurrency is not
The following code expands on the previous attempt by introducing a CloudFormation condition:
Parameters: ProvisionedConcurrency: Type: Number Default: 0 MinValue: 0 Conditions: HasProvisionedConcurrency: !Not [ !Equals [ !Ref ProvisionedConcurrency, 0 ] ] Resources: MyLambdaVersion: Type: AWS::Lambda::Version Condition: HasProvisionedConcurrency Properties: FunctionName: !Ref MyLambda ProvisionedConcurrencyConfig: ProvisionedConcurrentExecutions: !Ref MyLambdaProvisionedConcurrency
While this approach allows us to make provision concurrency configurable, it requires an intermediary step. Whenever you want to change the provisioned concurrency, we have to first go back to
0 to delete the
MyLambdaVersion resource and then we can set whichever provisioned concurrency we actually want. It's a bit tedious, but at least it's possible!
The other thing to look out for is that we also need to conditionally refer to either
MyLambda wherever the function ARN is required. Fortunately, that's simple enough using the
!If function and