Remote Debugging

sam deploy

Now that you've debugged your function locally, it's time to deploy it to the cloud and test it there. Copy and paste the following into a terminal window:

sam deploy

If you saved the configuration file after the previous guided deployment (the default), you should not need to enter any additional information.

Terminal window showing sam deploy run for a second time

sam deploy (second run)

Note the HelloWorldAPI URL output provided on completion; it should not have changed from your previous deployment.

You can also get the API URL by pasting the following command into a terminal window:

aws cloudformation describe-stacks \
  --stack-name sam-app \
  --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldAPI`].OutputValue' \
  --region eu-central-1

Be sure to change the value of the --stack-name parameter if you did not name your app sam-app.

Terminal window showing outputs from aws cloudformation describe-stacks

aws cloudformation describe-stacks output

Remote test

Send another HTTP POST request to your API endpoint. For example, using httpie:

http post <endpoint> body="GoDays Berlin"

This time you should receive an HTTP 502 error. Your function worked locally; how can you determine what went wrong?

Terminal window showing an http call returning a 502 error

502 error

CloudWatch Logs

Amazon CloudWatch is a monitoring and observability service that provides you with data and actionable insights to monitor your applications. CloudWatch collects monitoring and operational data in the form of logs, metrics, and events, including logs from your Lambda functions.

Lambda automatically integrates with CloudWatch Logs and pushes all logs from your code to a CloudWatch Logs group associated with a Lambda function, which is named /aws/lambda/<function name>. Lambda writes two types of data: metrics and billing data, and application logging data. Any information that your function writes to stdout is recorded in CloudWatch logs, as are function duration and error data.

Open the CloudWatch Logs Console in your browser and choose the log group associated with your function.

Screen capture of Amazon CloudWatch Logs console showing log groups

CloudWatch Logs Groups

Expand the AccessDeniedException line. CloudWatch tells you that your Lambda function is not authorized to perform: dynamodb:PutItem on your DynamoDB table.

Screen capture of Amazon CloudWatch Logs console showing AccessDeniedException detail

AccessDeniedException

Previously you did not specify an IAM Policy or Role for your SAM app or the Lambda functions in it. In this case, SAM creates a default IAM Role for your function that allows it to write to CloudWatch Logs and [AWS X-ray]. In order for your function to write to your DynamoDB table, you must explicitly grant it permission.

Best practice with IAM is to grant only the exact permissions needed. In this case, your function needs to be able to call dynamodb.PutItem only on your votes DynamoDB table. Copy and paste the following text into your template.yaml file underneath your HelloWorldFunction:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Policies:
        - AWSXrayWriteOnlyAccess
        - Statement:
          - Action: 
            - dynamodb:PutItem
            Effect: Allow
            Resource: !GetAtt VoteTable.Arn
          Version: '2012-10-17'

Run sam deploy again. Once complete, you can again post to your API endpoint, and this time you should receive an empty message with HTTP Status Code 200.

Terminal window showing the results of HTTP POST after deploying a new IAM policy

HTTP POST results

You can confirm that everything worked successfully by going to the votes table in the DynamoDB console and choosing Items.

Screen capture of votes table in the DynamoDB console

Votes table items