0

I'm trying to create some resources using Cloudformation with serverless framework, In which I need to substitute resource name from another resource. Tried to use !Sub but still I couldn't get Arn of another resource created.

Tried all the approaches in this stackoverflow question How to use Sub and GetAtt functions at the same time in CloudFormation template? to no avail.

I appreciate any help.

Resources:
  BasicParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /data/config-name
      Type: String
      Value:
        Fn::Base64:
          !Sub |

            {
                "filter_configs": [{
                    "stream_name": !GetAtt tpRecordDeliveryStream.Arn,
                    "events": [
                        {
                            "name": "event_name1",
                            "stream": "streamname1"
                        },
                        {
                            "name": "event_name2"
                        }
                    ]
                }]
            }
      Description: Configuration for stream filters
      Tags:
        project: projectname
        team: data
        owner: owner_name
Marcin
  • 215,873
  • 14
  • 235
  • 294
Somasundaram Sekar
  • 5,244
  • 6
  • 43
  • 85

2 Answers2

1

This was resolved by using serverless-pseudo-parameters serverless plugin. Serverless framework also uses ${} placeholder and it conflicts with Cloudformation placeholders. serverless-pseudo-parameters solves that by allowing us to replace those place holders with #{} which are replaced during sls deploy with cloud formation templates

Resources:
  streamConfig:
    Type: AWS::SSM::Parameter
    Properties:
      Name: config_name
      Type: String
      Value:
        Fn::Base64: |
          {
              "filter_configs": [{
                  "firehose_stream_arn": "#{tpRecordDeliveryStream.Arn}",
                  "events": [
                      {
                          "name": "config0",
                          "filter1": "value1"
                      },
                      {
                          "name": "config1"
                      }
                  ]
              }]
          }
      Description: Configuration for stream filters
Somasundaram Sekar
  • 5,244
  • 6
  • 43
  • 85
0

Since you have !Sub |, instead of

 "stream_name": !GetAtt tpRecordDeliveryStream.Arn,

the following should be enough

 "stream_name": "${tpRecordDeliveryStream.Arn}"

The alternative using !Sub in array notation:

Value:
  Fn::Base64:
    !Sub 
      - |
        {
            "filter_configs": [{
                "stream_name": "${tpRecordDeliveryStreamArn}",
                "events": [
                    {
                        "name": "event_name1",
                        "stream": "streamname1"
                    },
                    {
                        "name": "event_name2"
                    }
                ]
            }]
        }
      - tpRecordDeliveryStreamArn: !GetAtt tpRecordDeliveryStream.Arn
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • tried them both **with !Sub** `Invalid variable reference syntax for variable tpRecordDeliveryStream.Arn` and **without !Sub** `Fn::Base64 object must have a String-typed value` – Somasundaram Sekar Jun 11 '20 at 12:15
  • @SomasundaramSekar What is the definition of `tpRecordDeliveryStream`? Is it some other resource in same template file? – Marcin Jun 11 '20 at 12:19
  • it is a resource in a different file but part of the same cloudformation deployment Resources: tpRecordDeliveryStream: – Somasundaram Sekar Jun 11 '20 at 12:21
  • @SomasundaramSekar If its in different stack then you can't reference it like that. Have you exported is in `Outputs` of a stack where they are defined? – Marcin Jun 11 '20 at 12:22
  • I'm not sure that is the problem, as I can use that in a different place also part of the same deployment – Somasundaram Sekar Jun 11 '20 at 12:23
  • Ok, just verified, this works Fn::Base64: !GetAtt tpRecordDeliveryStream.Arn, outputs the correct arn – Somasundaram Sekar Jun 11 '20 at 12:25
  • @SomasundaramSekar I provided alternative way. Have to be careful about indentations. – Marcin Jun 11 '20 at 12:29
  • @SomasundaramSekar Any luck with the issue? – Marcin Jun 11 '20 at 23:53
  • Unfortunately I couldn't get anything to work, finally had to be helped by `serverless-pseudo-parameters` serverless plugin and this place holder #{tpRecordDeliveryStream.Arn}, I think the problem is ${} being place holder for both serverless framework and cloudformation and the subsequent conflict – Somasundaram Sekar Jun 12 '20 at 08:10