Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cloudformation Link API Key to API Gateway

I have the following Cloudformation template I am trying to deploy via SAM. This template correctly creates the DynamoDB table, an API Key, a Lambda function and the API Gateway, but I cannot figure out what I need to specify in the template to associate the API KEY with the API Gateway.

I have found plenty of snippets showing partial examples, but I am struggling to piece it all together.

Thank you in advance,

Denny

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
  TableName:
    Type: String
    Default: 'influencetabletest'
    Description: (Required) The name of the new DynamoDB table Minimum 3   characters
    MinLength: 3
    MaxLength: 50
    AllowedPattern: ^[A-Za-z-]+$
    ConstraintDescription: 'Required parameter. Must be characters only. No numbers allowed.'
  CorsOrigin:
    Type: String
    Default: '*'
    Description: (Optional) Cross-origin resource sharing (CORS) Origin. You can specify a single origin, all "*" or leave empty and no CORS will be applied.
    MaxLength: 250
Conditions:
  IsCorsDefined: !Not [!Equals [!Ref CorsOrigin, '']]
Resources:
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn:
      - ApiGetter
    Properties:
      Name: "TestApiKey"
      Description: "CloudFormation API Key V1"
      Enabled: "true"
  ApiGetter:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prd
      DefinitionBody:
        swagger: 2.0
        info:
          title:
            Ref: AWS::StackName
        paths:
          /getdynamicprice:
            post:
              responses: {}
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaGetter.Arn}/invocations
  LambdaGetter:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./index.js
      Handler: index.handler
      Runtime: nodejs8.10
      Environment:
        Variables:
          TABLE_NAME: !Ref TableName
          IS_CORS: IsCorsDefined
          CORS_ORIGIN: !Ref CorsOrigin
          PRIMARY_KEY: !Sub ${TableName}Id
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref TableName
      Events:
        Api:
          Type: Api
          Properties:
            Path: /getdynamicprice
            Method: POST
            RestApiId: !Ref ApiGetter
  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Ref TableName
      AttributeDefinitions:
        -
          AttributeName: !Sub "${TableName}Id"
          AttributeType: "S"
      KeySchema:
        -
          AttributeName: !Sub "${TableName}Id"
          KeyType: "HASH"
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES
Outputs:
  ApiKeyID:
    Value: !Ref ApiKey
  ApiUrl:
    Value: !Sub https://${ApiGetter}.execute-api.${AWS::Region}.amazonaws.com/prod/getdynamicprice
    Description: The URL of the API Gateway you invoke to get your dynamic pricing result.
  DynamoDBTableArn:
    Value: !GetAtt DynamoDBTable.Arn
    Description: The ARN of your DynamoDB Table
  DynamoDBTableStreamArn:
    Value: !GetAtt DynamoDBTable.StreamArn
    Description: The ARN of your DynamoDB Table Stream
like image 795
Denny Avatar asked Aug 07 '18 23:08

Denny


People also ask

What is API key in AWS API gateway?

API keys are alphanumeric string values that you distribute to application developer customers to grant access to your API. You can use API keys together with Lambda authorizers, IAM roles, or Amazon Cognito to control access to your APIs.


1 Answers

Edit (04/22/2020): there now seems to do all this using AWS SAM. Please see answer below

Here's a sample template where I have connected my API to a API key. But that's only been possible because I am using usage plans. I believe that is the primary purpose of an API key. API gateway usage plan

ApiKey: 
  Type: AWS::ApiGateway::ApiKey
  Properties: 
    Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
    Description: "CloudFormation API Key V1"
    Enabled: true
    GenerateDistinctId: false
ApiUsagePlan:
  Type: "AWS::ApiGateway::UsagePlan"
  Properties:
    ApiStages: 
    - ApiId: !Ref <API resource name>
      Stage: !Ref <stage resource name>     
    Description: !Join [" ", [{"Ref": "AWS::StackName"}, "usage plan"]]
    Quota:
      Limit: 2000
      Period: MONTH
    Throttle:
      BurstLimit: 10
      RateLimit: 10
    UsagePlanName: !Join ["", [{"Ref": "AWS::StackName"}, "-usage-plan"]]
ApiUsagePlanKey:
  Type: "AWS::ApiGateway::UsagePlanKey"
  Properties:
    KeyId: !Ref <API key>
    KeyType: API_KEY
    UsagePlanId: !Ref ApiUsagePlan

There does not seem to be a way to do this without a usage plan.

like image 70
asr9 Avatar answered Sep 29 '22 13:09

asr9