Home > Software engineering >  How is the !Ref function used in an AWS CloudFormation template?
How is the !Ref function used in an AWS CloudFormation template?

Time:01-04

Im tying to follow AWS tutorial for creating lambda function using sam cli It created the following yaml file

# This is the SAM template that represents the architecture of your serverless application
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-basics.html

# The AWSTemplateFormatVersion identifies the capabilities of the template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/format-version-structure.html
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  mfcBackend

# Transform section specifies one or more macros that AWS CloudFormation uses to process your template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-section-structure.html
Transform:
- AWS::Serverless-2016-10-31

# Resources declares the AWS resources that you want to include in the stack
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Tracing: Active
  Api:
    TracingEnabled: true

Resources:
  # Each Lambda function is defined by properties:
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction

  # This is a Lambda function config associated with the source code: get-all-items.js
  getAllItemsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/get-all-items.getAllItemsHandler
      Runtime: nodejs16.x
      Architectures:
      - x86_64
      MemorySize: 1000
      Timeout: 100
      Description: A simple example includes a HTTP get method to get all items from
        a DynamoDB table.
      Policies:
        # Give Create/Read/Update/Delete Permissions to the SampleTable
      - DynamoDBCrudPolicy:
          TableName: !Ref SampleTable
      Environment:
        Variables:
          # Make table name accessible as environment variable from function code during execution
          SAMPLE_TABLE: !Ref SampleTable
      Events:
        Api:
          Type: Api
          Properties:
            Path: /
            Method: GET
  # Each Lambda function is defined by properties:
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction

  # This is a Lambda function config associated with the source code: get-by-id.js
  getByIdFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/get-by-id.getByIdHandler
      Runtime: nodejs16.x
      Architectures:
      - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A simple example includes a HTTP get method to get one item by
        id from a DynamoDB table.
      Policies:
        # Give Create/Read/Update/Delete Permissions to the SampleTable
      - DynamoDBCrudPolicy:
          TableName: !Ref SampleTable
      Environment:
        Variables:
          # Make table name accessible as environment variable from function code during execution
          SAMPLE_TABLE: !Ref SampleTable
      Events:
        Api:
          Type: Api
          Properties:
            Path: /{id}
            Method: GET
  # Each Lambda function is defined by properties:
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction

  # This is a Lambda function config associated with the source code: put-item.js
  putItemFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/put-item.putItemHandler
      Runtime: nodejs16.x
      Architectures:
      - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A simple example includes a HTTP post method to add one item to
        a DynamoDB table.
      Policies:
        # Give Create/Read/Update/Delete Permissions to the SampleTable
      - DynamoDBCrudPolicy:
          TableName: !Ref SampleTable
      Environment:
        Variables:
          # Make table name accessible as environment variable from function code during execution
          SAMPLE_TABLE: !Ref SampleTable
      Events:
        Api:
          Type: Api
          Properties:
            Path: /
            Method: POST
  # Simple syntax to create a DynamoDB table with a single attribute primary key, more in
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlesssimpletable

  # DynamoDB table to store item: {id: <ID>, name: <NAME>}
  SampleTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
        Name: id
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 2
        WriteCapacityUnits: 2

  ApplicationResourceGroup:
    Type: AWS::ResourceGroups::Group
    Properties:
      Name:
        Fn::Join:
        - ''
        - - ApplicationInsights-SAM-
          - Ref: AWS::StackName
      ResourceQuery:
        Type: CLOUDFORMATION_STACK_1_0
  ApplicationInsightsMonitoring:
    Type: AWS::ApplicationInsights::Application
    Properties:
      ResourceGroupName:
        Fn::Join:
        - ''
        - - ApplicationInsights-SAM-
          - Ref: AWS::StackName
      AutoConfigurationEnabled: 'true'
    DependsOn: ApplicationResourceGroup
Outputs:
  WebEndpoint:
    Description: API Gateway endpoint URL for Prod stage
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

it also generated the following code

const tableName = process.env.SAMPLE_TABLE;

When I run the code, the value of tableName is set the SampleTable and this code fail with the error

{"statusCode":404,"body":"Unable to call DynamoDB. Table resource not found."}

This is due to the fact that the actual table name that was created by 'sam build' is eliaTst-SampleTable-OFRSBK12RIQV

When I do this in the code:

const tableName = "eliaTst-SampleTable-OFRSBK12RIQV"

I get no error

I was expecting SAMPLE_TABLE: !Ref SampleTable to pass the actual table name (i.e. "eliaTst-SampleTable-OFRSBK12RIQV")

Why isn't it set to the expected value?

How do I reference the actual table name in this yaml so that the env SAMPLE_TABLE will contain the actual table name that is created by SampleTable ?

CodePudding user response:

You can try with different Type like this:

SampleTable:
  Type: AWS::DynamoDB::Table
  Properties:
    AttributeDefinitions:
      - AttributeName: "id"
        AttributeType: "S"
    KeySchema:
      - AttributeName: "id"
        KeyType: "HASH"
    ProvisionedThroughput:
      ReadCapacityUnits: 2
      WriteCapacityUnits: 2

CodePudding user response:

Ref function is used to substitute the physical ID of resource. Returns the aws region where cloud formation template is running.

!Ref "AWS::Region"

If you want to create reusable parameters then use Parameters with a default value then Sub the value

Parameters:
  SampleTableName:
    Type: String
    Default: someName
...
Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          SAMPLE_TABLE: !Ref SampleTableName
...
  • Related