AWS CloudFormation Fn::ImportValue doesn't like !Join?

Viewed 1317

I have the following resource in my CloudFormation template that's trying to create a listener rule. The idea is, based on the passed-in EnvironmentType, and the AWS Region, I want to import the listener ARN from the appropriate CloudFormation stack that exported it.

Parameters:
  EnvironmentType:
    Type: String
    Default: "sandbox"
  ECSClusterStackNameParameter:
    Type: String
    Default: "ECS-US-Sandbox"

Mappings:
  production:
    us-east-1:
      stackWithAlbListenerInfo: "ECS-US-Prod"
    eu-north-1:
      stackWithAlbListenerInfo: "ECS-EU-Prod"
  staging:
    us-east-1:
      stackWithAlbListenerInfo: "ECS-US-Staging"
    eu-north-1:
      stackWithAlbListenerInfo: ""
  sandbox:
    us-east-1:
      stackWithAlbListenerInfo: "ECS-US-Sandbox"
    eu-north-1:
      stackWithAlbListenerInfo: ""

Conditions:
  StackExists:
    !Not [ !Equals [ !FindInMap [ !Ref EnvironmentType, !Ref "AWS::Region", stackWithAlbListenerInfo ], ""] ]

Resources:
  AlbListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Condition: UseListenerRule
    Properties:
      ListenerArn:
        !If
          - StackExists
          -
            - Fn::ImportValue:
                !Join
                  - "-"
                  - - !FindInMap [ !Ref EnvironmentType, !Ref "AWS::Region", stackWithAlbListenerInfo ]
                    - "ListenerArn"
          - Fn::ImportValue:
              - !Sub "${ECSClusterStackNameParameter}-ListenerArn"

However, it fails validation due to this error, and seems like the first Fn::ImportValue: doesn't like the !Join. But !Join returns a concatenated string correct? What am I missing?

ERROR: Service: marcom-stats-service, cfnUpdate error: com.amazonaws.services.cloudformation.model.AmazonCloudFormationException: Template error: the attribute in Fn::ImportValue must be a string or a function that returns a string (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: 2678552e-cf6c-46e1-b640-a7c07de385c2; Proxy: null)

UPDATE:

Though Robert Kossendey's answer fixed my error, my original template was wrong. This is really what I wanted to do. I hope it helps someone.

  AlbListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Condition: UseListenerRule
    Properties:
      ListenerArn:
        Fn::ImportValue: !Sub
          - ${StackName}-ListenerArn
          - { StackName: !If [ StackExists, !FindInMap [ !Ref EnvironmentType, !Ref "AWS::Region", stackWithAlbListenerInfo ], !Ref ECSClusterStackNameParameter ] }
1 Answers

Now I see it I think. At the second import you need to remove the dash in front of the !Sub:

- Fn::ImportValue:
  !Sub "${ECSClusterStackNameParameter}-ListenerArn"
Related