In Cloudformation YAML, use a Ref in a multiline string (? use Fn:Sub)

23,551

Solution 1

Using a pipe symbol | in YAML turns all of the following indented lines into a multi-line string.

A pipe, combined with !Sub will let you use:

  • your resources Ref return value easily like ${YourResource}
  • their Fn::GetAtt return values with just a period ${YourResource.TheAttribute}
  • any Pseudo Parameter just as is like ${AWS:region}

As easy as !Sub |, jumping to the next line and adding proper indentation. Example:

Resources:
  YourUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: blabla

Outputs:
  AmplifyConfig:
    Description: key/values to be passed to Amplify.configure(config);
    Value: !Sub |
      {
        'aws_cognito_identity_pool_id': '${YourUserPool}',
        'aws_sign_in_enabled': 'enable',
        'aws_user_pools_mfa_type': 'OFF',
      }
  AdvancedUsage:
    Description: use Pseudo Parameters and/or resources attributes
    Value: !Sub |
      {
        'aws_region': '${AWS::Region}',
        'user_pool_arn': '${YourUserPool.Arn}',
      }

Solution 2

I found out how to do this using Join

AmplifyConfig:
  Description: key/values to be passed to Amplify.configure(config);
  Value:
    Fn::Join:
      - ''
      - - "{"
        - "\n  'aws_cognito_identity_pool_id':"
        - Ref : IdentityPool
        - "\n  'aws_user_pools_id':"
        - Ref : UserPool
        - "\n  'aws_user_pools_web_client_id':"
        - Ref : UserPoolClient
        - ",\n  'aws_cognito_region': '${self:provider.region}'"
        - ",\n  'aws_sign_in_enabled': 'enable'"
        - ",\n  'aws_user_pools': 'enable'"
        - ",\n  'aws_user_pools_mfa_type': 'OFF'"
        - "\n}"

This works but it's kinda ugly. I'm going to leave this answer unaccepted for a while to see if anyone can show how to do this with Fn::Sub.

Solution 3

Using YAML you could compose this simply:

Outputs:  
  AmplifyConfig:
    Description: key/values to be passed to Amplify.configure(config);
    Value: !Sub '
      {
        "aws_cognito_identity_pool_id": "${IdentityPool}",
        "aws_sign_in_enabled": "enable",
        "aws_user_pools_mfa_type": "OFF",
      }'
Share:
23,551
honkskillet
Author by

honkskillet

Updated on December 04, 2021

Comments

  • honkskillet
    honkskillet over 2 years

    Imagine you have a aws resource such as

      Resources:
        IdentityPool:
          Type: "AWS::Cognito::IdentityPool"
          Properties:
            IdentityPoolName: ${self:custom.appName}_${self:provider.stage}_identity
            CognitoIdentityProviders:
              - ClientId:
                  Ref: UserPoolClient
    

    The Ref for "AWS::Cognito::IdentityPool" returns the id of this resource. Now lets say I want to reference that id in a multiline string. I've tried

    Outputs:  
      AmplifyConfig:
        Description: key/values to be passed to Amplify.configure(config);
        Value: |
          {
            'aws_cognito_identity_pool_id': ${Ref: IdentityPool}, ##<------ Error
            'aws_sign_in_enabled': 'enable',
            'aws_user_pools_mfa_type': 'OFF',
          }
    

    I've also tried to use Fn:Sub but without luck.

       AmplifyConfig:
          Description: key/values to be passed to Amplify.configure(config);
          Value: 
            Fn::Sub 
              - |
                {
                  'aws_cognito_identity_pool_id': '${Var1Name}',
                  'aws_sign_in_enabled': 'enable',
                }
              - Var1Name:
                  Ref: IdentityPool
    

    Any way to do this?