2
votes

I have a problem with AWS SAM and provisioning API Gateway configurations. I am trying to do a few things:

  1. Configure the API gateway to require api-key in the headers
  2. Create my own stage as defined in my config files.
  3. The API gateway model defined in my file is not being created

Currently, the API gateway gets provisioned and linked to my lambda function but it fails in the two requirements above. Below are my files: template.yaml and swagger.yaml.

Template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
    sam-nfeed-s3

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
    Function:
        Timeout: 60
    Api:
      EndpointConfiguration: REGIONAL
Resources:
  SAMnfeedS3API:
    Type: AWS::Serverless::Api
    Properties:
      StageName: alpha
      DefinitionUri: ./swagger.yaml
Resources:
  SAMnfeedS3Lambda:
    Type: AWS::Serverless::Function
    Properties:
        CodeUri: test-function-sam/
        Handler: nfeed_vdp_clusters.lambda_handler
        Runtime: python3.6
        Role: arn:aws:iam::XXXXXXX:role/Lambda
        Events:
            SAMnfeedS3API:
                Type: Api
                Properties:
                    Path: /vdp_clusters
                    Method: GET 
        Environment:
            Variables:
                TEST: test

Outputs:

    SAMnfeedS3API:
      Description: "API Gateway endpoint URL for Staging env"
      Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Staging/vdp_clusters"

    SAMnfeedS3Lambda:
      Description: "Lambda Function ARN"
      Value: !GetAtt SAMnfeedS3Lambda.Arn

Swagger.yaml

---
swagger: '2.0'
info:
  title: !Ref AWS::StackName
basePath: "/alpha"
schemes:
- "https"
x-amazon-apigateway-api-key-source : "HEADER"
paths:
  "/vdp_clusters":
    get:
      consumes:
      - application/json
      produces:
      - application/json
      parameters:
      - name: x-api-key
        in: header
        required: true
        type: string
      responses:
        200:
          description: "200 response"
          schema:
            $ref: "#/definitions/Empty"
      x-amazon-apigateway-integration:
        uri: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:XXXXXXXXX:function:${SAMnfeedS3Lambda.Arn}/invocations
        responses:
          default:
            statusCode: "200"
        httpMethod: "POST"
        type: aws_proxy
      security:
      - api_key: []
securityDefinitions:
  api_key:
    type: "apiKey"
    name: "x-api-key"
    in: "header"
definitions:
  Empty:
    type: "object"
    title: "Empty Schema"
    $schema: "http://json-schema.org/draft-04/schema#"

As defined in my swagger and template files, "alpha" stage should be created for the gateway but nothing appears. The "Empty" model and api-key requirement also do not appear. Any help, would be appreciated.

1
That template is generating syntax errors for me. Are you certain you copied it in here correctly?Alex Harvey
Hey @AlexHarvey, appreciate you trying to help. It’s cause I replaced my accountId with “XXXXX”. Should work if you change it to yours. Also the resource part for the lambda function got shifted let me fix thatJackieMoon

1 Answers

1
votes

The problem is you have duplicated the Resources key in the template.

I recommend always using the yamllint utility on your SAM templates, because it detects YAML formatting issues that sam validate can't always detect. Here is what I got:

▶ yamllint sam-app/template.yaml
sam-app/template.yaml
...
  18:1      error    duplication of key "Resources" in mapping  (key-duplicates)

If you then look in the packaged.yml file that is created by the sam build step, you'll notice that the API you defined will be missing. That's because it's impossible for a dict in Python to contain duplicate keys. The second Resources block you specified just overwrites the first one when the Python YAML library reads the file in.

SAM then generates the implicit API SAMnfeedS3API based on the API you specified in Events using its own generated Swagger rather than the one you (thought you) provided.

Note also that, after you fix up the duplicate key issue, you will also need to reference your API from the Events with a line like:

    Events:
      SAMnfeedS3API:
        Type: Api
        Properties:
          Path: /vdp_clusters
          Method: GET
          RestApiId: !Ref SAMnfeedS3API  ## ADD THIS LINE

See also my earlier answer here.