Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

aws cloudformation use Fn::Join in a list

I've a cloudformation template that uses custom resource backed by lambda function. One of the parameters of the lambda function is a list of strings. I have only one item to pass in the list and would like to use Fn:Join to concatenate create the string. However, using Fn::Join gives error as it leads to invalid json. Any inputs are appreciated.

"Subscriptions": [ "Fn::Join": [":", ["a", "b", "c"]]]

A client error (ValidationError) occurred when calling the CreateStack operation : Template format error: JSON not well-formed.

Cloudformation snippet:-

  "Resources": {
"MyCustomRes": {
      "Type": "Custom::CustomResource",
      "Properties": {
        "ServiceToken": { "Fn::Join": [ "", [
                                        "arn:aws:lambda:",
                                        { "Ref": "AWS::Region" },
                                        ":",
                                        { "Ref": "AWS::AccountId" },
                                        ":function:LambdaFn"
                                      ] ] },
        "Version": 1,
        "ResourceName": { "Ref": "ResourceName" },
        "Subscriptions"       : [ "Fn::Join": [ "", [
                                        "arn:aws:sns:",
                                        { "Ref": "AWS::Region" },
                                        ":",
                                        { "Ref": "AWS::AccountId" },
                                        ":Topic1"
                                      ] ] ]
    }
}     },
like image 251
user1573133 Avatar asked Oct 19 '16 19:10

user1573133


People also ask

What is FN :: join in CloudFormation?

The intrinsic function Fn::Join appends a set of values into a single value, separated by the specified delimiter. If a delimiter is the empty string, the set of values are concatenated with no delimiter.

What is FN in AWS?

The intrinsic function Fn::Sub substitutes variables in an input string with values that you specify. In your templates, you can use this function to construct commands or outputs that include values that aren't available until you create or update a stack.

How do I join the CFN?

Call CFN Helpdesk at the toll free number 800.899. 2236 to make an appointment 24 hours prior to the site go live.

What is AWS :: CloudFormation :: Waitconditionhandle?

An associated AWS::CloudFormation::WaitCondition resource checks the URL for the required number of success signals or for a failure signal.


1 Answers

The Fn::Join Intrinsic Function used to build the values for the Subscriptions property must be an object rather than an array.

It's invalid JSON syntax to declare an array like ['Fn::Join' : [...]] instead it must be of the form {"Fn::Join" : [...]}

The docs describe the syntax as

{ "Fn::Join" : [ "delimiter", [ comma-delimited list of values ] ] }

Therefore your CloudFormation template should use the following

{
  "Subscriptions": {
    "Fn::Join": [
      ":",
      [
        "arn:aws:sns",
        {
          "Ref": "AWS::Region"
        },
        {
          "Ref": "AWS::AccountId"
        },
        "Topic1"
      ]
    ]
  }
}

A more readable solution to constructing ARN exists using the Fn::Sub Intrinsic Function.

{
  "Fn::Sub": [
    "arn:${AWS::Partition}:sns:${AWS::Region}:${AWS::AccountId}:Topic1"
  ]
}
like image 158
georgealton Avatar answered Sep 21 '22 11:09

georgealton