Yuval Podoksik
Yuval Podoksik

Reputation: 528

AWS CloudFormation - using !Ref inside !Sub

I'm writing AWS CloudFormation template (using yaml) which creates AWS Service Catalog Product. I'm getting the template for the product using parameter S3FilePath which has a value like the above path: https://bucket.s3-eu-west-1.amazonaws.com/template.yml. The URL to the file needs to be send in a JSON format as shown here (this example works):

Resources:
    Type: AWS::ServiceCatalog::CloudFormationProduct
    Properties: 
      Description: Example Product
      Distributor: xyz
      Name: ExampleProduct
      Owner: xyz
      ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: { "LoadTemplateFromURL": "https://bucket.s3-eu-west-1.amazonaws.com/template.yml" }
          Name: Version1

I tried to replace the URL using !Sub and !Ref as shown below:

Parameters:
  S3FilePath:
      Type: String
      Description: file name
Resources:
    Type: AWS::ServiceCatalog::CloudFormationProduct
    Properties: 
      Description: Example Product
      Distributor: xyz
      Name: ExampleProduct
      Owner: xyz
      ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: !Sub
            - '{ "LoadTemplateFromURL": "${FILEPATH}" }'
            - {FILEPATH: !Ref S3FilePath}
          Name: Version1

But the CloudFormation stack fails with the error: "invalid input". I guess I am building the JSON in a wrong way, I tried to use \ before each ' " ' but it didn't help either and I couldn't find an example which explain how to build this correctly. There is no problem with the S3FilePath parameter.

Can you please advice how to use the !Sub and !Ref correctly to build the JSON? Thanks.

Upvotes: 2

Views: 6491

Answers (3)

Marcin
Marcin

Reputation: 238727

I think it should be simply:

     ProvisioningArtifactParameters: 
        - Description: Example Product
          Info: 
            LoadTemplateFromURL: !Ref S3FilePath
          Name: Version1

This is at least what I have in my own AWS::ServiceCatalog::CloudFormationProduct templates.

      ProvisioningArtifactParameters: 
        - DisableTemplateValidation: false
          Info: 
            LoadTemplateFromURL: !Ref S3FilePath

Upvotes: 0

Laurent Jalbert Simard
Laurent Jalbert Simard

Reputation: 6349

You can reference any Parameters or LogicalResourceId directly inside a !Sub like so:

  ProvisioningArtifactParameters: 
    - Description: Example Product
      Info: !Sub '{ "LoadTemplateFromURL": "${S3FilePath}" }'
      Name: Version1

This should work totally fine. The way you were doing substitutions is useful when you want to use conditions and/or mapping inside a !Sub.

Upvotes: 1

Shawn
Shawn

Reputation: 9442

Here is an example: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html#w2ab1c25c28c59c11

Despite the documentation saying the Info parameter is JSON, the example shows just a name/value pair (Map): https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-servicecatalog-cloudformationproduct-provisioningartifactproperties.html

Try formatting your string as

Info: !Sub
  - "LoadTemplateFromURL": "${FILEPATH}"
  - {FILEPATH: !Ref S3FilePath}

Upvotes: 1

Related Questions