aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.44k stars 590 forks source link

E6101 Exception "Attribute for resource doesn't exist" raised while validating 'fn_getatt' should not happen #3585

Closed dengmingtong closed 2 months ago

dengmingtong commented 2 months ago

CloudFormation Lint Version

cfn-lint 1.9.7

What operating system are you using?

Mac

Describe the bug

Our template if fine for 1.9.0 but error E6101 happened for v1.9.7 version.

Below is the template snapshot: "Outputs": { "IngestionCommonResourcesIngestionServerDNS": { "Description": "Server DNS", "Value": { "Fn::If": [ "IngestionCommonResourcesacceleratorEnableCondition0F76B8A4", { "Fn::GetAtt": [ "IngestionCommonResourcesGlobalAcceleratorAB9F423D", "DnsName" ] }, { "Fn::GetAtt": [ "IngestionCommonResourcesCreateApplicationLoadBalancerALBclickstreamingestionservicealb6731C6BD", "DNSName" ] } ] } },

Error detail as below: E6101 Exception "Attribute for resource doesn't exist" raised while validating 'fn_getatt' cdk.out/Test.template.json:3926:6

the line 3926 is below part:

 _{
  "Fn::GetAtt": [
   "IngestionCommonResourcesGlobalAcceleratorAB9F423D",
   "DnsName"
  ]
 },_

Because we use the condition to control output value, the cfn-lint can support condition?

Thanks, Mingtong

Expected behavior

Should no error happened, I think the template should be fine.

Reproduction template

...
 "Outputs": {
  "IngestionCommonResourcesIngestionServerDNS": {
   "Description": "Server DNS",
   "Value": {
    "Fn::If": [
     "IngestionCommonResourcesacceleratorEnableCondition0F76B8A4",
     {
      "Fn::GetAtt": [
       "IngestionCommonResourcesGlobalAcceleratorAB9F423D",
       "DnsName"
      ]
     },
     {
      "Fn::GetAtt": [
       "IngestionCommonResourcesCreateApplicationLoadBalancerALBclickstreamingestionservicealb6731C6BD",
       "DNSName"
      ]
     }
    ]
   }
  },
...
kddejong commented 2 months ago

Yes it supports conditions for that validation but it won't really matter as long as the resource exists. This is thrown from an attribute error that isn't caught. Most of the time in the rules we aren't grabbing that attribute unless we know it exists but its possible we are missing. a try,except.

Conditions:
  IngestionCommonResourcesacceleratorEnableCondition0F76B8A4: !Equals [!Ref "AWS::Region", "us-east-1"]
Resources:
  IngestionCommonResourcesGlobalAcceleratorAB9F423D:
    Type: AWS::GlobalAccelerator::Accelerator
    Properties:
      Name: SampleAccelerator
      Enabled: true
  IngestionCommonResourcesCreateApplicationLoadBalancerALBclickstreamingestionservicealb6731C6BD:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: clickstream-ingestion-service-alb
      Scheme: internet-facing
      Type: application
      Subnets:
      - Fn::ImportValue: IngestionCommonStack-subnet-1-id
      - Fn::ImportValue: IngestionCommonStack-subnet-2-id
      - Fn::ImportValue: IngestionCommonStack-subnet-3-id
Outputs:
  IngestionCommonResourcesIngestionServerDNS:
   Description: Server DNS
   Value:
    Fn::If:
    - IngestionCommonResourcesacceleratorEnableCondition0F76B8A4
    - Fn::GetAtt: IngestionCommonResourcesGlobalAcceleratorAB9F423D.DnsName
    - Fn::GetAtt: IngestionCommonResourcesCreateApplicationLoadBalancerALBclickstreamingestionservicealb6731C6BD.DNSName

Do I have the right resource types?

also if you run cfn-lint with --debug we should be able to fine the stack trace. I know where the ValueError is coming from but fn_getatt should be catching it and trying to figure out what line we are not catching it.

dengmingtong commented 2 months ago

below is the stack trace after running with --debug:

2024-08-13 23:19:58,720 - cfnlint.jsonschema.validators - DEBUG - Attribute for resource doesn't exist
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/jsonschema/validators.py", line 241, in iter_errors
    for err in (
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 157, in fn_getatt
    errs = list(
           ^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 112, in _resolve_getatt
    pointer = getatts.match(
              ^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 154, in match
    raise e
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 151, in match
    raise ValueError("Attribute for resource doesn't exist")
ValueError: Attribute for resource doesn't exist
2024-08-13 23:19:58,727 - cfnlint.jsonschema.validators - DEBUG - Attribute for resource doesn't exist
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/jsonschema/validators.py", line 241, in iter_errors
    for err in (
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 157, in fn_getatt
    errs = list(
           ^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 112, in _resolve_getatt
    pointer = getatts.match(
              ^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 154, in match
    raise e
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 151, in match
    raise ValueError("Attribute for resource doesn't exist")
ValueError: Attribute for resource doesn't exist
2024-08-13 23:19:58,729 - cfnlint.jsonschema.validators - DEBUG - Attribute for resource doesn't exist
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/jsonschema/validators.py", line 241, in iter_errors
    for err in (
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 157, in fn_getatt
    errs = list(
           ^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/rules/functions/GetAtt.py", line 112, in _resolve_getatt
    pointer = getatts.match(
              ^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 154, in match
    raise e
  File "/opt/homebrew/Cellar/cfn-lint/1.9.7/libexec/lib/python3.12/site-packages/cfnlint/template/getatts.py", line 151, in match
    raise ValueError("Attribute for resource doesn't exist")
ValueError: Attribute for resource doesn't exist
kddejong commented 2 months ago

Still not sure this is the exact issue but ran into this will trying to replicate this issue. I was able to replicate a version of this issue as well and this fix will fix both.

dengmingtong commented 2 months ago

Hello, I have to reopen this issue because the error still happened for out template.

I attachment the template and run command, I think you can reproduce this issue.

cfn-lint -e -r cn-north-1 -t Test.template.json

Test.template.json

If any other information need, please let me know.

Thanks, Mingtong

kddejong commented 2 months ago

Its not released yet. Did you install from GH?

kddejong commented 2 months ago

I'll get this released as it fixes your issue.

kddejong commented 2 months ago

Released and closing this