'Cloudformation YAML custom variable

I am trying to achieve something similar to below in a AWS Cloudformation YAML file:

AWSTemplateFormatVersion: 2010-09-09

testAttribute = "test"

Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.7
      Role: !GetAtt iam.Arn
      MemorySize: 128
      Timeout: 10
      Handler: lambda_function.lambda_handler
      FunctionName: "testName"+${testAttribute}
      Description: 'This is my lambda'
      Code:
        S3Bucket: myBucket
        S3Key: "lambda/testName"+${testAttribute}+".zip"

I know that above isn't quite correct, but I cant find a good answer when searching how to achieve it. Anyone who have some guidance on this matter?



Solution 1:[1]

You could use Parameters with a default value, and Sub later in the template:

AWSTemplateFormatVersion: 2010-09-09

Paramters:
  testAttribute:
    Type: String
    Default: test

Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.7
      Role: !GetAtt iam.Arn
      MemorySize: 128
      Timeout: 10
      Handler: lambda_function.lambda_handler
      FunctionName: !Sub "testName${testAttribute}"
      Description: 'This is my lambda'
      Code:
        S3Bucket: myBucket
        S3Key: !Sub "lambda/testName${testAttribute}.zip"

Solution 2:[2]

It depends on the use case but if the "variable" would be static and you don't need the change it when deploying the stack, I would suggest an alternative solution, to use the Mappings section.

This allows you to define some static values without sending them when deploying the stack (you will have much cleaner deploy commands, and the logic would be on the template side instead of the deploy side).

In this case, I'm using !Sub intrinsic function with a mapping (you can set multiple variables to be substituted using !Sub):

AWSTemplateFormatVersion: 2010-09-09

Mappings:
 attributes:
  lambda:
   testAttribute: "test"

Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.7
      Role: !GetAtt iam.Arn
      MemorySize: 128
      Timeout: 10
      Handler: lambda_function.lambda_handler
      FunctionName: !Sub 
                     - "testName${attr}"
                     - {attr: !FindInMap [attributes, lambda, testAttribute]}
      Description: 'This is my lambda'
      Code:
        S3Bucket: myBucket
        S3Key: !Sub 
                - "lambda/testName${attr}.zip"
                - {attr: !FindInMap [attributes, lambda, testAttribute]}

Note: Mappings have a mandatory three-level nesting, take this into consideration while designing your solution

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcin
Solution 2