2

I have the following EC2 UserData:

UserData: !Base64
    Fn::Sub: |
      #PROVISIONER_PEER_PASSWORD_INPUT=${AWS::AccountId} ${AWS::StackId} ${AWS::Region}

      #PROVISIONER_PEER_PASSWORD=${pDatabasePassword}

      #PROVISIONER_SHARED_UNIQUE_ID_INPUT=${AWS::AccountId} ${AWS::StackId} ${AWS::Region}

      #PROVISIONER_CFN_RESOURCE=Machine

      #PROVISIONER_CFN_STACK=${AWS::StackName}

      #PROVISIONER_CFN_REGION=${AWS::Region}

      #PROVISIONER_DATA_DISK=/dev/xvdc

      #PROVISIONER_TIER=frontend

      #PROVISIONER_PEER_ADDRESS=
      Fn::GetAtt:
        - rDatabaseCluster
        - Endpoint.Address

      #PROVISIONER_APP_PASSWORD=${pApplicationPassword}

The point where the user data code is breaking is here.

#PROVISIONER_PEER_ADDRESS=
      Fn::GetAtt:
        - rDatabaseCluster
        - Endpoint.Address

The Fn::GetAtt is not getting executed/resolved. The result of the user data code after the stack is successfully created, looks like this:

#PROVISIONER_PEER_PASSWORD_INPUT=11111333393 arn:aws:cloudformation:us-east-1:171602812093:stack/daxz/16085e70-5b2b-11ea-91e9-122e54527a47 us-east-1

#PROVISIONER_PEER_PASSWORD=Jane85

#PROVISIONER_SHARED_UNIQUE_ID_INPUT=11111333393 arn:aws:cloudformation:us-east-1:171602812093:stack/daxz/16085e70-5b2b-11ea-91e9-122e54527a47 us-east-1

#PROVISIONER_CFN_RESOURCE=Machine

#PROVISIONER_CFN_STACK=daxz

#PROVISIONER_CFN_REGION=us-east-1

#PROVISIONER_DATA_DISK=/dev/xvdc

#PROVISIONER_TIER=frontend

#PROVISIONER_PEER_ADDRESS=
Fn::GetAtt:
- rDatabaseCluster
- Endpoint.Address

#PROVISIONER_APP_PASSWORD=Jane85

As you can see the code for Fn::GetAtt went into the user data as is without resolving to the actual value.

#PROVISIONER_PEER_ADDRESS=
    Fn::GetAtt:
    - rDatabaseCluster
    - Endpoint.Address

How do I make Fn::GetAtt work under Fn::Sub? Or what is the best way to get the right value???

mayorsanmayor
  • 2,870
  • 4
  • 24
  • 44

2 Answers2

3

you can also use GetAtt inline like this:

!Sub "... ${rDatabaseCluster.Endpoint.Address}"

see here: How to use Sub and GetAtt functions at the same time in CloudFormation template?

mengmann
  • 416
  • 7
  • 11
1

The problem is that you have your GetAtt inside the string. To do what you want to do you need to use the more verbose version of Fn::Sub. A simple example would look like this:

Fun::Sub:
  - 'some string ${ValueToReplace}'
  - ValueToReplace: !GetAtt SomeResource.Attribute
Jason Wadsworth
  • 8,059
  • 19
  • 32