aws-cloudformation / cfn-lint

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

cfn-lint breaks with any errors in template and errors on `ServerlessRestApi` implicit reference #3301

Closed cyberwombat closed 3 months ago

cyberwombat commented 3 months ago

CloudFormation Lint Version

0.87.7

What operating system are you using?

macOS Sonoma 14.5

Describe the bug

It's twofold. What I am ultimately trying to do is allow the use of ServerlessRestApi in a SAM template. I am using this in VSCode and linter yields "Unable to find referenced value, 'ServerlessRestApi" for something like this:

# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
  Description: API Gateway endpoint URL for Prod stage for Hello World function
  Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/'

In an attempt to fix this I have tried the following:

I am using the VSCode plugin for cfn-lint.

What I noticed was that if the template is fine then cfn-lint just exits quietly. If I run from command line I get:

❯ cfn-lint /Users/Me/Code/sam-app/template.yaml
Traceback (most recent call last):
  File "/opt/homebrew/bin/cfn-lint", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/__main__.py", line 40, in main
    matches = list(cfnlint.core.get_matches(filenames, args))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/core.py", line 179, in get_matches
    matches = run_cli(
              ^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/core.py", line 84, in run_cli
    return run_checks(filename, template, rules, regions, mandatory_rules)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/core.py", line 354, in run_checks
    errors.extend(runner.transform())
                  ^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/runner.py", line 35, in transform
    matches = self.cfn.transform()
              ^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/template/template.py", line 170, in transform
    return transform.transform(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/template/transforms/transform.py", line 54, in transform
    cfn.graph = Graph(cfn)
                ^^^^^^^^^^
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/graph.py", line 90, in __init__
    self._add_outputs(cfn)
  File "/opt/homebrew/Cellar/cfn-lint/0.87.7/libexec/lib/python3.12/site-packages/cfnlint/graph.py", line 124, in _add_outputs
    for output_id in cfn.template.get("Outputs", {}).keys():
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'keys'

No errors are printed regarding the issue such as "Unable to find referenced value, 'ServerlessRestApi'".

If I run the VSCode linter it will have errors next to these lines AND the top entry "AWSTemplateFormatVersion: '2010-09-09'" shows a warning on hover which prints the same traceback errors as above. So it seems to be working? but always dumps errors when so?

I've attempted to ignore the issue by passing the flag "--ignore-checks W" which does nothing for this error.

Additionally 'cfn-lint u' hangs forever and appears to do nothing __

Expected behavior

I'd like to lint the default SAM HelloWorld template without warnings.

Reproduction template

Transform: AWS::Serverless-2016-10-31
Description: My integration

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Runtime: nodejs20.x
    Timeout: 180
    Handler: app.lambdaHandler
    Architectures:
      - x86_64

Resources:
  TriggerFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: trigger/

    Metadata: # Manage esbuild properties
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: es2020
        EntryPoints:
          - app.ts

Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
  Description: API Gateway endpoint URL for Prod stage for Hello World function
  Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/'
cyberwombat commented 3 months ago

I just disabled the extension and I see there are still errors regarding ServerlessRestApi which makes me think another plugin is showing error - I will close this while I fix this to see if that is the cause of the error dump.

kddejong commented 3 months ago

I'm able to reproduce on the latest version of the code. The extension is calling cfn-lint and probably producing this error.

kddejong commented 3 months ago

The transformed template I'm getting is. I'm not sure why I'm getting nulls for Outputs from the sam translator.

{
 "Description": "My integration",
 "HelloWorldApi": {
  "Description": "API Gateway endpoint URL for Prod stage for Hello World function",
  "Value": {
   "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  }
 },
 "Outputs": null,
 "Resources": {
  "TriggerFunction": {
   "Metadata": {
    "BuildMethod": "esbuild",
    "BuildProperties": {
     "EntryPoints": [
      "app.ts"
     ],
     "Minify": true,
     "Target": "es2020"
    }
   },
   "Properties": {
    "Architectures": [
     "x86_64"
    ],
    "Code": {
     "S3Bucket": "bucket",
     "S3Key": "value"
    },
    "Handler": "app.lambdaHandler",
    "Role": {
     "Fn::GetAtt": [
      "TriggerFunctionRole",
      "Arn"
     ]
    },
    "Runtime": "nodejs20.x",
    "Tags": [
     {
      "Key": "lambda:createdBy",
      "Value": "SAM"
     }
    ],
    "Timeout": 180
   },
   "Type": "AWS::Lambda::Function"
  },
  "TriggerFunctionRole": {
   "Metadata": {
    "BuildMethod": "esbuild",
    "BuildProperties": {
     "EntryPoints": [
      "app.ts"
     ],
     "Minify": true,
     "Target": "es2020"
    }
   },
   "Properties": {
    "AssumeRolePolicyDocument": {
     "Statement": [
      {
       "Action": [
        "sts:AssumeRole"
       ],
       "Effect": "Allow",
       "Principal": {
        "Service": [
         "lambda.amazonaws.com"
        ]
       }
      }
     ],
     "Version": "2012-10-17"
    },
    "ManagedPolicyArns": [
     "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
    ],
    "Tags": [
     {
      "Key": "lambda:createdBy",
      "Value": "SAM"
     }
    ]
   },
   "Type": "AWS::IAM::Role"
  }
 }
}
kddejong commented 3 months ago

@cyberwombat based on your indentation I can see why Outputs are null. I'll update the graphing functionality to validate the Outputs before assuming its correct.

cyberwombat commented 3 months ago

@kddejong I know... embarrassing :) After I disabled cfn-lint plugin and ran it I saw that. I was distracted by the error message regarding "ServerlessRestApi" which turns out came from a different plugin. Silly me.

Thanks