12

Instead of

  • (A) following a more traditional route for running a web application on AWS (e.g., using Ruby/Sinatra or Python/Flask on AWS EC2 or Beanstalk), or

  • (C) creating static HTML and JavaScript files in S3 and dynamic API endpoints in AWS Lambda (sending JSON data to those static web pages that use/interpret that data via JavaScript),

I want to reach a middle ground:

  • (B) create HTTP endpoints in AWS Lambda (e.g., in Python) that read and use HTML templates for generating complete HTML responses to the client.

That setup will result in a serverless web application where the AWS Lambda functions deliver server-side (the irony is not lost on me) generated HTML output.

In Python code for AWS Lambda functions, it is possible to include HTML code snippets, modify that (populate with data) in the function, and return the HTML as text/html output to the client. The drawback of that approach is that the HTML template is then 'embedded' in the Python code, and not external in a separate file.

Q1: How can I refer to a HTML template file somewhere in the code package - the template should be part of the package - have that read by the Python function, and generate the HMTL page by variable substitution in the template?

Q2: How can I specify / include / link to a set of HTML template files in my project using AWS Serverless Application Model (AWS SAM)?

3
  • 1
    Here is something that might be useful in serving static files (your templates) using serverless AWS lambda. :github.com/activescott/serverless-aws-static-file-handler I had always wanted to try this out, but didn't get a chance. Nonetheless, it is an interesting endeavour! Commented Oct 24, 2018 at 8:45
  • On adding the "python" tag: accepted, but it's not core to the question. Python is just an example language for programming the AWS Lambda functions, and could have been Node.js/JavaScript, Java, Go or C# as well. Commented Oct 26, 2018 at 9:24
  • 2
    In Node.js, I normally use Handlebars to achieve the same result: handlebarsjs.com Commented Oct 26, 2018 at 9:32

1 Answer 1

10
+50

I'm not sure where you are starting from here, so I'll start from the beginning.

  1. Create the YAML Config file referencing the handlers and the Event Resources and put in a deployment folder.

  2. For Templating, use "Mustashe for Python" pystashe.

  3. Create the parameterised HTML Template within your Python project/Virtualenv:

    <html>
    <head>
        <title>Customer: {{name}}</title>
    </head>
    <body>
        <div>
            <h2>Customer Name: {{name}}</h2> 
            <h4>Phone Number: {{phone}}</h4>
        </div>
    </body>
    </html>
    
  4. Create the data object to populate the parameterised template:

    {
      "name": "Tom Thumb",
      "phone": "0123456789"
    }
    
  5. Load the template from the location in the project

    template = file('%s/mypath/template.html'%py_root).read()
    
  6. Render the page from the data object:

    myhtml = pystache.render(template, data)
    
  7. Return the rendered html to the client:

    response = {
        "statusCode": 200,
        "body": myhtml,
        "headers": {
            'Content-Type': 'text/html',
        }
    }
    
  8. Zip the python code, site-packages, and html files and put in the deployment folder.

  9. From the deployment folder, package the SAM Project, which prepares and uploads to S3:

    aws cloudformation package --template-file myservice.yml --output-template-file deploy-myservice.yml --s3-bucket myserverless-deploy
    
  10. From the deployment folder, deploy the SAM Project to AWS:

    aws cloudformation deploy --template-file deploy-myservice.yml --stack-name mycontext-myservice-dev --capabilities CAPABILITY_IAM
    

For the record, I prefer option C, with NodeJS... :)

Sign up to request clarification or add additional context in comments.

8 Comments

That could work, thanks. Following this... how can I arrange that mypath/template.html is part of the package stored in/with the Lambda function handlers? Or is that done automatically when ZIPping the package? Then, does AWS Lambda accept that other non-Python files are part of the deployment, and can those be referenced from the function handler code?
"For the record, I prefer option C, with NodeJS." I've done option (C) a couple of times, writing static HTML files with JavaScript consuming Node.js-powered or AWS Lambda-provided API endpoints. A Node.js applications requires a web server (which is more costly than practically zero for AWS Lambda functions). Creating AWS Lambda API endpoints is fine, but then application logic is in two locations: JavaScript client-side, and AWS Lambda server-side. Approach (B) aims to bring all logic to just 'server-side': AWS Lambda functions, with the additional advantage of a low-cost solution.
The Lambda service unzips the zip file into the Lambda Container, so whatever structure you have in the zip file will be the same as the folder structure in the container. That includes anything, like images, binaries, libraries, etc.
I guess that's the solution then I had in mind for option (B). Thanks! /me accepting your answer
@JochemSchulenklopper Great post - Would this work with Jinja2 templates for python?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.