AWS Public Sector Blog

Modernize Moodle LMS with AWS serverless containers

Moodle is a popular open source learning management system (LMS). Many education institutions use Moodle to provide an online learning platform for their students to achieve their learning goals with 322 millions of users from 243 countries. Many education institutions adapted to COVID-19 in-person restrictions and shifted from traditional face-to-face learning to online learning. Moodle’s global community, plugins ecosystem, and no-cost model helped with this transition.

Moodle itself is a monolith application developed using PHP with database typically using MySQL or PostgreSQL. By default, Moodle stores its application data within the database and also in the filesystem directory called moodledata. To improve performance, Moodle also supports caching services such as Redis or Memcached.

Figure 1. High-level visualization of the infrastructure components within Moodle.

Figure 1. High-level visualization of the infrastructure components within Moodle.

Many education institutions deploy and run Moodle on a physical hardware or virtual machine (VM) environment. These institutions are looking to improve the scalability of their Moodle application to simplify operations and monitoring, and also optimize operating costs. One way to approach this is to use containers technology. Containers offer a way for developers to package the application code together with its dependencies and configuration. This makes the deployment of the application highly-portable, with the ability to be automated so it can be more reliable and predictable. In this blog post, learn how to deploy and run Moodle using serverless containers technology on Amazon Web Services (AWS).

Why use containers on AWS? The benefits of serverless containers for Moodle

AWS offers Amazon Elastic Container Services (Amazon ECS), a fully managed container orchestration service that makes it simple to deploy, manage, and scale containerized applications. Amazon ECS provides additional advantages in running Moodle compared to using physical hardware or a VM-based environment.

Serverless containers with AWS Fargate

Amazon ECS supports AWS Fargate as a launch type to provide a serverless, pay-as-you-go compute engine for containerized workloads. By using Fargate, customers can focus on deploying and managing the Moodle application rather than infrastructure. Fargate removes the operational overhead of scaling, patching, securing, and managing servers. Security is also improved through workload isolation by design, as each tasks run in their own dedicated runtime environment.

Integrated monitoring

Amazon ECS with a Fargate launch type has a built-in integration with Amazon CloudWatch Container Insights that can be enabled with one click to collect, aggregate, and summarize metrics and logs from applications. It automatically collects metrics from application such as CPU, memory, disk, network, and diagnostic information to help customers isolate performance issues and resolve them quickly.

Figure 2. Amazon CloudWatch Container Insights map view of resources within Amazon ECS.

Figure 2. Amazon CloudWatch Container Insights map view of resources within Amazon ECS.

Figure 3. Amazon CloudWatch Container Insights Performance Monitoring dashboard.

Figure 3. Amazon CloudWatch Container Insights performance monitoring dashboard.

Figure 4. Amazon CloudWatch Logs insights.

Reliably handle spiky traffic with faster scaling

Containers generally have faster start-up time compared to VM due to the lower overhead of not having to boot kernel and set-up hardware. Additionally with the recent improvement on Fargate scaling, using Amazon ECS service scheduler, customers can launch up to 500 Fargate tasks in under a minute per service. With the faster scaling and start-up time, Moodle application service can scale more quickly during spiky traffic where there are many concurrent users at the same time, such as with online classes, exams, and registrations. This can provide students with a more reliable and consistent experience in accessing the LMS. Faster scaling and start-up time also reduces the need from the operations team to pre-provision the compute capacity to meet the spikes in demand.

Optimize cost

By using Fargate, customers can configure Moodle tasks to use the right amount of vCPU and memory, reducing the need to over-provision compute capacity, therefore saving costs. Fargate also has a capacity provider called Fargate Spot which allows customers to launch Moodle tasks using spare capacity in the AWS Cloud for a discount of up to 70%. The solution in this blog post is configured to use Fargate Spot with a ratio of 3:1, meaning with every four replica of the tasks, three run on Fargate Spot and one runs on standard Fargate.

AWS architecture for running Moodle LMS with AWS serverless containers

Now that we’ve covered the advantages of running Moodle LMS with AWS serverless containers, let’s examine the architecture for the solution.

Figure 5. Architecture Diagram for running Moodle with Serverless Containers on AWS. The architecture features modular architecture using AWS services explained in more detail in the following section.

Figure 5. Architecture diagram for running Moodle with serverless containers on AWS. The architecture features modular architecture using AWS services explained in more detail in the following section.

The solution is deployed using AWS Cloud Development Kit (AWS CDK), which allows users to define cloud application resources using familiar programming languages. The solution is deployed using two Availability Zones (AZs) to provide high-availability.

On the application endpoint, an Amazon CloudFront distribution is created and used as the endpoint for end-users to access the Moodle application. CloudFront improves the performance of the application by serving the content near to where the end-users are located with low latency. The solution creates and associates an AWS Web Application Firewall (AWS WAF) web access control list (ACL) with the CloudFront distribution with Amazon IP reputation list managed rule group enabled. You can also enable additional rules as needed in this web ACL. Behind CloudFront, the Moodle application traffic is load-balanced using Application Load Balancer (ALB) and secured with encryption-in-transit with the TLS certificate stored in AWS Certificate Manager (ACM). ALB automatically distributes the incoming traffic across multiple Moodle instances. It monitors the health of its registered targets, and routes traffic only to the healthy targets. ALB scales the load balancer as the incoming traffic changes over time.

The incoming traffic distributed by ALB is received by a pool of Moodle instances which runs on Amazon ECS using combination of Fargate and Fargate Spot. The Amazon ECS service automatically orchestrates multiple Amazon ECS tasks that is running the Moodle containers. The container image for the application is based on Bitnami Moodle Docker image with some modifications to enable Redis caching integration. The container image is stored in Amazon Elastic Container Registry (Amazon ECR) which provides a fully-managed container registry.

To centralize and share moodledata files across multiple Moodle instances, a shared file system is required for this solution. Amazon Elastic File System (Amazon EFS) is a simple, serverless, set-and-forget elastic file system. Amazon EFS makes it simple to set up, scale, and cost-optimize file storage in AWS. Amazon EFS is deployed and mounted on the Amazon ECS tasks to be used as underlying Moodle and moodledata filesystem. The Moodle database is also centralized and deployed into an Amazon Relational Database Service (Amazon RDS) instance. With Amazon RDS, a managed service, you can set up, operate, and scale a relational database in the cloud. It provides cost-efficient and resizable capacity, while managing time-consuming database administration tasks, allowing you to focus on your applications and business.

Lastly, to improve the overall performance of the application, Moodle has a built-in caching mechanism that make use of memory, filesystem, or external cache store such as Memcached or Redis. This solution use Amazon ElastiCache for Redis as a centralized cache store. Amazon ElastiCache for Redis makes it simple to deploy and run Redis protocol-compliant server nodes in AWS.

How to run Moodle LMS on serverless containers with AWS

Prerequisites

1. Install and configure AWS Command Line Interface (AWS CLI) with your AWS Identity and Access Management (IAM) user.

2. Install AWS CDK.

3. Install Docker.

4. Install Git.

5. Pull the source code into your machine by running the following in your terminal:
git clone https://github.com/aws-samples/aws-cdk-ecs-refarch-moodle.git

Setting up domain name and TLS certificate

1. Set up a public domain name to request a public certificate in ACM. If you don’t have a public domain name yet, you can use Amazon Route 53 to register a new domain. This domain name is also used for CloudFront alternative domain name.

2. Request two public certificates for your domain name using ACM. The first one is for the ALB where this solution is deployed (e.g. ap-southeast-1); the second one is for the CloudFront in the us-east-1 Region. For example: moodle.example.com or *.example.com. Note the certificate Amazon Resource Names (ARNs) to be used in the deployment steps.

Publishing Moodle container image to Amazon ECR

Prior to deploying the solution, you must first build the Moodle container image locally and publish it into a container registry such as Amazon ECR or an external registry of your choice. In this case, I use Amazon ECR.

1. Open your preferred command line interface (CLI) such as Terminal or Command Prompt.

2. From the top directory of the source code, run the following to build the container image:
docker build -t moodle-image src/image/src

3. Authenticate to your default AWS account registry:
aws ecr get-login-password --region [your-region] | docker login --username AWS --password-stdin [your-aws-account-id].dkr.ecr.[your-region].amazonaws.com

4. Create a new ECR Repository to hold the image:
aws ecr create-repository --repository-name moodle-image --region [your-region]

5. Tag the image to push to your repository:
docker tag moodle-image:latest [your-aws-account-id].dkr.ecr.[your-region].amazonaws.com/moodle-image:latest

6. Push the image:
docker push [your-aws-account-id].dkr.ecr.[your-region].amazonaws.com/moodle-image:latest

Deployment steps

1. Configure the context in the file src/cdk/cdk.json.

a. Configure app-config/albCertificateArn and app-config/cfCertificateArn with the ACM certificate ARN.

b. Configure the app-config/cfDomain for CloudFront with the same domain name as the public certificates that you’ve requested during the prerequisites step. For example: moodle.example.com.

c. Configure the app-config/moodleImageUri with the Moodle container image URI that you’ve pushed prior to deployment steps, for example [your-aws-account-id].dkr.ecr.[your-region].amazonaws.com/moodle-image:latest.

2. Go to the AWS CDK app directory cd src/cdk and then run npm install.

3. Run cdk bootstrap to bootstrap CDK toolkit (you only need to perform this once).

4. Run cdk deploy --all to deploy the CDK app.

5. Once successfully deployed, Moodle begins first-time installation and it takes approximately 15-20 minutes. Check the progress by checking at the logs in Amazon ECS console.

6. Once it is completed, you can access the application endpoint on the ALB endpoint described in the deployment output APPLICATIONLOADBALANCERDNSNAME

Post-deployment steps

1. (Optional) You can configure a DNS record to map into the ALB endpoint to clear the SSL warning.

2. Use the username described in MOODLEUSERNAME output and fetch the password on AWS Secrets Manager with the ARN described in the MOODLEPASSWORDSECRETARN output.

3. To improve Moodle application performance, configure Moodle caching using the Amazon ElastiCache Redis endpoint described in the MOODLEREDISPRIMARYENDPOINTADDRESSANDPORT output.

a. Add the cache store instance using the Amazon ElastiCache Redis endpoint. Refer to the official Moodle documentation for Adding cache store instances.

b. Set the Application cache to use the Redis cache store instance that was added in the previous step. Refer to the official Moodle documentation for Setting the stores that get used when no mapping is present.

4. You can scale the number of the Moodle instance replicas by configuring app-config/serviceReplicaDesiredCount context in the file src/cdk/cdk.json. You can also configure the app-config/serviceHealthCheckGracePeriodSeconds context from 1800 to 300 seconds. You can run cdk diff to view the comparison between the current version with the already-deployed version. You can then run cdk deploy --all again to apply the latest configurations.

5. To access the Moodle application from CloudFront endpoint, you need to create a CNAME DNS record using the domain name that you set up earlier with the record value specified in CLOUDFRONTDNSNAME output. For example: moodle.example.com with value abcd1234efgh.cloudfront.net. If you are getting a 502 error, it might be that the the TLS handshake between CloudFront and ALB is failing because of the domain name in the TLS certificate for ALB does not match with the Host header forwarded from CloudFront (the Host header in this case is the domain name that you are using to access CloudFront).

Note: Due to the Moodle software design, some long-running operations are being done synchronously. For example, when administrator would like to install a plugin and then submit the request. Instead of performing the task in the background, Moodle processes the request and the browser waits for the Moodle server to finish the installation and return the response, which can take some time to complete. The current CloudFront origin response timeout is being set to the maximum allowed by default, which is 60 seconds. I recommend increasing this to 180 seconds to avoid any possible issues caused by CloudFront dropping the connection while operations are still running. You can submit the request to increase the timeout by creating a case in the AWS Support Center. Once the request has been approved, you can configure the app-config/cfDistributionOriginTimeoutSeconds context to the duration that you’ve requested. Alternatively, site administrator can use an Application Load Balancer endpoint to perform long-running operations.

Cleanup

You should consider deleting the application infrastructure once you no longer need it to save costs. To do that, follow these steps:

1. Open your preferred command line interface such as Terminal or Command Prompt.

2. From the top directory of the source code, go to the CDK app directory cd src/cdk

3. Run cdk destroy --all to delete the CDK application.

Conclusion

In this post, I discussed how you can deploy Moodle LMS using serverless containers technology on AWS to help remove the undifferentiated heavy-lifting in managing the servers, reliably handle spiky traffic with faster scaling from AWS Fargate, monitor the applications using integrated monitoring with Amazon CloudWatch, and optimize cost by using AWS Fargate Spot. If you use this solution and would like to provide comments about how it can be improved, you can provide feedback in GitHub using the “Issues” feature.

You can also find more information about each of the AWS services used for this solution in the AWS guides:

Learn more in these blog posts that feature common use-cases and integrations within Moodle:

Read more about AWS for education:


Subscribe to the AWS Public Sector Blog newsletter to get the latest in AWS tools, solutions, and innovations from the public sector delivered to your inbox, or contact us.

Please take a few minutes to share insights regarding your experience with the AWS Public Sector Blog in this survey, and we’ll use feedback from the survey to create more content aligned with the preferences of our readers.