Saturday, February 10, 2018

AWS Serverless Example

AWS Lambda and Node.js example

Let's build a page that will calculate the square of the number you provide. This is just a simple static HTML page that will make a POST call to AWS' API Gateway that calls a Lambda function that you have created. Data will be passed using JSON format. 
This example will utilize following AWS Features:
  • Lambda
  • API Gateway
  • S3 Bucket
    • Static Website Configuration
    • Bucket Policy
Other Stateless server example:
References:
  • https://nodejs.org/en/
  • https://aws.amazon.com/lambda/
  • https://aws.amazon.com/api-gateway/
  • https://aws.amazon.com/s3/
  • https://jquery.com/

Here are the steps:

  1. Go to AWS Lambda
  2. Create new function
  3. Create as follows:
  4. You can either create a new Role or use existing, but it should be able to at least write to log
  5.  Runtime and Handler should set properly for you. If you want to know more about handler, press info link
  6. Overwrite the "Hello World" sample with the below code:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    exports.handler = (event, context, callback) => {
        const requestBody = JSON.parse(event.body);
        const argument = requestBody.argument;
        const square = argument * argument;
        const answer = `${argument}^2 = ${square}`;
        console.log(answer);
        callback(null, {
            statusCode:201,
            body: JSON.stringify({
                Response: answer,
            }),
            headers: {
                'Access-Control-Allow-Origin': '*',
            },
        });
    };
    
    • Line 1: This is mandatory, see notes from step 5
    • Line 2: reads the input JSON value from website
    • Line 3: extracts "argument" variable 
    • Line 4 - 5: squares the value received from website
    • Line 6: posts this value to Cloudwatch Log
    • Line 7: callback function has two arguments, the first if this function encounters an error and second if it succeeds. 
    • Line 8 - 15: This is the response that will be sent back to website when it succeeds
    • Line 12: This is mandatory, otherwise you will get "no access-control-allow-origin" error
       
  7. Configure AWS API Gateway: go to API Gateway
  8. Create a new API
  9. Create Resource
  10. Fill the form as follows
  11. Create Method
  12. Select POST (be sure to press the check box)
  13. Fill out the form as follows (substitute for your region of choice)
  14. Enable CORS (Accept all defaults and warnings)
  15. Deploy API
  16. Fill out the form as follows
  17. Make note of the Invoke URL
  18. Create config.js file and populate with the above URL
    1
    2
    3
    4
    5
    window._config = {
        api: {
            invokeUrl: 'https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod'
        }
    };
    
  19. Create mycalc.js and populate as follows
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    (function myScopeWrapper($) {
        $(function onDocReady() {
      alert('Welcome');
      $('#enterBtn').click(handleRequestClick);
    
            if (!_config.api.invokeUrl) {
                $('#noApiMessage').show();
            }
        });
    
     function handleRequestClick(){
      var argument = $('#argument').val();
            calc(argument);
     }
     
     function calc(argument_var){
       $.ajax({
                method: 'POST',
                url: _config.api.invokeUrl + '/mycalc',
                headers: {
                
                },
                data: JSON.stringify({
                    argument: argument_var
                }),
                contentType: 'application/json',
                success: completeRequest,
                error: completeRequest
            });
        }
     
        function completeRequest(result) {
            console.log('Response received from API: ', result);
            displayUpdate(result.Response);
        }
    
        function displayUpdate(text) {
            $('#updates').append($('<li>' + text + '</li>'));
        } 
     
    }(jQuery));
    
    • Line 2: onDocReady is mandatory, the page will load this upon start. It prepares actions.
    • Line 11: This will take the argument variable and call the calc function
    • Line 17 - 29: this is the format you should use to pass HTTP content to the API
    • Line 19: this should point to the API name you defined in AWS API Gateway
    • Line 24: these are your JSON formatted list of variables
    • Line 27: this is the action to take on success
    • Line 28: this is the action to take on failure (I know this is lazy; I'm using the same function as success)
  20. Create myCalc.html
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
        <title>My Calc</title>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Serverless web application example">
        <meta name="author" content="">
    
    </head>
    
    <body>
        <div class="info panel panel-default">
      <p>Welcome. Enter a number and press enter to get the square value</p>
            <div class="panel-heading">
       <input id="argument"></input>
       <button id="enterBtn" class="btn btn-primary">Enter</button>
       
            </div>
            <div class="panel-body">
                <ul id="updates">
                    <li>2^2 = 4</li>
                </ul>
            </div>
        </div>
        <script src="js/vendor/jquery-3.1.0.js"></script>
        <script src="js/config.js"></script>
        <script src="js/mycalc.js"></script>
    </body>
    
    </html>
    
    • Line 20 of mycalc.html is called by Line 12 of mycalc.js
    • Line 21 of mycalc.html is called by Line 4 of mycalc.js
    • Line 25 of mycalc.html is updated by Line 38 of mycalc.js
    • Line 30 imports jquery library (mandatory), you can either use the file or one of many CDNs available such as https://developers.google.com/speed/libraries/#jquery
    • Line 31 imports the API Gateway location
    • Line 32 imports the JavaScript used in this page
  21. Import three files from above into your S3 bucket, be sure to drop all the JS files into appropriate sub directories
  22. Configure bucket for Static Website
  23. Edit Bucket Policy
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::BUCKET-NAME/*"
            }
        ]
    }
    
  24. Be aware that anyone can use this API call, so if you want to be cautious about it, you can restrict access to just your IP address:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::BUCKET-NAME/*",
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": "X.X.X.X/32"
                    }
                }
            }
        ]
    }
    
  25. Go to mycalc.html and open the link, it will look like this:
    https://s3.amazonaws.com/[bucket-name]/mycalc.html
  26. You can also go to the Static URL that was defined from step 22:
    http://[bucket-name].s3-website-us-east-1.amazonaws.com/


No comments:

Post a Comment

AWS WAF log4j query

How to query AWS WAF log for log4j attacks 1. Setup your Athena table using this instruction https://docs.aws.amazon.com/athena/latest/ug/wa...