简体   繁体   中英

How to access DynamoDB table from Lambda in a SAM Template?

I've been working on a website that shows my resume and also has a visitor count on it while using AWS Services. I've gotten a "hard coded" way but now would like to be able to deploy the API Gateway, Lambda code, and DynamoDB all in one go if I want to change things. The SAM CLI template seems to be perfect for it. I've scrounged together some code off the inte.net and from my own but it hasn't quite come together completely still. The lambda function is triggered by an APIGateway and then will access the visitor count in DynamoDB, add 1 to it and then both send it to the website and then store the new number in DynamoDB.

I realized my old Lambda function will not work as the DynamoDB names will change with the SAM Template. Is there a way to use the global variables and implement that into my Lambda function? I'm also realizing I created an additional column to store the count in my current dynamoDB table called 'visits' and am not sure how to add a column in the SAM Template?

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  resume_backend

  Sample SAM Template for resume_backend

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
  Runtime: python3.8 # language used at runtime
  Timeout: 180 # timeout for a given lambda function execution
  Environment:
      Variables: # these will be important later
          DYNAMO_TABLE: !Ref DynamoVisitorTable
          DB_ENDPOINT: http://dynamodb.us-east-1.amazonaws.com
          REGION_NAME: us-east-1


Resources:
  VisitorCountFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: visitorCount/
      Handler: app.lambda_handler
      Policies: AmazonDynamoDBFullAccess # default IAM policy 
      Runtime: python3.8
      Events:
        # Api:
        #   Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
        #   Properties:
        #     Path: /visitorCount
        #     Method: GET
        cors: true
        ApiGatewayApi:
          Type: AWS::Serverless::Api
          Properties:
            StageName: Prod
            Cors:
              AllowMethods: "'POST, GET'"
              AllowHeaders: "'X-Forwarded-For'"
              AllowOrigin: "'www.example.com'"
              MaxAge: "'600'"
              AllowCredentials: True
              Path: /visitorCount
              Method: GET


  DynamoVisitorTable:
    Type: AWS::Serverless::SimpleTable # if you want to define a more complex table, use AWS::DynamoDB::Table
    TableName: websiteVisitorTable
    PrimaryKey:
        Name: webPageCounted
        Type: S
    ProvisionedThroughput:
        ReadCapacityUnit: 5
        WriteCapacityUnits: 5
    Tags:
        AppType: Serverless

lambda_function: app.py

##
##aws SDK for python
import boto3

def lambda_handler(event, context):
    TABLE_NAME="websiteCounter"
    KEYPAIR = {'visitsMain'}
    client = boto3.resource("dynamodb")
    table = client.Table(TABLE_NAME)
    
    response = table.get_item(
        Key={
            "visitsMain":"mainPage",
        }
        )
    item = response['Item']
    table.update_item(
        Key={
            "visitsMain":"mainPage",
        },
        UpdateExpression='SET visits = :val1',
        ExpressionAttributeValues={
            ':val1': item['visits'] + 1
        }
    )
    return (item['visits'] + 1)

Did you check if the lambda function has access to DynamoDB?

Here's is an interesting article how to assig permissions. It can be done either manually or within the SAM template:

Link: https://aws.amazon.com/premiumsupport/knowledge-center/lambda-sam-template-permissions/

Syntax inside the SAM template:

Resources:
  MyFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/function.zip'
      Policies:
      # Give your Lambda full access to DynamoDB
      - AmazonDynamoDBFullAccess

I've been working on a website that shows my resume and also has a visitor count on it while using AWS Services. I've gotten a "hard coded" way but now would like to be able to deploy the API Gateway, Lambda code, and DynamoDB all in one go if I want to change things. The SAM CLI template seems to be perfect for it. I've scrounged together some code off the internet and from my own but it hasn't quite come together completely still. The lambda function is triggered by an APIGateway and then will access the visitor count in DynamoDB, add 1 to it and then both send it to the website and then store the new number in DynamoDB.

I realized my old Lambda function will not work as the DynamoDB names will change with the SAM Template. Is there a way to use the global variables and implement that into my Lambda function? I'm also realizing I created an additional column to store the count in my current dynamoDB table called 'visits' and am not sure how to add a column in the SAM Template?

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  resume_backend

  Sample SAM Template for resume_backend

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
  Runtime: python3.8 # language used at runtime
  Timeout: 180 # timeout for a given lambda function execution
  Environment:
      Variables: # these will be important later
          DYNAMO_TABLE: !Ref DynamoVisitorTable
          DB_ENDPOINT: http://dynamodb.us-east-1.amazonaws.com
          REGION_NAME: us-east-1


Resources:
  VisitorCountFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: visitorCount/
      Handler: app.lambda_handler
      Policies: AmazonDynamoDBFullAccess # default IAM policy 
      Runtime: python3.8
      Events:
        # Api:
        #   Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
        #   Properties:
        #     Path: /visitorCount
        #     Method: GET
        cors: true
        ApiGatewayApi:
          Type: AWS::Serverless::Api
          Properties:
            StageName: Prod
            Cors:
              AllowMethods: "'POST, GET'"
              AllowHeaders: "'X-Forwarded-For'"
              AllowOrigin: "'www.example.com'"
              MaxAge: "'600'"
              AllowCredentials: True
              Path: /visitorCount
              Method: GET


  DynamoVisitorTable:
    Type: AWS::Serverless::SimpleTable # if you want to define a more complex table, use AWS::DynamoDB::Table
    TableName: websiteVisitorTable
    PrimaryKey:
        Name: webPageCounted
        Type: S
    ProvisionedThroughput:
        ReadCapacityUnit: 5
        WriteCapacityUnits: 5
    Tags:
        AppType: Serverless

lambda_function: app.py

##
##aws SDK for python
import boto3

def lambda_handler(event, context):
    TABLE_NAME="websiteCounter"
    KEYPAIR = {'visitsMain'}
    client = boto3.resource("dynamodb")
    table = client.Table(TABLE_NAME)
    
    response = table.get_item(
        Key={
            "visitsMain":"mainPage",
        }
        )
    item = response['Item']
    table.update_item(
        Key={
            "visitsMain":"mainPage",
        },
        UpdateExpression='SET visits = :val1',
        ExpressionAttributeValues={
            ':val1': item['visits'] + 1
        }
    )
    return (item['visits'] + 1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM