How to use AWS Lambda in Drupal

25 / Aug / 2021 by Jeet Lal 0 comments

AWS Lambda@Edge allows you to run applications and services without worrying about managing infrastructure. Your application still runs on servers, but all the server management is done by the Cloud provider. You no longer have to provision, scale, and maintain servers to run your applications, databases, and storage systems. AWS globally distributes your web application to run out of dozens of AWS data centers across the regions

AWS Lambda is used to develop serverless architecture based applications and services. The concept of Serverless architecture is “Focus on your application, not the infrastructure”. It means application developers can focus on writing business logic instead of server infrastructure, cost, scaling, and availability.

With AWS Lambda, you can run your code virtually for any type of application or service without managing AWS infrastructure. It can be used to develop microservices and these services can be bound with any application to perform a specific task.

AWS Lambda functions can be uploaded in zip format on container image and the Lambda function automatically allocates memory, execution power, and execute your Lambda functions. The Lambda functions can be executed based on the predefined events. Lambda functions can be executed by more than 200 AWS services, call it directly from your web application or mobile application. AWS Lambda functions can be written in your favorite programming languages such as Python, Node.js, Go, Java, Ruby, and many more. AWS SAM or Docker CLI can be used to build, test and deploy your functions.

Advantage of AWS Lambda

  • No server to manage
  • Lower costs and scalability.
  • Faster development and deployment.
  • Reduced expenses on human resources.
  • Focus on business needs.
  • The simplest way to run your code in the cloud
  • Automatically scales and high availability (HA)
  • Connects and extends cloud services
  • Code can run closer to the end-user, decreasing latency

How it Works

How AWS Lambda function work

Prerequisite to Use AWS Lambda Function in Drupal 8/9

  • AWS Cloud platform
  • The programming language supported by the AWS Lambda functions
  • Event to execute the Lambda functions
  • Drupal 8/9 Application

Use Cases of AWS Lambda Functions in Drupal

  • Clear CloudFront cache.
  • Generate Reports and send over email.
  • Run Scheduler
  • Image processing after upload to AWS S3 Bucket.
  • Push MySql data to the Search engine, Queue, etc.
  • Send bulk emails to customers.
  • Real-time File Processing.
  • Real-time Stream Processing.
  • Data processing.

Clear CloudFront Cache Example

  • Download AWS SDK via composer manager composer require aws/aws-sdk-php
  • Create a module name examples with all required files.
  • Create examples.module file in the root

1. File: modules/custom/examples/examples.module

<?php

/**
* @file
* Contains examples.module file.
*/

use Drupal\Core\Entity\EntityInterface;

/**
* Implements HOOK_node_update().
*/
function examples_node_update(EntityInterface $entity) {
   // Clear cloud front cache.
   $awsLambda = new AwsLambda();
   // Put your logic here to clear cache when the page updated.
   // Do the same in HOOK_node_insert & HOOK_node_delete.
   $awsLambda->clearCache($entity);
}

2. File: modules/custom/examples/src/Service/AwsLambdaService.php

<?php

namespace Drupal\examples\Service;

use Drupal\Core\Url;
use Aws\Lambda\LambdaClient;

/**
* Class AwsLambdaService.
*
* @package Drupal\examples\Service\AwsLambdaService
*/
class AwsLambdaService {

  private $currentUser;

  /**
  * Initialize class variables.
  */
  public function __construct() {
    // Dipendency injection can be used here.
    $this->currentUser = \Drupal::service('current_user');
  }

/**
* Get Entity URL.
*
* @param object $entity
*   Entity object.
*
* @return string
*   Return Entity URL.
*/
private function getEntityUrl($entity) {
  $type = $entity->getEntityTypeId();
  // Universal way.
  if (!$entity->get('path')->isEmpty() && !empty($entity->get('path')->alias)) {
    $url = $entity->get('path')->alias;
  }
  else {
    // If URL alias is empty.
    $url = Url::fromRoute('entity.' . $type . '.canonical', [$type => $entity->id()])->toString();
  }
  return $url;
}

/**
* Clear CloudFront cache wrapper.
*
* @param object $entity
*   Entity object.
*/
public function clearCache($entity) {
  $urlArray = [];
  if ($entity && $entity->bundle()) {
    // Put your logic here to clear the cache of multiple pages.
    $urlArray[] = $this->getEntityUrl($entity);
    return $this->clearCloudFrontCache($urlArray);
  }
}

/**
* Clear cloud front cache of CMS pages.
*
* @param array $urls
*   List of URLS in array.
*
* @return bool
*   Return TRUE on success and FALSE on fail.
*/
public function clearCloudFrontCache(array $urls) {
  try {
    // Reset index value.
    sort($urls);
    // Get current user name and email Id.
    // Pass into Lambda functions to track who cleared the cache.
    $user = $this->currentUser->getDisplayName() . ':' . $this->currentUser->getEmail();
    $client = LambdaClient::factory(
     [
       'version' => 'latest',
       'region' => 'ap-south-1',
     ]
    );
    // Get Lambda functions name from environment variable.
    // Name 'arn:aws:lambda:ap-south-1:532738712:function:clearCache'.
    $lambda = getenv('LAMBDA_CMS_CAHE_CLEAR');
    if ($client && $client->invoke([
      'FunctionName' => 'function:' . $lambda,
      'Payload' => json_encode(['urls' => $urls, 'user' => $user]),
    ])) {
    \Drupal::messenger()->addMessage(t('Cache cleared of <strong>%urls</strong> URL(s).', ['%urls' => implode(', ', $urls)]));
    return TRUE;
   }
  }
  catch (\Exception $e) {
    $this->writeLog('clearCloudFrontCache', $e->getMessage(), $e->getCode(), 'error');
  }
  return FALSE;
}

3. AWS Lambda function written in Python to clear the cache.
File: clear_cache.py

#!/usr/bin/env python3
# encoding: UTF-8

def lambda_handler(event, cont):
  try:
    urls = event.get('urls')
    user = event.get('user')
    message = 'Cloud front cache cleared by %s of following page(s):' % user
    # Put your logic here to clear cache.
 except Exception as e:
    message = "ERROR: CMS Cache Clear - Error occurred: %s" % (str(e))
    print(message)

4. Upload your python code in zip format on AWS and get the Function name as below image

AWS Lambda function configuration

Disadvantage of Lambda Functions (Server Less Architecture)

  • Testing and debugging become more challenging
  • Lambda functions are not built for long-running processes
  • Reduced overall control.
  • Testing locally becomes tricky.

Conclusion

With AWS Lambda, we can minimize Drupal processing, computation & memory. In the above example, clearing the CloudFront cache is done by the AWS Lambda function. Like the above example, we can create more AWS Lambda functions to perform more complex tasks and that can be executed by Invoking Lambda function from Drupal, executing Lambda function by AWS scheduler or AWS services.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *