Code and walkthrough labs to set up a serverless web application for the Wild Rydes Workshop
HTML JavaScript
Latest commit d0dddcb Jan 31, 2017 @jpignata jpignata committed on GitHub Merge pull request #3 from awslabs/jp/updates-from-sfloft-feedback
Address SF Loft Feedback

README.md

Wild Rydes Serverless Web Application Workshop

Introduction

Wild Rydes

Wild Rydes needs your help! With fresh funding from its seed investors, Wild Rydes is seeking to build the world’s greatest mobile/VR/AR unicorn transportation system. The scrappy startup needs a first-class webpage to begin marketing to new users and to begin its plans for global domination. Join us to help Wild Rydes build a website using a serverless architecture.

Overview of Workshop Labs

The Wild Rydes Serverless Web Application Workshop introduces the basics of building serverless web applications using Amazon Simple Storage Service (S3), AWS Lambda, Amazon API Gateway, Amazon DynamoDB, Amazon Cognito, Amazon Simple Email Service (SES), Amazon CloudFront, and other AWS services. In this workshop, you are an early founding employee of Wild Rydes who is tasked with building out the company’s marketing website and other initiatives using a serverless architecture and AWS.

Requirements

You'll be configuring serverless solutions in your own AWS account. All of the services required for this lab are covered under the AWS Free Tier for accounts that were created within the past 12 months. Accounts that have been created within the last 24 hours might not yet have access to servers required for this workshop.

To complete this lab, you'll need:

Labs

Pre-lab: Static Website Hosting

In this module, you'll verify your local environment is setup, create an Amazon S3 bucket to host your assets, and configure it to serve a static website. Because Wild Rydes is a startup preparing for global scale you'll also configure an Amazon CloudFront distribution to accelerate delivery of your assets to your potential users across the world.

Lab 1: Beta Sign-up Mailing List

Visitors to your website who are interested in participating in your beta program can enroll by filling out a form to join your beta users mailing list. You'll create an Amazon DynamoDB table to store these email addresses and an Amazon Cognito identity pool and an AWS Identity and Access Management (IAM) policy to allow unauthenticated users to post it. Using DynamoDB Streams, AWS Lambda, and Amazon SES, beta users will receive a confirmation email thanking them for enrolling and providing further details.

Lab 2: Administrative Interface

Your marketing team needs an administrative interface to manage aspects of the site. In this module, you'll create an Amazon Cognito user pool for your administrator users and start building endpoints in Amazon API Gateway. You'll configure an authorizer to validate the identity of your administrators and wire up a page to view users who have signed up for the beta program.

Lab 3: Product Update Blog

To keep your visitors up to date on your progress building your product, your marketing team would like to publish a blog of product updates. Using your new administrative interface, you'll add an interface to publish posts to the product update blog using Amazon API Gateway and AWS Lambda which will appear on your landing page.

Tips

  • Open a blank text editor file for scratch notes. Whenever a step instructs you to note an item, copy and paste that item into your scratch notes for later reference.

  • Look for error messages in the Google Chrome Developer Console if you encounter an issue with any of the functionality loading on the site. You can access the console by pressing Control + Shift + J on Linux and Windows or Command + Option + J on macOS.

  • There are several components of the setup which are case sensitive (e.g. DynamoDB tables and keys). To avoid errors, prefer copying and pasting to re-typing.

Pre-lab: Static Website Hosting

In this module, you'll setup an Amazon S3 bucket to host your assets and configure it to serve a static website. Because Wild Rydes is a startup preparing for global scale you'll also configure an Amazon CloudFront distribution to accelerate delivery of your assets to your potential users across the world.

  1. If you do not have a personal AWS account for testing, create one and login to your account.

  2. Pick a single Region into which you'll deploy services. You'll need to ensure all required services (Amazon S3, AWS Lambda, Amazon API Gateway, Amazon Cognito, Amazon SES, Amazon DynamoDB, Amazon CloudFront, IAM) are available in the Region you choose. See the Region Table for details about what services are available in which Regions. US East (N. Virginia), US West (Oregon), and EU (Ireland) offer all of the services required for this workshop.

    All of the resources created in the below labs must be created within a single Region.

  3. Ensure you have the following installed:

  4. Clone the lab contents locally.

    git clone https://github.com/awslabs/aws-serverless-website-workshop.git

    This repository contains files required for all four labs and a work directory for you to copy files into as you progress through the workshop.

  5. Ensure your installation of the AWS CLI is properly configured with credentials that have administrator access to your account.

  6. Select S3 from the AWS Management Console.

  7. Click the Create Bucket button.
  8. Enter a name for the bucket in Bucket Name. Bucket names must be globally unique within AWS so prefix the name of the bucket with your last name to prevent collisions. For example, in our examples we'll follow the convention of LAST_NAME-wildrydes so we'll use smith-wildrydes.
  9. Select the Region in which you'll use for this lab in the Region drop down. See the note in the requirements section about which Region to choose. US East (N. Virginia) is called US Standard in Amazon S3 for legacy reasons.
  10. Click the Create button.

    Create Bucket

  11. Expand the Permissions section.

  12. Click the Add bucket policy link.

    Bucket permissions

  13. Create a bucket policy to allow anonymous read access to your bucket. This will make the bucket content publicly readable and allow Amazon S3 to serve it to web users. Ensure that you change the INSERT_BUCKET_NAME_HERE placeholder to the name you chose in Step 3.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": "*",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::INSERT_BUCKET_NAME_HERE/*"
        }
      ]
    }

    Bucket policy

  14. Click the Save button.

  15. Expand the Static Website Hosting section.
  16. Select Enable website hosting.
  17. Enter index.html as the website's Index Document. This will redirect requests to the root of your website to the object index.html.
  18. Note the hostname in Endpoint.

    Website hosting

  19. Click the Save button.

  20. Copy the Wild Rydes static website files from prelab/ to your work directory. The work directory will act as a staging area for our static site while we build it. We'll be incrementally copying files from each lab-specific directory into it and editing them as we progress through the workshop.

    On Linux and macOS:

    cp -R prelab/* work

    On Windows:

    xcopy /E /Y prelab work
  21. Copy the Wild Rydes static website files into your bucket. Replace the INSERT_BUCKET_NAME_HERE placeholder with the bucket you created earlier.

    aws s3 sync work/ s3://INSERT_BUCKET_NAME_HERE
  22. Browse to the hostname that you noted above in Step 13 and ensure that the website loads. Verify that the links work.

    Website

  23. In the AWS Management Console, click Services in the navigation bar and select CloudFront.

  24. Click the Create Distribution button.
  25. To create a web distribution, click the Get Started button under the Web header.
  26. Enter the static hosting endpoint from the Amazon S3 bucket that you noted above in Step 13 and browsed to in Step 17 in Origin Domain Name. Ensure that you enter in the static website hosting endpoint and do not use the autocompleter as that option will configure traffic to use bucket rather than its website endpoint which cannot serve web pages correctly.

    Origin domain name

  27. Select Customize from Object Caching.

  28. Enter 5 as the Default TTL. This will cache objects for 5 seconds before checking for file updates with the origin. In production, this value would be set much higher but we're lowering it to 5 for demonstration purposes during the workshop.

    Customize cache settings

  29. Click the Create Distribution button.

  30. Wait for the Status field to change from In Progress to Deployed. This may take upwards of 30 minutes.

    CloudFront distributions

  31. Once deployed, test your CloudFront distribution by putting the Domain Name of your distribution into a web browser. Click around and verify that the site works as it did in Step 17.

    Website via CloudFront

PRE-LAB COMPLETE

In this lab you've:

  • Configured your local environment for the rest of the labs
  • Created an Amazon S3 bucket
  • Configured it for static web site hosting
  • Created a Amazon CloudFront distribution to deliver your content around the world

Lab 1: Beta Sign-up Mailing List

Visitors to your website who are interested in participating in your beta program can enroll by filling out a form to join your beta users mailing list. You'll create an Amazon DynamoDB table to store these email addresses and an Amazon Cognito identity pool and an AWS Identity and Access Management (IAM) policy to allow unauthenticated users to post it. Using DynamoDB Streams, AWS Lambda, and Amazon SES, beta users will receive a confirmation email thanking them for enrolling and providing further details.

  1. Select SES from the AWS Management Console.
  2. Click Email Addresses in the left hand navigation menu.
  3. Click the Verify a New Email Address button.
  4. Enter an email address where you can receive email in Email Address. By default, Amazon SES operates in sandbox mode which means that you must verify all email addresses used to send and receive email. This is useful for development and demonstration purposes. The email address you enter here must be able to receive emails and we'll also use it as the sender in our workshop.
  5. Click the Verify this Email Address button.
  6. Click the Close button.
  7. Wait for the verification email from Amazon SES to arrive in the inbox of the email address you provided in Step 4.
  8. Open the email and click the verification link.

    Email

    You should see a page with a header Congratulations! indicating that you can now send email from this address.

  9. Click Services in the navigation bar and select IAM.

  10. Click Roles in the left-hand navigation.
  11. Click the Create New Role button.
  12. Enter LambdaSESRole for Role Name.
  13. Click the Next Step button.
  14. Click the Select button next to AWS Lambda.

    Role type

  15. Attach the AmazonSESFullAccess and AWSLambdaBasicExecutionRole managed policies to the role by searching for them in the Filter text box and clicking the checkbox. These policies contain the permissions that your AWS Lambda function will have within your account and will allow your function to send email via Amazon SES and to send logs to Amazon CloudWatch Logs. Take a moment to look at the AmazonSESFullAccess and AWSLambdaBasicExecutionRole policies to see what permissions you're granting your Lambda function.

  16. Click Next Step.
  17. Verify the Trusted Entities and Policies section against the screenshot and click Create Role.

    Role review

  18. Click Services in the navigation bar and select DynamoDB.

  19. Click the Create table button.
  20. Enter Wildrydes_Emails in Table name. Ensure you type this exactly as displayed as DynamoDB is case sensitive.
  21. Enter Email and select String in Primary key. Ensure you type this exactly as displayed as DynamoDB is case sensitive.
  22. Leave Use default settings checked.

    Create table

  23. Click the Create button.

  24. Scroll down to the bottom of the Table Details section and note the Amazon Resource Name (ARN).

    Table details

  25. Click Services in the navigation bar and select Cognito.

  26. Click the Manage Federated Identities button.
  27. Click the Create new identity pool button.
  28. Enter wildrydes in Identity pool name.
  29. Check Enable access to unauthenticated identities.

    Create pool

  30. Click the Create Pool button.

  31. This page will allow you to define authenticated and unauthenticated roles associated with your identity pool and the appropriate permissions for each. Expand the View Details section. Next, expand the View Policy Document section for the Cognito_wildrydesUnauth_Role role.
  32. Click Edit next to the policy document. You'll be asked to ensure you've read the documentation prior to editing. Click Ok.
  33. Replace the INSERT_DYNAMODB_ARN_HERE placeholder below with the value you noted in Step 24 and copy and paste the result into the policy document text area. When finished, the text area should only contain the below policy.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "dynamodb:PutItem",
          "Resource": "INSERT_DYNAMODB_ARN_HERE"
        }
      ]
    }

    When the policy has been entered correctly, your screen should resemble the below:

    Unauth Policy

  34. Click the Allow button.

  35. Click Edit identity pool in the upper right and note the Identity pool ID.

    Pool details

  36. Copy the Wild Rydes static website files from lab1/ to your work directory.

    On Linux and macOS:

    cp -R lab1/* work

    On Windows:

    xcopy /E /Y lab1 work
  37. In your work directory, open scripts/config.js in your text editor.

  38. Enter the Region in which you've created the Cognito Identity Pool in Step 30 into the region attribute. This value will be the first half of the Identity Pool ID up to the colon you noted in Step 35.

    For example:

    var Wildrydes = {
      config: {
        region: 'us-east-1',
        identityPoolId: '',
        userPoolId: '',
        userPoolClientId: '',
        apiUrl: '',
      }
    }
  39. Enter the Identity Pool ID you noted in Step 35 into the identityPoolId attribute.

    For example:

    var Wildrydes = {
      config: {
        region: 'us-east-1',
        identityPoolId: 'us-east-1:ffffffff-ffff-ffff-ffff-ffffffffffff',
        userPoolId: '',
        userPoolClientId: '',
        apiUrl: '',
      }
    }
  40. Save the file.

  41. Update the contents of the Amazon S3 bucket created the pre-lab with the new files:

    aws s3 sync work/ s3://INSERT_BUCKET_NAME_HERE
  42. Navigate to the URL of the Amazon CloudFront distribution created in Lab 1.

  43. Scroll down to the Sign Up form and enter the email address you verified in Step 4 into the form and click Submit. The form will be replaced with a confirmation message.

    Confirmation

    If something went wrong you will receive an error as a JavaScript alert. Open your developer console (see Tips section for insturctions) for more information.

    Common errors are:

    • ResourceNotFoundException: Missing credentials in config

      Your config.js does not map to a valid Cognito identity pool. Ensure that you've entered the identityPoolId correctly by checking your work in steps 37 through 40.

    • ResourceNotFoundException: Requested resource not found

      The DynamoDB could not be found. Check your DynamoDB table name and confirm it is named Wildrydes_Emails as directed in step 20. If not, recreate the table.

    • ValidationException: One or more parameter values were invalid: Missing the key [column] in the item

      The DynamoDB table was found but the primary key wasn't correctly entered. Check your DynamoDB table settings and confirm the primary key is named Email as directed in step 21. If not, recreate the table.

    • AccessDeniedException: User: arn:aws:sts::123456789012:assumed-role/Cognito_wildrydesUnauth_Role/CognitoIdentityCredentials is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-west-2:123456789012:table/Wildrydes_Emails

      The policy associated with your unauthenticated Cognito role has not been created correctly. Go to IAM, click on Roles, find and click on Cognito_wildrydesUnauth_Role, and click on Edit Policy. Ensure the policy you have matches the policy outlined in step 33 exactly.

  44. Click Services in the navigation bar of the AWS Management Console and select DynamoDB.

  45. Click Tables in the left-hand navigation.
  46. Click Wildrydes_Emails.
  47. Select the Items tab and ensure that the email address you submitted has been written to the table.

    Items

  48. Select the Triggers tab.

  49. Click the Create trigger button and select New function.
  50. Select Wildrydes_Emails from DynamoDB table.
  51. Enter 1 for Batch Size.
  52. Select Latest from Starting position. This will instruct AWS Lambda to start processing records from the end of the stream.
  53. Check the Enable trigger checkbox.

    Configure trigger

  54. Click the Next button.

  55. Enter ConfirmationEmail in Name.
  56. Select Node.js 4.3 from Runtime.
  57. Use the code below for the Lambda function code.

    var AWS = require('aws-sdk');
    var ses = new AWS.SES({apiVersion: '2010-12-01'});
    
    exports.handler = (event, context, callback) => {
      event.Records.forEach((record) => {
        var params = {
          Source: process.env.EMAIL_ADDRESS,
          Destination: {
            ToAddresses: [record.dynamodb.NewImage.Email.S]
          },
          Message: {
            Body: {
              Html: {
                Data: '<html><h1>Thank you!</h1><p>Wild Rydes is coming soon! Stay tuned for more info about unicorns near you!</p></html>'
              },
              Text: {
                Data: 'Wild Rydes is coming soon! Stay tuned for more info about unicorns near you!'
              }
            },
            Subject: {
              Data: 'Wild Rydes Limited Private Beta Confirmation'
            }
          }
        };
    
        ses.sendEmail(params, (err, data) => {
          if (err) context.fail(err);
          else     context.succeed(null);
        });
      });
    };
  58. Add an environment variable for the email address from which to send the confirmation email. Enter EMAIL_ADDRESS as the Key and the email address you defined in Amazon SES in Step 4 as the Value.

    Environment variables

  59. Select Choose an existing role from Role.

  60. Select LambdaSESRole from Existing role.
  61. Click the Next button.
  62. Click the Create Function button.
  63. Open your web browser and open the landing page of the Wild Rydes marketing site using the CloudFront URL you created in Lab 1.
  64. Submit a sub-address of the email address you verified in Step 4. For example, if you're using gmail, you can append a plus sign with a random label to your email to write new records to the table that will be delivered to your address. For example, example+1@gmail.com will be delivered to example@gmail.com.
  65. Wait for the function to begin processing records which could take a few moments. Check the triggers tab in your Lambda function and wait for Last result to change to OK. You can also check the function's logs and metrics in the monitoring tab.

    Monitor trigger

  66. Open your email inbox and verify you receive confirmation messages when you fill out and submit the form.

    Email

LAB 1 COMPLETE

In this lab you've:

  • Validated an email address within Amazon SES from which marketing emails are delivered.
  • Created an Amazon DynamoDB table to capture the email address of visitors to your site.
  • Configured an Amazon Cognito identity pool that allows anonymous users to post to an Amazon DynamoDB table.
  • Added a trigger to the Amazon DynamoDB table to email users who sign up for your beta program.

Lab 2: Administrative Interface

Your marketing team needs an administrative interface to manage aspects of the site. In this module, you'll create an Amazon Cognito user pool for your administrator users and start building endpoints in Amazon API Gateway. You'll configure an authorizer to validate the identity of your administrators and wire up a page to view users who have signed up for the beta program.

  1. Select Cognito from the AWS Management Console.
  2. Click the Manage your User Pools button.
  3. Click the Create a User Pool button.
  4. Enter Wildrydes_Admin in Pool name.
  5. Click the Review Defaults link.
  6. Click the pen icon in the box that contains the Required attributes attribute.
  7. Deselect email.
  8. Click the Save changes button.
  9. Click the pen icon in the box that contains the User sign ups allowed? attribute.
  10. Select Only allow administrators to create users from Do you want to allow users to sign themselves up?
  11. Click the Save changes button.
  12. Click the pen icon in the box that contains the Verifications attribute.
  13. Deselect Email from Do you want to require verification of emails or phone numbers?
  14. Click the Save changes button.
  15. Click the Add client... link in the box that contains Apps.
  16. Click the Add an app link.
  17. Enter web as the App name.
  18. Deselect Generate client secret.
  19. Click the Create app button.
  20. Click the Save changes button.
  21. Click the Create pool button.
  22. Note the Pool Id in the Pool details section.

    Pool details

  23. Click Apps on the left hand navigation menu.

  24. Note the App client id.

    App details

  25. Click Users on the left-hand navigation.

  26. Click the Create user button.
  27. Enter your email address in Username (required).
  28. Enter a password into Temporary password. Create and note a password that meets the default password policy requirements of at least eight characters containing at least one upper case letter, number, and symbol.
  29. Deselect Send an invitation to this new user?, Mark phone number as verified?, Mark email as verified?.

    Create user

  30. Click the Create user button.

  31. Click the AWS logo in the navigation bar and click on IAM.
  32. Click Roles in the left-hand navigation.
  33. Click the Create New Role button.
  34. Enter LambdaDynamoDBRole for Role Name.
  35. Click the Next Step button.
  36. Click the Select button next to AWS Lambda.
  37. Attach the AmazonDynamoDBFullAccess and AWSLambdaBasicExecutionRole managed policies to the role by searching for them in the Filter text box and clicking the checkbox.
  38. Click Next Step.
  39. Click Create Role.
  40. Click Services in the navigation bar and select Lambda.
  41. Click the Create a Lambda function button.
  42. Click Blank Function to start with an empty blueprint.
  43. Skip configuring triggers by clicking on the Next button.
  44. Enter GetAllEmails as the Name of the Lambda function.
  45. Select Node.js 4.3 as Runtime.
  46. Use the code below for the Lambda function code.

    var aws = require('aws-sdk');
    var dynamodb = new aws.DynamoDB({});
    
    exports.handler = (event, context, callback) => {
     var params = {
       TableName: "Wildrydes_Emails"
     };
    
     dynamodb.scan(params, function(err, data) {
       if (!err) {
         var emails = [];
         data.Items.forEach((item) => emails.push(item.Email.S));
    
         context.succeed({
           statusCode: '200',
           headers: { 'Access-Control-Allow-Origin': '*'},
           body: JSON.stringify({ Emails: emails })
         });
       } else {
         context.fail(err);
       }
     });  
    };
  47. Select Choose an existing role from Role.

  48. Select LambdaDynamoDBRole from Existing role.

    Select role

  49. Click the Next button.

  50. Click the Create Function button.
  51. Click Services in the navigation bar and select API Gateway.
  52. Click the Get Started button to create a new API.
  53. Select New API.
  54. Enter Wildrydes as the API name.
  55. Click the Create API button. This will default to an example API. Click on the OK button to dismiss the modal.
  56. Click the Authorizers link in the left hand navigation menu.
  57. Click the Create button with the drop-down list and click Cognito User Pool Authorizer.
  58. Select the Region you're using from Cognito Region.
  59. Select Wildrydes_Admin from the Cognito user pool drop-down list.
  60. Leave Wildrydes_Admin in Authorizer name.
  61. Leave method.request.header.Authorization in Identity token source.

    Authorizer

  62. Click the Create button.

  63. Click the Resources link in the left-hand navigation.
  64. Click on the Actions button.
  65. Click on the Create Resource link.
  66. Enter emails as Resource Name.
  67. Select Enable API Gateway CORS.
  68. Click the Create Resource button.
  69. Click the Actions button.
  70. Click the Create Method link.
  71. Select GET from the drop down and click the check mark.
  72. Check Use Lambda Proxy integration.
  73. Select the Region you're using from Lambda Region.
  74. Enter GetAllEmails as Lambda Function.

    Create method

  75. Click the Save button. You will be prompted to give permission to API Gateway to invoke your Lambda function. Click the OK button.

  76. Click Method Request.
  77. Click the pen icon in Authorization.
  78. Select Wildrydes_Admin under Cognito user pool authorizers and click the check mark.
  79. Click the Actions button.
  80. Click Deploy API link.
  81. Select [New Stage] from Deployment stage.
  82. Enter prod as the Stage name.
  83. Click on the Deploy button.
  84. Note the Invoke URL of your new API.

    Invoke URL

  85. Copy the Wild Rydes static website files from lab2/ into your work directory.

    On Linux and macOS:

    cp -R lab2/* work

    On Windows:

    xcopy /E /Y lab2 work
  86. In your work directory, open scripts/config.js in your text editor.

  87. Enter the User Pool ID from the user pool you noted in Step 22 as the userPoolId attribute.

    For example:

    var Wildrydes = {
      config: {
        region: 'us-east-1',
        identityPoolId: 'us-east-1:ffffffff-ffff-ffff-ffff-ffffffffffff',
        userPoolId: 'us-east-1_0Vt8rntSI',
        userPoolClientId: '',
        apiUrl: '',
      }
    }
  88. Enter the Client ID from the web app you added to the user pool you noted in Step 24 as the userPoolClientId attribute.

    For example:

    var Wildrydes = {
      config: {
        region: 'us-east-1',
        identityPoolId: 'us-east-1:ffffffff-ffff-ffff-ffff-ffffffffffff',
        userPoolId: 'us-east-1_0Vt8rntSI',
        userPoolClientId: 'jc2f4p2ft4r7mmbeg9s3c8vtq',
        apiUrl: '',
      }
    }
  89. Enter the Invoke URL from the API you noted in Step 84 as the apiUrl attribute.

    For example:

    var Wildrydes = {
      config: {
        region: 'us-east-1',
        identityPoolId: 'us-east-1:ffffffff-ffff-ffff-ffff-ffffffffffff',
        userPoolId: 'us-east-1_0Vt8rntSI',
        userPoolClientId: 'jc2f4p2ft4r7mmbeg9s3c8vtq',
        apiUrl: 'https://aaaaaaaaaaaa.execute-api.us-east-1.amazonaws.com/prod',
      }
    }
  90. Update the contents of the Amazon S3 bucket created in the pre-lab with the new files:

    aws s3 sync work/ s3://INSERT_BUCKET_NAME_HERE
  91. Open your web browser and open the admin page of the Wild Rydes marketing site using the CloudFront URL you created in Lab 1 and append /admin to it.

    Admin

  92. Log into the admin site using the credentials you created in Step 30.

  93. Click on the View Emails link.
  94. Verify that you see a full list of emails that have been submitted to the site. Submit other email addresses and reload this page to ensure they are also returned.

LAB 2 COMPLETE

In this lab you've:

  • Created an Amazon Cognito user pool to manage identities for your administrator users.
  • Created an Amazon DynamoDB function to return email addresses through a Amazon API Gateway proxy to an AWS Lambda method.
  • Added an API for our site and added an emails resource with a GET method only accessible to authenticated administrator users.

Lab 3: Product Update Blog

To keep your visitors up to date on your progress building your product, your marketing team would like to publish a blog of product updates. Using your new administrative interface, you'll add an interface to publish posts to the product update blog using API Gateway and Lambda which will appear on your landing page.

  1. Select DynamoDB from the AWS Management Console.
  2. Click the Create table button.
  3. Enter Wildrydes_Posts in Table name. Ensure that you type this exactly as displayed because Amazon DynamoDB is case sensitive.
  4. Enter Blog and select String in Primary key. Ensure that you type this exactly as displayed because Amazon DynamoDB is case sensitive.
  5. Check Add sort key.
  6. Enter Timestamp and select Number in the Sort key field that appears under the check box. Ensure that you type this exactly as displayed because Amazon DynamoDB is case sensitive.
  7. Leave Use default settings checked.

    Create table

  8. Click the Create button.

  9. Click Services in the navigation bar and select Lambda.
  10. Click the Create a Lambda function button.
  11. Select the Blank Function blueprint.
  12. Skip configuring triggers by clicking the Next button.
  13. Enter CreatePost as the Name of the Lambda function.
  14. Select Node.js 4.3 as Runtime.
  15. Use the code below for the Lambda function code.

    var aws = require('aws-sdk');
    var dynamodb = new aws.DynamoDB({});
    
    exports.handler = (event, context, callback) => {
     var body = JSON.parse(event.body);
     var params = {
       TableName: 'Wildrydes_Posts',
       Item: {
         Blog: { S: 'product-updates' },
         Timestamp: { N: body.Timestamp },
         Title: { S: body.Title },
         Body: { S: body.Body }
       }
     };
    
     dynamodb.putItem(params, (err, data) => {
       if (!err) {
          context.succeed({
           statusCode: '200',
           headers: { 'Access-Control-Allow-Origin': '*'},
           body: JSON.stringify({})
          });
       } else {
          context.fail(err);
       }
     });
    };
  16. Select Choose an existing role from Role.

  17. Select LambdaDynamoDBRole from Existing role.
  18. Click the Next button.
  19. Click the Create Function button.
  20. Click Dashboard in the left-hand navigation and click the Create a Lambda Function button.
  21. Select the Blank Function blueprint.
  22. Skip configuring triggers by clicking on the Next button.
  23. Enter GetAllPosts as the Name of the Lambda function.
  24. Select Node.js 4.3 as Runtime.
  25. Use the code below for the Lambda function code.

    var aws = require('aws-sdk');
    var dynamodb = new aws.DynamoDB({});
    
    exports.handler = (event, context, callback) => {
     var params = {
       TableName: 'Wildrydes_Posts',
       ScanIndexForward: false,
       KeyConditions: {
            Blog: {
                ComparisonOperator: 'EQ',
                AttributeValueList: [ { S: 'product-updates' } ],
            }
       }
     };
    
     dynamodb.query(params,(err, data) => {
       if (!err) {
         var posts = [];
    
         data.Items.forEach((item) => {
           posts.push({
             Timestamp: item.Timestamp.N,
             Title: item.Title.S,
             Body: item.Body.S
           })             
         });
    
         context.succeed({
           statusCode: '200',
           headers: { 'Access-Control-Allow-Origin': '*'},
           body: JSON.stringify({ Posts: posts })
         });
       } else {
         context.fail(err);
       }
     });  
    };
  26. Select Choose an existing role from Role.

  27. Select LambdaDynamoDBRole from Existing role.
  28. Click the Next button.
  29. Click the Create Function button.
  30. Click Services in the navigation bar and select API Gateway.
  31. Click the Wildrydes API.
  32. Click the Actions button.
  33. Click the Create Resource link.
  34. Enter posts as Resource Name.
  35. Select Enable API Gateway CORS.

    Create resource

  36. Click the Create Resource button.

  37. Click the Actions button.
  38. Click the Create Method link.
  39. Select POST from the drop-down list and click the check mark.
  40. Check Use Lambda Proxy integration.
  41. Select the Region you're using from Lambda Region.
  42. Enter CreatePost as Lambda Function.

    Create POST method

  43. Click the Save button. You will be prompted to give permission to API Gateway to invoke your Lambda function. Click the OK button.

  44. Click Method Request.
  45. Click the pen icon in Authorization.
  46. Select Wildrydes_Admin under Cognito user pool authorizers and click the check mark.

    Authorization

  47. Click the Actions button.

  48. Click the Create Method link.
  49. Select GET from the drop-down list and click the check mark.
  50. Check Use Lambda Proxy integration.
  51. Select the Region you're using from Lambda Region.
  52. Enter GetAllPosts as Lambda Function.
  53. Click the Save button. You will be prompted to give permission to API Gateway to invoke your Lambda function. Click the OK button.
  54. Click the Actions button.
  55. Click Deploy API link.
  56. Select prod from the Deployment stage drop-down list.
  57. Click the Deploy button.
  58. Copy the Wild Rydes static website files from lab3/ into your work directory.

    On Linux and macOS:

    cp -R lab3/* work

    On Windows:

    xcopy /E /Y lab3 work
  59. Update the contents of the Amazon S3 bucket created in the pre-lab with the new files:

    aws s3 sync work/ s3://INSERT_BUCKET_NAME_HERE
  60. Go to the admin section of the web site, log in if prompted, and click New Post.

  61. Add a new post by filling out Title and Body and click Post.

    New post

  62. Verify that you're redirected to the blog page and that you see the post you just created.

    Post

LAB 3 COMPLETE

In this lab you've:

  • Created an Amazon DynamoDB table for blog posts.
  • Added pages and endpoints in Amazon API Gateway to show blog posts to visitors and to allow administrator users to create blog posts.