首页 > 解决方案 > 如何从 SAM 模板中的 Lambda 访问 DynamoDB 表?

问题描述

我一直在一个网站上工作,该网站显示我的简历,并且在使用 AWS 服务时也有访问者数量。我已经获得了一种“硬编码”方式,但如果我想改变一些东西,现在希望能够一次性部署 API 网关、Lambda 代码和 DynamoDB。SAM CLI 模板似乎非常适合它。我已经从互联网上和我自己的代码中搜集了一些代码,但它还没有完全组合在一起。lambda 函数由 APIGateway 触发,然后将访问 DynamoDB 中的访问者计数,将其加 1,然后将其发送到网站,然后将新数字存储在 DynamoDB 中。

我意识到我的旧 Lambda 函数将无法工作,因为 DynamoDB 名称将随 SAM 模板而改变。有没有办法使用全局变量并将其实现到我的 Lambda 函数中?我还意识到我创建了一个额外的列来将计数存储在我当前的名为“visits”的 dynamoDB 表中,并且不确定如何在 SAM 模板中添加一个列?

模板.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)

标签: amazon-web-servicesaws-lambdaamazon-dynamodbaws-sam-cli

解决方案


您是否检查过 lambda 函数是否可以访问 DynamoDB?

这是一篇有趣的文章如何分配权限。它可以手动完成,也可以在 SAM 模板中完成:

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

SAM 模板中的语法:

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

推荐阅读