This repo contains guides and [Azure Resource Manager](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview) templates designed to help you deploy and manage a highly available and scalable
[Moodle](https://moodle.com) cluster on Azure. In addition, the repo contains other useful information relevant to running Moodle on Azure such as a listing of Azure-relevant Moodle plugins and information on how to offer Moodle as a Managed Application on the Azure Marketplace or on an IT Service Catalog.
If you have Azure account you can deploy Moodle via the [Azure portal](https://portal.azure.com) using the button below, or you can [deploy Moodle via the
CLI](docs/Deploy.md). Please note that while you can use an [Azure free account](https://azure.microsoft.com/en-us/free/) to get started depending on which template configuration you choose you will likely be required to upgrade to a paid account.
30 minutes) and requires only 2 VM cores currently that'll fit even in a free trial Azure subscription. The cost of this deployment can be estimated at
[this Azure Pricing Calculator link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1). Note the displayed cost in
in the calculator is the minimum cost. The actual cost will be bigger with potentially
[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Ftshirt-sizing%2Fazuredeploy-minimal.json)
Try the following button if you'd like to deploy our templates for small-to-mid-size workload (about up to 1000 concurrent users).
All configurations are fixed and you just need to pass your ssh public key to the template
for logging in to the deployed VMs. This deployment will use NFS (no high availability) and MySQL (8 vCores),
without other options like elastic search or redis cache. The cost of this deployment can be estimated at
[this Azure Pricing Calculator link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc). Note the displayed cost in
in the calculator is the minimum cost. The actual cost will be bigger with potentially
autoscaled VMs and network cost.
[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Ftshirt-sizing%2Fazuredeploy-small2mid-noha.json)
## Large size deployment (with high availability)
Try the following button if you'd like to deploy our templates for large workload (more than 2000 concurrent users).
All configurations are fixed and you just need to pass your ssh public key to the template
for logging in to the deployed VMs. This deployment will use Gluster (for high availability, requiring 2 VMs), MySQL (16 vCores) and redis cache,
without other options like elastic search. The cost of this deployment can be estimated at
[this Azure Pricing Calculator link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7). Note the displayed cost in
in the calculator is the minimum cost. The actual cost will be bigger with potentially
autoscaled VMs and network cost.
[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Ftshirt-sizing%2Fazuredeploy-large-ha.json)
## Maximal deployment
Try the following button if you'd like to deploy our templates with maximal resources
for best performance. Note that this deployment will incur significant cost.
All configurations are fixed and you just need to pass your ssh public key to the template
for logging in to the deployed VMs. This maximal deployment will use Gluster (for
high availability, adding 2 VMs for a Gluster cluster), MySQL with highest SKU,
redis cache, elastic search (3 VMs), and pretty large storage sizes (both data
disks and DB). The cost of this deployment can be estimated
at [this Azure Pricing Calculator link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5). Note the displayed cost in
in the calculator is the minimum cost of this deployment. The actual cost will be bigger with potentially
[![Deploy to Azure Maximally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Ftshirt-sizing%2Fazuredeploy-maximal.json)
- [Azure Database for MySQL](https://azure.microsoft.com/en-us/services/mysql/) or [Azure Database for PostgreSQL](https://azure.microsoft.com/en-us/services/postgresql/) or [Azure SQL Database](https://azure.microsoft.com/en-us/services/sql-database/)
- [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/) instance for Moodle caching (optional)
- ObjectFS in [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/) (Moodle sitedata)
- Three Elasticsearch VMs for search indexing in Moodle (optional)
- Dual Gluster nodes for high availability access to Moodle files
The template also optionally installs a handful of useful plugins that allow Moodle to be integrated with select Azure services (see below for details) and optionally allows you to configure a backup using Azure.
- [Trigger Plugin](https://github.com/catalyst/moodle-tool_trigger) and [Restful Webservice Plugin](https://github.com/catalyst/moodle-webservice_restful) for [Azure Logic Apps](https://azure.microsoft.com/en-us/services/logic-apps/) (requires use of [Moodle Connector](https://github.com/catalyst/azure-connector_moodle) now in development)
- [Object File System Plugin*](https://github.com/catalyst/moodle-tool_objectfs) for [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/)
- [Office 365 and Azure Active Directory Plugins for Moodle*](https://github.com/Microsoft/o365-moodle) for [Azure Active Directory](https://azure.microsoft.com/en-us/services/active-directory/)
At the current time this template allows the optional installation of all of the plugins above with an * next to them. Please note these plugins can be installed at any time post deployment via Moodle's own [plugin directory](https://moodle.org/plugins/). You can find a list of all Azure relevant plugins in the Moodle plugin directory [here](https://moodle.org/plugins/browse.php?list=set&id=91). You might also choose to follow this list via RSS.
You can learn more about how you can offer Moodle as a Managed Application on the Azure Marketplace or on an IT Service Catalog [here](https://github.com/Azure/Moodle/tree/master/managedApplication). This is a great read if you are offering Moodle hosting services today for your customers.
The following sections describe observations about the current template that you will likely want to review before deploying:
**Database.** Currently the best performance is achieved with [Azure Database for MySQL](https://azure.microsoft.com/en-us/services/mysql/) and [Azure SQL Database](https://azure.microsoft.com/en-us/services/sql-database/). With [Azure Database for PostgreSQL](https://azure.microsoft.com/en-us/services/postgresql/) we have hit database constraints which caused processes to load up on the frontends until they ran out of memory. It is possible some PostgreSQL tuning might help here. At this stage Azure Database for MySQL and PostgreSQL do not support being moved to a vnet. As a workaround, we use a firewall-based IP restriction allow access only to the controller VM and VMSS load-balancer IPs.
**Search.** Azure supports running an Elasticsearch cluster, however it does not offer a fully-managed Elasticsearch service, so for those looking for a fully-managed Search service [Azure Search](https://azure.microsoft.com/en-us/services/logic-apps/) is recommended.
**Caching.** While enabling Redis cache can improve performance can be improved for a large Moodle site we have not seen it be very effective for small-to-medium size sites.
**Regions.** Note that not all resources types (such as databases) may be available in your region. You should check the list of [Azure Products by Region](https://azure.microsoft.com/en-us/global-infrastructure/services/) to for local availabiliy.
1.**Is this template Moodle as IaaS or PaaS?** While the current template leverages PaaS services such as Redis, MySQL, Postgres, MS SQL etc. the current template offers Moodle as IaaS. Given limitations to Moodle our focus is IaaS for the time being however we would love to be informed of your experience running Moodle as PaaS on Azure (i.e. using [Azure Container Service](https://azure.microsoft.com/en-us/services/container-service/) or [Azure App Service](https://azure.microsoft.com/en-us/services/container-service/)).
2.**The current template uses Ubuntu. Will other Operating Systems such as CentOS or Windows Server be supported in the future?** Unfortunately we only have plans to support Ubuntu at this time. It is highly unlikely that this will change.
3.**What configuration do you recommend for my Moodle site?** The answer is it depends. We are still building out our load testing tools and methodologies and at this stage are not providing t-shirt sized deployment recommendations. With that being said this is an area we are investing heavily in this area and we would love your contributions (i.e. load testing scripts, tools, methodologies etc.). If you have an immediate need for guidance for a larger sized deployment, you might want to share some details around your deployment on our [issues page](https://github.com/Azure/Moodle/issues) and we will do our best to respond.
4.**Did Microsoft build this template alone or with the help of the Moodle community?** We did not build this template alone. We relied on the expertise and guidance of many capable Moodle partners around the world. The initial implementation of the template was done by [Catalyst IT](https://github.com/catalyst).
5.**How does this template relate to other Moodle offerings available on the Azure Marketplace?** It is generally not a good idea to run Moodle as a single VM in a production setting. This template is highly configurable and allows for high availability and redundancy.
6.**How does this template relate to this [Azure Quickstart Template for Moodle](https://github.com/Azure/azure-quickstart-templates/tree/master/moodle-scalable-cluster-ubuntu)?** This repo is the working repo for the quickstart template. We will be pushing changes from this template to the quickstart template on a regular cadence.
7.**I am already running Moodle on Azure. How does this work benefit me?** We are looking for painpoints from you and the broader Moodle on Azure community that we can help solve. We are also looking to understand where our implementation of Moodle on Azure outperforms or underperforms other implementations such as yours that are out in the wild. If you have observations, performance benchmarks or just general feedback about your experience running Moodle on Azure that you'd like to share we're extremely interested! Load testing is a very big area of focus, so if you have scripts you wouldn't mind contributing please let us know.
8.**Has anyone run this template sucessfully in production?** Yes they have. With that being said we do not make any performance guarantees about this architecture.
9.**What type of improvements have you succeeded in making** Since we first began this effort we have managed to make great gains, achieving a >2x performance boost from our original configuration by making tweaks to things like where PHP files were stored. Our work is nowhere near over.
10.**What other Azure services (i.e. [Azure CDN](https://azure.microsoft.com/en-us/services/cdn/), [Azure Media Services](https://azure.microsoft.com/en-us/services/media-services/), [Azure Bot Service](https://azure.microsoft.com/en-us/services/bot-service/) etc.) will you be integrating with when this effort is complete?** It's not clear yet. We'll need your [feedback](https://github.com/Azure/Moodle/issues) to decide.
11.**Why the database on a public subnet?** At this stage Azure Database for MySQL and PostgreSQL do not support being moved to a vnet. As a workaround, we use a firewall-based IP restriction allow access only to the controller VM and VMSS load-balancer IPs.
* Access to an installed instance of the Azure CLI
* A SSH keypair
The Travis CI process uses the *Azure CLI Service Principal* login method to authenticate against Azure. The documentation for logging in via a Service Principal can be found here: https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli?view=azure-cli-latest#logging-in-with-a-service-principal
Before you can log in using the Service Principal process you need to create a *Service Principal*. The documentation to create a Service Principal login can be found here: https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest
When a Service Principal is created using the Azure CLI a JSON response is returned containing:
* **name** - This is the Service Principal username.
* **password** - This is the Service Principal password.
* **tenantId** - This is the Service Principal tenant unique ID.
You will need these three above values to have Travis and Azure deploy and test your template.
The next step is to take the above values returned by the Service Principal creation and use them to define *environment variables* in Travis CI.
The following link shows how to set up per repository environment variables in Travis CI: https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings Using this documention set up the following three *hidden* environment variables in Travis CI for your fork of this repository.
* **SPNAME** - The value of the *name* parameter returned by the Service Principal create proccess.
* **SPPASSWORD** - The value of the *password* parameter returned by the Service Principal create proccess.
* **SPTENANT** - The value of the *tenant* parameter returned by the Service Principal create proccess.
* **SPSSHKEY** *(default: generate new)*- A public SSH key that you have the corresponding private key for. This is currently not used but is required for the build to be successful.
* **LOCATION** *(default: southcentralus)*- Location for the test resource group.
* **RESOURCEGROUP** *(default: azmdl-travis-XXX)*- Name to use for the resource group.
* **FULLCI_BRANCHES** *(default: master)*- Name of branches (separated by ':') to always run FULL CI (if credentials are provided). Full CI will run a deployment test which will create and use resources from your Azure account.