liuhongbo
liuhongbo

Reputation: 2131

Can two aws cloudformation stacks share one AWS::Serverless::Function?

Here is my SAM template, it has a paramert called CompanyParameter, so when i deploy to the stack, I will pass a company name, it will create a queue per company, but i want to all the stacks for different companies point to the same lambda function.

right now, when i create the 2nd stack, it will fail with the message:

batch-sqs-queue-process already exists in stack.....

Is this even possible? The reason I want to do this so that if changed some code of the lambda function, I just need to update once for all companies. Is this the right direction?

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Processing batch system messages on an SQS queue with Lambda
Parameters:
  CompanyParameter:
    Type: String
    Description: Company name
    AllowedPattern: "[A-Za-z0-9]+"
    ConstraintDescription: Company name must only contain uppercase and lowercase letters and numbers
Resources:
  BatchSQSQueueFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./index.js
      Description: process the batch data messages
      FunctionName: batch-sqs-queue-process
      Handler: index.handler
      Runtime: nodejs8.10
      Events:
        BatchSQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt BatchSqsQueue.Arn
            BatchSize: 10

  BatchSqsQueue:
    Type: AWS::SQS::Queue
    Properties:       
      QueueName: !Sub batch-sqs-queue-${CompanyParameter}                   

Upvotes: 0

Views: 894

Answers (1)

matsev
matsev

Reputation: 33779

The current implementation does not work the way you want, each CloudFormation template that you deploy will create its own SQS queue and its own Lambda function. If the Lambda source code is changed, you must redeploy the stack for all companies. An alternative could be to create an AWS Lambda Layer and put all shared code in the layer and then configure the Lambdas with each respective SQS to use the layer. That will solve the code re-use, however there is one caveat. Copied from the documentation:

You choose a specific version of a layer to use. If you want to use a different version later, update your function's configuration.

In other words, the code is re-used between the Lambda resources, but you must still re-deploy all functions with the new version number of the Lambda layer.


Another alternative may be to implement a CloudFormation Macro. Take a look at the Count example, but imagine feeding it with an array of your companies instead of a number. Disclaimer, I have not yet tried to use macros together with AWS SAM.


Side note, the problem that you are facing batch-sqs-queue-process already exists in stack.... is because you have specified FunctionName as part of your SAM template. Lambda function names must be unique in all stacks, read more about the CloudFormation Name Type in the user guide. By removing the function name, CloudFormation will generate a unique name (typically based on the stack name, the resource name and some random characters) that is unique.

Upvotes: 1

Related Questions