3

I'm trying to build a serverless API that calls a lambda function with an ApiKey. AWS SDK in Visual Studio gives me an error stating that the reference is an invalid type.

I have compared my serverless template to several other working examples, but I must be overlooking some specific detail.

Any ideas?

Error message from VS 2019

Here is my serverless template... what am I missing?

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "An AWS Serverless Application.",
  "Resources": {
    "SendEmailFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "ServerlessTest3::ServerlessTest3.Functions::SendEmail",
        "Runtime": "dotnetcore3.1",
        "CodeUri": "",
        "MemorySize": 12,
        "Timeout": 30,
        "Role": null,
        "Policies": [
          "AWSLambdaBasicExecutionRole"
        ],
        "Events": {
            "ProxyResource": {
                "Type": "Api",
                "Properties": {
                    "Path": "/{proxy+}",
                    "Method": "POST",
                    "RestApiId": {
                        "Ref": "ApiGatewayApi"
                    }
                }
            },
            "RootResource": {
                "Type": "Api",
                "Properties": {
                    "Path": "/",
                    "Method": "POST",
                    "RestApiId": {
                        "Ref": "ApiGatewayApi"
                    }
                }
            }
        }
      }
    },    
    "ApiUsagePlan": {
        "Type": "AWS::ApiGateway::UsagePlan",
        "Properties": {
            "ApiStages": [
                {
                    "ApiId": {
                        "Ref": "ApiGatewayApi"
                    },
                    "Stage": "Prod"
                }
            ]
        }
    },
    "ApiUsagePlanKey": {
        "Type": "AWS::ApiGateway::UsagePlanKey",
        "Properties": {
            "KeyId": {
                "Ref": "ApiKey"
            },
            "KeyType": "API_KEY",
            "UsagePlanId": {
                "Ref": "ApiUsagePlan"
            }
        }
    },
    "ApiKey": {
        "Type": "AWS::ApiGateway::ApiKey",
        "Properties": {
            "Name": "my-api-key-name",
            "Enabled": "true",
            "StageKeys": [{
                "RestApiId": {
                    "Ref": "ApiGatewayApi"
                },
                "StageName": "Prod"
                }
            ]
        }
    },
    "ApiGatewayApi": {
        "Type": "AWS::Serverless::Api",
        "Properties": {
            "StageName": "Prod",
            "Auth": {
                "ApiKeyRequired": "true"
            }
        }
    }
  },
  "Outputs": {
    "ApiURL": {
      "Description": "API endpoint URL for Prod environment",
      "Value": {
        "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
      }
    }
  }
}
mpalmer78
  • 370
  • 3
  • 15

2 Answers2

0

ApiId is a string, not an object.

You can fix by just putting "ApiGatewayApi" there

{
"ApiId": "ApiGatewayApi"
}

Ref: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-usageplan-apistage.html#cfn-apigateway-usageplan-apistage-apiid

duyvh
  • 419
  • 3
  • 5
  • Thanks, but that doesn't seem to work either. I do see it's supposed to be a string but the Ref function returns a string representing the Id of another resource. – mpalmer78 Jun 07 '21 at 20:39
0

You are referring an AWS::Serverless::Api resource for your ApiId and the template is expecting a AWS::ApiGateway::RestApi resource. That's reason behind that error.

The error disappears once you update the type of your ApiGatewayApi

"ApiGatewayApi": {
    "Type": "AWS::ApiGateway::RestApi",
    "Properties": {
        "Body": {
            "OpenAPI specification": null
        },
        "Description": "A test API",
        "Name": "MyRestAPI"
    }
}

Updated template

Prayag Sagar
  • 651
  • 1
  • 8
  • 21
  • Thanks, Prayag. Yes, that makes the error go away, but now the template won't publish. I get this error message `"Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [SendEmailFunction] is invalid. Event with id [RootResource] is invalid. RestApiId property of Api event must reference a valid resource in the same template. Failed to publish AWS Serverless application"` – mpalmer78 Jun 07 '21 at 21:03