Search code examples
amazon-web-servicesaws-lambdaserverless-framework

How can I reference lambda version in `serverless.yml`?


I am using serverless to deploy lambda to AWS. I have a case that the lambda is defined in functions section but the provision concurrency is configured in resources because I need to use the Condition. The problem I have is that how I can reference the published lambda version from resources?

functions:
  getTransactionsHandler:
    ...

resources:
  Conditions:
    CommonPCNotZero: !Not [!Equals [0, '${self:custom.commonPC}']]
  Resources:
    !If 
      - CommonPCNotZero
      - getTransactionsHandler:
        Type: AWS::Lambda::Alias
          Properties:
            FunctionName: !Ref GetTransactionsHandlerLambdaFunction
            FunctionVersion: HOW CAN I GET THE VERSION?
            ProvisionedConcurrencyConfig:
              ProvisionedConcurrentExecutions: '${self:custom.commonPC}'
      - !Ref AWS::NoValue

Solution

  • Put a placeholder for the reference in serverless.yml file.

    [serverless-scriptable-plugin] LambdaFunctionARN: THIS_IS_SET_IN_SCRIPT

    The scriptable plugin uses a hook

    custom:
        scriptHooks:
            before:aws:package:finalize:saveServiceState: scripts/completeLambdaAssociation.js
    

    The script completeLambdaAssociation.js updates the LambdaFunctionARN by searching for the AWS::Lambda::Version resource.

    // serverless injected by serverless-scriptable-plugin
    // noinspection JSUnresolvedVariable
    const sls = serverless;
    
    // noinspection JSUnresolvedVariable
    const resources = sls.service.provider.compiledCloudFormationTemplate.Resources;
    const resourceType = 'AWS::Lambda::Version';
    const prefix = 'RewriteUriLambdaVersion';
    const resourceNames = Object.keys(resources).filter(name => resources[name].Type === resourceType && name.startsWith(prefix))
    if (resourceNames.length !== 1) {
        throw Error(`Must have exactly 1 resource of type ${resourceType} and prefix ${prefix}, found ${resourceNames}`);
    }
    
    const distConfig = resources['CFDistribution']['Properties']['DistributionConfig'];
    distConfig['DefaultCacheBehavior']['LambdaFunctionAssociations'][0]['LambdaFunctionARN'] = { Ref: resourceNames[0] };
    console.log(`[${__filename}] Updated LambdaFunctionARN on first LambdaFunctionAssociation on DefaultCacheBehavior`);