aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.4k stars 576 forks source link

Errors after upgrading to v1.3 #3383

Closed vchepkov closed 1 week ago

vchepkov commented 1 week ago

CloudFormation Lint Version

1.3.3

What operating system are you using?

macOS

Describe the bug

after upgrade to v1.3, cfn-lint fails unexpectedly, It generates multiple errors

E1019 {'Ref': 'additionalSubnetBits'} is not of type 'integer' when 'Ref' is resolved when 'Ref' is resolved E3024 {'Ref': 'additionalSubnetBits'} is not of type 'integer' when 'Ref' is resolved when 'Ref' is resolved E1020 {'Ref': 'additionalSubnetBits'} is not of type 'integer' when 'Ref' is resolved

There are identical Select functions, one in !If function passes , but the line in !Sub function fails

The code is deployed in CloudFormation, so we know it's valid

Expected behavior

Code is valid, cfn-lint shouldn't fail

Reproduction template

  AdditionalSubnet1:
    Type: 'AWS::EC2::Subnet'
    Condition: isAdditionalVpc
    DependsOn: AdditionalVpcCIDR
    Properties:
      AvailabilityZone: !If [usesetaz, !Select [0, !Split [",", !Ref physicalazlist]], !Select [0, !GetAZs '']]
      CidrBlock:
        !If
          - isAdditionalCidr1Empty
          - !Select [0, !Cidr [!Ref additionalVpcCidr, 4, !Ref additionalSubnetBits] ]
          - !Ref AdditionalSubnet1Cidr
      MapPublicIpOnLaunch: false
      Tags:
      - Key: Name
        Value: !Sub
        - ${appCode}-${envType}-additional1-${az}-${cidr}
        -
          az: !If [usesetaz, !Select [0, !Split [",", !Ref physicalazlist]], !Select [0, !GetAZs '']]
          cidr: !Select [0, !Cidr [!Ref additionalVpcCidr, 4, !Ref additionalSubnetBits] ]
      VpcId: !Ref vpc
kddejong commented 1 week ago

The issue here comes down to the Fn::Sub.

This is invalid. Once we are evaluating the elements to a function we need to turn off strict type checking. The output type from the function has to be a string.

Resources:
  MyPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          Action: "*"
          Resource: "*"
          Effect: Allow
  Parameter:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Value:
        Fn::Sub: 
        - "${Value}"
        - Value: !GetAtt MyPolicy.AttachmentCount
vchepkov commented 1 week ago

@kddejong , thank you for the prompt response. v1.3.4 cleaned most of the errors. This section in outputs still fails though

  AdditionalCidrs:
    Condition: isAdditionalVpc
    Value: !Join [',', !Cidr [!Ref additionalVpcCidr, 3, 8]]
E1022 {'Fn::Cidr': [{'Ref': 'additionalVpcCidr'}, 3, 8]} is not of type 'array'
template.yml:1915:24

Do you want a new ticket?

Thanks again

kddejong commented 1 week ago

Nah here is good. Easy fix we just need to add Fn::Cidr as a supported function for the join.

vchepkov commented 1 week ago

@kddejong , I tried v1.3.6, it now fails differently on the same output block

E1020 {'Ref': 'additionalVpcCidr'} does not match '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$' when 'Ref' is resolved

Since it's a conditional block, it should expect a valid string all the time, right? It's a runtime evaluation

Conditions:
  isAdditionalVpc:
    Fn::Not: [ !Equals [ !Ref additionalVpcCidr , ""] ]

Outputs:
  AdditionalCidrs:
    Condition: isAdditionalVpc
    Value: !Join [',', !Cidr [!Ref additionalVpcCidr, 3, 8]]
kddejong commented 1 week ago

@vchepkov #3414 should handle that scenario. Added the logic to consider conditions inside resources but not for outputs. Had to rework the output logic a little more to add it in there as well. Added your cases as test scenarios as well.