Manually provision an AWS::Lambda::Function resource

Hi, we need to upgrade our deployment infrastructure to use a Blue/Green strategy without AWS CodeDeploy. We are prepared to do some manual work for this such as managing additional state about the environment (whether it is blue/green), and defining resources based on the environment slot (color) we intend to deploy to.

A big part of this is to be able to deploy lambda function code EITHER to the green function or the blue function, without touching the other. However, when defining all of the infrastructure using CloudFormation YML, the only resource type I am stuck on is serverless’ built-in functions. There seems to be no way to override the function name to include either blue or green depending on the parameterized slot. I would also like to make use of CloudFormation’s DeletionPolicy: Retain on these resources so that the other slot’s function won’t be deleted from within the stack.

Failing to do this with the built-in serverless version leads me to try provisioning this resources manually using Resource Type AWS::Lambda::Function. However, the main problem with defining this is not knowing the s3 bucket path from which the function is normally deployed from. Serverless seems to include a large timestamp with milliseconds in the filename so I can’t simply build it from strings. Is there a variable which has the bucket path in it for the lambda functions so that I can point the AWS::Lambda::Function code to the bucket name?

Are there any other possible solutions for this scenario, as every path so far has lead me to a dead-end with serverless. I would really rather not rewrite my whole infrastructure by code to use something else like Terraform just to set the name of a lambda.

After some deep digging, I figured out how to do this. Hope this helps someone. With the version available at the time I have done the following:

For the lambda name, it’s as simple as setting the name property which gets translated to cloudformation’s functionName directly, in my example where I wanted a custom naming convention:

functions:
  queryIndex:
    name: ${self:service}-${self:custom.Environment}-${self:custom.GBPrefix}queryIndex

I am very happy with this solution because the other resources like LogGroups are also named after it and all link together using serverless.

For the deletion policy on the lambda, I added this under resources in YML:

  extensions:
    QueryIndexLambdaFunction:
      DeletionPolicy: Retain

The naming of the function is documented under override cloudformation extensions