aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.46k stars 596 forks source link

Fn::ForEach could not be resolved when values array references Map using AccountId key #3747

Closed nosnilmot closed 1 month ago

nosnilmot commented 1 month ago

CloudFormation Lint Version

cfn-lint 1.16.1 / git v1.16.1-5-g07652d4a4

What operating system are you using?

Mac

Describe the bug

cfn-lint fails to resolve Fn::ForEach when values array comes from Map with AccountId key

$ cfn-lint mapt.yaml 
E0001 Error transforming template: Fn::ForEach could not be resolved
mapt.yaml:11:7

Expected behavior

cfn-lint passes

Reproduction template

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::LanguageExtensions
Mappings:
  AccountMap:
    12345678901:
      Emails:
        - test@test.com
Resources:
  'Fn::ForEach::Subscriptions':
    - Email
    - !FindInMap [AccountMap, !Ref AWS::AccountId, Emails]
    - 'SubscriptionFor&{Email}':
        Type: AWS::SNS::Subscription
        Properties:
          TopicArn: "arn:aws:sns:us-east-1:12345678901:my-sns-topic"
          Protocol: email
          Endpoint: !Ref Email
nosnilmot commented 1 month ago

Still fails if the found list is empty. Does this need a new issue?

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::LanguageExtensions
Mappings:
  AccountMap:
    '012345678901':
      Emails: []
Resources:
  'Fn::ForEach::Subscriptions':
    - Email
    - !FindInMap [AccountMap, !Ref AWS::AccountId, Emails]
    - 'SubscriptionFor&{Email}':
        Type: AWS::SNS::Subscription
        Properties:
          TopicArn: "arn:aws:sns:us-east-1:012345678901:my-sns-topic"
          Protocol: email
          Endpoint: !Ref Email
$ cfn-lint map3747.yaml 
E0001 Error transforming template: Fn::ForEach could not be resolved
map3747.yaml:10:7

It only fails if first map entry has empty list, i.e. this also fails:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::LanguageExtensions
Mappings:
  AccountMap:
    '012345678901':
      Emails: []
    '123456789012':
      Emails:
        - test@test.com
Resources:
  'Fn::ForEach::Subscriptions':
    - Email
    - !FindInMap [AccountMap, !Ref AWS::AccountId, Emails]
    - 'SubscriptionFor&{Email}':
        Type: AWS::SNS::Subscription
        Properties:
          TopicArn: "arn:aws:sns:us-east-1:012345678901:my-sns-topic"
          Protocol: email
          Endpoint: !Ref Email
$ cfn-lint map3747.yaml 
E0001 Error transforming template: Fn::ForEach could not be resolved
map3747.yaml:13:7

But ths passes:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::LanguageExtensions
Mappings:
  AccountMap:
    '123456789012':
      Emails:
        - test@test.com
    '012345678901':
      Emails: []
Resources:
  'Fn::ForEach::Subscriptions':
    - Email
    - !FindInMap [AccountMap, !Ref AWS::AccountId, Emails]
    - 'SubscriptionFor&{Email}':
        Type: AWS::SNS::Subscription
        Properties:
          TopicArn: "arn:aws:sns:us-east-1:012345678901:my-sns-topic"
          Protocol: email
          Endpoint: !Ref Email
$ cfn-lint map3747.yaml 
$