aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.43k stars 586 forks source link

[Bug] Impossible, rules-unaware condition errors #3630

Closed alnoki closed 1 week ago

alnoki commented 2 weeks ago

CloudFormation Lint Version

1.11.0

What operating system are you using?

Mac pre-commit

Describe the bug

The reproduction template throws:

W1001 Ref to resource 'InternetGateway' that may not be available when condition 'ProvisionStack' is False and when condition 'ProvisionVpc' is True at Resources/InternetGatewayAttachment/Properties/InternetGatewayId

Specifically, the purported hypothetical situation

when condition 'ProvisionStack' is False and when condition 'ProvisionVpc' is True

is impossible per the ProvisionVpc rule.

Expected behavior

The lint should pass, without having to duplicate ProvisionVpc rule logic in the ProvisionVpc condition. E.g. while updating the condition to:

  ProvisionVpc: !And
  - !Condition 'ProvisionStack'
  - !Equals
    - !Ref 'ProvisionVpc'
    - 'true'

results in a successful lint, this situation requires duplicate definitions just to satisfy the linter, thus reducing maintainability.

Moreover, since cfn-lint's static analysis is based off of conditions instead of rules (presumably, based on the reproduction template), templates that pass lints might not preserve the intended behavior if a cascaded condition is added without an accompanying duplicate rule.

Reproduction template

---
Conditions:
  ProvisionStack: !Equals
  - !Ref 'ProvisionStack'
  - 'true'
  ProvisionVpc: !Equals
  - !Ref 'ProvisionVpc'
  - 'true'
Parameters:
  ProvisionStack:
    AllowedValues:
    - 'false'
    - 'true'
    Type: 'String'
  ProvisionVpc:
    AllowedValues:
    - 'false'
    - 'true'
    Type: 'String'
Resources:
  InternetGateway:
    Condition: 'ProvisionStack'
    Type: 'AWS::EC2::InternetGateway'
  InternetGatewayAttachment:
    Condition: 'ProvisionVpc'
    Properties:
      InternetGatewayId: !Ref 'InternetGateway'
      VpcId: !Ref 'Vpc'
    Type: 'AWS::EC2::VPCGatewayAttachment'
  Vpc:
    Condition: 'ProvisionVpc'
    Properties:
      CidrBlock: '0.0.0.0/16'
    Type: 'AWS::EC2::VPC'
Rules:
  ProvisionVpc:
    Assertions:
    - Assert: !Or
      - Fn::Not: !Condition 'ProvisionVpc'
      - !Condition 'ProvisionStack'
...
kddejong commented 2 weeks ago

Duplicate #1888. We would need to add support for Rules.