diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 0e6dd46..a9992a5 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -1,4 +1,4 @@ -# Contributing to Moodle on Azure +# Contributing to LAMP on Azure The TL;DR version is: @@ -11,10 +11,8 @@ The TL;DR version is: ## How the project is managed This project welcomes contributions and suggestions. Our goal is to -work on Azure specific tooling for deploying and managing the open -source [Moodle](http://moodle.org) learning management system on -Azure. We do not work on Moodle itself here, instead we work upstream -as appropriate. +work on Azure specific tooling for deploying and managing PHP (LAMP) +applications on Azure. The short version of how to contribute to this project is "just do it". Where "it" can be defined as any valuable contribution (and to be @@ -126,8 +124,7 @@ where to spend their time. For example: Priority 0 under your leadership. * Wontfix items are considered out of scope for this project. Community members should seek to solve the problem in different - ways. Often this will mean contribution to Moodle itself or a - plugin that is external to this community. + ways. ## Community roles diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 0ada1d6..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,14 +0,0 @@ -var grunt = require('grunt'); -require('load-grunt-tasks')(grunt); - -var templates = ['nested/*.json', 'managedApplication/*.json', 'loadtest/*.json', '*.json']; - -grunt.initConfig({ - jshint: { - files: templates, - options: { - jshintrc: '.jshintrc' - } - } -}); -grunt.registerTask('test', ['jshint']); diff --git a/README.md b/README.md index 6fdaa6f..da216e8 100644 --- a/README.md +++ b/README.md @@ -2,137 +2,161 @@ # Deploy and Manage a Scalable LAMP Cluster on Azure 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 -[LAMP](https://en.wikipedia.org/wiki/LAMP_(software_bundle)) cluster on Azure. Please note that this work is a derivative of the [Moodle on Azure project](https://github.com/Azure/Moodle/tree/master) and as such may contain references to Moodle (a specific LAMP application) in either the documentation or the scripts provided here. This project is currently a work in progress and will be continuously updated. Finally, the template(s) provided here deploy an *empty* infrastructure/stack to deploy any general LAMP application. +[LAMP](https://en.wikipedia.org/wiki/LAMP_(software_bundle)) cluster on Azure. The template(s) provided here deploy an *empty* infrastructure/stack to deploy any general LAMP application. -If you have Azure account you can deploy LAMP via the [Azure portal](https://portal.azure.com) using the button below. 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. +If you have Azure account you can deploy LAMP via the [Azure Portal](https://portal.azure.com) using the buttons below. Please note that while you can use an [Azure free account](https://aka.ms/azure-free-phprefarch) to get started, depending on which template configuration you choose you will likely be required to upgrade to a paid account. ## Fully configurable deployment -The following button will allow you to specify various configurations for your LAMP cluster -deployment. The number of configuration options might be overwhelming, so some pre-defined/restricted deployment options for -typical LAMP scenarios follow this. +The following button will allow you to specify various configurations for your LAMP cluster deployment. The number of configuration options might be overwhelming, so some pre-defined/restricted deployment options for typical LAMP scenarios follow this. -[![Deploy to Azure Fully Configurable](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) - -NOTE: All of the deployment options require you to provide a valid SSH protocol 2 (SSH-2) RSA public-private key pairs with a minimum length of 2048 bits. Other key formats such as ED25519 and ECDSA are not supported. If you are unfamiliar with SSH then you should read this [article](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/mac-create-ssh-keys) which will explain how to generate a key using the Windows Subsystem for Linux (it's easy and takes only a few minutes). If you are new to SSH, remember SSH is a key pair solution. What this means is you have a public key and a private key, and the one you will be using to deploy your template is the public key. +[![Deploy to Azure Fully Configurable](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy.json) [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy.json) ## Predefined deployment options -Below are a list of pre-defined/restricted deployment options based on typical deployment scenarios (i.e. dev/test, production etc.) All configurations are fixed and you just need to pass your ssh public key to the template for logging in to the deployed VMs. Please note that the actual cost will be bigger with potentially autoscaled VMs, backups and network cost. + +Below are a list of pre-defined/restricted deployment options based on typical deployment scenarios (i.e. dev/test, production etc.) All configurations are fixed and you just need to pass your SSH public key to the template for logging in to the deployed VMs. Please note that the actual cost will be bigger with potentially autoscaled VMs, backups and network cost. | Deployment Type | Description | Estimated Cost | Launch | | --- | --- | --- | --- -| Minimal | This deployment will use NFS, Microsoft SQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores currently that'll fit even in a free trial Azure subscription.|[link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1)|[![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%2Fhs-lampgen%2Fazuredeploy-minimal.json) -| Small to Mid-Size | Supporting up to 1000 concurrent users. This deployment will use NFS (no high availability) and MySQL (8 vCores), without other options like elastic search or redis cache.|[link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc)|[![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%2Fhs-lampgen%2Fazuredeploy-small2mid-noha.json) -|Large size deployment (with high availability)| Supporting more than 2000 concurrent users. This deployment will use Gluster (for high availability, requiring 2 VMs), MySQL (16 vCores) and redis cache, without other options like elastic search. |[link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7)|[![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%2Fhs-lampgen%2Fazuredeploy-large-ha.json) -| Maximum |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).|[link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5)|[![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%2Fhs-lampgen%2Fazuredeploy-maximal.json) +| Minimal | This deployment will use NFS, Microsoft SQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores. Currently this will fit even in a free Azure trial subscription.|[link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-minimal.json) +| Small to Mid-Size | Supporting up to 1,000 concurrent users. This deployment will use NFS (with no high availability) and MySQL (8 vCores), without other options like Redis Cache.|[link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-small2mid-noha.json) +|Large size deployment (with high availability)| Supporting more than 2,000 concurrent users. This deployment will use GlusterFS (in high availability, requiring 2 VMs), MySQL (16 vCores) and Redis Cache. |[link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-large-ha.json) +| Maximum |This maximal deployment will use GlusterFS (in high availability, adding 2 VMs for a GlusterFS cluster), MySQL with the highest SKU, Redis Cache, and pretty large storage sizes (for both data disks and DB).|[link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5)|[![Deploy to Azure Maximally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-maximal.json) -NOTE: Depending on the region you choose to deploy the stack in - the deployment might fail due to SKUs being hardcoded in the template where they are not available. For example, today our small-mid-size deployment option hard codes Gen-4 Azure MySQL SKUs into the template, and if a region where that is currently not available in (i.e. westus2) is used, your deployment will fail. If your deployment fails, please revert to the fully configurable template where possible and change the SKU paramater to one that exists in your region (i.e. Gen-5) or alternatively change your deployment region to one in which the SKU is available (i.e. southcentralus). +NOTE: Depending on the region you choose to deploy the stack in, the deployment might fail due to SKUs being hardcoded in the template where they are not available. For example, today our small-mid-size deployment option hard codes Gen-4 Azure MySQL SKUs into the template, and if an Azure region where that is currently not available in (i.e. West US 2) is used, your deployment will fail. If your deployment fails, please revert to the fully configurable template where possible and change the SKU paramater to one that exists in your region (i.e. Gen-5), or alternatively change your deployment region to one in which the SKU is available (i.e. South Central US). ## Stack Architecture This template set deploys the following infrastructure core to your LAMP instance: -- Autoscaling web frontend layer (Nginx for https termination, Varnish for caching, Apache/php or nginx/php-fpm) -- Private virtual network for frontend instances -- Controller instance running cron and handling syslog for the autoscaled site -- [Azure Load balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to balance across the autoscaled instances -- [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/) -- Dual [GlusterFS](https://www.gluster.org/) nodes or NFS for high availability access to LAMP files +- Autoscaling web frontend layer (with nginx and PHP-FPM) +- Private Virtual Network for frontend instances +- Controller VM running cron and handling syslog for the autoscaling cluster +- [Azure Load balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to balance across the autoscaling instances +- [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/) +- Dual [GlusterFS](https://www.gluster.org/) nodes or NFS for highly available access to LAMP files +# Next Steps -## Next Steps - -# Prepare deployed cluster for LAMP applications - -If you chose Apache as your `webServerType` and `true` for the `htmlLocalCopy` switch at your LAMP cluster deployment time, you can install additional LAMP sites on your cluster, utilizing Apache's VirtualHost feature (we call this "LAMP generalization"). To manage your installed cluster, you'll first need to login to the LAMP cluster controller virtual machine. The directory you'll need to work out of is `/azlamp`. You will need privileged access which means that you'll either need to be root (superuser) or have *sudo* access. +## Prepare deployed cluster for LAMP applications +If you chose `true` for the `htmlLocalCopy` switch at your LAMP cluster deployment time, you can install additional LAMP sites on your cluster, utilizing Nginx's virtual host feature. To manage your installed cluster, you'll first need to login to the LAMP cluster controller virtual machine. The directory you'll need to work out of is `/azlamp`. You will need privileged access which means that you'll either need to be root (superuser) or have *sudo* access. ## Configuring the controller for a specific LAMP application (WordPress) +### Connect via SSH + +You can connect via SSH to the controller VM. From a Linux, macOS or Windows 10 client using the Windows Subsystem for Linux, you can connect to the controller's VM using SSH and the public IP or DNS name of the controller. + +```sh +ssh user@ip-or-dns +``` + +The username can be configured with `sshUsername`; the default value is `azureadmin`. You'll be authenticating using your SSH private key, so no password is necessary for the SSH user. ### Installation Destination -An example LAMP application (WordPress) is illustrated here for the sake of clarity. The approach is similar to any LAMP application out there. + +An example LAMP application (WordPress) is illustrated here for the sake of clarity. The approach is similar to any LAMP application out there. First, you'd need to navigate to `/azlamp/html` and create a directory based on a domain name you have in mind. An example domain name is used below: -``` +```sh cd /azlamp/html mkdir wpsitename.mydomain.com cd /azlamp/html/wpsitename.mydomain.com ``` -Once that's done and you've downloaded the latest version of WordPress, please follow the instructions here to complete configuring a database and finishing a [WordPress install](https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Installation). +Download the latest version of WordPress, for example with: -``` +```sh wget https://wordpress.org/latest.tar.gz tar xvfz latest.tar.gz --strip 1 ``` - ### SSL Certs The certificates for your LAMP application reside in `/azlamp/certs/yourdomain` or in this instance, `/azlamp/certs/wpsitename.mydomain.com` -``` +```sh mkdir /azlamp/certs/wpsitename.mydomain.com ``` Copy over the .crt and .key files over to `/azlamp/certs/wpsitename.mydomain.com`. -The file names should be changed to `nginx.crt` and `nginx.key` in order to be recognized by the configured nginx servers. Depending on your local environment, -you may choose to use the utility *scp* or a tool like [WinSCP](https://winscp.net/eng/download.php) to copy these files over to the cluster controller virtual machine. +The file names should be changed to `nginx.crt` and `nginx.key` in order to be recognized by the configured nginx servers. Depending on your local environment, you may choose to use the utility *scp* or a tool like [WinSCP](https://winscp.net/eng/download.php) to copy these files over to the cluster controller virtual machine. + +You can also generate a self-signed certificate, useful for testing only: + +```sh +openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /azlamp/certs/wpsitename.mydomain.com/nginx.key \ + -out /azlamp/certs/wpsitename.mydomain.com/nginx.crt \ + -subj "/C=US/ST=WA/L=Redmond/O=IT/CN=wpsitename.mydomain.com" +``` It's recommended that the certificate files be read-only to owner and that these files are owned by *www-data*: +```sh +chown www-data:www-data /azlamp/certs/wpsitename.mydomain.com/nginx.* +chmod 400 /azlamp/certs/wpsitename.mydomain.com/nginx.* ``` -chown www-data:www-data /azlamp/certs/wpsitename.mydomain.com/* -chmod 400 /azlamp/certs/wpsitename.mydomain.com/* -``` - ### Linking to the content/cluster data location Navigate to the WordPress content directory and run the following command: -``` +```sh mkdir -p /azlamp/data/wpsitename.mydomain.com/wp-content/uploads -cd /azlamp/html/wpsitename.mydomain.com -ln -s /azlamp/data/wpsitename.mydomain.com/wp-content/uploads . +ln -s /azlamp/data/wpsitename.mydomain.com/wp-content/uploads /azlamp/html/wpsitename.mydomain.com/wp-content/uploads +chmod 0777 /azlamp/data/wpsitename.mydomain.com/wp-content/uploads ``` -This step is needed because the `/wp-content/uploads` directory need to be shared across all web frontend instances, and Wordpress configuration doesn't allow an external directory to be used as the uploads repository. In fact, Drupal also has a similar design, so a similar symbolic link will be needed for Drupal as well. This is in contrary to Moodle, which allows users to configure any external directory as its file storage location. +This step is needed because the `/wp-content/uploads` directory need to be shared across all web frontend instances, and WordPress configuration doesn't allow an external directory to be used as the uploads repository. In fact, Drupal also has a similar design, so a similar symbolic link will be needed for Drupal as well. This is in contrary to Moodle, which allows users to configure any external directory as its file storage location. -### Update Apache configurations on all web frontend instances +### Update Nginx configurations on all web frontend instances -Once the correspnding html/data/certs directories are configured, we need to reconfigure all Apache services on web frontend instances, so that newly created sites are added to the Apache VirtualHost configurations and deleted sites are removed from them as well. This is done by the `/azlamp/bin/update-vmss-config` hook (executed every minute on each and every VMSS instance using a cron job), which requires us to provide the commands to run (to reconfigure Apache service) on each VMSS instance. There's already a utility script installed for that, so it's easy to achieve as follows. +Once the correspnding html/data/certs directories are configured, we need to reconfigure all Nginx services on web frontend instances, so that a virtual host is added for each newly added site, and old ones are removed. This is done by the `/azlamp/bin/update-vmss-config` hook (executed every minute on each and every VMSS instance using a cron job), which requires us to provide the commands to run on each VMSS instance. There's already a utility script installed for that, so it's easy to achieve this. On the controller machine, look up the file `/azlamp/bin/update-vmss-config`. If you haven't modified that file, you'll see the following lines in the file: -``` +```sh #1) # . /azlamp/bin/utils.sh - # reset_all_sites_on_vmss true VMSS apache + # reset_all_sites_on_vmss true VMSS #;; ``` -Remove all the leading `#` characters from these lines (uncommenting) and save the file, then wait for a minute. After that, your newly added sites should be available through the domain names specified/used as the directory names (Of course this assumes you set up your DNS records for your new site FQDNs so that their CNAME records point to the deployed Moodle cluster's load balancer DNS name, whis is of the form `lb-xyz123.an_azure_region.cloudapp.azure.com`). +Remove all the leading `#` characters from these lines (to uncomment them) and save the file, then wait for about a minute. After that, your newly added sites should be available through the domain names specified/used as the directory names (Of course this assumes you set up your DNS records for your new site FQDNs so that their CNAME records point to the deployed LAMP cluster's load balancer DNS name, whis is of the form `lb-xyz123.an_azure_region.cloudapp.azure.com`). -If you are adding sites for the second or later time, you'll already have the above lines commented out. Just create another `case` block, copying the 4 lines, but make sure to change the number so that it's one greater than the last VMSS config version number (you should be able to find that from the script). As an example, the final text would look like: +If you make changes and add or remove websites at a later time, you'll already have the above lines commented out. Just create another `case` block, copying the 4 lines, but make sure to change the number so that it's one greater than the last VMSS config version number (you should be able to find that from the script). As an example, the final text would look like: -``` +```sh 1) . /azlamp/bin/utils.sh - reset_all_sites_on_vmss true VMSS apache + reset_all_sites_on_vmss true VMSS ;; 2) . /azlamp/bin/utils.sh - reset_all_sites_on_vmss true VMSS apache + reset_all_sites_on_vmss true VMSS ;; ``` +### Replicate PHP files -The last step is to let the `/azlamp/html` directory sync with `/var/www/html` in every VMSS instance. This should be done by running `/usr/local/bin/update_last_modified_time.azlamp.sh` script on the controller machine as root. Once this is run and after a minute, the `/var/www/html` directory on every VMSS instance should be the same as `/azlamp/html`, and the newly added sites should be available. +The last step is to let the `/azlamp/html` directory sync with `/var/www/html` in every VMSS instance. This should be done by running **this script on the controller machine**, as root: -At this point, your LAMP application is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. +```sh +/usr/local/bin/update_last_modified_time.azlamp.sh +``` + +Once this is run and after a minute, the `/var/www/html` directory on every VMSS instance should be the same as `/azlamp/html`, and the newly added sites should be available. + +At this point, your app is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. + +### WordPress installer + +Once you completed the steps above and you can see your WordPress website running in the browser, please follow the instructions here to complete configuring a database and finishing a [WordPress install](https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Installation). + +If you chose `true` for the `htmlLocalCopy` switch, WordPress will be running from a read-only directory, so the installer won't be able to create a `wp-config.php` file for you. However, the installer will provide you with the full content of the required config file. On the controller VM, copy that content into the file `/azlamp/html/wpsitename.mydomain.com/wp-config.php`. You then need to trigger a replication of the data, by running the script `/usr/local/bin/update_last_modified_time.azlamp.sh` again from the controller VM, as root. Data will be replicated in around one minute. ## Code of Conduct @@ -167,4 +191,3 @@ Privacy information can be found at https://privacy.microsoft.com/en-us/ Microsoft and any contributors reserve all others rights, whether under their respective copyrights, patents, or trademarks, whether by implication, estoppel or otherwise. - diff --git a/azuredeploy-large-ha.json b/azuredeploy-large-ha.json index 31e054a..b8b20c2 100644 --- a/azuredeploy-large-ha.json +++ b/azuredeploy-large-ha.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/Azure/Moodle/master/" + "defaultValue": "https://raw.githubusercontent.com/Azure/LAMP/master/" }, "_artifactsLocationSasToken": { "type": "securestring", diff --git a/azuredeploy-maximal.json b/azuredeploy-maximal.json index b410184..3cdbab9 100644 --- a/azuredeploy-maximal.json +++ b/azuredeploy-maximal.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/Azure/Moodle/master/" + "defaultValue": "https://raw.githubusercontent.com/Azure/LAMP/master/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -35,7 +35,6 @@ "_artifactsLocationSasToken": { "value": "[parameters('_artifactsLocationSasToken')]" }, "redisDeploySwitch": { "value": true }, "azureBackupSwitch": { "value": true }, - "searchType": { "value": "elastic" }, "sshPublicKey": { "value": "[parameters('sshPublicKey')]" }, "mysqlPgresVcores": { "value": 16 }, "mysqlPgresStgSizeGB": { "value": 512 }, @@ -56,6 +55,6 @@ }, "variables": { "documentation01": "This wrapper template calls the main-template with maximum configs and the only required parameter (sshPublicKey).", - "documentation02": "For the best-possible performance, highly available, and most Moodle features, other parameters are fixed in this tempalte and overriden as above." + "documentation02": "For the best-possible performance, and highly available. Other parameters are fixed in this tempalte and overriden as above." } } diff --git a/azuredeploy-minimal.json b/azuredeploy-minimal.json index 49b4c75..08810a6 100644 --- a/azuredeploy-minimal.json +++ b/azuredeploy-minimal.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/Azure/Moodle/master/" + "defaultValue": "https://raw.githubusercontent.com/Azure/LAMP/master/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -57,7 +57,7 @@ "documentation01": "This wrapper template calls the main-template with bare minimum configs and the only required parameter (sshPublicKey).", "documentation02": "To speed up deployment and consume least resources, other parameters are fixed in this tempalte and overriden as follows:", "documentation03": " - fileServerType: nfs", - "documentation04": " - autoscaleVmSku: Standard_DS1_vs", + "documentation04": " - autoscaleVmSku: Standard_DS1_v2", "documentation05": " - fileServerDiskCount: 2", "documentation06": " - dbServerType: mssql", "documentation07": " - redisDeploySwitch: false" diff --git a/azuredeploy-small2mid-noha.json b/azuredeploy-small2mid-noha.json index 5f8202f..a3704d7 100644 --- a/azuredeploy-small2mid-noha.json +++ b/azuredeploy-small2mid-noha.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/Azure/Moodle/master/" + "defaultValue": "https://raw.githubusercontent.com/Azure/LAMP/master/" }, "_artifactsLocationSasToken": { "type": "securestring", diff --git a/azuredeploy.json b/azuredeploy.json index 5501881..9eb6466 100644 --- a/azuredeploy.json +++ b/azuredeploy.json @@ -7,7 +7,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/Azure/Moodle/hs-lampgen/" + "defaultValue": "https://raw.githubusercontent.com/Azure/LAMP/master/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -33,7 +33,7 @@ "redisDeploySwitch": { "defaultValue": false, "metadata": { - "description": "Switch to deploy a redis cache or not. Note that certain versions of Moodle (e.g., 3.1) don't work well with Redis, so use this only for known well-working Moodle versions (e.g., 3.4)." + "description": "Switch to deploy a Redis Cache or not." }, "type": "bool" }, @@ -44,31 +44,10 @@ }, "type": "bool" }, - "installObjectFsSwitch": { - "defaultValue": false, - "metadata": { - "description": "Switch to install Moodle Object FS plugins (with Azure Blob storage)" - }, - "type": "bool" - }, - "installO365pluginsSwitch": { - "defaultValue": false, - "metadata": { - "description": "Switch to install Moodle Office 365 plugins. As of May 22, 2018, O365 plugins for Moodle 3.5 haven't been released, so to set this true, you must set the moodleVersion to 3.4 or below." - }, - "type": "bool" - }, - "installGdprPluginsSwitch": { - "defaultValue": false, - "metadata": { - "description": "(Should be used only for Moodle 3.4 & 3.3) Switch to install Moodle GDPR plugins. Note these require Moodle versions 3.4.2+ or 3.3.5+ and these are included by default in Moodle 3.5. So if you choose MOODLE_35_STABLE as your moodleVersion, do not set this to true." - }, - "type": "bool" - }, "htmlLocalCopySwitch": { "defaultValue": true, "metadata": { - "description": "Switch to create a local copy of /moodle/html or not" + "description": "Switch to create a local copy of /azlamp/html or not" }, "type": "bool" }, @@ -101,33 +80,14 @@ ], "defaultValue": "VMSS", "metadata": { - "description": "Indicates where https termination occurs. 'VMSS' is for https termination at the VMSS instance VMs (using nginx https proxy). 'AppGw' is for https termination with an Azure Application Gateway. When selecting this, you need to specify all appGw* parameters. 'None' is for testing only with no https. 'None' may not be used with a separately configured https termination layer. If you want to use the 'None' option with your separately configured https termination layer, you'll need to update your Moodle config.php manually for $cfg->wwwroot and $cfg->sslproxy." + "description": "Indicates where https termination occurs. 'VMSS' is for https termination at the VMSS instance VMs (using nginx https proxy). 'AppGw' is for https termination with an Azure Application Gateway. When selecting this, you need to specify all appGw* parameters. 'None' is for testing only with no https. 'None' may not be used with a separately configured https termination layer." }, "type": "string" }, "siteURL": { "defaultValue": "www.example.org", "metadata": { - "description": "URL for Moodle site" - }, - "type": "string" - }, - "moodleVersion": { - "allowedValues": [ - "MOODLE_35_STABLE", - "MOODLE_34_STABLE", - "v3.4.3", - "v3.4.2", - "v3.4.1", - "MOODLE_33_STABLE", - "MOODLE_32_STABLE", - "MOODLE_31_STABLE", - "MOODLE_30_STABLE", - "MOODLE_29_STABLE" - ], - "defaultValue": "MOODLE_35_STABLE", - "metadata": { - "description": "The Moodle version you want to install." + "description": "URL for LAMP site" }, "type": "string" }, @@ -151,17 +111,6 @@ }, "type": "string" }, - "webServerType": { - "defaultValue": "apache", - "allowedValues": [ - "apache", - "nginx" - ], - "metadata": { - "description": "Web server type" - }, - "type": "string" - }, "autoscaleVmSku": { "defaultValue": "Standard_DS2_v2", "metadata": { @@ -492,107 +441,21 @@ "Standard_ZRS" ], "metadata": { - "description": "Storage Account type. This storage account is only for the Moodle ObjectFS plugin and/or the (currently disabled) Azure Files file share option" - }, - "type": "string" - }, - "searchType": { - "defaultValue": "none", - "allowedValues": [ - "none", - "azure", - "elastic" - ], - "metadata": { - "description": "options of moodle global search" - }, - "type": "string" - }, - "tikaService": { - "defaultValue": "none", - "allowedValues": [ - "none", - "tika" - ], - "metadata": { - "description": "options of enabling tika service for file searching in moodle" - }, - "type": "string" - }, - "azureSearchSku": { - "defaultValue": "basic", - "allowedValues": [ - "free", - "basic", - "standard", - "standard2", - "standard3" - ], - "metadata": { - "description": "the search service level you want to create." - }, - "type": "string" - }, - "azureSearchReplicaCount": { - "defaultValue": 3, - "minValue": 1, - "maxValue": 12, - "metadata": { - "description": "Replicas distribute search workloads across the service. You need 2 or more to support high availability (applies to Basic and Standard only)." - }, - "type": "int" - }, - "azureSearchPartitionCount": { - "defaultValue": 1, - "allowedValues": [ - 1, - 2, - 3, - 4, - 6, - 12 - ], - "metadata": { - "description": "Partitions allow for scaling of document count as well as faster indexing by sharding your index over multiple Azure Search units." - }, - "type": "int" - }, - "azureSearchHostingMode": { - "defaultValue": "default", - "allowedValues": [ - "default", - "highDensity" - ], - "metadata": { - "description": "Applicable only for azureSearchSku set to standard3. You can set this property to enable a single, high density partition that allows up to 1000 indexes, which is much higher than the maximum indexes allowed for any other azureSearchSku." - }, - "type": "string" - }, - "elasticVmSku": { - "defaultValue": "Standard_DS2_v2", - "metadata": { - "description": "VM size for the elastic search nodes" - }, - "type": "string" - }, - "tikaVmSku": { - "defaultValue": "Standard_DS2_v2", - "metadata": { - "description": "VM size for the tika search nodes" + "description": "Storage Account type. This storage account is only for the (currently disabled) Azure Files file share option" }, "type": "string" }, "customVnetId": { "defaultValue": "", "metadata": { - "description": "Azure Resource ID of the Azure virtual network where you want to deploy your Moodle resources. A vnet resource ID is of the following format: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx/resourceGroups/gggg/providers/Microsoft.Network/virtualNetworks/vvvv. Note that this virtual network must be on the same Azure location as this template deployment location. If this parameter is blank, a new Azure virtual network will be created and used. In that case, the address space of the newly created virtual network will be */16 of the following vNetAddressSpace parameter value below." + "description": "Azure Resource ID of the Azure virtual network where you want to deploy your LAMP resources. A vnet resource ID is of the following format: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx/resourceGroups/gggg/providers/Microsoft.Network/virtualNetworks/vvvv. Note that this virtual network must be on the same Azure location as this template deployment location. If this parameter is blank, a new Azure virtual network will be created and used. In that case, the address space of the newly created virtual network will be */16 of the following vNetAddressSpace parameter value below." }, "type": "string" }, "vNetAddressSpace": { "defaultValue": "172.31.0.0", "metadata": { - "description": "Address range for the Moodle virtual network and various subnets - presumed /16 for a newly created vnet in case customVnetId is blank. Further subneting (a number of */24 subnets starting from the xxx.yyy.zzz.0/24 will be created on a newly created vnet or your BYO-vnet (specified in customVnetId parameter)." + "description": "Address range for the LAMP virtual network and various subnets - presumed /16 for a newly created vnet in case customVnetId is blank. Further subneting (a number of */24 subnets starting from the xxx.yyy.zzz.0/24 will be created on a newly created vnet or your BYO-vnet (specified in customVnetId parameter)." }, "type": "string" }, @@ -658,12 +521,12 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'network.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'network.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -674,12 +537,12 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'storageAccount.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'storageAccount.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -693,8 +556,8 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "lbPubIp": { "value": "[reference('networkTemplate').outputs.lbPubIp.value]" @@ -704,7 +567,7 @@ } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl, 'db-', parameters('dbServerType'), '.json', parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl, 'db-', parameters('dbServerType'), '.json', parameters('_artifactsLocationSasToken'))]" } } }, @@ -716,12 +579,12 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'recoveryservices.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'recoveryservices.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -736,63 +599,15 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "subnetIdRedis": { "value": "[reference('networkTemplate').outputs.subnetIdRedis.value]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl, 'redis.json', parameters('_artifactsLocationSasToken'))]" - } - } - }, - { - "condition": "[not(equals(parameters('searchType'), 'none'))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "Microsoft.Resources/deployments/networkTemplate", - "Microsoft.Resources/deployments/recoveryTemplate" - ], - "name": "searchTemplate", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" - }, - "subnetIdElastic": { - "value": "[reference('networkTemplate').outputs.subnetIdElastic.value]" - } - }, - "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl, 'search-', parameters('searchType'), '.json', parameters('_artifactsLocationSasToken'))]" - } - } - }, - { - "condition": "[and(equals(parameters('tikaService'), 'tika'), not(equals(parameters('searchType'), 'none')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "Microsoft.Resources/deployments/networkTemplate", - "Microsoft.Resources/deployments/recoveryTemplate" - ], - "name": "tikaTemplate", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" - }, - "subnetIdTika": { - "value": "[reference('networkTemplate').outputs.subnetIdTika.value]" - } - }, - "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl, 'tika.json', parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl, 'redis.json', parameters('_artifactsLocationSasToken'))]" } } }, @@ -808,15 +623,15 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "subnetIdSan": { "value": "[reference('networkTemplate').outputs.subnetIdSan.value]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'gluster.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'gluster.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -845,22 +660,22 @@ "value": "[reference('networkTemplate').outputs.subnetIdSan.value]" }, "node0IPAddr": { - "value": "[variables('moodleCommon').nfsHaNode0IP]" + "value": "[variables('lampCommon').nfsHaNode0IP]" }, "node1IPAddr": { - "value": "[variables('moodleCommon').nfsHaNode1IP]" + "value": "[variables('lampCommon').nfsHaNode1IP]" }, "nfsClientsIPRange": { - "value": "[variables('moodleCommon').nfsHaClientsIPRange]" + "value": "[variables('lampCommon').nfsHaClientsIPRange]" }, "lbFrontEndIpAddr": { - "value": "[variables('moodleCommon').nfsHaLbIP]" + "value": "[variables('lampCommon').nfsHaLbIP]" }, "enableAccelNwSwitch": { "value": "[parameters('enableAccelNwForOtherVmsSwitch')]" }, "vmSku": { - "value": "[variables('moodleCommon').fileServerVmSku]" + "value": "[variables('lampCommon').fileServerVmSku]" }, "adminUserName": { "value": "[parameters('sshUsername')]" @@ -869,7 +684,7 @@ "value": "[parameters('sshPublicKey')]" }, "osType": { - "value": "[variables('moodleCommon').osType]" + "value": "[variables('lampCommon').osType]" }, "osDiskStorageType": { "value": "[parameters('osDiskStorageType')]" @@ -885,7 +700,7 @@ } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl, 'nfs-ha.json', parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl, 'nfs-ha.json', parameters('_artifactsLocationSasToken'))]" } } }, @@ -896,15 +711,14 @@ "Microsoft.Resources/deployments/networkTemplate", "Microsoft.Resources/deployments/dbTemplate", "Microsoft.Resources/deployments/redisTemplate", - "Microsoft.Resources/deployments/searchTemplate", "Microsoft.Resources/deployments/storageAccountTemplate" ], "name": "vmSetupParamsTemplate", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "dbFQDN": { "value": "[reference('dbTemplate').outputs.dbFQDN.value]" @@ -914,13 +728,10 @@ }, "redisKey": { "value": "[if(parameters('redisDeploySwitch'), reference('redisTemplate').outputs.redisKey.value, 'None')]" - }, - "azureSearchKey": { - "value": "[if(equals(parameters('searchType'), 'azure'), reference('searchTemplate').outputs.azureSearchKey.value, 'None')]" } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'vmsetupparams.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'vmsetupparams.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -935,15 +746,14 @@ "Microsoft.Resources/deployments/networkTemplate", "Microsoft.Resources/deployments/dbTemplate", "Microsoft.Resources/deployments/redisTemplate", - "Microsoft.Resources/deployments/searchTemplate", "Microsoft.Resources/deployments/storageAccountTemplate" ], "name": "controllerTemplate", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "subnetIdWeb": { "value": "[reference('networkTemplate').outputs.subnetIdWeb.value]" @@ -956,7 +766,7 @@ } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'controller.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'controller.json',parameters('_artifactsLocationSasToken'))]" } } }, @@ -974,8 +784,8 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[variables('moodleCommon')]" + "lampCommon": { + "value": "[variables('lampCommon')]" }, "subnetIdWeb": { "value": "[reference('networkTemplate').outputs.subnetIdWeb.value]" @@ -985,7 +795,7 @@ } }, "templateLink": { - "uri": "[concat(variables('moodleCommon').baseTemplateUrl,'webvmss.json',parameters('_artifactsLocationSasToken'))]" + "uri": "[concat(variables('lampCommon').baseTemplateUrl,'webvmss.json',parameters('_artifactsLocationSasToken'))]" } } } @@ -993,7 +803,7 @@ "outputs": { "siteURL": { "type": "string", - "value": "[variables('moodleCommon').siteURL]" + "value": "[variables('lampCommon').siteURL]" }, "controllerInstanceIP": { "type": "string", @@ -1005,50 +815,37 @@ }, "databaseAdminUsername": { "type": "string", - "value": "[variables('moodleCommon').dbUsername]" + "value": "[variables('lampCommon').dbUsername]" }, "databaseAdminPassword": { "type": "string", - "value": "[variables('moodleCommon').dbLoginPassword]" + "value": "[variables('lampCommon').dbLoginPassword]" }, "firstFrontendVmIP": { "type": "string", "value": "[reference('scaleSetTemplate').outputs.webvm1IP.value]" }, - "moodleAdminPassword": { - "type": "string", - "value": "[variables('moodleCommon').moodleAdminPass]" - }, - "moodleDbUsername": { - "type": "string", - "value": "[variables('moodleCommon').moodleDbUserAzure]" - }, - "moodleDbPassword": { - "type": "string", - "value": "[variables('moodleCommon').moodleDbPass]" - }, "loadBalancerDNS": { "type": "string", - "value": "[variables('moodleCommon').lbDns]" + "value": "[variables('lampCommon').lbDns]" }, "loadBalancerSku": { "type": "string", - "value": "[variables('moodleCommon').lbSku]" + "value": "[variables('lampCommon').lbSku]" } }, "variables": { - "documentation01": "This main-template calls multiple sub-templates to create the moodle system", + "documentation01": "This main-template calls multiple sub-templates to create the LAMP system", "documentation02": " recoveryservices0 - dummy template (see next statement)", "documentation03": " recoveryservices1 - creates a recovery vault that will be subsequently used by the VM Backup - a paramter swtich controls whethe is is called or bypassed", "documentation04": " redis - creates a redis cache", "documentation05": " postgres / mysql - creates a postgresql / mysql server", "documentation06": " vnet - creates a virtual network with three subnets", - "documentation07": " elastic - creates a elastic search cluster on a vm farm", - "documentation08": " gluster - creates a gluster file system on a vm farm", - "documentation09": " webvmss - creates a vm scale set", - "documentation10": " controller - creates a controller VM and deploys code", - "documentation11": "GlusterFS Sizing guidance", - "moodleCommon": { + "documentation07": " gluster - creates a gluster file system on a vm farm", + "documentation08": " webvmss - creates a vm scale set", + "documentation09": " controller - creates a controller VM and deploys code", + "documentation10": "GlusterFS Sizing guidance", + "lampCommon": { "baseTemplateUrl": "[concat(parameters('_artifactsLocation'), 'nested/')]", "scriptLocation": "[concat(parameters('_artifactsLocation'), 'scripts/')]", "artifactsSasToken": "[parameters('_artifactsLocationSasToken')]", @@ -1065,12 +862,6 @@ "autoscaleVmCountMin": "[parameters('autoscaleVmCountMin')]", "autoscaleVmSku": "[parameters('autoscaleVmSku')]", "azureBackupSwitch": "[parameters('azureBackupSwitch')]", - "azureSearchHostingMode": "[parameters('azureSearchHostingMode')]", - "azureSearchName": "[concat('azure-search-',variables('resourceprefix'))]", - "azureSearchNameHost": "[concat('azure-search-',variables('resourceprefix'),'.search.windows.net')]", - "azureSearchPartitionCount": "[parameters('azureSearchPartitionCount')]", - "azureSearchReplicaCount": "[parameters('azureSearchReplicaCount')]", - "azureSearchSku": "[parameters('azureSearchSku')]", "commonFunctionsScriptUri": "[concat(parameters('_artifactsLocation'),'scripts/helper_functions.sh',parameters('_artifactsLocationSasToken'))]", "controllerVmSku": "[parameters('controllerVmSku')]", "customVnetId": "[parameters('customVnetId')]", @@ -1085,20 +876,6 @@ "dbUsername": "[concat(parameters('dbLogin'), '@', parameters('dbServerType'), '-', variables('resourceprefix'))]", "ddosPlanName": "[concat('ddos-plan-',variables('resourceprefix'))]", "ddosSwitch": "[parameters('ddosSwitch')]", - "elasticVmSku": "[parameters('elasticVmSku')]", - "elasticAvailabilitySetName": "[concat('elastic-avset-',variables('resourceprefix'))]", - "elasticClusterName": "[concat('es-cluster-',variables('resourceprefix'))]", - "elasticNicName1": "[concat('elastic-vm-nic-01-',variables('resourceprefix'))]", - "elasticNicName2": "[concat('elastic-vm-nic-02-',variables('resourceprefix'))]", - "elasticNicName3": "[concat('elastic-vm-nic-03-',variables('resourceprefix'))]", - "elasticScriptFilename": "install_elastic.sh", - "elasticVm1IP": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),4)), '.20')]", - "elasticVm2IP": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),4)), '.21')]", - "elasticVm3IP": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),4)), '.22')]", - "elasticVmName": "[concat('elastic-vm-',variables('resourceprefix'))]", - "elasticVmName1": "[concat('elastic-vm-01-',variables('resourceprefix'))]", - "elasticVmName2": "[concat('elastic-vm-02-',variables('resourceprefix'))]", - "elasticVmName3": "[concat('elastic-vm-03-',variables('resourceprefix'))]", "enableAccelNwForCtlrVmSwitch": "[parameters('enableAccelNwForCtlrVmSwitch')]", "enableAccelNwForOtherVmsSwitch": "[parameters('enableAccelNwForOtherVmsSwitch')]", "extBeName": "[concat('lb-backend-',variables('resourceprefix'))]", @@ -1115,26 +892,17 @@ "gatewayPublicIPName": "[concat('vnet-gw-ip-',variables('resourceprefix'))]", "gatewayType": "[parameters('gatewayType')]", "gfsNameRoot": "[concat('gluster-vm-',variables('resourceprefix'))]", - "gfxAvailabilitySetName": "[concat('gluster-avset-',variables('resourceprefix'))]", + "gfsAvailabilitySetName": "[concat('gluster-avset-',variables('resourceprefix'))]", "glusterScriptFilename": "install_gluster.sh", "htmlLocalCopySwitch": "[parameters('htmlLocalCopySwitch')]", "httpsTermination": "[parameters('httpsTermination')]", - "installGdprPluginsSwitch": "[parameters('installGdprPluginsSwitch')]", - "installO365pluginsSwitch": "[parameters('installO365pluginsSwitch')]", - "installObjectFsSwitch": "[parameters('installObjectFsSwitch')]", "lbDns": "[concat('lb-',variables('resourceprefix'),'.',parameters('location'),'.cloudapp.azure.com')]", "lbSku": "[parameters('loadBalancerSku')]", "lbName": "[concat('lb-',variables('resourceprefix'))]", "lbPipName": "[concat('lb-pubip-',variables('resourceprefix'))]", "location": "[parameters('location')]", - "moodleAdminPass": "[concat(toUpper('xl'), substring(uniqueString(resourceGroup().id, deployment().name), 6, 7),',1*8')]", - "moodleDbName": "moodle", - "moodleDbPass": "[concat('9#36^', substring(uniqueString(resourceGroup().id, deployment().name), 5, 8), toUpper('ercq'))]", - "moodleDbUser": "moodle", - "moodleDbUserAzure": "[concat('moodle', '@', parameters('dbServerType'), '-', variables('resourceprefix'))]", - "moodleInstallScriptFilename": "install_moodle.sh", - "moodleOnAzureConfigsJsonPath": "/var/lib/cloud/instance/moodle_on_azure_configs.json", - "moodleVersion": "[parameters('moodleVersion')]", + "controllerInstallScriptFilename": "setup_controller.sh", + "lampOnAzureConfigsJsonPath": "/var/lib/cloud/instance/lamp_on_azure_configs.json", "mssqlDbServiceObjectiveName": "[parameters('mssqlDbServiceObjectiveName')]", "mssqlDbSize": "[parameters('mssqlDbSize')]", "mssqlDbEdition": "[parameters('mssqlDbEdition')]", @@ -1164,7 +932,6 @@ "redisDeploySwitch": "[parameters('redisDeploySwitch')]", "redisDns": "[concat('redis-',variables('resourceprefix'),'.redis.cache.windows.net')]", "resourcesPrefix": "[variables('resourceprefix')]", - "searchType": "[parameters('searchType')]", "serverName": "[concat(parameters('dbServerType'), '-',variables('resourceprefix'))]", "siteURL": "[if(or(empty(parameters('siteURL')), equals(parameters('siteURL'), 'www.example.org')), concat(if(equals(parameters('httpsTermination'), 'AppGw'),'appgw-','lb-'),variables('resourceprefix'),'.',parameters('location'),'.cloudapp.azure.com'), parameters('siteURL'))]", "sshPublicKey": "[parameters('sshPublicKey')]", @@ -1175,9 +942,6 @@ "subnetAppGw": "[concat('appgw-subnet-',variables('resourceprefix'))]", "subnetAppGwPrefix": "[concat(variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),6)))]", "subnetAppGwRange": "[concat(variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),6)), '.0/24')]", - "subnetElastic": "[concat('elastic-subnet-',variables('resourceprefix'))]", - "subnetElasticPrefix": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),5)))]", - "subnetElasticRange": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),5)), '.0/24')]", "subnetGateway": "GatewaySubnet", "subnetGatewayPrefix": "[concat(variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),4)))]", "subnetGatewayRange": "[concat(variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),4)), '.0/24')]", @@ -1187,20 +951,11 @@ "subnetSan": "[concat('san-subnet-',variables('resourceprefix'))]", "subnetSanPrefix": "[variables('subnetSanPrefix')]", "subnetSanRange": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),2)), '.0/24')]", - "subnetTika": "[concat('tika-subnet-',variables('resourceprefix'))]", - "subnetTikaPrefix": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),1)))]", - "subnetTikaRange": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),1)), '.0/24')]", "subnetWeb": "[concat('web-subnet-',variables('resourceprefix'))]", "subnetWebPrefix": "[concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),0)))]", "subnetWebRange": "[variables('subnetWebRange')]", "thumbprintSslCert": "[if(or(empty(parameters('keyVaultResourceId')), empty(parameters('sslCertThumbprint'))), 'None', parameters('sslCertThumbprint'))]", "thumbprintCaCert": "[if(or(empty(parameters('keyVaultResourceId')), empty(parameters('caCertThumbprint'))), 'None', parameters('caCertThumbprint'))]", - "tikaNicName": "[concat('tika-vm-nic-',variables('resourceprefix'))]", - "tikaScriptFilename": "install_tika.sh", - "tikaService": "[parameters('tikaService')]", - "tikaVmIP": "[if(equals(parameters('tikaService'), 'tika'), concat( variables('octets')[0], '.', variables('octets')[1], '.', string(add(int(variables('octets')[2]),5)), '.20'), 'none')]", - "tikaVmName": "[concat('tika-vm-',variables('resourceprefix'))]", - "tikaVmSku": "[parameters('tikaVmSku')]", "vNetAddressSpace": "[parameters('vNetAddressSpace')]", "vaultName": "[concat('vault-',variables('resourceprefix'))]", "vmssName": "[concat('vmss-',variables('resourceprefix'))]", @@ -1208,8 +963,7 @@ "vnetGwDeploySwitch": "[parameters('vnetGwDeploySwitch')]", "vnetName": "[concat('vnet-',variables('resourceprefix'))]", "vpnType": "[parameters('vpnType')]", - "webServerSetupScriptFilename": "setup_webserver.sh", - "webServerType": "[parameters('webServerType')]" + "webServerSetupScriptFilename": "setup_webserver.sh" }, "certUrlArray": [ { diff --git a/docs/Cleanup.md b/docs/Cleanup.md index a959531..623e656 100644 --- a/docs/Cleanup.md +++ b/docs/Cleanup.md @@ -1,6 +1,6 @@ # Cleanup All Resources -To cleanup a Moodle/LAMP deployment simply delete the Resource Group that +To cleanup a LAMP deployment simply delete the Resource Group that contains it. The commands below will iterate over your workspace directory and delete all deployments. @@ -10,13 +10,10 @@ First we need to ensure our [environment variables](./Environment-Variables.md) ## Remove each resource group -This command will delete all resources in *all* resource groups. Run -with caution. +This command will delete all resources in *all* resource groups. Run with caution. -Note, that this command will not fully delete the resource group if -you have Azure Backup enabled since the Recovery Services Vault will -not be deleted (it's got the backups of you data!). +Note, that this command will not fully delete the resource group if you have Azure Backup enabled since the Recovery Services Vault will not be deleted (it's got the backups of you data!). ``` bash -for filename in $MOODLE_AZURE_WORKSPACE/*; do az group delete --yes --name $(basename $filename) --no-wait; done +for filename in $LAMP_AZURE_WORKSPACE/*; do az group delete --yes --name $(basename $filename) --no-wait; done ``` diff --git a/docs/Deploy.md b/docs/Deploy.md index acd975a..6732dbb 100644 --- a/docs/Deploy.md +++ b/docs/Deploy.md @@ -1,37 +1,30 @@ -# Deploy Autoscaling Moodle Stack to Azure +# Deploy Autoscaling LAMP Stack to Azure -After following the steps in this this document you will have a -new Moodle site with caching for speed and scaling frontends to handle -load. The filesystem behind it is mirrored for high availability and -optionally backed up through Azure. Filesystem permissions and options -have also been tuned to make Moodle more secure than a default -install. +After following the steps in this this document you will have a new cluster with auto-scaling frontends, ready to host your LAMP applications at scale. +The filesystem behind it is mirrored for high availability and +optionally backed up through Azure. ## Prerequisites -To make things consitent across different sessions managing Moodle we +To make things consitent across different sessions managing the cluster we should [configure the environment](./Preparation.md). - ## Create Resource Group -When you create the Moodle cluster you will create many resources. On -Azure it is a best practice to collect such resources together in a -Resource Group. The first thing we need to do, therefore, is create a -resource group: +When you deploy the template, you will create many resources. On Azure it is a best practice to collect such resources together in a Resource Group. The first thing we need to do, therefore, is create a resource group: -``` -az group create --name $MOODLE_RG_NAME --location $MOODLE_RG_LOCATION +```sh +az group create --name $LAMP_RG_NAME --location $LAMP_RG_LOCATION ``` Results: ```expected_similarity=0.4 { - "id": "/subscriptions/325e7c34-99fb-4190-aa87-1df746c67705/resourceGroups/rgmoodlearm3", + "id": "/subscriptions/325e7c34-99fb-4190-aa87-1df746c67705/resourceGroups/rglamparm3", "location": "westus2", "managedBy": null, - "name": "rgmoodlearm3", + "name": "rglamparm3", "properties": { "provisioningState": "Succeeded" }, @@ -47,7 +40,7 @@ parameters interactively via the command line by simply omitting the paramaters file in the command in the next section. However, it is more reproducible if we use a paramaters file. -A good set of defaults are provided in the git repository. These +A good set of defaults are provided in the GitHub repository. These defaults create a scalable cluster that is suitable for low volume testing. If you are building out a production service you should review the section below on sizing considerations. For now we will @@ -57,13 +50,13 @@ placeholder in the parameters template file with an SSH key used for testing puporses (this is created as part of the envrionment setup in the prerequisites): -``` bash -ssh_pub_key=`cat $MOODLE_SSH_KEY_FILENAME.pub` +```sh +ssh_pub_key=`cat $LAMP_SSH_KEY_FILENAME.pub` echo $ssh_pub_key -sed "s|GEN-SSH-PUB-KEY|$ssh_pub_key|g" $MOODLE_AZURE_WORKSPACE/arm_template/azuredeploy.parameters.json > $MOODLE_AZURE_WORKSPACE/$MOODLE_RG_NAME/azuredeploy.parameters.json +sed "s|GEN-SSH-PUB-KEY|$ssh_pub_key|g" $LAMP_AZURE_WORKSPACE/arm_template/azuredeploy.parameters.json > $LAMP_AZURE_WORKSPACE/$LAMP_RG_NAME/azuredeploy.parameters.json ``` -If you'd like to configure the Moodle cluster (to be deployed) +If you'd like to configure the cluster (to be deployed) with your own SSL certificate for your domain (siteURL) at the deployment time, you can do so by using [Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/) and following the instructions in the [SSL cert documentation](SslCert.md). @@ -75,23 +68,26 @@ For more information see the [parameters documentation](Parameters.md). Now that we have a resource group and a configuration file we can create the cluster itself. This is done with a single command: -``` -az group deployment create --name $MOODLE_DEPLOYMENT_NAME --resource-group $MOODLE_RG_NAME --template-file $MOODLE_AZURE_WORKSPACE/arm_template/azuredeploy.json --parameters $MOODLE_AZURE_WORKSPACE/$MOODLE_RG_NAME/azuredeploy.parameters.json +```sh +az group deployment create \ + --name $LAMP_DEPLOYMENT_NAME \ + --resource-group $LAMP_RG_NAME \ + --template-file $LAMP_AZURE_WORKSPACE/arm_template/azuredeploy.json \ + --parameters $LAMP_AZURE_WORKSPACE/$LAMP_RG_NAME/azuredeploy.parameters.json ``` ## Using the created stack In testing, stacks typically took between 0.5 and 1 hour to finish, depending on spec. Once complete you will receive a JSON output -containing information needed to manage your Moodle install (see +containing information needed to manage your cluster (see `outputs`). You can also retrieve this infromation from the portal or the CLI. - -Once Moodle has been created, and (where necessary) you have + +Once the cluster has been created, and (where necessary) you have configured your custom `siteURL` DNS to point to the `loadBalancerDNS`, you should be able to load the `siteURL` in a -browser and login with the username "admin" and the -`moodleAdminPassword`. Note that the values for each of these +browser. Note that the values for each of these parameters are available in the portal or the `outputs` section of the JSON response from the previous deploy command. See [documentation on how to retrieve configuration data](./Get-Install-Data.md) along @@ -104,18 +100,11 @@ cluster](./Manage.md). ## Sizing Considerations and Limitations -Depending on what you're doing with Moodle you will want to configure -your deployment appropriately.The defaults included produce a cluster -that is inexpensive but probably too low spec to use beyond simple -testing scenarios. This section includes an overview of how to size -the database and VM instances for your use case. +Depending on the LAMP apps you deploy and the expected traffic, you will want to configure your deployment appropriately. The defaults included produce a cluster that is inexpensive but probably too low spec to use beyond simple testing scenarios. This section includes an overview of how to size the database and VM instances for your use case. ### Database Sizing -As of the time of this writing, Azure supports "Basic", "General Purpose" and "Memory Optimized" -tiers for MySQL/PostgreSQL database instances. In addition the mysqlPgresVcores defines -the number of vCores for each DB server instance, and the number of those you can use is limited by -database tier: +As of the time of this writing, Azure supports "Basic", "General Purpose" and "Memory Optimized" tiers for MySQL/PostgreSQL database instances. In addition the `mysqlPgresVcores` parameter defines the number of vCores for each DB server instance, and the number of those you can use is limited by database tier: - Basic: 1, 2 - General Purpose: 2, 4, 8, 16, 32 @@ -124,35 +113,25 @@ database tier: This value also limits the maximum number of connections, as defined here: https://docs.microsoft.com/en-us/azure/mysql/concepts-limits -As the Moodle database will handle cron processes as well as the -website, any public facing website with more than 10 users will likely -require upgrading to 2. Once the site reaches 30+ users it will -require upgrading to General Purpose for more compute units. This depends -entirely on the individual site. As MySQL databases cannot change (or -be restored to a different tier) once deployed it is a good idea to -slightly overspec your database. +The appropriate size for the database depends entirely on the individual sites and the traffic. As MySQL databases cannot change to (or be restored to) a different tier (e.g. Basic to General Purpose) once deployed, it is a good idea to slightly overspec your database. -All MySQL/PostgreSQL database storage, regardless of tier, has a hard upper limit of 1 -terabyte (1024 GB), starting from 5 GB minimum, increasing by 1 GB. You gain additional iops for each added GB, so if -you're expecting a heavy amount of traffic you will want to oversize -your storage. The current maximum iops with a 1TB disk is 3000. +All MySQL/PostgreSQL database storage, regardless of tier, have a hard upper limit of 1 +terabyte (1024 GB), starting from 5 GB minimum, increasing by 1 GB. You gain additional iops for each added GB, so if you're expecting a heavy amount of traffic you will want to oversize your storage. The current maximum iops with a 1TB disk is 3,000. ### Controller instance sizing -The controller handles both syslog and cron duties. Depending on how -big your Moodle cron runs are this may not be sufficient. If cron jobs -are very delayed and cron processes are building up on the controller -then an upgrade in tier is needed. +The controller primarily acts as a syslog server. + +Depending on the applications you are installing in your cluster, you might want to leverage the controller VM also for running cron jobs (example of applications which need that include Moodle, NextCloud, etc). In this case, sizing for the controller instance depends on how big your cron runs are; if they are very delayed and cron processes are building up on the controller, then an upgraded tier might be necessary. ### Frontend instances In general the frontend instances will not be the source of any bottlenecks unless they are severely undersized versus the rest of the -cluster. More powerful instances will be needed should fpm processes +cluster. More powerful instances will be needed should FPM processes spawn and exhaust memory during periods of heavy site load. This can -also be mitigated against by increasing the number of VMs but spawning -new VMs is slower (and potentially more expensive) than having that -capacity already available. +also be mitigated against by increasing the number of VMs, but spawning +new VMs is slower than having that capacity already available. It is worth noting that the memory allowances on these instances allow for more memory than they may be able to provide with lower instance @@ -165,4 +144,4 @@ during many small jobs. ## Next Steps 1. [Retrieve configuration details using CLI](./Get-Install-Data.md) - 1. [Manage the Moodle cluster](./Manage.md) + 1. [Manage the cluster](./Manage.md) diff --git a/docs/Environment-Variables.md b/docs/Environment-Variables.md index 998db85..1614b8e 100644 --- a/docs/Environment-Variables.md +++ b/docs/Environment-Variables.md @@ -1,132 +1,113 @@ # Environment Variables -In order to configure our deployment and tools we'll set up some -environment variables to ensure consistency. If you are running these -scripts through SimDem you can customize these values by copying and -editing `env.json` into `env.local.json`. +In order to configure our deployment and tools we'll set up some environment variables to ensure consistency. If you are running these scripts through SimDem you can customize these values by copying and editing `env.json` into `env.local.json`. -We'll need a unique name for our Resource Group in Azure, but when -running in an automated mode it is useful to have a (mostly) unique -name for your deployment and related resources. We'll use a timestamp. -If the environmnt variable `MOODLE_RG_NAME` is not set we will -create a new value using a timestamp: +We'll need a unique name for our Resource Group in Azure, but when running in an automated mode it is useful to have a (mostly) unique name for your deployment and related resources. We'll use a timestamp. If the environmnt variable `LAMP_RG_NAME` is not set we will create a new value using a timestamp: - -``` shell -if [ -z "$MOODLE_RG_NAME" ]; then MOODLE_RG_NAME=moodle_$(date +%Y-%m-%d-%H); fi +```sh +if [ -z "$LAMP_RG_NAME" ]; then LAMP_RG_NAME=lamp_$(date +%Y-%m-%d-%H); fi ``` -Other configurable values for our Azure deployment include the -location and depoloyment name. We'll standardize these, but you can -use different values if you like. +Other configurable values for our Azure deployment include the location and depoloyment name. We'll standardize these, but you can use different values if you like. -``` shell -MOODLE_RG_LOCATION=southcentralus -MOODLE_DEPLOYMENT_NAME=MasterDeploy +```sh +LAMP_RG_LOCATION=southcentralus +LAMP_DEPLOYMENT_NAME=MasterDeploy ``` -We also need to provide an SSH key. Later we'll generate this if it -doesn't already exist but to enable us to reuse an existing key we'll -store it's filename in an Environment Variable. +We also need to provide an SSH key. Later, we'll generate this if it doesn't already exist but to enable us to reuse an existing key we'll store it's filename in an Environment Variable. -``` shell -MOODLE_SSH_KEY_FILENAME=~/.ssh/moodle_id_rsa +```sh +LAMP_SSH_KEY_FILENAME=~/.ssh/lamp_id_rsa ``` We need a workspace for storing configuration files and other per-deployment artifacts: -``` shell -MOODLE_AZURE_WORKSPACE=~/.moodle +```sh +LAMP_AZURE_WORKSPACE=~/azure-lamp ``` ## Create Workspace Ensure the workspace for this particular deployment exists: -``` -mkdir -p $MOODLE_AZURE_WORKSPACE/$MOODLE_RG_NAME +```sh +mkdir -p $LAMP_AZURE_WORKSPACE/$LAMP_RG_NAME ``` ## Validation -After working through this file there should be a number of -environment variables defined that will be used to provide a common -setup for all our Moodle on Azure work. +After working through this file there should be a number of environment variables defined that will be used to provide a common setup for all our LAMP on Azure work. -The resource group name defines the name of the group into which all -resources will be, or are, deployed. +The resource group name defines the name of the group into which all resources will be, or are, deployed. -```bash -echo "Resource Group for deployment: $MOODLE_RG_NAME" +```sh +echo "Resource Group for deployment: $LAMP_RG_NAME" ``` Results: -``` +```text Resource Group for deployment: southcentralus ``` The resource group location is: -```bash -echo "Deployment location: $MOODLE_RG_LOCATION" +```sh +echo "Deployment location: $LAMP_RG_LOCATION" ``` Results: -``` +```text Deployment location: southcentralus ``` -When deploying a Moodle cluster the deployment will be given a name so -that it can be identified later should it be neceessary to debug. +When deploying a LAMP cluster the deployment will be given a name so that it can be identified later should it be neceessary to debug. - -```bash -echo "Deployment name: $MOODLE_DEPLOYMENT_NAME" +```sh +echo "Deployment name: $LAMP_DEPLOYMENT_NAME" ``` Results: -``` +```text Deployment name: MasterDeploy ``` -The SSH key to use can be found in a file, if necessary this will be -created as part of these scripts. +The SSH key to use can be found in a file, if necessary this will be created as part of these scripts. -``` shell -echo "SSH key filename: $MOODLE_SSH_KEY_FILENAME" +```sh +echo "SSH key filename: $LAMP_SSH_KEY_FILENAME" ``` Results: -``` -SSH key filename: ~/.ssh/moodle_id_rsa +```text +SSH key filename: ~/.ssh/lamp_id_rsa ``` Configuration files will be written to / read from a customer directory: -``` shell -echo "Workspace directory: $MOODLE_AZURE_WORKSPACE" +```sh +echo "Workspace directory: $LAMP_AZURE_WORKSPACE" ``` Results: -``` -Workspace directory: ~/.moodle +```text +Workspace directory: ~/azure-lamp ``` Ensure the workspace directory exists: - -``` bash -if [ ! -f "$MOODLE_AZURE_WORKSPACE/$MOODLE_RG_NAME" ]; then echo "Workspace exists"; fi +```sh +if [ ! -f "$LAMP_AZURE_WORKSPACE/$LAMP_RG_NAME" ]; then echo "Workspace exists"; fi ``` Results: -``` +```text Workspace exists ``` diff --git a/docs/Generalize-To-Lamp.md b/docs/Generalize-To-Lamp.md deleted file mode 100644 index d37c499..0000000 --- a/docs/Generalize-To-Lamp.md +++ /dev/null @@ -1,162 +0,0 @@ - -# Deploy and Manage an (empty) Scalable LAMP Cluster on Azure - -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 -[LAMP](https://en.wikipedia.org/wiki/LAMP_(software_bundle)) cluster on Azure. I - -If you have Azure account you can deploy LAMP via the [Azure portal](https://portal.azure.com) using the button below. 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. - -## Fully configurable deployment - -The following button will allow you to specify various configurations for your LAMP cluster -deployment. The number of configuration options might be overwhelming, so some pre-defined/restricted deployment options for -typical LAMP scenarios follow this. - -[![Deploy to Azure Fully Configurable](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) - -NOTE: All of the deployment options require you to provide a valid SSH protocol 2 (SSH-2) RSA public-private key pairs with a minimum length of 2048 bits. Other key formats such as ED25519 and ECDSA are not supported. If you are unfamiliar with SSH then you should read this [article](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/mac-create-ssh-keys) which will explain how to generate a key using the Windows Subsystem for Linux (it's easy and takes only a few minutes). If you are new to SSH, remember SSH is a key pair solution. What this means is you have a public key and a private key, and the one you will be using to deploy your template is the public key. - -## Predefined deployment options -Below are a list of pre-defined/restricted deployment options based on typical deployment scenarios (i.e. dev/test, production etc.) All configurations are fixed and you just need to pass your ssh public key to the template for logging in to the deployed VMs. Please note that the actual cost will be bigger with potentially autoscaled VMs, backups and network cost. - -| Deployment Type | Description | Estimated Cost | Launch | -| --- | --- | --- | --- -| Minimal | This deployment will use NFS, Microsoft SQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores currently that'll fit even in a free trial Azure subscription.|[link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1)|[![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%2Fhs-lampgen%2Fazuredeploy-minimal.json) -| Small to Mid-Size | Supporting up to 1000 concurrent users. This deployment will use NFS (no high availability) and MySQL (8 vCores), without other options like elastic search or redis cache.|[link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc)|[![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%2Fhs-lampgen%2Fazuredeploy-small2mid-noha.json) -|Large size deployment (with high availability)| Supporting more than 2000 concurrent users. This deployment will use Gluster (for high availability, requiring 2 VMs), MySQL (16 vCores) and redis cache, without other options like elastic search. |[link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7)|[![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%2Fhs-lampgen%2Fazuredeploy-large-ha.json) -| Maximum |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).|[link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5)|[![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%2Fhs-lampgen%2Fazuredeploy-maximal.json) - -NOTE: Depending on the region you choose to deploy the stack in - the deployment might fail due to SKUs being hardcoded in the template where they are not available. For example, today our small-mid-size deployment option hard codes Gen-4 Azure MySQL SKUs into the template, and if a region where that is currently not available in (i.e. westus2) is used, your deployment will fail. If your deployment fails, please revert to the fully configurable template where possible and change the SKU paramater to one that exists in your region (i.e. Gen-5) or alternatively change your deployment region to one in which the SKU is available (i.e. southcentralus). - -## Stack Architecture - -This template set deploys the following infrastructure core to your LAMP instance: -- Autoscaling web frontend layer (Nginx for https termination, Varnish for caching, Apache/php or nginx/php-fpm) -- Private virtual network for frontend instances -- Controller instance running cron and handling syslog for the autoscaled site -- [Azure Load balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to balance across the autoscaled instances -- [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/) -- Dual [GlusterFS](https://www.gluster.org/) nodes or NFS for high availability access to LAMP files - - -For a more detailed discussion of how to contribute see our [Contribution Guide](CONTRIBUTE.md). - -## Code of Conduct - -This project has adopted the [Microsoft Open Source Code of -Conduct](https://opensource.microsoft.com/codeofconduct/). For more -information see the [Code of Conduct -FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact -[opencode@microsoft.com](mailto:opencode@microsoft.com) with any -additional questions or comments. - -## Legal Notices - -Microsoft and any contributors grant you a license to the Microsoft -documentation and other content in this repository under the [Creative -Commons Attribution 4.0 International Public -License](https://creativecommons.org/licenses/by/4.0/legalcode), see -the [LICENSE](LICENSE) file, and grant you a license to any code in -the repository under the [MIT -License](https://opensource.org/licenses/MIT), see the -[LICENSE-CODE](LICENSE-CODE) file. - -Microsoft, Windows, Microsoft Azure and/or other Microsoft products -and services referenced in the documentation may be either trademarks -or registered trademarks of Microsoft in the United States and/or -other countries. The licenses for this project do not grant you rights -to use any Microsoft names, logos, or trademarks. Microsoft's general -trademark guidelines can be found at -http://go.microsoft.com/fwlink/?LinkID=254653. - -Privacy information can be found at https://privacy.microsoft.com/en-us/ - -Microsoft and any contributors reserve all others rights, whether -under their respective copyrights, patents, or trademarks, whether by -implication, estoppel or otherwise. - -## Next Steps - -# Prepare deployed cluster for LAMP applications - -If you chose Apache as your `webServerType` and `true` for the `htmlLocalCopy` switch at your LAMP cluster deployment time, you can install additional LAMP sites on your cluster, utilizing Apache's VirtualHost feature (we call this "LAMP generalization"). To manage your installed cluster, you'll first need to login to the LAMP cluster controller virtual machine. The directory you'll need to work out of is `/azlamp`. You will need privileged access which means that you'll either need to be root (superuser) or have *sudo* access. - - -## Configuring the controller for a specific LAMP application (WordPress) - - -### Installation Destination -An example LAMP application (WordPress) is illustrated here for the sake of clarity. The approach is similar to any LAMP application out there. - -First, you'd need to navigate to `/azlamp/html` and create a directory based on a domain name you have in mind. An example domain name is used below: - -``` -cd /azlamp/html -mkdir wpsitename.mydomain.com -cd /azlamp/html/wpsitename.mydomain.com -``` - -Once that's done and you've downloaded the latest version of WordPress, please follow the instructions here to complete configuring a database and finishing a [WordPress install](https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Installation). - -``` -wget https://wordpress.org/latest.tar.gz -tar xvfz latest.tar.gz --strip 1 -``` - - -### SSL Certs - -The certificates for your LAMP application reside in `/azlamp/certs/yourdomain` or in this instance, `/azlamp/certs/wpsitename.mydomain.com` - -``` -mkdir /azlamp/certs/wpsitename.mydomain.com -``` - -Copy over the .crt and .key files over to `/azlamp/certs/wpsitename.mydomain.com`. -The file names should be changed to `nginx.crt` and `nginx.key` in order to be recognized by the configured nginx servers. Depending on your local environment, -you may choose to use the utility *scp* or a tool like [WinSCP](https://winscp.net/eng/download.php) to copy these files over to the cluster controller virtual machine. - -It's recommended that the certificate files be read-only to owner and that these files are owned by *www-data*: - -``` -chown www-data:www-data /azlamp/certs/wpsitename.mydomain.com/* -chmod 400 /azlamp/certs/wpsitename.mydomain.com/* -``` - - -### Linking to the content/cluster data location - -Navigate to the WordPress content directory and run the following command: - -``` -mkdir -p /azlamp/data/wpsitename.mydomain.com/wp-content/uploads -cd /azlamp/html/wpsitename.mydomain.com -ln -s /azlamp/data/wpsitename.mydomain.com/wp-content/uploads . -``` - -This step is needed because the `/wp-content/uploads` directory need to be shared across all web frontend instances, and Wordpress configuration doesn't allow an external directory to be used as the uploads repository. In fact, Drupal also has a similar design, so a similar symbolic link will be needed for Drupal as well. This is in contrary to Moodle, which allows users to configure any external directory as its file storage location. - -### Update Apache configurations on all web frontend instances - -Once the correspnding html/data/certs directories are configured, we need to reconfigure all Apache services on web frontend instances, so that newly created sites are added to the Apache VirtualHost configurations and deleted sites are removed from them as well. This is done by the `/azlamp/bin/update-vmss-config` hook (executed every minute on each and every VMSS instance using a cron job), which requires us to provide the commands to run (to reconfigure Apache service) on each VMSS instance. There's already a utility script installed for that, so it's easy to achieve as follows. - -On the controller machine, look up the file `/azlamp/bin/update-vmss-config`. If you haven't modified that file, you'll see the following lines in the file: - -``` - #1) - # . /azlamp/bin/utils.sh - # reset_all_sites_on_vmss true VMSS apache - #;; -``` - -Remove all the leading `#` characters from these lines (uncommenting) and save the file, then wait for a minute. After that, your newly added sites should be available through the domain names specified/used as the directory names (Of course this assumes you set up your DNS records for your new site FQDNs so that their CNAME records point to the deployed Moodle cluster's load balancer DNS name, whis is of the form `lb-xyz123.an_azure_region.cloudapp.azure.com`). - -If you are adding sites for the second or later time, you'll already have the above lines commented out. Just create another `case` block, copying the 4 lines, but make sure to change the number so that it's one greater than the last VMSS config version number (you should be able to find that from the script). - -<<<<<<< HEAD -At this point, your LAMP application is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. -======= -The last step is to let the `/azlamp/html` directory sync with `/var/www/html` in every VMSS instance. This should be done by running `/usr/local/bin/update_last_modified_time.azlamp.sh` script on the controller machine as root. Once this is run and after a minute, the `/var/www/html` directory on every VMSS instance should be the same as `/azlamp/html`, and the newly added sites should be available. - -At this point, your LAMP application is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. ->>>>>>> hs-lampgen diff --git a/docs/Get-Install-Data.md b/docs/Get-Install-Data.md index 26a653c..e27e751 100644 --- a/docs/Get-Install-Data.md +++ b/docs/Get-Install-Data.md @@ -1,154 +1,128 @@ # Retrieve essential install details -Once a deployment has completed the ARM template will output some -values that you will need for managing your Moodle installation. These -are available in the portal, but in this document we will retrieve -them using the AZ command line tools and through the AZ CLI tool. This -document describes the available parameters and how to retrieve them. +Once a deployment has completed the ARM template will output some values that you will need for managing your cluster. These are available in the Azure Portal too, but in this document we will retrieve them using the Azure CLI. This document describes the available parameters and how to retrieve them. ## Prerequisites -In order to configure our deployment and tools we'll set up some -[environment variables](./Environment-Variables.md) to ensure consistency. +In order to configure our deployment and tools we'll set up some [environment variables](./Environment-Variables.md) to ensure consistency. ## Output Paramater Overview The available output parameters are: - - **siteURL**: If you provided a `siteURL` parameter when deploying this - will be set to the supplied value. Otherwise it will be the same as - the loadBalancerDNS, see below. - - **loadBalancerDNS**: This is the DNS name of your application load - balancer. If you provided a `siteURL` parameter when deploying - you'll need to add a CNAME entry in your DNS zone that should point to this address. - - **moodleAdminPassword**: The generated password for the "admin" user - in your Moodle install. + - **loadBalancerDNS**: This is the DNS name of your application load balancer. To add a custom domain, you'll need to add a CNAME entry in your DNS zone that should point to this address. - **controllerInstanceIP**: This is the IP address of the controller Virtual Machine. You will need to SSH into this to make changes to - your Moodle code or view logs. - - **databaseDNS**: This is the public DNS of your database instance. If - you wish to set up local backups or access the DB directly, you'll - need to use this. - - **databaseAdminUsername**: The admin username for your database - (this is not the same as your Moodle username). - - **databaseAdminPassword**: The admin password for your - database (this is not the same as your Moodle password). + your applications' code, or view logs. + - **databaseDNS**: This is the public DNS of your database instance. If you wish to set up local backups or access the DB directly, you'll need to use this. (Note that by default, firewall rules forbid access to the database from external resources; you can configure the database's firewall using the Azure Portal) + - **databaseAdminUsername**: The admin username for your database (MySQL, PostgreSQL or Azure SQL). + - **databaseAdminPassword**: The admin password for your database (MySQL, PostgreSQL or Azure SQL). ## Retrieving Output Parameters Using the CLI To get a complete list of outputs in json format use: -```bash -az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out json --query *.outputs +```sh +az group deployment show \ + --resource-group $LAMP_RG_NAME \ + --name $LAMP_DEPLOYMENT_NAME \ + --out json \ + --query *.outputs ``` Individual outputs can be retrieved by filtering, for example, to get -just the value of the `siteURL` use: +just the value of the `loadBalancerDNS` use: -``` bash -az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out json --query *.outputs.siteURL.value +```sh +az group deployment show \ + --resource-group $LAMP_RG_NAME \ + --name $LAMP_DEPLOYMENT_NAME \ + --out json \ + --query *.outputs.loadBalancerDNS.value ``` However, since we are requesting JSON output (the default) the value is enclosed in quotes. In order to remove these we can output as a tab separated list (TSV): -``` bash -az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.siteURL +```sh +az group deployment show \ + --resource-group $LAMP_RG_NAME \ + --name $LAMP_DEPLOYMENT_NAME \ + --out tsv \ + --query *.outputs.loadBalancerDNS ``` Now we can assign individual values to environment variables, for example: -``` bash -MOODLE_SITE_URL="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.siteURL.value)" +```sh +LAMP_LOAD_BALANCER_DNS="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.loadBalancerDNS.value)" ``` -### Retrieving Moodle Site URL - -The Site URL is the value used to configure Moodle's base URL. The -site URL can be provided as an input to the template via the parameter -`siteURL`, in which case you will not need to retrieve this from the -outputs. However, if you do not define this, or if you leave it as the -default "www.example.org" you will need to retrieve this value from -Azure using the following command: - -```bash -MOODLE_SITE_URL="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.siteURL.value)" -``` - -#### Retrieving Moodle Site Load Balancer URL +### Retrieving Site Load Balancer URL The load balancer DNS is the publicly registered DNS name for your -Moodle DNS. If this is different from the site URL it is important to -ensure that you configure your DNS entry for site URL to point at the -load balancer. +cluster's DNS. You should point your custom domain to this hostname, with a CNAME record. -```bash -MOODLE_LOAD_BALANCER_DNS="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.loadBalancerDNS.value)" -``` - -### Retrieving Moodle Administrator Password - -Moodle admin password (username is "admin"): - -```bash -MOODLE_ADMIN_PASSWORD="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.moodleAdminPassword.value)" +```sh +LAMP_LOAD_BALANCER_DNS="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.loadBalancerDNS.value)" ``` ### Retriving Controller Virtual Machine Details -The controller VM runs management tasks for the cluster, such as cron jobs and syslog. +The controller VM runs management tasks for the cluster, such as syslog. -```bash -MOODLE_CONTROLLER_INSTANCE_IP="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.controllerInstanceIP.value)" +```sh +LAMP_CONTROLLER_INSTANCE_IP="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.controllerInstanceIP.value)" ``` -There is no username and password for this VM since a username and SSH -key are provided as input parameters to the template. +There is no username and password for this VM since a username and SSH key are provided as input parameters to the template. ### Retreiving Database Information #### Database URL -``` bash -MOODLE_DATABASE_DNS="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseDNS.value)" +```sh +LAMP_DATABASE_DNS="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseDNS.value)" ``` + #### Database admin username -``` bash -MOODLE_DATABASE_ADMIN_USERNAME="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseAdminUsername.value)" +```sh +LAMP_DATABASE_ADMIN_USERNAME="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseAdminUsername.value)" ``` #### Database admin password -``` bash -MOODLE_DATABASE_ADMIN_PASSWORD="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseAdminPassword.value)" +```sh +LAMP_DATABASE_ADMIN_PASSWORD="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.databaseAdminPassword.value)" ``` -### Retrieving Moodle Application VNET Information +### Retrieving Virtual Network Information First frontend VM IP: -``` bash -MOODLE_FIRST_FRONTEND_VM_IP="$(az group deployment show --resource-group $MOODLE_RG_NAME --name $MOODLE_DEPLOYMENT_NAME --out tsv --query *.outputs.firstFrontendVmIP.value)" +```sh +LAMP_FIRST_FRONTEND_VM_IP="$(az group deployment show --resource-group $LAMP_RG_NAME --name $LAMP_DEPLOYMENT_NAME --out tsv --query *.outputs.firstFrontendVmIP.value)" ``` -# Validation +This will be a private IP, inside the Virtual Network. You can connect to this VM using the controller instance as jumpbox, and SSH agent forwarding (see the instructions in the [Readme](./Readme.md)) + +## Validation After having run each of the commands in this document you should have each of the output parameters available in environment variable: -``` bash -echo $MOODLE_SITE_URL -echo $MOODLE_LOAD_BALANCER_DNS -echo $MOODLE_ADMIN_PASSWORD -echo $MOODLE_CONTROLLER_INSTANCE_IP -echo $MOODLE_DATABASE_DNS -echo $MOODLE_DATABASE_ADMIN_USERNAME -echo $MOODLE_DATABASE_ADMIN_PASSWORD -echo $MOODLE_FIRST_FRONTEND_VM_IP +```sh +echo $LAMP_LOAD_BALANCER_DNS +echo $LAMP_ADMIN_PASSWORD +echo $LAMP_CONTROLLER_INSTANCE_IP +echo $LAMP_DATABASE_DNS +echo $LAMP_DATABASE_ADMIN_USERNAME +echo $LAMP_DATABASE_ADMIN_PASSWORD +echo $LAMP_FIRST_FRONTEND_VM_IP ``` ## Next Steps - 1. [Manage the Moodle cluster](./Manage.md) + 1. [Manage the cluster](./Manage.md) diff --git a/docs/Manage.md b/docs/Manage.md index 2b8124f..08a54b0 100644 --- a/docs/Manage.md +++ b/docs/Manage.md @@ -1,7 +1,7 @@ -# Managing a Scalable Moodle Cluster in Azure +# Managing a Scalable LAMP Cluster in Azure This document provides an overview of how to perform various -management tasks on a scalable Moodle cluster on Azure. +management tasks on a scalable LAMP cluster on Azure. ## Prerequisites @@ -9,42 +9,35 @@ In order to configure our deployment and tools we'll set up some [environment variables](./Environment-Variables.md) to ensure consistency. In order to manage a cluster it is clearly necessary to first [deploy -a scalable Moodle cluster on Azure](./Deploy.md). +a scalable LAMP cluster on Azure](./Deploy.md). For convenience and readability this document also assumes that essential [deployment details for your cluster have been assigned to environment variables](./Get-Install-Data.md). -## Updating Moodle code/settings +## Updating PHP application code/settings -Your controller Virtual Machine has Moodle/LAMP code and data stored in +Your controller Virtual Machine has your PHP applications' code and data stored in `/azlamp`. The site code is stored in `/azlamp/html//`. If `gluster` or `nfs-ha` is selected for the `fileServerType` parameter at the deployment time, this data is replicated across dual gluster or NFS-HA nodes to provide high -availability. This directory is also mounted to your autoscaled +availability. This directory is also mounted to your autoscaling frontends so all changes to files on the controller VM are immediately available to all frontend machines (when the `htmlLocalCopySwitch` in `azuredeploy.json` -is false--otherwise, see below). Note that any updates on Moodle code/settings -(e.g., additional plugin installations, Moodle version upgrade) have to be done -on the controller VM using shell commands, not through a web browser, because the -HTML directory's permission is read-only for the web frontend VMs (thus any web-based -Moodle code updates will fail). +is false–otherwise, see below). + +Note that **the HTML directory is read-only for the web frontend VMs**. This means that any updates to your code or settings need to be done on the controller VM, manually replacing files or through shell commands, not a web browser. For example, you won't be able to use web-based admin tools that some applications offer (like WordPress, Drupal, Moodle...) to automatically update the codebase, install plugins and templates, etc. Depending on how large your Gluster/NFS disks are sized, it may be helpful -to keep multiple older versions (`/azlamp/html/site1`, `/azlamp/html-backups/site1`, etc) to -roll back if needed. +to keep multiple older versions (`/azlamp/html/site1`, `/azlamp/html-backups/site1`, etc) to roll back if needed. -To connect to your Controller VM use SSH with a username of -`azureadmin` and the SSH provided in the `sshPublicKey` input -parameter. For example, to retrieve a listing of files and directories -in the `/azlamp` directory use: +To connect to your Controller VM use SSH with a username of `azureadmin` (this can be changed with the `adminUsername` parameter when deploying the template) and the SSH provided in the `sshPublicKey` input parameter. For example, to retrieve a listing of files and directories in the `/azlamp` directory use: -``` -ssh -o StrictHostKeyChecking=no azureadmin@$MOODLE_CONTROLLER_INSTANCE_IP ls -l /azlamp +```sh +ssh -o StrictHostKeyChecking=no azureadmin@$LAMP_CONTROLLER_INSTANCE_IP ls -l /azlamp ``` Results: -``` -Warning: Permanently added '52.228.45.38' (ECDSA) to the list of known hosts. +```text total 32 drwxr-xr-x 2 root root 4096 Aug 28 18:27 bin drwxr-xr-x 5 root root 4096 Aug 8 16:49 certs @@ -52,88 +45,98 @@ drwxr-xr-x 5 root root 4096 Aug 8 16:52 data drwxr-xr-x 5 root root 4096 Aug 8 16:48 html ``` -**IMPORTANT NOTE** - -It is important to realize that the `-o StrictHostKeyChecking=no` -option in the above SSH command presents a security risk. It is -included here to facilitate automated validation of these commands. It -is not recommended to use this option in production environments, -instead run the command manually and validate the host key. -Subsequent executions of an SSH command will not require this -validation step. For more information there is an excellent -[superuser.com +> **Important note** It is important to realize that the `-o StrictHostKeyChecking=no` option in the above SSH command presents a security risk. It is included here to facilitate automated validation of these commands. It is not recommended to use this option in production environments, instead run the command manually and validate the host key. Subsequent executions of an SSH command will not require this validation step. For more information there is an excellent [superuser.com Q&A](https://superuser.com/questions/421074/ssh-the-authenticity-of-host-host-cant-be-established/421084#421084). -### If you set `htmlLocalCopySwitch` to true (this is the default now) +### If you set `htmlLocalCopySwitch` to true (this is the default option) -Originally the `/azlamp/html` directory was accessed by web server processes directly across all autoscaled -web VMs through the specified file server (Gluster or NFS), and this is -not good for web response time. Therefore, we introduced the -`htmlLocalCopySwitch` that'll copy the `/azlamp/html` directory to -`/var/www/html` in each autoscaled web VM and reconfigures the web -server (apache/nginx)'s server root directory accordingly, when it's set -to true. This now requires directory sync between `/azlamp/html` and -`/var/www/html`, and currently it's addressed by simple polling -(minutely). Therefore, if you are going to update your Moodle -code/settings with the switch set to true, please follow the -following steps: +Originally the `/azlamp/html` directory was accessed by web server processes directly across all autoscaled web VMs through the specified file server (Gluster or NFS), and this is was good for web response time. Therefore, we introduced the `htmlLocalCopySwitch` that'll copy the `/azlamp/html` directory to `/var/www/html` in each autoscaled web VM and reconfigures the (nginx) web server's server root directory accordingly, when it's set to true. This now requires directory sync between `/azlamp/html` and `/var/www/html`, and currently it's addressed by simple polling (minutely). Therefore, if you are going to update your application's PHP code/settings with the switch set to true, please follow the following steps: -* Put your Moodle site to maintenance mode. +* Depending on the application that you're running, you might want to put it in maintenance mode first, if possible (this is application-specific). * This will need to be done on the contoller VM with some shell command. * It should be followed by running the following command to propagate the change to all autoscaled web VMs: - ```bash - $ sudo /usr/local/bin/update_last_modified_time.moodle_on_azure.sh + ```sh + sudo /usr/local/bin/update_last_modified_time.azlamp.sh ``` * Once this command is executed, each autoscaled web VM will pick up (sync) the changes within 1 minute, so wait for one minute. -* Then you can start updating your Moodle code/settings, like installing/updating plugins or upgrading Moodle version or changing Moodle configurations. Again, note that this should be all done on the controller VM using some shell commands. -* When you are done updating your Moodle code/settings, run the same command as above to let each autoscaled web VM pick up (sync) the changes (wait for another minute here, for the same reason). +* Then you can start updating your application's code/settings, like installing/updating plugins, or upgrading version, or changing configurations stored in files. Again, note that this should be all done on the controller VM using some shell commands, or manually replacing files using SFTP (file transfer over SSH). +* When you are done updating your code/settings, run the same command as above (`sudo /usr/local/bin/update_last_modified_time.azlamp.sh`) to let each autoscaled web VM pick up (sync) the changes (wait for another minute here, for the same reason). -Please do let us know on this Github repo's Issues if you encounter any problems with this process. +Please do let us know on this GitHub repo's Issues if you encounter any problems with this process. -## Getting an SQL dump +### SSH Access to other VMs in the cluster -By default a daily sql dump of your database is taken at 02:22 and -saved to `/azlamp/data//db-backup.sql.gz`. This file can be retrieved -using SCP or similar. For example: +By default, only the Controller VM has port 22 open to accept connections from external clients. The LAMP cluster is designed to be fully automated and self-healing, and all of the webservers' logs are sent to the Controller VM. -``` bash -scp azureadmin@$MOODLE_CONTROLLER_INSTANCE_IP:/azlamp/data//db-backup.sql.gz /tmp/moodle-db-backup.sql.gz +In the rare case you need to connect to another VM inside the cluster (e.g. one of the web servers in the VMSS cluster, or a GlusterFS node), you can use the controller VM as jumpbox, and connect using SSH agent forwarding. + +First, identify the private IP of the VM you want to connect to inside the cluster. By default, VMs are in the `172.31.0.0/16` address space (configurable with the `vNetAddressSpace` property), and you can see the list of VMs connected to a Virtual Network by looking at the VNet on the Azure Portal. + +The next step is to enable SSH agent forwarding **on your laptop**. On Linux, macOS and on Windows 10 using the Windows Subsystem for Linux, assuming your SSH private key is in `~/.ssh/id_rsa`, first add the private key to your SSH agent with: + +```sh +# On your laptop: +ssh-add ~/.ssh/id_rsa +# If the private key has a password, you'll be asked to type it ``` -To obtain a more recent SQL dump you run the commands appropriate for -your chosen database on the Controller VM. The following sections will -help with this task. +Connect to the public IP or DNS name of the controller VM, making sure to specify the `-A` switch to enable forwarding of your SSH agent: -#### Postgres +```sh +# On your laptop: +ssh -A user@ip-or-dns +``` -Postgress provides a `pg_dump` command that can be used to take a +Once you're connected via SSH to the controller, you can jump to other nodes connecting via SSH to their private IPs. For example: + +```sh +# From the controller (connected via SSH) +# "private-ip" is something like 172.31.0.5 +ssh private-ip +``` + +## Getting a database dump + +To obtain a SQL dump you run the commands appropriate for your chosen database on the Controller VM. + +### PostgreSQL + +PostgreSQL provides a `pg_dump` command that can be used to take a snapshot of the database via SSH. For example, use the following -command: +command (make sure to specify the database name replacing `database_name`): -``` bash -ssh azureadmin@$MOODLE_CONTROLLER_INSTANCE_IP 'pg_dump -Fc -h $MOODLE_DATABASE_DNS -U $MOODLE_DATABASE_ADMIN_USERNAME moodle > /azlamp/data//db-snapshot.sql' +```sh +ssh azureadmin@$LAMP_CONTROLLER_INSTANCE_IP 'pg_dump -Fc -h $LAMP_DATABASE_DNS -U $LAMP_DATABASE_ADMIN_USERNAME database_name | gzip > /azlamp/data//db-snapshot.sql.gz' +``` + +You can also download the file directly to your laptop: + +```sh +ssh azureadmin@$LAMP_CONTROLLER_INSTANCE_IP 'pg_dump -Fc -h $LAMP_DATABASE_DNS -U $LAMP_DATABASE_ADMIN_USERNAME database_name' | gzip > db-snapshot.sql.gz' ``` See the Postgres documentation for full details of the [`pg_dump`](https://www.postgresql.org/docs/9.5/static/backup-dump.html) command. -#### MySQL +### MySQL MySQL provides a `mysql_dump` command that can be used to take a snapshot of the database via SSH. For example, use the following -command: +command (make sure to specify the database name replacing `database_name`): -``` bash -ssh azureadmin@$MOODLE_CONTROLLER_INSTANCE_IP 'mysqldump -h $mysqlIP -u ${azuremoodledbuser} -p'${moodledbpass}' --databases ${moodledbname} | gzip > /azlamp/data//db-backup.sql.gz' +```sh +ssh azureadmin@$LAMP_CONTROLLER_INSTANCE_IP 'mysqldump -h $LAMP_DATABASE_DNS -u $LAMP_DATABASE_ADMIN_USERNAME -p'${LAMP_DATABASE_ADMIN_PASSWORD}' --databases database_name | gzip > /azlamp/data//db-backup.sql.gz' +``` + +You can also download the file directly to your laptop: + +```sh +ssh azureadmin@$LAMP_CONTROLLER_INSTANCE_IP 'mysqldump -h $LAMP_DATABASE_DNS -u $LAMP_DATABASE_ADMIN_USERNAME -p'${LAMP_DATABASE_ADMIN_PASSWORD}' --databases database_name' | gzip > db-backup.sql.gz' ``` ## Backup and Recovery -If you have set the `azureBackupSwitch` in the input parameters to `1` -then Azure will provide VM backups of your Gluster node. This is -recommended as it contains both your Moodle code and your sitedata. -Restoring a backed up VM is outside the scope of this doc, but Azure's -documentation on Recovery Services can be found here: -https://docs.microsoft.com/en-us/azure/backup/backup-azure-vms-first-look-arm +If you have set the `azureBackupSwitch` in the input parameters to `1` then Azure will provide VM backups of your GlusterFS nodes, using the Azure Backup service. This is recommended as it contains both your PHP code and your site data. +Restoring a backed-up VM is outside the scope of this doc, but documentation on Azure Recovery Services can be found here: https://docs.microsoft.com/en-us/azure/backup/backup-azure-vms-first-look-arm ## Resizing your Database @@ -141,23 +144,16 @@ Note: This process involves site downtime and should therefore only be carried out during a planned maintenance window. At the time of writing Azure does not support resizing MySQL or -Postgres databases. You can, however, create a new database instance, +PostgreSQL databases between tiers. You can, however, create a new database instance, with a different size, and change your config to point to that. To get a different size database you'll need to: - 1. [Place your Moodle site into maintenance - mode](https://docs.moodle.org/34/en/Maintenance_mode). You can do - this either via the web interface or the command line on the - controller VM. + 1. Depending on the application that you're running, you might want to put it in maintenance mode first, if possible (this is application-specific); follow the same process as when you are updating the code. 2. Perform an SQL dump of your database. See above for more details. - 3. Create a new Azure database of the size you want inside your - existing resource group. - 4. Using the details in your `/azlamp/html//config.php` create a - new user and database matching the details in config.php. Make - sure to grant all rights on the db to the user. - 5. On the controller instance, change the db setting in - `/azlamp/html//config.php` to point to the new database. - 6. Take Moodle site out of maintenance mode. + 3. Create a new Azure database of the size you want inside your existing Resource Group. + 4. Restore the dump in the new database. Make sure you re-create the same databases (with the same names) and users. + 5. On the controller instance, change the db setting in your app's `config.php` file to point to the new database (the exact location and configuration is specific to your application). + 6. Take your site out of maintenance mode; follow the same process as when you are updating the code. 7. Once confirmed working, delete the previous database instance. How long this takes depends entirely on the size of your database and @@ -171,26 +167,21 @@ basic testing, but a public website will want a real cert. After purchasing a trusted certificate, it can be copied to the following files to be ready immediately: - - `/azlamp/certs//nginx.key`: Your certificate's private key - - `/azlamp/certs//nginx.crt`: Your combined signed certificate and trust chain certificate(s). + - `/azlamp/certs//nginx.key`: Your certificate's private key + - `/azlamp/certs//nginx.crt`: Your combined signed certificate and trust chain certificate(s). ## Managing Azure DDoS protection By default, every plublic IP is protected by Azure DDoS protection Basic SKU. You can find more information about Azure DDoS protection Basic SKU [here](https://docs.microsoft.com/en-us/azure/virtual-network/ddos-protection-overview). -If you want more protection, you can activate Azure DDoS protection Standard SKU by setting -the ddosSwith to true. You can find how to work with Azure DDoS -protection plan [here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#work-with-ddos-protection-plans). +If you want more protection, you can activate Azure DDoS protection Standard SKU by setting the `ddosSwith` to true. You can find how to work with Azure DDoS protection plan [here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#work-with-ddos-protection-plans). -If you want to disable the Azure DDoS protection, you can follow the instruction -[here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#disable-ddos-for-a-virtual-network). +If you want to disable the Azure DDoS protection, you can follow the instruction [here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#disable-ddos-for-a-virtual-network). -Be careful, disabling the Azure DDoS protection on your vnet will not stop the fee. -You have to delete the Azure DDoS protection plan if you want to stop the fee. +Be careful, disabling the Azure DDoS protection on your VNet will not stop charges. You have to delete the Azure DDoS protection plan if you want to stop being charged. -If you have deployed your cluster without Azure DDoS protection plan, you still can activate the -Azure DDoS protection plan thanks to the instruction [here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#enable-ddos-for-an-existing-virtual-network). +If you have deployed your cluster without Azure DDoS protection plan, you still can activate the Azure DDoS protection plan thanks to the instruction [here](https://docs.microsoft.com/en-us/azure/virtual-network/manage-ddos-protection#enable-ddos-for-an-existing-virtual-network). ## Next Steps diff --git a/docs/Parameters.md b/docs/Parameters.md index 67700f9..8b47419 100644 --- a/docs/Parameters.md +++ b/docs/Parameters.md @@ -1,24 +1,17 @@ -# Moodle on Azure Parameters +# LAMP on Azure Parameters -Our goal with these templates is to make it as easy as possible to -deploy a Moodle on Azure cluster that can be customized to your -specific needs. To that end we provide a great manay configuration -options. This document attempts to document all these parameters, -however, like all documentation it can sometimes fall behind. For a -canonical reference you should review the `azuredeploy.json` file. +Our goal with these templates is to make it as easy as possible to deploy a LAMP on Azure cluster that can be customized to your specific needs. To that end we provide a great manay configuration options. This document attempts to document all these parameters, however, like all documentation it can sometimes fall behind. For a canonical reference you should review the `azuredeploy.json` file. ## Extracting documentation from azuredeploy.json -To make it a litte easier to read `azuredeploy.json` you might want to -run the following commands which will extract the necessary -information and display it in a more readable form. +To make it a litte easier to read `azuredeploy.json` you might want to run the following commands which will extract the necessary information and display it in a more readable form. -```bash +```sh sudp apt install jq ``` -``` bash -jq -r '.parameters | to_entries[] | "### " + .key + "\n\n" + .value.metadata.description + "\n\nType: " + .value.type + "\n\nPossible Values: " + (.value.allowedValues | @text) + "\n\nDefault: " + (.value.defaultValue | @text) + "\n\n"' azuredeploy.json +```sh +jq -r '.parameters | to_entries[] | "### " + .key + "\n\n" + .value.metadata.description + "\n\nType: " + .value.type + "\n\nPossible Values: " + (.value.allowedValues | @text) + "\n\nDefault: " + (.value.defaultValue | @text) + "\n"' azuredeploy.json ``` ## Available Parameters @@ -31,8 +24,7 @@ Type: string Possible Values: null -Default: https://raw.githubusercontent.com/Azure/Moodle/master/ - +Default: https://raw.githubusercontent.com/Azure/LAMP/master/ ### _artifactsLocationSasToken @@ -42,8 +34,7 @@ Type: securestring Possible Values: null -Default: - +Default: ### applyScriptsSwitch @@ -55,7 +46,6 @@ Possible Values: null Default: true - ### azureBackupSwitch Switch to configure AzureBackup and enlist VM's @@ -66,10 +56,9 @@ Possible Values: null Default: false - ### redisDeploySwitch -Switch to deploy a redis cache or not. Note that certain versions of Moodle (e.g., 3.1) don't work well with Redis, so use this only for known well-working Moodle versions (e.g., 3.4). +Switch to deploy a Redis Cache or not. Type: bool @@ -77,7 +66,6 @@ Possible Values: null Default: false - ### vnetGwDeploySwitch Switch to deploy a virtual network gateway or not @@ -88,43 +76,9 @@ Possible Values: null Default: false - -### installObjectFsSwitch - -Switch to install Moodle Object FS plugins (with Azure Blob storage) - -Type: bool - -Possible Values: null - -Default: false - - -### installO365pluginsSwitch - -Switch to install Moodle Office 365 plugins. As of May 22, 2018, O365 plugins for Moodle 3.5 haven't been released, so to set this true, you must set the moodleVersion to 3.4 or below. - -Type: bool - -Possible Values: null - -Default: false - - -### installGdprPluginsSwitch - -(Should be used only for Moodle 3.4 & 3.3) Switch to install Moodle GDPR plugins. Note these require Moodle versions 3.4.2+ or 3.3.5+ and these are included by default in Moodle 3.5. So if you choose MOODLE_35_STABLE as your moodleVersion, do not set this to true. - -Type: bool - -Possible Values: null - -Default: false - - ### htmlLocalCopySwitch -Switch to create a local copy of /moodle/html or not +Switch to create a local copy of /azlamp/html or not Type: bool @@ -132,7 +86,6 @@ Possible Values: null Default: true - ### ddosSwitch Switch to create a DDoS protection plan @@ -143,7 +96,6 @@ Possible Values: null Default: false - ### enableAccelNwForCtlrVmSwitch Switch to enable Azure Accelerated Networking on the controller VM. Default to false because currently the default controller VM SKU (D1) doesn't support AN. Change this to true if you set the controller VM SKU to eligibible ones (e.g., D2) for better performance. @@ -154,7 +106,6 @@ Possible Values: null Default: false - ### enableAccelNwForOtherVmsSwitch Switch to enable Azure Accelerated Networking on all other VMs. Default to true because currently the default controller VM SKU for all other VMS (D2) does support AN. Change this to false if you set the SKU of any other VMs to an ineligibible one (e.g., D1) to avoid deployment failure. @@ -165,10 +116,9 @@ Possible Values: null Default: true - ### httpsTermination -Indicates where https termination occurs. 'VMSS' is for https termination at the VMSS instance VMs (using nginx https proxy). 'AppGw' is for https termination with an Azure Application Gateway. When selecting this, you need to specify all appGw* parameters. 'None' is for testing only with no https. 'None' may not be used with a separately configured https termination layer. If you want to use the 'None' option with your separately configured https termination layer, you'll need to update your Moodle config.php manually for $cfg->wwwroot and $cfg->sslproxy. +Indicates where https termination occurs. 'VMSS' is for https termination at the VMSS instance VMs (using nginx https proxy). 'AppGw' is for https termination with an Azure Application Gateway. When selecting this, you need to specify all appGw* parameters. 'None' is for testing only with no https. 'None' may not be used with a separately configured https termination layer. Type: string @@ -176,10 +126,9 @@ Possible Values: ["VMSS","AppGw","None"] Default: VMSS - ### siteURL -URL for Moodle site +URL for LAMP site Type: string @@ -187,18 +136,6 @@ Possible Values: null Default: www.example.org - -### moodleVersion - -The Moodle version you want to install. - -Type: string - -Possible Values: ["MOODLE_35_STABLE","MOODLE_34_STABLE","v3.4.3","v3.4.2","v3.4.1","MOODLE_33_STABLE","MOODLE_32_STABLE","MOODLE_31_STABLE","MOODLE_30_STABLE","MOODLE_29_STABLE"] - -Default: MOODLE_35_STABLE - - ### sshPublicKey ssh public key @@ -209,7 +146,6 @@ Possible Values: null Default: null - ### sshUsername ssh user name @@ -220,7 +156,6 @@ Possible Values: null Default: azureadmin - ### controllerVmSku VM size for the controller VM @@ -231,18 +166,6 @@ Possible Values: null Default: Standard_DS1_v2 - -### webServerType - -Web server type - -Type: string - -Possible Values: ["apache","nginx"] - -Default: apache - - ### autoscaleVmSku VM size for autoscaled web VMs @@ -253,7 +176,6 @@ Possible Values: null Default: Standard_DS2_v2 - ### autoscaleVmCountMax Maximum number of autoscaled web VMs @@ -264,7 +186,6 @@ Possible Values: null Default: 10 - ### autoscaleVmCountMin Minimum (also initial) number of autoscaled web VMs @@ -275,7 +196,6 @@ Possible Values: null Default: 1 - ### osDiskStorageType Azure storage type for all VMs' OS disks. With htmlLocalCopySwith true, Premium_LRS (SSD) is strongly recommended, as PHP files will be served from OS disks. @@ -286,7 +206,6 @@ Possible Values: ["Premium_LRS","Standard_LRS"] Default: Premium_LRS - ### dbServerType Database type @@ -297,7 +216,6 @@ Possible Values: ["postgres","mysql","mssql"] Default: mysql - ### dbLogin Database admin username @@ -308,7 +226,6 @@ Possible Values: null Default: dbadmin - ### mysqlPgresVcores MySql/Postgresql vCores. For Basic tier, only 1 & 2 are allowed. For GeneralPurpose tier, 2, 4, 8, 16, 32 are allowed. For MemoryOptimized, 2, 4, 8, 16 are allowed. @@ -319,7 +236,6 @@ Possible Values: [1,2,4,8,16,32] Default: 2 - ### mysqlPgresStgSizeGB MySql/Postgresql storage size in GB. Minimum 5GB, increase by 1GB, up to 1TB (1024 GB) @@ -330,7 +246,6 @@ Possible Values: null Default: 125 - ### mysqlPgresSkuTier MySql/Postgresql sku tier @@ -341,7 +256,6 @@ Possible Values: ["Basic","GeneralPurpose","MemoryOptimized"] Default: GeneralPurpose - ### mysqlPgresSkuHwFamily MySql/Postgresql sku hardware family. Central US is Gen4 only, so make sure to change this parameter to Gen4 if your deployment is on Central US. @@ -352,7 +266,6 @@ Possible Values: ["Gen4","Gen5"] Default: Gen5 - ### mysqlVersion Mysql version @@ -363,7 +276,6 @@ Possible Values: ["5.6","5.7"] Default: 5.7 - ### postgresVersion Postgresql version @@ -374,7 +286,6 @@ Possible Values: ["9.5","9.6"] Default: 9.6 - ### sslEnforcement MySql/Postgresql SSL connection @@ -385,7 +296,6 @@ Possible Values: ["Disabled","Enabled"] Default: Disabled - ### mssqlDbServiceObjectiveName MS SQL database service object names @@ -396,7 +306,6 @@ Possible Values: ["S1","S2","S3","S4","S5","S6","S7","S9"] Default: S1 - ### mssqlDbSize MS SQL database size @@ -407,7 +316,6 @@ Possible Values: ["100MB","250MB","500MB","1GB","2GB","5GB","10GB","20GB","30GB" Default: 250GB - ### mssqlDbEdition MS SQL DB edition @@ -418,7 +326,6 @@ Possible Values: ["Basic","Standard"] Default: Standard - ### mssqlVersion Mssql version @@ -429,7 +336,6 @@ Possible Values: ["12.0"] Default: 12.0 - ### fileServerType File server type: GlusterFS, NFS, and NFS-HA (2-VM highly available NFS cluster) @@ -440,7 +346,6 @@ Possible Values: ["gluster","nfs","nfs-ha","nfs-byo"] Default: nfs - ### nfsByoIpExportPath IP address and export path of the BYO-NFS share when fileServerType == nfs-byo. E.g., 172.16.1.8:/msazure @@ -449,8 +354,7 @@ Type: string Possible Values: null -Default: - +Default: ### fileServerDiskSize @@ -462,7 +366,6 @@ Possible Values: null Default: 127 - ### fileServerDiskCount Number of disks in raid0 per gluster node or nfs server @@ -473,7 +376,6 @@ Possible Values: null Default: 4 - ### fileServerVmSku VM size for the gluster or NFS-HA nodes @@ -484,7 +386,6 @@ Possible Values: null Default: Standard_DS2_v2 - ### keyVaultResourceId (VMSS https termination only) Azure Resource Manager resource ID of the Key Vault in case you stored your SSL cert in an Azure Key Vault (Note that this Key Vault must have been pre-created on the same Azure region where this template is being deployed). Leave this blank if you didn't. Resource ID example: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/xxx/providers/Microsoft.KeyVault/vaults/yyy. This value can be obtained from keyvault.sh output if you used the script to store your SSL cert in your Key Vault. @@ -493,8 +394,7 @@ Type: string Possible Values: null -Default: - +Default: ### sslCertKeyVaultURL @@ -504,8 +404,7 @@ Type: string Possible Values: null -Default: - +Default: ### sslCertThumbprint @@ -515,8 +414,7 @@ Type: string Possible Values: null -Default: - +Default: ### caCertKeyVaultURL @@ -526,8 +424,7 @@ Type: string Possible Values: null -Default: - +Default: ### caCertThumbprint @@ -537,8 +434,7 @@ Type: string Possible Values: null -Default: - +Default: ### appGwSslCertKeyVaultResourceId @@ -548,8 +444,7 @@ Type: string Possible Values: null -Default: - +Default: ### appGwSslCertKeyVaultSecretName @@ -559,8 +454,7 @@ Type: string Possible Values: null -Default: - +Default: ### appGwSkuName @@ -572,7 +466,6 @@ Possible Values: ["Standard_Small","Standard_Medium","Standard_Large","WAF_Mediu Default: Standard_Medium - ### appGwSkuTier (App Gateway https termination only) Tier of the Applicate Gateway @@ -583,7 +476,6 @@ Possible Values: ["Standard","WAF"] Default: Standard - ### appGwSkuCapacity (App Gateway https termination only) Capacity instance count) of the Applicate Gateway @@ -594,10 +486,9 @@ Possible Values: null Default: 2 - ### storageAccountType -Storage Account type. This storage account is only for the Moodle ObjectFS plugin and/or the (currently disabled) Azure Files file share option +Storage Account type. This storage account is only for the (currently disabled) Azure Files file share option Type: string @@ -605,109 +496,19 @@ Possible Values: ["Standard_LRS","Standard_GRS","Standard_ZRS"] Default: Standard_LRS - -### searchType - -options of moodle global search - -Type: string - -Possible Values: ["none","azure","elastic"] - -Default: none - - -### tikaService - -options of enabling tika service for file searching in moodle - -Type: string - -Possible Values: ["none","tika"] - -Default: none - - -### azureSearchSku - -the search service level you want to create. - -Type: string - -Possible Values: ["free","basic","standard","standard2","standard3"] - -Default: basic - - -### azureSearchReplicaCount - -Replicas distribute search workloads across the service. You need 2 or more to support high availability (applies to Basic and Standard only). - -Type: int - -Possible Values: null - -Default: 3 - - -### azureSearchPartitionCount - -Partitions allow for scaling of document count as well as faster indexing by sharding your index over multiple Azure Search units. - -Type: int - -Possible Values: [1,2,3,4,6,12] - -Default: 1 - - -### azureSearchHostingMode - -Applicable only for azureSearchSku set to standard3. You can set this property to enable a single, high density partition that allows up to 1000 indexes, which is much higher than the maximum indexes allowed for any other azureSearchSku. - -Type: string - -Possible Values: ["default","highDensity"] - -Default: default - - -### elasticVmSku - -VM size for the elastic search nodes - -Type: string - -Possible Values: null - -Default: Standard_DS2_v2 - - -### tikaVmSku - -VM size for the tika search nodes - -Type: string - -Possible Values: null - -Default: Standard_DS2_v2 - - ### customVnetId -Azure Resource ID of the Azure virtual network where you want to deploy your Moodle resources. A vnet resource ID is of the following format: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx/resourceGroups/gggg/providers/Microsoft.Network/virtualNetworks/vvvv. Note that this virtual network must be on the same Azure location as this template deployment location. If this parameter is blank, a new Azure virtual network will be created and used. In that case, the address space of the newly created virtual network will be */16 of the following vNetAddressSpace parameter value below. +Azure Resource ID of the Azure virtual network where you want to deploy your LAMP resources. A vnet resource ID is of the following format: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx/resourceGroups/gggg/providers/Microsoft.Network/virtualNetworks/vvvv. Note that this virtual network must be on the same Azure location as this template deployment location. If this parameter is blank, a new Azure virtual network will be created and used. In that case, the address space of the newly created virtual network will be */16 of the following vNetAddressSpace parameter value below. Type: string Possible Values: null -Default: - +Default: ### vNetAddressSpace -Address range for the Moodle virtual network and various subnets - presumed /16 for a newly created vnet in case customVnetId is blank. Further subneting (a number of */24 subnets starting from the xxx.yyy.zzz.0/24 will be created on a newly created vnet or your BYO-vnet (specified in customVnetId parameter). +Address range for the LAMP virtual network and various subnets - presumed /16 for a newly created vnet in case customVnetId is blank. Further subneting (a number of */24 subnets starting from the xxx.yyy.zzz.0/24 will be created on a newly created vnet or your BYO-vnet (specified in customVnetId parameter). Type: string @@ -715,7 +516,6 @@ Possible Values: null Default: 172.31.0.0 - ### gatewayType Virtual network gateway type @@ -726,7 +526,6 @@ Possible Values: ["Vpn","ER"] Default: Vpn - ### vpnType Virtual network gateway vpn type @@ -737,7 +536,6 @@ Possible Values: ["RouteBased","PolicyBased"] Default: RouteBased - ### loadBalancerSku Loadbalancer SKU @@ -748,7 +546,6 @@ Possible Values: ["Basic","Standard"] Default: Basic - ### location Azure Location for all resources. @@ -758,5 +555,3 @@ Type: string Possible Values: null Default: [resourceGroup().location] - - diff --git a/docs/Preparation.md b/docs/Preparation.md index 66db609..b0f3e55 100644 --- a/docs/Preparation.md +++ b/docs/Preparation.md @@ -1,19 +1,23 @@ # Environment Preparation -This document describes how to ensure your environment is configured -for working with Moodle on Azure. +This document describes how to ensure your local environment (ie. your laptop) is configured for working with LAMP on Azure. ## Prerequisites -In order to configure our deployment and tools we'll set up some -[environment variables](./Environment-Variables.md) to ensure consistency. +In order to configure our deployment and tools we'll set up some [environment variables](./Environment-Variables.md) to ensure consistency. ## Required software -We'll use a number of tools when working with Moodle on Azure. Let's -ensure they are all installed: +We'll use a number of tools when working with this template. Let's +ensure they are all installed. -``` shell +### Linux (Ubuntu) and Windows Subsystem for Linux + +> If you're using Windows 10, we recommend you use the Windows Subsystem for Linux to have a full bash shell experience, based on Ubuntu. See the [documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10) on how to enable the Windows Subsystem for Linux. + +On the terminal in Ubuntu and WSL: + +```sh sudo apt-get update sudo apt-get install wget -y sudo apt-get openssh-client -y @@ -21,52 +25,62 @@ sudo apt-get openssh-client -y The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-apt?view=azure-cli-latest) is also important: -```bash +```sh AZ_REPO=$(lsb_release -cs) echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | sudo tee /etc/apt/sources.list.d/azure-cli.list curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - sudo apt-get update && sudo apt-get install apt-transport-https azure-cli ``` +### macOS + +On macOS, most dependencies are already pre-installed in the system by default. + +You can install the Azure CLI with Homebrew. Please follow the instructions in the [documentation](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-macos?view=azure-cli-latest). + ## Ensure we have a valid SSH key pair We use SSH for secure communication with our hosts. The following line will check there is a valid SSH key available and, if not, create one. +```sh +if [ ! -f "$LAMP_SSH_KEY_FILENAME" ]; then ssh-keygen -t rsa -b 4096 -N "" -f $LAMP_SSH_KEY_FILENAME; fi ``` -if [ ! -f "$MOODLE_SSH_KEY_FILENAME" ]; then ssh-keygen -t rsa -N "" -f $MOODLE_SSH_KEY_FILENAME; fi -``` -## Checkout the Moodle ARM Template -The Moodle Azure Resource Manager template is hosted on GitHub. We'll +### Note on SSH keys + +All of the deployment options require you to provide a valid SSH protocol 2 (SSH-2) RSA public-private key pair, with a minimum length of 2048 bits. Other key formats such as ED25519 and ECDSA are not supported. If you are unfamiliar with SSH then you should read this [article](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/mac-create-ssh-keys) which will explain how to generate a key using the Windows Subsystem for Linux, or a Mac or Linux laptop (it's easy and takes only a few minutes). If you are new to SSH, remember SSH is a key pair-based solution. What this means is that you have a public key and a private key, and the one you will be using to deploy your template is the public key. + +## Checkout the LAMP ARM Template + +The LAMP Azure Resource Manager template is hosted on GitHub. We'll checkout the template into our workspace. -``` -git clone git@github.com:Azure/Moodle.git $MOODLE_AZURE_WORKSPACE/arm_template +```sh +git clone git@github.com:Azure/LAMP.git $LAMP_AZURE_WORKSPACE/arm_template ``` -# Validation +## Validation -After completing these steps we should have, amonst other things, a -complete checkout of the Moodle templates from GitHub: +After completing these steps we should have, among other things, a complete checkout of the LAMP templates from GitHub: -``` bash -ls $MOODLE_AZURE_WORKSPACE/arm_template +```sh +ls $LAMP_AZURE_WORKSPACE/arm_template ``` Results: -``` expected_similarity=0.4 +```expected_similarity=0.4 azuredeploy.json azuredeploy.parameters.json CONTRIBUTE.md docs env.json etc images LICENSE LICENSE-DOCS metadata.json nested README.md ``` We should also have a number of applications installed, such as the Azure CLI: -``` bash +```sh if hash az 2>/dev/null; then echo "Azure CLI Installed"; else echo "Missing dependency: Azure CLI"; fi ``` -``` +```text AzureCLI Installed ``` diff --git a/docs/Readme.md b/docs/Readme.md index f0948b9..da216e8 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -1,138 +1,162 @@ -# Deploy and Manage an (empty) Scalable LAMP Cluster on Azure +# Deploy and Manage a Scalable LAMP Cluster on Azure 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 -[LAMP](https://en.wikipedia.org/wiki/LAMP_(software_bundle)) cluster on Azure. +[LAMP](https://en.wikipedia.org/wiki/LAMP_(software_bundle)) cluster on Azure. The template(s) provided here deploy an *empty* infrastructure/stack to deploy any general LAMP application. -If you have Azure account you can deploy LAMP via the [Azure portal](https://portal.azure.com) using the button below. 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. +If you have Azure account you can deploy LAMP via the [Azure Portal](https://portal.azure.com) using the buttons below. Please note that while you can use an [Azure free account](https://aka.ms/azure-free-phprefarch) to get started, depending on which template configuration you choose you will likely be required to upgrade to a paid account. ## Fully configurable deployment -The following button will allow you to specify various configurations for your LAMP cluster -deployment. The number of configuration options might be overwhelming, so some pre-defined/restricted deployment options for -typical LAMP scenarios follow this. +The following button will allow you to specify various configurations for your LAMP cluster deployment. The number of configuration options might be overwhelming, so some pre-defined/restricted deployment options for typical LAMP scenarios follow this. -[![Deploy to Azure Fully Configurable](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FMoodle%2Fhs-lampgen%2Fazuredeploy.json) - -NOTE: All of the deployment options require you to provide a valid SSH protocol 2 (SSH-2) RSA public-private key pairs with a minimum length of 2048 bits. Other key formats such as ED25519 and ECDSA are not supported. If you are unfamiliar with SSH then you should read this [article](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/mac-create-ssh-keys) which will explain how to generate a key using the Windows Subsystem for Linux (it's easy and takes only a few minutes). If you are new to SSH, remember SSH is a key pair solution. What this means is you have a public key and a private key, and the one you will be using to deploy your template is the public key. +[![Deploy to Azure Fully Configurable](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy.json) [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy.json) ## Predefined deployment options -Below are a list of pre-defined/restricted deployment options based on typical deployment scenarios (i.e. dev/test, production etc.) All configurations are fixed and you just need to pass your ssh public key to the template for logging in to the deployed VMs. Please note that the actual cost will be bigger with potentially autoscaled VMs, backups and network cost. + +Below are a list of pre-defined/restricted deployment options based on typical deployment scenarios (i.e. dev/test, production etc.) All configurations are fixed and you just need to pass your SSH public key to the template for logging in to the deployed VMs. Please note that the actual cost will be bigger with potentially autoscaled VMs, backups and network cost. | Deployment Type | Description | Estimated Cost | Launch | | --- | --- | --- | --- -| Minimal | This deployment will use NFS, Microsoft SQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores currently that'll fit even in a free trial Azure subscription.|[link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1)|[![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%2Fhs-lampgen%2Fazuredeploy-minimal.json) -| Small to Mid-Size | Supporting up to 1000 concurrent users. This deployment will use NFS (no high availability) and MySQL (8 vCores), without other options like elastic search or redis cache.|[link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc)|[![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%2Fhs-lampgen%2Fazuredeploy-small2mid-noha.json) -|Large size deployment (with high availability)| Supporting more than 2000 concurrent users. This deployment will use Gluster (for high availability, requiring 2 VMs), MySQL (16 vCores) and redis cache, without other options like elastic search. |[link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7)|[![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%2Fhs-lampgen%2Fazuredeploy-large-ha.json) -| Maximum |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).|[link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5)|[![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%2Fhs-lampgen%2Fazuredeploy-maximal.json) +| Minimal | This deployment will use NFS, Microsoft SQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores. Currently this will fit even in a free Azure trial subscription.|[link](https://azure.com/e/5f9752c934ab41799ae3264dd2ee57d1)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-minimal.json) +| Small to Mid-Size | Supporting up to 1,000 concurrent users. This deployment will use NFS (with no high availability) and MySQL (8 vCores), without other options like Redis Cache.|[link](https://azure.com/e/fd794268d0bf421aa17c626fb88f25bc)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-small2mid-noha.json) +|Large size deployment (with high availability)| Supporting more than 2,000 concurrent users. This deployment will use GlusterFS (in high availability, requiring 2 VMs), MySQL (16 vCores) and Redis Cache. |[link](https://azure.com/e/078f7294ab6544e8911ddc2ee28850d7)|[![Deploy to Azure Minimally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-large-ha.json) +| Maximum |This maximal deployment will use GlusterFS (in high availability, adding 2 VMs for a GlusterFS cluster), MySQL with the highest SKU, Redis Cache, and pretty large storage sizes (for both data disks and DB).|[link](https://azure.com/e/e0f959b93ed84eb891dcc44f7883f5b5)|[![Deploy to Azure Maximally](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FLAMP%2Fmaster%2Fazuredeploy-maximal.json) -NOTE: Depending on the region you choose to deploy the stack in - the deployment might fail due to SKUs being hardcoded in the template where they are not available. For example, today our small-mid-size deployment option hard codes Gen-4 Azure MySQL SKUs into the template, and if a region where that is currently not available in (i.e. westus2) is used, your deployment will fail. If your deployment fails, please revert to the fully configurable template where possible and change the SKU paramater to one that exists in your region (i.e. Gen-5) or alternatively change your deployment region to one in which the SKU is available (i.e. southcentralus). +NOTE: Depending on the region you choose to deploy the stack in, the deployment might fail due to SKUs being hardcoded in the template where they are not available. For example, today our small-mid-size deployment option hard codes Gen-4 Azure MySQL SKUs into the template, and if an Azure region where that is currently not available in (i.e. West US 2) is used, your deployment will fail. If your deployment fails, please revert to the fully configurable template where possible and change the SKU paramater to one that exists in your region (i.e. Gen-5), or alternatively change your deployment region to one in which the SKU is available (i.e. South Central US). ## Stack Architecture This template set deploys the following infrastructure core to your LAMP instance: -- Autoscaling web frontend layer (Nginx for https termination, Varnish for caching, Apache/php or nginx/php-fpm) -- Private virtual network for frontend instances -- Controller instance running cron and handling syslog for the autoscaled site -- [Azure Load balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to balance across the autoscaled instances -- [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/) -- Dual [GlusterFS](https://www.gluster.org/) nodes or NFS for high availability access to LAMP files +- Autoscaling web frontend layer (with nginx and PHP-FPM) +- Private Virtual Network for frontend instances +- Controller VM running cron and handling syslog for the autoscaling cluster +- [Azure Load balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to balance across the autoscaling instances +- [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/) +- Dual [GlusterFS](https://www.gluster.org/) nodes or NFS for highly available access to LAMP files +# Next Steps -## Next Steps - -# Prepare deployed cluster for LAMP applications - -If you chose Apache as your `webServerType` and `true` for the `htmlLocalCopy` switch at your LAMP cluster deployment time, you can install additional LAMP sites on your cluster, utilizing Apache's VirtualHost feature (we call this "LAMP generalization"). To manage your installed cluster, you'll first need to login to the LAMP cluster controller virtual machine. The directory you'll need to work out of is `/azlamp`. You will need privileged access which means that you'll either need to be root (superuser) or have *sudo* access. +## Prepare deployed cluster for LAMP applications +If you chose `true` for the `htmlLocalCopy` switch at your LAMP cluster deployment time, you can install additional LAMP sites on your cluster, utilizing Nginx's virtual host feature. To manage your installed cluster, you'll first need to login to the LAMP cluster controller virtual machine. The directory you'll need to work out of is `/azlamp`. You will need privileged access which means that you'll either need to be root (superuser) or have *sudo* access. ## Configuring the controller for a specific LAMP application (WordPress) +### Connect via SSH + +You can connect via SSH to the controller VM. From a Linux, macOS or Windows 10 client using the Windows Subsystem for Linux, you can connect to the controller's VM using SSH and the public IP or DNS name of the controller. + +```sh +ssh user@ip-or-dns +``` + +The username can be configured with `sshUsername`; the default value is `azureadmin`. You'll be authenticating using your SSH private key, so no password is necessary for the SSH user. ### Installation Destination -An example LAMP application (WordPress) is illustrated here for the sake of clarity. The approach is similar to any LAMP application out there. + +An example LAMP application (WordPress) is illustrated here for the sake of clarity. The approach is similar to any LAMP application out there. First, you'd need to navigate to `/azlamp/html` and create a directory based on a domain name you have in mind. An example domain name is used below: -``` +```sh cd /azlamp/html mkdir wpsitename.mydomain.com cd /azlamp/html/wpsitename.mydomain.com ``` -Once that's done and you've downloaded the latest version of WordPress, please follow the instructions here to complete configuring a database and finishing a [WordPress install](https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Installation). +Download the latest version of WordPress, for example with: -``` +```sh wget https://wordpress.org/latest.tar.gz tar xvfz latest.tar.gz --strip 1 ``` - ### SSL Certs The certificates for your LAMP application reside in `/azlamp/certs/yourdomain` or in this instance, `/azlamp/certs/wpsitename.mydomain.com` -``` +```sh mkdir /azlamp/certs/wpsitename.mydomain.com ``` Copy over the .crt and .key files over to `/azlamp/certs/wpsitename.mydomain.com`. -The file names should be changed to `nginx.crt` and `nginx.key` in order to be recognized by the configured nginx servers. Depending on your local environment, -you may choose to use the utility *scp* or a tool like [WinSCP](https://winscp.net/eng/download.php) to copy these files over to the cluster controller virtual machine. +The file names should be changed to `nginx.crt` and `nginx.key` in order to be recognized by the configured nginx servers. Depending on your local environment, you may choose to use the utility *scp* or a tool like [WinSCP](https://winscp.net/eng/download.php) to copy these files over to the cluster controller virtual machine. + +You can also generate a self-signed certificate, useful for testing only: + +```sh +openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /azlamp/certs/wpsitename.mydomain.com/nginx.key \ + -out /azlamp/certs/wpsitename.mydomain.com/nginx.crt \ + -subj "/C=US/ST=WA/L=Redmond/O=IT/CN=wpsitename.mydomain.com" +``` It's recommended that the certificate files be read-only to owner and that these files are owned by *www-data*: +```sh +chown www-data:www-data /azlamp/certs/wpsitename.mydomain.com/nginx.* +chmod 400 /azlamp/certs/wpsitename.mydomain.com/nginx.* ``` -chown www-data:www-data /azlamp/certs/wpsitename.mydomain.com/* -chmod 400 /azlamp/certs/wpsitename.mydomain.com/* -``` - ### Linking to the content/cluster data location Navigate to the WordPress content directory and run the following command: -``` +```sh mkdir -p /azlamp/data/wpsitename.mydomain.com/wp-content/uploads -cd /azlamp/html/wpsitename.mydomain.com -ln -s /azlamp/data/wpsitename.mydomain.com/wp-content/uploads . +ln -s /azlamp/data/wpsitename.mydomain.com/wp-content/uploads /azlamp/html/wpsitename.mydomain.com/wp-content/uploads +chmod 0777 /azlamp/data/wpsitename.mydomain.com/wp-content/uploads ``` -This step is needed because the `/wp-content/uploads` directory need to be shared across all web frontend instances, and Wordpress configuration doesn't allow an external directory to be used as the uploads repository. In fact, Drupal also has a similar design, so a similar symbolic link will be needed for Drupal as well. This is in contrary to Moodle, which allows users to configure any external directory as its file storage location. +This step is needed because the `/wp-content/uploads` directory need to be shared across all web frontend instances, and WordPress configuration doesn't allow an external directory to be used as the uploads repository. In fact, Drupal also has a similar design, so a similar symbolic link will be needed for Drupal as well. This is in contrary to Moodle, which allows users to configure any external directory as its file storage location. -### Update Apache configurations on all web frontend instances +### Update Nginx configurations on all web frontend instances -Once the correspnding html/data/certs directories are configured, we need to reconfigure all Apache services on web frontend instances, so that newly created sites are added to the Apache VirtualHost configurations and deleted sites are removed from them as well. This is done by the `/azlamp/bin/update-vmss-config` hook (executed every minute on each and every VMSS instance using a cron job), which requires us to provide the commands to run (to reconfigure Apache service) on each VMSS instance. There's already a utility script installed for that, so it's easy to achieve as follows. +Once the correspnding html/data/certs directories are configured, we need to reconfigure all Nginx services on web frontend instances, so that a virtual host is added for each newly added site, and old ones are removed. This is done by the `/azlamp/bin/update-vmss-config` hook (executed every minute on each and every VMSS instance using a cron job), which requires us to provide the commands to run on each VMSS instance. There's already a utility script installed for that, so it's easy to achieve this. On the controller machine, look up the file `/azlamp/bin/update-vmss-config`. If you haven't modified that file, you'll see the following lines in the file: -``` +```sh #1) # . /azlamp/bin/utils.sh - # reset_all_sites_on_vmss true VMSS apache + # reset_all_sites_on_vmss true VMSS #;; ``` -Remove all the leading `#` characters from these lines (uncommenting) and save the file, then wait for a minute. After that, your newly added sites should be available through the domain names specified/used as the directory names (Of course this assumes you set up your DNS records for your new site FQDNs so that their CNAME records point to the deployed Moodle cluster's load balancer DNS name, whis is of the form `lb-xyz123.an_azure_region.cloudapp.azure.com`). +Remove all the leading `#` characters from these lines (to uncomment them) and save the file, then wait for about a minute. After that, your newly added sites should be available through the domain names specified/used as the directory names (Of course this assumes you set up your DNS records for your new site FQDNs so that their CNAME records point to the deployed LAMP cluster's load balancer DNS name, whis is of the form `lb-xyz123.an_azure_region.cloudapp.azure.com`). -If you are adding sites for the second or later time, you'll already have the above lines commented out. Just create another `case` block, copying the 4 lines, but make sure to change the number so that it's one greater than the last VMSS config version number (you should be able to find that from the script). As an example, the final text would look like: +If you make changes and add or remove websites at a later time, you'll already have the above lines commented out. Just create another `case` block, copying the 4 lines, but make sure to change the number so that it's one greater than the last VMSS config version number (you should be able to find that from the script). As an example, the final text would look like: -``` +```sh 1) . /azlamp/bin/utils.sh - reset_all_sites_on_vmss true VMSS apache + reset_all_sites_on_vmss true VMSS ;; 2) . /azlamp/bin/utils.sh - reset_all_sites_on_vmss true VMSS apache + reset_all_sites_on_vmss true VMSS ;; ``` +### Replicate PHP files -The last step is to let the `/azlamp/html` directory sync with `/var/www/html` in every VMSS instance. This should be done by running `/usr/local/bin/update_last_modified_time.azlamp.sh` script on the controller machine as root. Once this is run and after a minute, the `/var/www/html` directory on every VMSS instance should be the same as `/azlamp/html`, and the newly added sites should be available. +The last step is to let the `/azlamp/html` directory sync with `/var/www/html` in every VMSS instance. This should be done by running **this script on the controller machine**, as root: -At this point, your LAMP application is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. +```sh +/usr/local/bin/update_last_modified_time.azlamp.sh +``` + +Once this is run and after a minute, the `/var/www/html` directory on every VMSS instance should be the same as `/azlamp/html`, and the newly added sites should be available. + +At this point, your app is setup to use in the LAMP cluster. If you'd like to install a separate LAMP application (WordPress or otherwise), you'll have to repeat the process listed here with a new domain for the new application. + +### WordPress installer + +Once you completed the steps above and you can see your WordPress website running in the browser, please follow the instructions here to complete configuring a database and finishing a [WordPress install](https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Installation). + +If you chose `true` for the `htmlLocalCopy` switch, WordPress will be running from a read-only directory, so the installer won't be able to create a `wp-config.php` file for you. However, the installer will provide you with the full content of the required config file. On the controller VM, copy that content into the file `/azlamp/html/wpsitename.mydomain.com/wp-config.php`. You then need to trigger a replication of the data, by running the script `/usr/local/bin/update_last_modified_time.azlamp.sh` again from the controller VM, as root. Data will be replicated in around one minute. ## Code of Conduct @@ -167,4 +191,3 @@ Privacy information can be found at https://privacy.microsoft.com/en-us/ Microsoft and any contributors reserve all others rights, whether under their respective copyrights, patents, or trademarks, whether by implication, estoppel or otherwise. - diff --git a/docs/SslCert.md b/docs/SslCert.md index 5049512..b64b606 100644 --- a/docs/SslCert.md +++ b/docs/SslCert.md @@ -1,64 +1,44 @@ # SSL Certificate Management -A valid SSL (TLS) certificate should be used with your domain name for the Moodle/LAMP -site to be deployed using the templates. By default, the templates will configure -the HTTPS server with a self-signed SSL server certificate/private key, which can -be manually changed with your own valid SSL server certificate/private key after -the deployment. +A valid SSL (TLS) certificate should be used with your domain name for the website to be deployed using the templates. By default, the templates will configure the HTTPS server with a self-signed SSL server certificate/private key, which can be manually changed with your own valid SSL server certificate/private key after the deployment. -If you'd like to configure the Moodle/LAMP cluster (to be deployed) with your own domain -and your valid SSL server certificate/private key, then you can do so by utilizing -[Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/) and -configuring the related template parameters as described below. This support is -based on [another similar work](https://github.com/Azure/azure-quickstart-templates/tree/master/201-vmss-ubuntu-web-ssl) -and adapted to our situation. +If you'd like to configure the cluster (to be deployed) with your own domain and your valid SSL server certificate/private key, then you can do so by utilizing [Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/) and configuring the related template parameters as described below. This support is based on [another similar work](https://github.com/Azure/azure-quickstart-templates/tree/master/201-vmss-ubuntu-web-ssl) and adapted to our situation. ## Initial deployment -To configure the Moodle/LAMP cluster (to be deployed) with your purchased SSL certificate, -currently the related files should be stored in an Azure Key Vault as secrets, so that -Azure Resource Manager can retrieve them when it deploys VMs as specified in templates. +To configure the cluster (to be deployed) with your purchased SSL certificate, currently the related files should be stored in an Azure Key Vault as secrets, so that Azure Resource Manager can retrieve them when it deploys VMs as specified in templates. -You can create your own Azure Key Vault and store your purchased SSL certificate (called -'import' in Azure Key Vault terminology) by following related documentation like -[this](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-manage-with-cli2). -However, the related files must be stored in a specific format, so we created a -shell script (`keyvault.sh`) that will perform all necessary steps for this purpose. -To use this script, you'll first need to upload your SSL certificate/private key files -(.pem) to your deployment environment you set up by following the [preparation document](Preparation.md) -(a Linux command line). The .pem files should be as follows: +You can create your own Azure Key Vault and store your purchased SSL certificate (called "import" in Azure Key Vault terminology) by following related documentation like [this](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-manage-with-cli2). +However, the related files must be stored in a specific format, so we created a shell script (`keyvault.sh`) that will perform all necessary steps for this purpose. +To use this script, you'll first need to upload your SSL certificate/private key files (.pem) to your deployment environment you set up by following the [preparation document](Preparation.md) (a Linux command line). The .pem files should be as follows: - `cert.pem`: The SSL certificate only in PEM format - `key.pem`: The private key for the SSL certificate only in PEM format - `chain.pem`: This is optional in case your server certificate is signed by an intermediate CA (Certificate Authority) certificate, instead of a root CA certificate. Currently only one intermediate CA certificate is supported by the script. -Once you uploaded the files to your deployment environment, you can run the following command -to create an Azure Key Vault on your subscription and store your SSL certificate, private key, and optionally -the intermediate CA certificate: +Once you uploaded the files to your deployment environment, you can run the following command to create an Azure Key Vault on your subscription and store your SSL certificate, private key, and optionally the intermediate CA certificate: -``` bash -$ bash $MOODLE_AZURE_WORKSPACE/arm_template/etc/keyvault.sh cert.pem key.pem chain.pem +```sh +bash $LAMP_AZURE_WORKSPACE/arm_template/etc/keyvault.sh cert.pem key.pem chain.pem ``` -Make sure to set `` the same as the Azure region you'll be using to deploy the Moodle template. -Assign desired names for ``, `` (you can use an existing resource group) and ``. -`` is not very important in our deployment. Then you'll get outputs as follows: +Make sure to set `` the same as the Azure region you'll be using to deploy the template. +Assign desired names for ``, `` (you can use an existing resource group) and ``. `` is not very important in our deployment. Then you'll get outputs as follows: -``` +```text ... -Specified SSL cert/key .pem files are now stored in your Azure Key Vault and ready to be used by the template. -Use the following values for the related template parameters: +Specified SSL cert/key .pem files are now stored in your Azure Key Vault and ready to be used by the template. Use the following values for the related template parameters: - keyVaultResourceId: /subscriptions/206c66fc-a48c-480d-ad06-0d429e82c586/resourceGroups/keyvault/providers/Microsoft.KeyVault/vaults/mdl-kv -- sslCertKeyVaultURL: https://mdl-kv.vault.azure.net/secrets/mymoodlesitecert/4c88452fe72b4d469253af48348f4944 +- sslCertKeyVaultURL: https://mdl-kv.vault.azure.net/secrets/mylampsitecert/4c88452fe72b4d469253af48348f4944 - sslCertThumbprint: 56478E4F9555662476E2763D909F50B3DD26FF84 -- caCertKeyVaultURL: https://mdl-kv.vault.azure.net/secrets/camymoodlesitecert/684efab1f2124e71a2c809457d10808b +- caCertKeyVaultURL: https://mdl-kv.vault.azure.net/secrets/camylampsitecert/684efab1f2124e71a2c809457d10808b - caCertThumbprint: E6A3B45B062D509B3382282D196EFE97D5956CCB Done ``` This example outputs assumes `"keyvault"` is used for ``, `"mdl-kv"` for ``, -and `"mymoodlesitecert"` for ``. Note that `caCertKeyVaultURL` and `caCertThumbprint` will be empty +and `"mylampsitecert"` for ``. Note that `caCertKeyVaultURL` and `caCertThumbprint` will be empty if you didn't specify `chain.pem`. Then you can copy these outputs to the template's corresponding parameters, and Azure Resource Manager will install the certificate and the private key on the deployed VMs and the deployed HTTPS server will use this certificate and private key. diff --git a/docs/Test.md b/docs/Test.md index 0992587..d616225 100644 --- a/docs/Test.md +++ b/docs/Test.md @@ -1,8 +1,8 @@ -# Test a Moodle Instance +# Test a LAMP Instance ## Prerequisites -It is obviously necessary to have a [Moodle cluster up and running](./Deploy.md). +It is obviously necessary to have a [LAMP cluster up and running](./Deploy.md). ## Next Steps diff --git a/docs/env.json b/docs/env.json index 28cbab8..8bdfce0 100644 --- a/docs/env.json +++ b/docs/env.json @@ -1,5 +1,5 @@ { - "MOODLE_RG_NAME": "rgmoodlearm13tagging", - "MOODLE_RG_LOCATION": "canadacentral", - "MOODLE_DEPLOYMENT_NAME": "MainDeployment" + "LAMP_RG_NAME": "rglamparm13tagging", + "LAMP_RG_LOCATION": "canadacentral", + "LAMP_DEPLOYMENT_NAME": "MainDeployment" } diff --git a/env.json b/env.json deleted file mode 100644 index 838d537..0000000 --- a/env.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "MOODLE_RG_NAME": "rgmoodlearm12", - "MOODLE_RG_LOCATION": "canadacentral", - "MOODLE_DEPLOYMENT_NAME": "MainDeployment" -} diff --git a/metadata.json b/metadata.json index cc26c63..59eb49c 100644 --- a/metadata.json +++ b/metadata.json @@ -1,7 +1,7 @@ { - "itemDisplayName": "Autoscalable Moodle on Azure", - "description": "Deploys an autoscaling Moodle cluster with configurable objectfs storage, Azure redis, Azure MySQL/Postgres/MSSQu, and Elasticsearch. Can be configured for very small or very large sites. Deploys frontend components to a private network with a jumphost to access nodes. Requires keyed SSH access.", - "summary": "Moodle autoscale with redis/db/elasticsearch", + "itemDisplayName": "Autoscalable LAMP on Azure", + "description": "Deploys an autoscaling LAMP cluster with configurable objectfs storage, Azure redis, Azure MySQL/Postgres. Can be configured for very small or very large sites. Deploys frontend components to a private network with a jumphost to access nodes. Requires keyed SSH access.", + "summary": "LAMP autoscale with redis/db", "githubUsername": "hosungsmsft", "dateUpdated": "2018-04-20" } diff --git a/nested/appgw.json b/nested/appgw.json index 926bb62..c5145b6 100644 --- a/nested/appgw.json +++ b/nested/appgw.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -24,14 +24,14 @@ "resources": [ { "type": "Microsoft.Network/applicationGateways", - "name": "[parameters('moodleCommon').appGwName]", - "location": "[parameters('moodleCommon').location]", + "name": "[parameters('lampCommon').appGwName]", + "location": "[parameters('lampCommon').location]", "apiVersion": "2018-02-01", "properties": { "sku": { - "name": "[parameters('moodleCommon').appGwSkuName]", - "tier": "[parameters('moodleCommon').appGwSkuTier]", - "capacity": "[parameters('moodleCommon').appGwSkuCapacity]" + "name": "[parameters('lampCommon').appGwSkuName]", + "tier": "[parameters('lampCommon').appGwSkuTier]", + "capacity": "[parameters('lampCommon').appGwSkuCapacity]" }, "gatewayIPConfigurations": [ { @@ -123,8 +123,8 @@ ], "variables": { "documentation1": "This sub-template creates an Azure Application Gateway for SSL offloading. It expects certain values in the 'common' datastructure.", - "appGwBePoolName": "[parameters('moodleCommon').appGwBePoolName]", - "appGwPublicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('moodleCommon').appGwPipName)]", - "appGwID": "[resourceId('Microsoft.Network/applicationGateways', parameters('moodleCommon').appGwName)]" + "appGwBePoolName": "[parameters('lampCommon').appGwBePoolName]", + "appGwPublicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('lampCommon').appGwPipName)]", + "appGwID": "[resourceId('Microsoft.Network/applicationGateways', parameters('lampCommon').appGwName)]" } } \ No newline at end of file diff --git a/nested/controller.json b/nested/controller.json index 28420c1..58b3f39 100644 --- a/nested/controller.json +++ b/nested/controller.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -22,7 +22,7 @@ }, "vmSetupParamsObj": { "metadata": { - "description": "JSON-structured VM setup params that'll be injected to the VM (through cloud-init) and used by the custom script (install_moodle.sh)" + "description": "JSON-structured VM setup params that'll be injected to the VM (through cloud-init) and used by the custom script (setup_controller.sh)" }, "type": "object" } @@ -31,8 +31,8 @@ { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').ctlrNsgName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').ctlrNsgName]", "properties": { "securityRules": [ { @@ -71,10 +71,10 @@ "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2017-10-01", "dependsOn": [ - "[concat('Microsoft.Network/networkSecurityGroups/', parameters('moodleCommon').ctlrNsgName)]" + "[concat('Microsoft.Network/networkSecurityGroups/', parameters('lampCommon').ctlrNsgName)]" ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').ctlrNicName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').ctlrNicName]", "properties": { "networkSecurityGroup": { "id": "[variables('nsgRef')]" @@ -93,7 +93,7 @@ } } ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForCtlrVmSwitch]" + "enableAcceleratedNetworking": "[parameters('lampCommon').enableAccelNwForCtlrVmSwitch]" }, "tags": { "displayName": "ctlrNic" @@ -103,13 +103,13 @@ "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2017-03-30", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', parameters('moodleCommon').ctlrNicName)]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('lampCommon').ctlrNicName)]" ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').ctlrVmName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').ctlrVmName]", "properties": { "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').controllerVmSku]" + "vmSize": "[parameters('lampCommon').controllerVmSku]" }, "networkProfile": { "networkInterfaces": [ @@ -119,32 +119,32 @@ ] }, "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerName": "[parameters('moodleCommon').ctlrVmName]", - "secrets": "[parameters('moodleCommon').ctlrVmSecrets]", - "customData": "[base64(concat('#cloud-config\nwrite_files:\n- encoding: b64\n content: ', base64(string(parameters('vmSetupParamsObj'))), '\n owner: root:root\n path: ', parameters('moodleCommon').moodleOnAzureConfigsJsonPath, '\n permissions: ', variables('singleQuote'), '0400', variables('singleQuote')))]", + "adminUsername": "[parameters('lampCommon').sshUsername]", + "computerName": "[parameters('lampCommon').ctlrVmName]", + "secrets": "[parameters('lampCommon').ctlrVmSecrets]", + "customData": "[base64(concat('#cloud-config\nwrite_files:\n- encoding: b64\n content: ', base64(string(parameters('vmSetupParamsObj'))), '\n owner: root:root\n path: ', parameters('lampCommon').lampOnAzureConfigsJsonPath, '\n permissions: ', variables('singleQuote'), '0400', variables('singleQuote')))]", "linuxConfiguration": { "disablePasswordAuthentication": true, "ssh": { "publicKeys": [ { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" + "path": "[concat('/home/', parameters('lampCommon').sshUsername, '/.ssh/authorized_keys')]", + "keyData": "[parameters('lampCommon').sshPublicKey]" } ] } } }, "storageProfile": { - "imageReference": "[parameters('moodleCommon').osType]", + "imageReference": "[parameters('lampCommon').osType]", "osDisk": { "createOption": "FromImage", "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" + "storageAccountType": "[parameters('lampCommon').osDiskStorageType]" }, - "name": "[parameters('moodleCommon').ctlrVmName]" + "name": "[parameters('lampCommon').ctlrVmName]" }, - "dataDisks": "[take(variables('nfsDiskArray'),if(equals(parameters('moodleCommon').fileServerType,'nfs'), parameters('moodleCommon').fileServerDiskCount, 0))]" + "dataDisks": "[take(variables('nfsDiskArray'),if(equals(parameters('lampCommon').fileServerType,'nfs'), parameters('lampCommon').fileServerDiskCount, 0))]" } }, "tags": { @@ -152,51 +152,51 @@ } }, { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", + "condition": "[parameters('lampCommon').applyScriptsSwitch]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', parameters('moodleCommon').ctlrVmName)]" + "[concat('Microsoft.Compute/virtualMachines/', parameters('lampCommon').ctlrVmName)]" ], - "name": "[concat(parameters('moodleCommon').ctlrVmName,'-ScriptProcessor')]", + "name": "[concat(parameters('lampCommon').ctlrVmName,'-ScriptProcessor')]", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl, 'controllersetup.json', parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl, 'controllersetup.json', parameters('lampCommon').artifactsSasToken)]" } } }, { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", + "condition": "[parameters('lampCommon').azureBackupSwitch]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/',parameters('moodleCommon').ctlrVmName)]" + "[concat('Microsoft.Compute/virtualMachines/',parameters('lampCommon').ctlrVmName)]" ], - "name": "[concat(parameters('moodleCommon').ctlrVmName,'-Backup')]", + "name": "[concat(parameters('lampCommon').ctlrVmName,'-Backup')]", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "vmName": { - "value": "[parameters('moodleCommon').ctlrVmName]" + "value": "[parameters('lampCommon').ctlrVmName]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('lampCommon').artifactsSasToken)]" } } } ], "variables": { - "documentation01": "This sub-template drives the controller/jump-box which is used as the access-point for other moodle VM's ", + "documentation01": "This sub-template drives the controller/jump-box which is used as the access-point for other VMs in the cluster", "documentation02": "It expects certain values in the 'common' datastructure.", "documentation03": " vnetName - name of virtual network", "documentation04": " subnetWeb - name of subnet for controller (and vm scale set)", @@ -206,8 +206,8 @@ "documentation09": "This sub-template calls other sub-templates", "documentation10": " controllerconfig - conditionally applies post-deployment script on the VM", "documentation18": " recoveryservicesEnlist - conditionally enlists the VM into the backup regimen", - "nicRef": "[resourceId('Microsoft.Network/networkInterfaces', parameters('moodleCommon').ctlrNicName)]", - "nsgRef": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('moodleCommon').ctlrNsgName)]", + "nicRef": "[resourceId('Microsoft.Network/networkInterfaces', parameters('lampCommon').ctlrNicName)]", + "nsgRef": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('lampCommon').ctlrNsgName)]", "singleQuote": "'", "copy": [ { @@ -217,7 +217,7 @@ "managedDisk": { "storageAccountType": "Premium_LRS" }, - "diskSizeGB": "[parameters('moodleCommon').fileServerDiskSize]", + "diskSizeGB": "[parameters('lampCommon').fileServerDiskSize]", "lun": "[copyIndex('nfsDiskArray')]", "createOption": "Empty" } @@ -226,7 +226,7 @@ }, "outputs": { "controllerIP": { - "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', parameters('moodleCommon').ctlrPipName), '2017-10-01').ipAddress]", + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', parameters('lampCommon').ctlrPipName), '2017-10-01').ipAddress]", "type": "string" } } diff --git a/nested/controllersetup.json b/nested/controllersetup.json index a6f8f09..2efc2a0 100644 --- a/nested/controllersetup.json +++ b/nested/controllersetup.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" } @@ -13,25 +13,25 @@ { "type": "Microsoft.Compute/virtualMachines/extensions", "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').ctlrVmName,'/','install_moodle')]", + "location": "[parameters('lampCommon').location]", + "name": "[concat(parameters('lampCommon').ctlrVmName,'/','setup_controller')]", "properties": { "autoUpgradeMinorVersion": true, "publisher": "Microsoft.Azure.Extensions", "settings": { "fileUris": [ "[variables('scriptUri')]", - "[parameters('moodleCommon').commonFunctionsScriptUri]" + "[parameters('lampCommon').commonFunctionsScriptUri]" ] }, "protectedSettings":{ - "commandToExecute": "[concat('bash ', parameters('moodleCommon').moodleInstallScriptFilename, ' ', parameters('moodleCommon').moodleOnAzureConfigsJsonPath)]" + "commandToExecute": "[concat('bash ', parameters('lampCommon').controllerInstallScriptFilename, ' ', parameters('lampCommon').lampOnAzureConfigsJsonPath)]" }, "type": "CustomScript", "typeHandlerVersion": "2.0" }, "tags": { - "displayName": "install_moodle" + "displayName": "setup_controller" } } ], @@ -39,19 +39,15 @@ "documentation01": "This sub-template applies a specific post-deployment script to the controller vm", "documentation02": "It expects certain values in the 'common' datastructure.", "documentation03": " scriptLocation - web URI", - "documentation04": " moodleInstallScriptFilename - name of script file", + "documentation04": " controllerInstallScriptFilename - name of script file", "documentation05": " siteURL - URL of the website", "documentation06": " gfsNameRoot - nameroot of gluster farm - note that the code applies a 0 to get to the first node", "documentation07": " ctlrVmName - name of the controller/jumpb ox VM", "documentation08": " dbServerType - postgres or mysql", - "documentation09": " moodleDbName - database name for moodle", - "documentation10": " moodleDbUser - database user for moodle", - "documentation11": " moodleDbPass - database password for moodleDbUser", - "documentation12": " moodleAdminPass - password for moodle admin user", - "documentation13": " mssqlDbServiceObjectiveName - MS SQL porformance tier.", - "documentation14": " mssqlDbEdition - MS SQL edition tier", - "documentation15": " mssqlDbSize - MS SQL database size", + "documentation09": " mssqlDbServiceObjectiveName - MS SQL porformance tier.", + "documentation10": " mssqlDbEdition - MS SQL edition tier", + "documentation11": " mssqlDbSize - MS SQL database size", - "scriptUri": "[concat(parameters('moodleCommon').scriptLocation,parameters('moodleCommon').moodleInstallScriptFilename,parameters('moodleCommon').artifactsSasToken)]" + "scriptUri": "[concat(parameters('lampCommon').scriptLocation,parameters('lampCommon').controllerInstallScriptFilename,parameters('lampCommon').artifactsSasToken)]" } } diff --git a/nested/db-mssql.json b/nested/db-mssql.json index 4603098..fce6116 100644 --- a/nested/db-mssql.json +++ b/nested/db-mssql.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01-preview/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -26,20 +26,20 @@ "type": "Microsoft.Sql/servers", "apiVersion": "2015-05-01-preview", "kind": "", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').serverName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').serverName]", "properties": { - "administratorLogin": "[parameters('moodleCommon').dbLogin]", - "administratorLoginPassword": "[parameters('moodleCommon').dbLoginPassword]", - "version": "[parameters('moodleCommon').mssqlVersion]" + "administratorLogin": "[parameters('lampCommon').dbLogin]", + "administratorLoginPassword": "[parameters('lampCommon').dbLoginPassword]", + "version": "[parameters('lampCommon').mssqlVersion]" }, "resources": [ { "apiVersion": "2014-04-01", "dependsOn": [ - "[concat('Microsoft.Sql/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.Sql/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "mssql-firewall-allow-lb", "properties": { "startIpAddress": "[parameters('lbPubIp')]", @@ -50,9 +50,9 @@ { "apiVersion": "2014-04-01", "dependsOn": [ - "[concat('Microsoft.Sql/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.Sql/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "mssql-firewall-allow-ctlr", "properties": { "startIpAddress": "[parameters('ctlrPubIp')]", @@ -66,7 +66,7 @@ "outputs": { "dbFQDN": { "type": "string", - "value": "[reference(parameters('moodleCommon').serverName).fullyQualifiedDomainName]" + "value": "[reference(parameters('lampCommon').serverName).fullyQualifiedDomainName]" } }, "variables": { diff --git a/nested/db-mysql.json b/nested/db-mysql.json index 7a41049..e135586 100644 --- a/nested/db-mysql.json +++ b/nested/db-mysql.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -26,32 +26,32 @@ "type": "Microsoft.DBforMySQL/servers", "apiVersion": "2017-12-01", "kind": "", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').serverName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').serverName]", "properties": { - "administratorLogin": "[parameters('moodleCommon').dbLogin]", - "administratorLoginPassword": "[parameters('moodleCommon').dbLoginPassword]", - "sslEnforcement": "[parameters('moodleCommon').sslEnforcement]", + "administratorLogin": "[parameters('lampCommon').dbLogin]", + "administratorLoginPassword": "[parameters('lampCommon').dbLoginPassword]", + "sslEnforcement": "[parameters('lampCommon').sslEnforcement]", "storageProfile": { - "storageMB": "[mul(parameters('moodleCommon').mysqlPgresStgSizeGB, 1024)]", + "storageMB": "[mul(parameters('lampCommon').mysqlPgresStgSizeGB, 1024)]", "backupRetentionDays": "35", "geoRedundantBackup": "Enabled" }, - "version": "[parameters('moodleCommon').mysqlVersion]" + "version": "[parameters('lampCommon').mysqlVersion]" }, "sku": { - "capacity": "[parameters('moodleCommon').mysqlPgresVcores]", - "name": "[parameters('moodleCommon').mysqlPgresSkuName]", - "tier": "[parameters('moodleCommon').mysqlPgresSkuTier]", - "family": "[parameters('moodleCommon').mysqlPgresSkuHwFamily]" + "capacity": "[parameters('lampCommon').mysqlPgresVcores]", + "name": "[parameters('lampCommon').mysqlPgresSkuName]", + "tier": "[parameters('lampCommon').mysqlPgresSkuTier]", + "family": "[parameters('lampCommon').mysqlPgresSkuHwFamily]" }, "resources": [ { "apiVersion": "2017-12-01", "dependsOn": [ - "[concat('Microsoft.DBforMySQL/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.DBforMySQL/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "mysql-firewall-allow-lb", "properties": { "startIpAddress": "[parameters('lbPubIp')]", @@ -62,9 +62,9 @@ { "apiVersion": "2017-12-01", "dependsOn": [ - "[concat('Microsoft.DBforMySQL/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.DBforMySQL/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "mysql-firewall-allow-ctlr", "properties": { "startIpAddress": "[parameters('ctlrPubIp')]", @@ -78,7 +78,7 @@ "outputs": { "dbFQDN": { "type": "string", - "value": "[reference(parameters('moodleCommon').serverName).fullyQualifiedDomainName]" + "value": "[reference(parameters('lampCommon').serverName).fullyQualifiedDomainName]" } }, "variables": { diff --git a/nested/db-postgres.json b/nested/db-postgres.json index 3fc6404..fe4bdcd 100644 --- a/nested/db-postgres.json +++ b/nested/db-postgres.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -26,32 +26,32 @@ "type": "Microsoft.DBforPostgreSQL/servers", "apiVersion": "2017-12-01", "kind": "", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').serverName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').serverName]", "properties": { - "administratorLogin": "[parameters('moodleCommon').dbLogin]", - "administratorLoginPassword": "[parameters('moodleCommon').dbLoginPassword]", - "sslEnforcement": "[parameters('moodleCommon').sslEnforcement]", + "administratorLogin": "[parameters('lampCommon').dbLogin]", + "administratorLoginPassword": "[parameters('lampCommon').dbLoginPassword]", + "sslEnforcement": "[parameters('lampCommon').sslEnforcement]", "storageProfile": { - "storageMB": "[mul(parameters('moodleCommon').mysqlPgresStgSizeGB, 1024)]", + "storageMB": "[mul(parameters('lampCommon').mysqlPgresStgSizeGB, 1024)]", "backupRetentionDays": "35", "geoRedundantBackup": "Enabled" }, - "version": "[parameters('moodleCommon').postgresVersion]" + "version": "[parameters('lampCommon').postgresVersion]" }, "sku": { - "capacity": "[parameters('moodleCommon').mysqlPgresVcores]", - "name": "[parameters('moodleCommon').mysqlPgresSkuName]", - "tier": "[parameters('moodleCommon').mysqlPgresSkuTier]", - "family": "[parameters('moodleCommon').mysqlPgresSkuHwFamily]" + "capacity": "[parameters('lampCommon').mysqlPgresVcores]", + "name": "[parameters('lampCommon').mysqlPgresSkuName]", + "tier": "[parameters('lampCommon').mysqlPgresSkuTier]", + "family": "[parameters('lampCommon').mysqlPgresSkuHwFamily]" }, "resources": [ { "apiVersion": "2017-12-01", "dependsOn": [ - "[concat('Microsoft.DBforPostgreSQL/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.DBforPostgreSQL/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "postgres-firewall-allow-lb", "properties": { "startIpAddress": "[parameters('lbPubIp')]", @@ -62,9 +62,9 @@ { "apiVersion": "2017-12-01", "dependsOn": [ - "[concat('Microsoft.DBforPostgreSQL/servers/', parameters('moodleCommon').serverName)]" + "[concat('Microsoft.DBforPostgreSQL/servers/', parameters('lampCommon').serverName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "postgres-firewall-allow-ctlr", "properties": { "startIpAddress": "[parameters('ctlrPubIp')]", @@ -78,7 +78,7 @@ "outputs": { "dbFQDN": { "type": "string", - "value": "[reference(parameters('moodleCommon').serverName).fullyQualifiedDomainName]" + "value": "[reference(parameters('lampCommon').serverName).fullyQualifiedDomainName]" } }, "variables": { diff --git a/nested/gluster.json b/nested/gluster.json index f7260a4..ae0a6b5 100644 --- a/nested/gluster.json +++ b/nested/gluster.json @@ -2,9 +2,9 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -19,8 +19,8 @@ { "type": "Microsoft.Compute/availabilitySets", "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').gfxAvailabilitySetName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').gfsAvailabilitySetName]", "properties": { "platformFaultDomainCount": 2, "platformUpdateDomainCount": 5 @@ -36,11 +36,11 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "copy": { - "count": "[parameters('moodleCommon').fileServerVmCount]", + "count": "[parameters('lampCommon').fileServerVmCount]", "name": "vmloop" }, "dependsOn": [ - "[concat('Microsoft.Compute/availabilitySets/',parameters('moodleCommon').gfxAvailabilitySetName)]" + "[concat('Microsoft.Compute/availabilitySets/',parameters('lampCommon').gfsAvailabilitySetName)]" ], "name": "[concat('glustervm',copyindex())]", "properties": { @@ -49,15 +49,15 @@ "counter": { "value": "[copyindex()]" }, - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "subnetIdSan": { "value": "[parameters('subnetIdSan')]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'glustervm.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'glustervm.json',parameters('lampCommon').artifactsSasToken)]" } } } @@ -65,7 +65,7 @@ "variables": { "documentation1": "This sub-template drives the gluster (scale-out network-attached storage file system) creation process.", "documentation2": "It expects certain values in the 'common' datastructure.", - "documentation4": " gfxAvailabilitySetName - name of availability set for the gluster farm", + "documentation4": " gfsAvailabilitySetName - name of availability set for the gluster farm", "documentation5": " fileServerVmCount - number of nodes to create", "documentation6": "This sub-template calls other sub-templates", "documentation7": " glustervm - number of nodes in the gluster farm" diff --git a/nested/glustervm.json b/nested/glustervm.json index 11a045b..5fd0e4f 100644 --- a/nested/glustervm.json +++ b/nested/glustervm.json @@ -8,9 +8,9 @@ }, "type": "int" }, - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -25,7 +25,7 @@ { "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "[variables('nicName')]", "properties": { "ipConfigurations": [ @@ -39,7 +39,7 @@ } } ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" + "enableAcceleratedNetworking": "[parameters('lampCommon').enableAccelNwForOtherVmsSwitch]" }, "tags": { "displayName": "Gluster VM NIC" @@ -51,14 +51,14 @@ "dependsOn": [ "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "[variables('vmName')]", "properties": { "availabilitySet": { "id": "[variables('asRef')]" }, "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').fileServerVmSku]" + "vmSize": "[parameters('lampCommon').fileServerVmSku]" }, "networkProfile": { "networkInterfaces": [ @@ -68,38 +68,38 @@ ] }, "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", + "adminUsername": "[parameters('lampCommon').sshUsername]", "computerName": "[variables('vmName')]", "linuxConfiguration": { "disablePasswordAuthentication": true, "ssh": { "publicKeys": [ { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" + "path": "[concat('/home/', parameters('lampCommon').sshUsername, '/.ssh/authorized_keys')]", + "keyData": "[parameters('lampCommon').sshPublicKey]" } ] } } }, "storageProfile": { - "imageReference": "[parameters('moodleCommon').osType]", + "imageReference": "[parameters('lampCommon').osType]", "osDisk": { "createOption": "FromImage", "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" + "storageAccountType": "[parameters('lampCommon').osDiskStorageType]" }, "name": "[variables('vmName')]" }, "copy": [ { "name": "dataDisks", - "count": "[parameters('moodleCommon').fileServerDiskCount]", + "count": "[parameters('lampCommon').fileServerDiskCount]", "input": { "managedDisk": { "storageAccountType": "Premium_LRS" }, - "diskSizeGB": "[parameters('moodleCommon').fileServerDiskSize]", + "diskSizeGB": "[parameters('lampCommon').fileServerDiskSize]", "lun": "[copyIndex('dataDisks')]", "createOption": "Empty" } @@ -112,7 +112,7 @@ } }, { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", + "condition": "[parameters('lampCommon').applyScriptsSwitch]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "dependsOn": [ @@ -122,8 +122,8 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "vmName": { "value": "[ variables('vmName')]" @@ -133,12 +133,12 @@ } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'glustervmsetup.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'glustervmsetup.json',parameters('lampCommon').artifactsSasToken)]" } } }, { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", + "condition": "[parameters('lampCommon').azureBackupSwitch]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "dependsOn": [ @@ -148,24 +148,24 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "vmName": { "value": "[variables('vmName')]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('lampCommon').artifactsSasToken)]" } } } ], "variables": { - "asRef": "[resourceId('Microsoft.Compute/availabilitySets', parameters('moodleCommon').gfxAvailabilitySetName)]", + "asRef": "[resourceId('Microsoft.Compute/availabilitySets', parameters('lampCommon').gfsAvailabilitySetName)]", "documentation01": "This sub-template create the nodes of the gluster farm", "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation04": " gfxAvailabilitySetName - name of availability set for the gluster farm", + "documentation04": " gfsAvailabilitySetName - name of availability set for the gluster farm", "documentation05": " vnetName - name of virtual network", "documentation06": " subnetSan - name of subnet for gluster", "documentation07": " gfsNameRoot - nameroot for the gluster nodes - combined with counter to get actual name of each node - disk and nic follow the naming scheme", @@ -179,6 +179,6 @@ "documentation20": " fileServerDiskSize - Size per disk for gluster", "nicName": "[concat(variables('vmName'),'-nic')]", "nicRef": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]", - "vmName": "[concat(parameters('moodleCommon').gfsNameRoot,parameters('counter'))]" + "vmName": "[concat(parameters('lampCommon').gfsNameRoot,parameters('counter'))]" } } diff --git a/nested/glustervmsetup.json b/nested/glustervmsetup.json index 0a9f25e..b0d5187 100644 --- a/nested/glustervmsetup.json +++ b/nested/glustervmsetup.json @@ -2,9 +2,9 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -25,7 +25,7 @@ { "type": "Microsoft.Compute/virtualMachines/extensions", "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "[concat(parameters('vmName'),'/','install_gluster')]", "properties": { "publisher": "Microsoft.Azure.Extensions", @@ -46,13 +46,13 @@ } ], "variables": { - "cmdExec": "[concat('bash ', parameters('moodleCommon').glusterScriptFilename, ' ', parameters('moodleCommon').gfsNameRoot, ' ', parameters('moodleCommon').subnetSanPrefix, ' data ', parameters('vmNumber'), ' ', parameters('moodleCommon').fileServerVmCount)]", + "cmdExec": "[concat('bash ', parameters('lampCommon').glusterScriptFilename, ' ', parameters('lampCommon').gfsNameRoot, ' ', parameters('lampCommon').subnetSanPrefix, ' data ', parameters('vmNumber'), ' ', parameters('lampCommon').fileServerVmCount)]", "documentation01": "This sub-template applies a specific post-deployment script to the gluster vms", "documentation02": "It expects certain values in the 'common' datastructure.", "documentation03": " scriptLocation - partial web URI (equivalent to folder)", "documentation04": " glusterScriptFilename - name of script file", "documentation06": " gfsNameRoot - nameroot of gluster farm - note that the code applies a vmNumber to get to the specific node", "documentation07": " fileServerVmCount - number of gluster VMs", - "scriptUri": "[concat(parameters('moodleCommon').scriptLocation,parameters('moodleCommon').glusterScriptFilename,parameters('moodleCommon').artifactsSasToken)]" + "scriptUri": "[concat(parameters('lampCommon').scriptLocation,parameters('lampCommon').glusterScriptFilename,parameters('lampCommon').artifactsSasToken)]" } } diff --git a/nested/network-subnets.json b/nested/network-subnets.json index 4fa7ea3..72fc6c7 100644 --- a/nested/network-subnets.json +++ b/nested/network-subnets.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -19,83 +19,59 @@ { "type": "Microsoft.Network/virtualNetworks/subnets", "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetWeb)]", - "location": "[parameters('moodleCommon').location]", + "name": "[concat(parameters('vnetName'), '/', parameters('lampCommon').subnetWeb)]", + "location": "[parameters('lampCommon').location]", "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetWebRange]" + "addressPrefix": "[parameters('lampCommon').subnetWebRange]" } }, { "type": "Microsoft.Network/virtualNetworks/subnets", "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetSan)]", - "location": "[parameters('moodleCommon').location]", + "name": "[concat(parameters('vnetName'), '/', parameters('lampCommon').subnetSan)]", + "location": "[parameters('lampCommon').location]", "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetWeb)]" + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('lampCommon').subnetWeb)]" ], "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetSanRange]" + "addressPrefix": "[parameters('lampCommon').subnetSanRange]" } }, { "type": "Microsoft.Network/virtualNetworks/subnets", "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetRedis)]", - "location": "[parameters('moodleCommon').location]", + "name": "[concat(parameters('vnetName'), '/', parameters('lampCommon').subnetRedis)]", + "location": "[parameters('lampCommon').location]", "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetSan)]" + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('lampCommon').subnetSan)]" ], "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetRedisRange]" + "addressPrefix": "[parameters('lampCommon').subnetRedisRange]" + } + }, + { + "condition": "[parameters('lampCommon').vnetGwDeploySwitch]", + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2017-10-01", + "name": "[concat(parameters('vnetName'), '/', parameters('lampCommon').subnetGateway)]", + "location": "[parameters('lampCommon').location]", + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('lampCommon').subnetRedis)]" + ], + "properties": { + "addressPrefix": "[parameters('lampCommon').subnetGatewayRange]" } }, { "type": "Microsoft.Network/virtualNetworks/subnets", "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetElastic)]", - "location": "[parameters('moodleCommon').location]", + "name": "[concat(parameters('vnetName'), '/', parameters('lampCommon').subnetAppGw)]", + "location": "[parameters('lampCommon').location]", "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetRedis)]" + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('lampCommon').subnetGateway)]" ], "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetElasticRange]" - } - }, - { - "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetTika)]", - "location": "[parameters('moodleCommon').location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetElastic)]" - ], - "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetTikaRange]" - } - }, - { - "condition": "[parameters('moodleCommon').vnetGwDeploySwitch]", - "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetGateway)]", - "location": "[parameters('moodleCommon').location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetTika)]" - ], - "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetGatewayRange]" - } - }, - { - "type": "Microsoft.Network/virtualNetworks/subnets", - "apiVersion": "2017-10-01", - "name": "[concat(parameters('vnetName'), '/', parameters('moodleCommon').subnetAppGw)]", - "location": "[parameters('moodleCommon').location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('moodleCommon').subnetGateway)]" - ], - "properties": { - "addressPrefix": "[parameters('moodleCommon').subnetAppGwRange]" + "addressPrefix": "[parameters('lampCommon').subnetAppGwRange]" } } ], diff --git a/nested/network-vnet-ddos.json b/nested/network-vnet-ddos.json index f2dbdc4..01e1856 100644 --- a/nested/network-vnet-ddos.json +++ b/nested/network-vnet-ddos.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -25,17 +25,17 @@ { "type": "Microsoft.Network/ddosProtectionPlans", "apiVersion": "2018-02-01", - "condition": "[parameters('moodleCommon').ddosSwitch]", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').ddosPlanName]" + "condition": "[parameters('lampCommon').ddosSwitch]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').ddosPlanName]" }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2018-02-01", "dependsOn": [ - "[resourceId('Microsoft.Network/ddosProtectionPlans', parameters('moodleCommon').ddosPlanName)]" + "[resourceId('Microsoft.Network/ddosProtectionPlans', parameters('lampCommon').ddosPlanName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "[parameters('vnetName')]", "properties": { "addressSpace": { @@ -44,9 +44,9 @@ ] }, "ddosProtectionPlan": { - "id": "[resourceId('Microsoft.Network/ddosProtectionPlans', parameters('moodleCommon').ddosPlanName)]" + "id": "[resourceId('Microsoft.Network/ddosProtectionPlans', parameters('lampCommon').ddosPlanName)]" }, - "enableDdosProtection": "[parameters('moodleCommon').ddosSwitch]" + "enableDdosProtection": "[parameters('lampCommon').ddosSwitch]" } } ], diff --git a/nested/network-vnet.json b/nested/network-vnet.json index 255553d..cfacc79 100644 --- a/nested/network-vnet.json +++ b/nested/network-vnet.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" } @@ -13,12 +13,12 @@ { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').vnetName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').vnetName]", "properties": { "addressSpace": { "addressPrefixes": [ - "[concat(parameters('moodleCommon').vNetAddressSpace,'/16')]" + "[concat(parameters('lampCommon').vNetAddressSpace,'/16')]" ] } } diff --git a/nested/network.json b/nested/network.json index 774bec0..b2de0d4 100644 --- a/nested/network.json +++ b/nested/network.json @@ -2,34 +2,34 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" } }, "resources": [ { - "condition": "[equals(parameters('moodleCommon').customVnetId, '')]", + "condition": "[equals(parameters('lampCommon').customVnetId, '')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "name": "vnetTemplate", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'network-vnet.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'network-vnet.json',parameters('lampCommon').artifactsSasToken)]" } } }, { "apiVersion": "2018-02-01", - "condition": "[parameters('moodleCommon').ddosSwitch]", + "condition": "[parameters('lampCommon').ddosSwitch]", "dependsOn": [ "Microsoft.Resources/deployments/vnetTemplate" ], @@ -39,18 +39,18 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "vnetName": { "value": "[variables('vnetName')]" }, "vNetAddressSpace": { - "value": "[if(equals(parameters('moodleCommon').customVnetId, ''), concat(parameters('moodleCommon').vNetAddressSpace,'/16'), reference(parameters('moodleCommon').customVnetId, '2017-10-01').addressSpace.addressPrefixes[0])]" + "value": "[if(equals(parameters('lampCommon').customVnetId, ''), concat(parameters('lampCommon').vNetAddressSpace,'/16'), reference(parameters('lampCommon').customVnetId, '2017-10-01').addressSpace.addressPrefixes[0])]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'network-vnet-ddos.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'network-vnet-ddos.json',parameters('lampCommon').artifactsSasToken)]" } }, "type": "Microsoft.Resources/deployments" @@ -68,24 +68,24 @@ "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "vnetName": { "value": "[variables('vnetName')]" } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'network-subnets.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'network-subnets.json',parameters('lampCommon').artifactsSasToken)]" } } }, { - "condition": "[parameters('moodleCommon').vnetGwDeploySwitch]", + "condition": "[parameters('lampCommon').vnetGwDeploySwitch]", "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').gatewayPublicIPName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').gatewayPublicIPName]", "properties": { "publicIPAllocationMethod": "Dynamic" }, @@ -94,26 +94,26 @@ } }, { - "condition": "[parameters('moodleCommon').vnetGwDeploySwitch]", + "condition": "[parameters('lampCommon').vnetGwDeploySwitch]", "type": "Microsoft.Network/virtualNetworkGateways", "apiVersion": "2017-10-01", "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', parameters('moodleCommon').gatewayPublicIPName)]", + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('lampCommon').gatewayPublicIPName)]", "Microsoft.Resources/deployments/subnetTemplate" ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').gatewayName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').gatewayName]", "properties": { "activeActive": false, "enableBgp": false, - "gatewayType": "[parameters('moodleCommon').gatewayType]", + "gatewayType": "[parameters('lampCommon').gatewayType]", "ipConfigurations": [ { "name": "vnet-Gateway-Config", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('moodleCommon').gatewayPublicIPName)]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('lampCommon').gatewayPublicIPName)]" }, "subnet": { "id": "[variables('subnetIdGateway')]" @@ -126,21 +126,21 @@ "tier": "VpnGw1", "capacity": 2 }, - "vpnType": "[parameters('moodleCommon').vpnType]" + "vpnType": "[parameters('lampCommon').vpnType]" } }, { - "condition": "[not(equals(parameters('moodleCommon').httpsTermination, 'AppGw'))]", + "condition": "[not(equals(parameters('lampCommon').httpsTermination, 'AppGw'))]", "type": "Microsoft.Network/publicIPAddresses", "sku": { - "name": "[parameters('moodleCommon').lbSku]" + "name": "[parameters('lampCommon').lbSku]" }, "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').lbPipName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').lbPipName]", "properties": { "dnsSettings": { - "domainNameLabel": "[parameters('moodleCommon').lbName]" + "domainNameLabel": "[parameters('lampCommon').lbName]" }, "publicIPAllocationMethod": "Static" }, @@ -149,14 +149,14 @@ } }, { - "condition": "[equals(parameters('moodleCommon').httpsTermination, 'AppGw')]", + "condition": "[equals(parameters('lampCommon').httpsTermination, 'AppGw')]", "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').appGwPipName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').appGwPipName]", "properties": { "dnsSettings": { - "domainNameLabel": "[parameters('moodleCommon').appGwName]" + "domainNameLabel": "[parameters('lampCommon').appGwName]" }, "publicIPAllocationMethod": "Dynamic" }, @@ -167,11 +167,11 @@ { "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').ctlrPipName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').ctlrPipName]", "properties": { "dnsSettings": { - "domainNameLabel": "[parameters('moodleCommon').ctlrPipName]" + "domainNameLabel": "[parameters('lampCommon').ctlrPipName]" }, "publicIPAllocationMethod": "Static" }, @@ -180,26 +180,26 @@ } }, { - "condition": "[not(equals(parameters('moodleCommon').httpsTermination, 'AppGw'))]", + "condition": "[not(equals(parameters('lampCommon').httpsTermination, 'AppGw'))]", "type": "Microsoft.Network/loadBalancers", "sku": { - "name": "[parameters('moodleCommon').lbSku]" + "name": "[parameters('lampCommon').lbSku]" }, "apiVersion": "2017-10-01", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/',parameters('moodleCommon').lbPipName)]" + "[concat('Microsoft.Network/publicIPAddresses/',parameters('lampCommon').lbPipName)]" ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').lbName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').lbName]", "properties": { "backendAddressPools": [ { - "name": "[parameters('moodleCommon').extBeName ]" + "name": "[parameters('lampCommon').extBeName ]" } ], "frontendIPConfigurations": [ { - "name": "[parameters('moodleCommon').extFeName ]", + "name": "[parameters('lampCommon').extFeName ]", "properties": { "publicIPAddress": { "id": "[variables('lbPipID')]" @@ -249,7 +249,7 @@ ], "probes": [ { - "name": "[parameters('moodleCommon').extProbeHTTP ]", + "name": "[parameters('lampCommon').extProbeHTTP ]", "properties": { "intervalInSeconds": 5, "numberOfProbes": 3, @@ -258,7 +258,7 @@ } }, { - "name": "[parameters('moodleCommon').extProbeHTTPS ]", + "name": "[parameters('lampCommon').extProbeHTTPS ]", "properties": { "intervalInSeconds": 5, "numberOfProbes": 3, @@ -270,19 +270,19 @@ } }, { - "condition": "[equals(parameters('moodleCommon').httpsTermination, 'AppGw')]", + "condition": "[equals(parameters('lampCommon').httpsTermination, 'AppGw')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2017-05-10", "dependsOn": [ "Microsoft.Resources/deployments/subnetTemplate", - "[concat('Microsoft.Network/publicIPAddresses/',parameters('moodleCommon').lbPipName)]" + "[concat('Microsoft.Network/publicIPAddresses/',parameters('lampCommon').lbPipName)]" ], "name": "appGwTemplate", "properties": { "mode": "Incremental", "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" + "lampCommon": { + "value": "[parameters('lampCommon')]" }, "subnetIdAppGw": { "value": "[variables('subnetIdAppGw')]" @@ -290,53 +290,49 @@ "sslCertData": { "reference": { "keyVault": { - "id": "[parameters('moodleCommon').appGwSslCertKeyVaultResourceId]" + "id": "[parameters('lampCommon').appGwSslCertKeyVaultResourceId]" }, - "secretName": "[parameters('moodleCommon').appGwSslCertKeyVaultSecretName]" + "secretName": "[parameters('lampCommon').appGwSslCertKeyVaultSecretName]" } } }, "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'appgw.json',parameters('moodleCommon').artifactsSasToken)]" + "uri": "[concat(parameters('lampCommon').baseTemplateUrl,'appgw.json',parameters('lampCommon').artifactsSasToken)]" } } } ], "variables": { - "documentation01": "This sub-template creates a virtual network with a number of subnets and then creates the moodle load-balancer (or an Azure Application Gateway) with public IP/dns", - "extBeID": "[concat(variables('extLbID'),'/backendAddressPools/',parameters('moodleCommon').extBeName)]", - "extFeID": "[concat(variables('extLbID'),'/frontendIPConfigurations/',parameters('moodleCommon').extFeName)]", - "extLbID": "[resourceId('Microsoft.Network/loadBalancers',parameters('moodleCommon').lbName)]", - "extProbeHTTPID": "[concat(variables('extLbID'),'/probes/',parameters('moodleCommon').extProbeHTTP)]", - "extProbeHTTPSID": "[concat(variables('extLbID'),'/probes/',parameters('moodleCommon').extProbeHTTPS)]", - "lbPipID": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('moodleCommon').lbPipName)]", - "ctlrPipID": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('moodleCommon').ctlrPipName)]", - "customVnetIdArr": "[split(parameters('moodleCommon').customVnetId, '/')]", - "vnetSub": "[if(equals(parameters('moodleCommon').customVnetId, ''), subscription().subscriptionId, variables('customVnetIdArr')[2])]", - "vnetRg": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceGroup().name, variables('customVnetIdArr')[4])]", - "vnetName": "[if(equals(parameters('moodleCommon').customVnetId, ''), parameters('moodleCommon').vnetName, variables('customVnetIdArr')[8])]", - "customVnetSubnetIdWeb": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetWeb)]", - "customVnetSubnetIdSan": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetSan)]", - "customVnetSubnetIdRedis": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetRedis)]", - "customVnetSubnetIdElastic": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetElastic)]", - "customVnetSubnetIdTika": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetTika)]", - "customVnetSubnetIdGateway": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetGateway)]", - "customVnetSubnetIdAppGw": "[concat(parameters('moodleCommon').customVnetId, '/subnets/', parameters('moodleCommon').subnetAppGw)]", - "subnetIdWeb": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetWeb), variables('customVnetSubnetIdWeb'))]", - "subnetIdSan": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetSan), variables('customVnetSubnetIdSan'))]", - "subnetIdRedis": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetRedis), variables('customVnetSubnetIdRedis'))]", - "subnetIdElastic": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetElastic), variables('customVnetSubnetIdElastic'))]", - "subnetIdTika": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetTika), variables('customVnetSubnetIdTika'))]", - "subnetIdGateway": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetGateway), variables('customVnetSubnetIdGateway'))]", - "subnetIdAppGw": "[if(equals(parameters('moodleCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('moodleCommon').subnetAppGw), variables('customVnetSubnetIdAppGw'))]" + "documentation01": "This sub-template creates a virtual network with a number of subnets and then creates the load-balancer (or an Azure Application Gateway) with public IP/dns", + "extBeID": "[concat(variables('extLbID'),'/backendAddressPools/',parameters('lampCommon').extBeName)]", + "extFeID": "[concat(variables('extLbID'),'/frontendIPConfigurations/',parameters('lampCommon').extFeName)]", + "extLbID": "[resourceId('Microsoft.Network/loadBalancers',parameters('lampCommon').lbName)]", + "extProbeHTTPID": "[concat(variables('extLbID'),'/probes/',parameters('lampCommon').extProbeHTTP)]", + "extProbeHTTPSID": "[concat(variables('extLbID'),'/probes/',parameters('lampCommon').extProbeHTTPS)]", + "lbPipID": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('lampCommon').lbPipName)]", + "ctlrPipID": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('lampCommon').ctlrPipName)]", + "customVnetIdArr": "[split(parameters('lampCommon').customVnetId, '/')]", + "vnetSub": "[if(equals(parameters('lampCommon').customVnetId, ''), subscription().subscriptionId, variables('customVnetIdArr')[2])]", + "vnetRg": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceGroup().name, variables('customVnetIdArr')[4])]", + "vnetName": "[if(equals(parameters('lampCommon').customVnetId, ''), parameters('lampCommon').vnetName, variables('customVnetIdArr')[8])]", + "customVnetSubnetIdWeb": "[concat(parameters('lampCommon').customVnetId, '/subnets/', parameters('lampCommon').subnetWeb)]", + "customVnetSubnetIdSan": "[concat(parameters('lampCommon').customVnetId, '/subnets/', parameters('lampCommon').subnetSan)]", + "customVnetSubnetIdRedis": "[concat(parameters('lampCommon').customVnetId, '/subnets/', parameters('lampCommon').subnetRedis)]", + "customVnetSubnetIdGateway": "[concat(parameters('lampCommon').customVnetId, '/subnets/', parameters('lampCommon').subnetGateway)]", + "customVnetSubnetIdAppGw": "[concat(parameters('lampCommon').customVnetId, '/subnets/', parameters('lampCommon').subnetAppGw)]", + "subnetIdWeb": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('lampCommon').subnetWeb), variables('customVnetSubnetIdWeb'))]", + "subnetIdSan": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('lampCommon').subnetSan), variables('customVnetSubnetIdSan'))]", + "subnetIdRedis": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('lampCommon').subnetRedis), variables('customVnetSubnetIdRedis'))]", + "subnetIdGateway": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('lampCommon').subnetGateway), variables('customVnetSubnetIdGateway'))]", + "subnetIdAppGw": "[if(equals(parameters('lampCommon').customVnetId, ''), resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnetName'), parameters('lampCommon').subnetAppGw), variables('customVnetSubnetIdAppGw'))]" }, "outputs": { "lbPubIp": { - "value": "[if(equals(parameters('moodleCommon').httpsTermination, 'AppGw'), '0.0.0.0', reference(parameters('moodleCommon').lbPipName, '2017-10-01').ipAddress)]", + "value": "[if(equals(parameters('lampCommon').httpsTermination, 'AppGw'), '0.0.0.0', reference(parameters('lampCommon').lbPipName, '2017-10-01').ipAddress)]", "type": "string" }, "ctlrPubIp": { - "value": "[reference(parameters('moodleCommon').ctlrPipName, '2017-10-01').ipAddress]", + "value": "[reference(parameters('lampCommon').ctlrPipName, '2017-10-01').ipAddress]", "type": "string" }, "ctlrPubIpId": { @@ -354,14 +350,6 @@ "subnetIdRedis": { "value": "[variables('subnetIdRedis')]", "type": "string" - }, - "subnetIdElastic": { - "value": "[variables('subnetIdElastic')]", - "type": "string" - }, - "subnetIdTika": { - "value": "[variables('subnetIdTika')]", - "type": "string" } } } diff --git a/nested/recoveryservices.json b/nested/recoveryservices.json index 6089595..c00a9b5 100644 --- a/nested/recoveryservices.json +++ b/nested/recoveryservices.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" } @@ -13,8 +13,8 @@ { "type": "Microsoft.RecoveryServices/vaults", "apiVersion": "2016-06-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').vaultName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').vaultName]", "properties": {}, "sku": { "name": "RS0", @@ -25,10 +25,10 @@ "type": "Microsoft.RecoveryServices/vaults/backupPolicies", "apiVersion": "2017-07-01", "dependsOn": [ - "[concat('Microsoft.RecoveryServices/vaults/', parameters('moodleCommon').vaultName)]" + "[concat('Microsoft.RecoveryServices/vaults/', parameters('lampCommon').vaultName)]" ], - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').vaultName, '/', parameters('moodleCommon').policyName)]", + "location": "[parameters('lampCommon').location]", + "name": "[concat(parameters('lampCommon').vaultName, '/', parameters('lampCommon').policyName)]", "properties": { "backupManagementType": "AzureIaasVM", "retentionPolicy": { diff --git a/nested/recoveryservicesEnlist.json b/nested/recoveryservicesEnlist.json index b110aa3..21aed75 100644 --- a/nested/recoveryservicesEnlist.json +++ b/nested/recoveryservicesEnlist.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -19,10 +19,10 @@ { "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", "apiVersion": "2016-06-01", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').vaultName, '/', variables('backupFabric'), '/', variables('v2VmContainer'), concat(resourceGroup().name,';',parameters('vmName')), '/', variables('v2Vm'), concat(resourceGroup().name,';',parameters('vmName')))]", + "location": "[parameters('lampCommon').location]", + "name": "[concat(parameters('lampCommon').vaultName, '/', variables('backupFabric'), '/', variables('v2VmContainer'), concat(resourceGroup().name,';',parameters('vmName')), '/', variables('v2Vm'), concat(resourceGroup().name,';',parameters('vmName')))]", "properties": { - "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies',parameters('moodleCommon').vaultName,parameters('moodleCommon').policyName )]", + "policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies',parameters('lampCommon').vaultName,parameters('lampCommon').policyName )]", "protectedItemType": "[variables('v2VmType')]", "sourceResourceId": "[resourceId(subscription().subscriptionId,resourceGroup().name,'Microsoft.Compute/virtualMachines',parameters('vmName'))]" } diff --git a/nested/redis.json b/nested/redis.json index e1ab17c..47ca4e7 100644 --- a/nested/redis.json +++ b/nested/redis.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -19,8 +19,8 @@ { "type": "Microsoft.Cache/Redis", "apiVersion": "2016-04-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').redisCacheName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').redisCacheName]", "properties": { "enableNonSslPort": true, "sku": { @@ -35,7 +35,7 @@ "variables": { "documentation1": "This sub-template creates a redis cache. It expects certain values in the 'common' datastructure.", "documentation2": " redisCacheName - name of cache", - "redisResourceId": "[resourceId('Microsoft.Cache/Redis', parameters('moodleCommon').redisCacheName)]" + "redisResourceId": "[resourceId('Microsoft.Cache/Redis', parameters('lampCommon').redisCacheName)]" }, "outputs": { "redisKey": { diff --git a/nested/search-azure.json b/nested/search-azure.json deleted file mode 100644 index 95fb6af..0000000 --- a/nested/search-azure.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "moodleCommon": { - "metadata": { - "description": "Common Moodle values" - }, - "type": "object" - }, - "subnetIdElastic": { - "metadata": { - "description": "Azure resource ID of the subnet where the Elastic Search VMs are to be deployed (if any)" - }, - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Search/searchServices", - "apiVersion": "2015-08-19", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').azureSearchName]", - "sku": { - "name": "[parameters('moodleCommon').azureSearchSku]" - }, - "properties": { - "replicaCount": "[parameters('moodleCommon').azureSearchReplicaCount]", - "partitionCount": "[parameters('moodleCommon').azureSearchPartitionCount]", - "hostingMode": "[parameters('moodleCommon').azureSearchHostingMode]" - } - } - ], - "variables": { - "documentation01": "This sub-template drives the Azure Search which is used as the access-point for other moodle VM's ", - "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation03": " azureSearchName - the name of the Azure Search.", - "documentation04": " azureSearchSku - the level of Azure Search service.", - "documentation06": " azureSearchReplicaCount - number of Azure Search replicas.", - "documentation07": " azureSearchPartitionCount - number of Azure Search partitions.", - "documentation08": " azureSearchHostingMode - the type of Azure Search hosting mode.", - "azureSearchServiceId": "[resourceId('Microsoft.Search/searchServices', parameters('moodleCommon').azureSearchName)]" - }, - "outputs": { - "azureSearchKey": { - "value": "[listAdminKeys(variables('azureSearchServiceId'), '2015-08-19').PrimaryKey]", - "type": "string" - } - } -} diff --git a/nested/search-elastic-config.json b/nested/search-elastic-config.json deleted file mode 100644 index 36c7bda..0000000 --- a/nested/search-elastic-config.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "moodleCommon": { - "metadata": { - "description": "Common Moodle values" - }, - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').elasticVmName1,'/','install_elastic')]", - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Azure.Extensions", - "settings": { - "fileUris": [ - "[variables('scriptUri')]" - ] - }, - "protectedSettings":{ - "commandToExecute": "[variables('cmdExec')]" - }, - "type": "CustomScript", - "typeHandlerVersion": "2.0" - }, - "tags": { - "displayName": "install_elastic" - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').elasticVmName2,'/','install_elastic')]", - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Azure.Extensions", - "settings": { - "fileUris": [ - "[variables('scriptUri')]" - ] - }, - "protectedSettings":{ - "commandToExecute": "[variables('cmdExec')]" - }, - "type": "CustomScript", - "typeHandlerVersion": "2.0" - }, - "tags": { - "displayName": "install_elastic" - } - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').elasticVmName3,'/','install_elastic')]", - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Azure.Extensions", - "settings": { - "fileUris": [ - "[variables('scriptUri')]" - ] - }, - "protectedSettings":{ - "commandToExecute": "[variables('cmdExec')]" - }, - "type": "CustomScript", - "typeHandlerVersion": "2.0" - }, - "tags": { - "displayName": "install_elastic" - } - } - ], - "variables": { - "cmdExec": "[concat('bash ', parameters('moodleCommon').elasticScriptFilename, ' ', parameters('moodleCommon').elasticClusterName, ' ', parameters('moodleCommon').elasticVm1IP, ' ', parameters('moodleCommon').elasticVm2IP, ' ', parameters('moodleCommon').elasticVm3IP)]", - "documentation01": "This sub-template applies a specific post-deployment script to the controller vm", - "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation03": " scriptLocation - web URI", - "documentation04": " elasticScriptFilename - name of script file", - "documentation05": " elasticVmName - name of the elastic search vm generic name", - "scriptUri": "[concat(parameters('moodleCommon').scriptLocation,parameters('moodleCommon').elasticScriptFilename,parameters('moodleCommon').artifactsSasToken)]" - } -} diff --git a/nested/search-elastic.json b/nested/search-elastic.json deleted file mode 100644 index 042845d..0000000 --- a/nested/search-elastic.json +++ /dev/null @@ -1,395 +0,0 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "moodleCommon": { - "metadata": { - "description": "Common Moodle values" - }, - "type": "object" - }, - "subnetIdElastic": { - "metadata": { - "description": "Azure resource ID of the subnet where the Elastic Search VMs are to be deployed (if any)" - }, - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticNicName1]", - "properties": { - "ipConfigurations": [ - { - "name": "ipcfg-elastic1", - "properties": { - "privateIPAllocationMethod": "Static", - "privateIPAddress": "[parameters('moodleCommon').elasticVm1IP]", - "subnet": { - "id": "[parameters('subnetIdElastic')]" - } - } - } - ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" - }, - "tags": { - "displayName": "Elastic NIC 1" - } - }, - { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2017-03-30", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', parameters('moodleCommon').elasticNicName1)]" - ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticVmName1]", - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').elasticVmSku]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[variables('nicRef1')]" - } - ] - }, - "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerName": "[parameters('moodleCommon').elasticVmName1]", - "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { - "publicKeys": [ - { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" - } - ] - } - } - }, - "storageProfile": { - "dataDisks": [], - "imageReference": "[parameters('moodleCommon').osType]", - "osDisk": { - "createOption": "FromImage", - "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" - }, - "name": "[parameters('moodleCommon').elasticVmName1]" - } - } - }, - "tags": { - "displayName": "Elastic Search Virtual Machine" - } - }, - { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', parameters('moodleCommon').elasticVmName1)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName1,'-ScriptProcessor')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - } - - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'elasticconfig.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/',parameters('moodleCommon').elasticVmName1)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName1,'-Backup')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - }, - "vmName": { - "value": "[parameters('moodleCommon').elasticVmName1]" - } - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticNicName2]", - "properties": { - "ipConfigurations": [ - { - "name": "ipcfg-elastic2", - "properties": { - "privateIPAllocationMethod": "Static", - "privateIPAddress": "[parameters('moodleCommon').elasticVm2IP]", - "subnet": { - "id": "[parameters('subnetIdElastic')]" - } - } - } - ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" - }, - "tags": { - "displayName": "Elastic NIC 2" - } - }, - { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2017-03-30", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', parameters('moodleCommon').elasticNicName2)]" - ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticVmName2]", - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').elasticVmSku]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[variables('nicRef2')]" - } - ] - }, - "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerName": "[parameters('moodleCommon').elasticVmName2]", - "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { - "publicKeys": [ - { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" - } - ] - } - } - }, - "storageProfile": { - "dataDisks": [], - "imageReference": "[parameters('moodleCommon').osType]", - "osDisk": { - "createOption": "FromImage", - "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" - }, - "name": "[parameters('moodleCommon').elasticVmName2]" - } - } - }, - "tags": { - "displayName": "Elastic Search Virtual Machine" - } - }, - { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', parameters('moodleCommon').elasticVmName2)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName2,'-ScriptProcessor')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - } - - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'search-elastic-config.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/',parameters('moodleCommon').elasticVmName2)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName2,'-Backup')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - }, - "vmName": { - "value": "[parameters('moodleCommon').elasticVmName2]" - } - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticNicName3]", - "properties": { - "ipConfigurations": [ - { - "name": "ipcfg-elastic3", - "properties": { - "privateIPAllocationMethod": "Static", - "privateIPAddress": "[parameters('moodleCommon').elasticVm3IP]", - "subnet": { - "id": "[parameters('subnetIdElastic')]" - } - } - } - ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" - }, - "tags": { - "displayName": "Elastic NIC 2" - } - }, - { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2017-03-30", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', parameters('moodleCommon').elasticNicName3)]" - ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').elasticVmName3]", - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').elasticVmSku]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[variables('nicRef3')]" - } - ] - }, - "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerName": "[parameters('moodleCommon').elasticVmName3]", - "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { - "publicKeys": [ - { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" - } - ] - } - } - }, - "storageProfile": { - "dataDisks": [], - "imageReference": "[parameters('moodleCommon').osType]", - "osDisk": { - "createOption": "FromImage", - "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" - }, - "name": "[parameters('moodleCommon').elasticVmName3]" - } - } - }, - "tags": { - "displayName": "Elastic Search Virtual Machine" - } - }, - { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', parameters('moodleCommon').elasticVmName3)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName3,'-ScriptProcessor')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - } - - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'elasticconfig.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/',parameters('moodleCommon').elasticVmName3)]" - ], - "name": "[concat(parameters('moodleCommon').elasticVmName3,'-Backup')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - }, - "vmName": { - "value": "[parameters('moodleCommon').elasticVmName3]" - } - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - } - ], - "variables": { - "documentation01": "This sub-template drives the elastic which is used as the access-point for other moodle VM's ", - "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation03": " vnetName - name of the virtual network", - "documentation04": " subnetElastic - name of subnet for elastic (and vm scale set)", - "documentation06": " elasticNicName1 - name of the eastlic vm 1 network interface", - "documentation07": " elasticNicName2 - name of the eastlic vm 2 network interface", - "documentation08": " elasticNicName3 - name of the eastlic vm 3 network interface", - "documentation09": " elasticVmName1 - name of the eastlic vm 1", - "documentation10": " elasticVmName2 - name of the eastlic vm 2", - "documentation11": " elasticVmName3 - name of the eastlic vm 3", - "documentation12": " elasticVm1IP - IP of the eastlic vm 1", - "documentation13": " elasticVm2IP - IP of the eastlic vm 2", - "documentation14": " elasticVm3IP - IP of the eastlic vm 3", - "documentation15": "This sub-template calls other sub-templates", - "documentation16": " elasticconfig - conditionally applies post-deployment script on the VM", - "documentation17": " recoveryservicesEnlist - conditionally enlists the VM into the backup regimen", - "nicRef1": "[resourceId('Microsoft.Network/networkInterfaces', parameters('moodleCommon').elasticNicName1)]", - "nicRef2": "[resourceId('Microsoft.Network/networkInterfaces', parameters('moodleCommon').elasticNicName2)]", - "nicRef3": "[resourceId('Microsoft.Network/networkInterfaces', parameters('moodleCommon').elasticNicName3)]" - } -} diff --git a/nested/storageAccount.json b/nested/storageAccount.json index 45061ce..b47d335 100644 --- a/nested/storageAccount.json +++ b/nested/storageAccount.json @@ -2,9 +2,9 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" } @@ -13,11 +13,11 @@ { "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2017-06-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').storageAccountName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').storageAccountName]", "kind": "Storage", "sku": { - "name": "[parameters('moodleCommon').storageAccountType]" + "name": "[parameters('lampCommon').storageAccountType]" }, "properties": { "encryption": { @@ -45,7 +45,7 @@ "documentation1": "This sub-template creates a storage account. It expects certain values in the 'common' datastructure.", "documentation2": " storageAccountName - name of storage account", "documentation3": " storageAccountType - type of storage account", - "storageAccountId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('moodleCommon').storageAccountName)]" + "storageAccountId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('lampCommon').storageAccountName)]" }, "outputs": { "storageAccountKey": { diff --git a/nested/tika.json b/nested/tika.json deleted file mode 100644 index 25c0f25..0000000 --- a/nested/tika.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "moodleCommon": { - "metadata": { - "description": "Common Moodle values" - }, - "type": "object" - }, - "subnetIdTika": { - "metadata": { - "description": "Azure resource ID of the subnet where this Tika VM is to be deployed" - }, - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2017-10-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').tikaNicName]", - "properties": { - "ipConfigurations": [ - { - "name": "ipcfg-tika", - "properties": { - "privateIPAllocationMethod": "Static", - "privateIPAddress": "[parameters('moodleCommon').tikaVmIP]", - "subnet": { - "id": "[parameters('subnetIdTika')]" - } - } - } - ], - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" - }, - "tags": { - "displayName": "Tika NIC" - } - }, - { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2017-03-30", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', parameters('moodleCommon').tikaNicName)]" - ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').tikaVmName]", - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('moodleCommon').tikaVmSku]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[variables('nicRef')]" - } - ] - }, - "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerName": "[parameters('moodleCommon').tikaVmName]", - "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { - "publicKeys": [ - { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" - } - ] - } - } - }, - "storageProfile": { - "dataDisks": [], - "imageReference": "[parameters('moodleCommon').osType]", - "osDisk": { - "createOption": "FromImage", - "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" - }, - "name": "[parameters('moodleCommon').tikaVmName]" - } - } - }, - "tags": { - "displayName": "Tika Service Virtual Machine" - } - }, - { - "condition": "[parameters('moodleCommon').applyScriptsSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', parameters('moodleCommon').tikaVmName)]" - ], - "name": "[concat(parameters('moodleCommon').tikaVmName,'-ScriptProcessor')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - } - - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'tikaconfig.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - }, - { - "condition": "[parameters('moodleCommon').azureBackupSwitch]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2017-05-10", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/',parameters('moodleCommon').tikaVmName)]" - ], - "name": "[concat(parameters('moodleCommon').tikaVmName,'-Backup')]", - "properties": { - "mode": "Incremental", - "parameters": { - "moodleCommon": { - "value": "[parameters('moodleCommon')]" - }, - "vmName": { - "value": "[parameters('moodleCommon').tikaVmName]" - } - }, - "templateLink": { - "uri": "[concat(parameters('moodleCommon').baseTemplateUrl,'recoveryservicesEnlist.json',parameters('moodleCommon').artifactsSasToken)]" - } - } - } - ], - "variables": { - "documentation01": "This sub-template drives the tika service which is used as the access-point for moodle VM's when using tika search or azure search", - "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation03": " vnetName - name of the virtual network", - "documentation04": " subnetTika - name of subnet for tika (and vm scale set)", - "documentation06": " tikaNicName - name of the tika vm network interface", - "documentation11": " tikaVmName - name of the tika vm", - "documentation12": " tikaVmIP - IP of the tika vm", - "documentation15": "This sub-template calls other sub-templates", - "documentation16": " tikaconfig - conditionally applies post-deployment script on the VM", - "documentation17": " recoveryservicesEnlist - conditionally enlists the VM into the backup regimen", - "nicRef": "[resourceId('Microsoft.Network/networkInterfaces', parameters('moodleCommon').tikaNicName)]" - } -} diff --git a/nested/tikaconfig.json b/nested/tikaconfig.json deleted file mode 100644 index b0868a5..0000000 --- a/nested/tikaconfig.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "moodleCommon": { - "metadata": { - "description": "Common Moodle values" - }, - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2017-03-30", - "location": "[parameters('moodleCommon').location]", - "name": "[concat(parameters('moodleCommon').tikaVmName,'/','install_tika')]", - "properties": { - "autoUpgradeMinorVersion": true, - "publisher": "Microsoft.Azure.Extensions", - "settings": { - "fileUris": [ - "[variables('scriptUri')]" - ] - }, - "protectedSettings":{ - "commandToExecute": "[variables('cmdExec')]" - }, - "type": "CustomScript", - "typeHandlerVersion": "2.0" - }, - "tags": { - "displayName": "install_tika" - } - } - ], - "variables": { - "cmdExec": "[concat('bash ', parameters('moodleCommon').tikaScriptFilename, ' ', parameters('moodleCommon').tikaVmIP)]", - "documentation01": "This sub-template applies a specific post-deployment script to the tika vm", - "documentation02": "It expects certain values in the 'common' datastructure.", - "documentation03": " scriptLocation - web URI", - "documentation04": " tikaScriptFilename - name of script file", - "documentation05": " tikaVmName - name of the tika search vm generic name", - "scriptUri": "[concat(parameters('moodleCommon').scriptLocation,parameters('moodleCommon').tikaScriptFilename,parameters('moodleCommon').artifactsSasToken)]" - } -} diff --git a/nested/vmsetupparams.json b/nested/vmsetupparams.json index ffd3497..10353e2 100644 --- a/nested/vmsetupparams.json +++ b/nested/vmsetupparams.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -25,12 +25,6 @@ "description": "Redis cache key from the redis deployment ('None' if redis is not selected). This just gets passed through to the controllersetup.json." }, "type": "string" - }, - "azureSearchKey": { - "metadata": { - "description": "Azure Search primary key from the Azure Search service deployment ('None' if Azure Search service is not selected)" - }, - "type": "string" } }, "resources": [], @@ -38,52 +32,37 @@ "documentation01": "This sub-template doesn't create any Azure resource, but just constructs/returns a JSON object that'll be injected to controller & VMSS VMs (through cloud-init) so that VM setup custom script can read/use, instead of receiving these as a long list of cmdline args", "vmSetupParamsObj": { "siteProfile": { - "siteURL": "[parameters('moodleCommon').siteURL]", - "httpsTermination": "[parameters('moodleCommon').httpsTermination]", - "thumbprintSslCert": "[parameters('moodleCommon').thumbprintSslCert]", - "thumbprintCaCert": "[parameters('moodleCommon').thumbprintCaCert]" + "siteURL": "[parameters('lampCommon').siteURL]", + "httpsTermination": "[parameters('lampCommon').httpsTermination]", + "thumbprintSslCert": "[parameters('lampCommon').thumbprintSslCert]", + "thumbprintCaCert": "[parameters('lampCommon').thumbprintCaCert]" }, - "moodleProfile": { - "version": "[parameters('moodleCommon').moodleVersion]", - "dbName": "[parameters('moodleCommon').moodleDbName]", - "dbUser": "[parameters('moodleCommon').moodleDbUser]", - "dbUserAzure": "[parameters('moodleCommon').moodleDbUserAzure]", - "dbPassword": "[parameters('moodleCommon').moodleDbPass]", - "adminPassword": "[parameters('moodleCommon').moodleAdminPass]", - "storageAccountName": "[parameters('moodleCommon').storageAccountName]", + "lampProfile": { + "storageAccountName": "[parameters('lampCommon').storageAccountName]", "storageAccountKey": "[parameters('storageAccountKey')]", - "redisDns": "[parameters('moodleCommon').redisDns]", + "redisDns": "[parameters('lampCommon').redisDns]", "redisKey": "[parameters('redisKey')]", - "elasticVm1IP": "[parameters('moodleCommon').elasticVm1IP]", - "installO365pluginsSwitch": "[parameters('moodleCommon').installO365pluginsSwitch]", - "installObjectFsSwitch": "[parameters('moodleCommon').installObjectFsSwitch]", - "installGdprPluginsSwitch": "[parameters('moodleCommon').installGdprPluginsSwitch]", - "searchType": "[parameters('moodleCommon').searchType]", - "azureSearchKey": "[parameters('azureSearchKey')]", - "azureSearchNameHost": "[parameters('moodleCommon').azureSearchNameHost]", - "tikaVmIP": "[parameters('moodleCommon').tikaVmIP]", - "syslogServer": "[parameters('moodleCommon').ctlrVmName]", - "webServerType": "[parameters('moodleCommon').webServerType]", - "htmlLocalCopySwitch": "[parameters('moodleCommon').htmlLocalCopySwitch]" + "syslogServer": "[parameters('lampCommon').ctlrVmName]", + "htmlLocalCopySwitch": "[parameters('lampCommon').htmlLocalCopySwitch]" }, "dbServerProfile": { - "type": "[parameters('moodleCommon').dbServerType]", + "type": "[parameters('lampCommon').dbServerType]", "fqdn": "[parameters('dbFQDN')]", - "adminLogin": "[parameters('moodleCommon').dbLogin]", - "adminLoginAzure": "[concat(parameters('moodleCommon').dbLogin, '@', parameters('moodleCommon').dbServerType, '-', parameters('moodleCommon').resourcesPrefix)]", - "adminPassword": "[parameters('moodleCommon').dbLoginPassword]", - "mssqlDbServiceObjectiveName": "[parameters('moodleCommon').mssqlDbServiceObjectiveName]", - "mssqlDbEdition": "[parameters('moodleCommon').mssqlDbEdition]", - "mssqlDbSize": "[parameters('moodleCommon').mssqlDbSize]" + "adminLogin": "[parameters('lampCommon').dbLogin]", + "adminLoginAzure": "[concat(parameters('lampCommon').dbLogin, '@', parameters('lampCommon').dbServerType, '-', parameters('lampCommon').resourcesPrefix)]", + "adminPassword": "[parameters('lampCommon').dbLoginPassword]", + "mssqlDbServiceObjectiveName": "[parameters('lampCommon').mssqlDbServiceObjectiveName]", + "mssqlDbEdition": "[parameters('lampCommon').mssqlDbEdition]", + "mssqlDbSize": "[parameters('lampCommon').mssqlDbSize]" }, "fileServerProfile": { - "type": "[parameters('moodleCommon').fileServerType]", - "nfsVmName": "[parameters('moodleCommon').ctlrVmName]", - "glusterVmName": "[concat(parameters('moodleCommon').gfsNameRoot, '0')]", + "type": "[parameters('lampCommon').fileServerType]", + "nfsVmName": "[parameters('lampCommon').ctlrVmName]", + "glusterVmName": "[concat(parameters('lampCommon').gfsNameRoot, '0')]", "glusterVolName": "data", - "nfsByoIpExportPath": "[parameters('moodleCommon').nfsByoIpExportPath]", - "nfsHaLbIP": "[parameters('moodleCommon').nfsHaLbIP]", - "nfsHaExportPath": "[parameters('moodleCommon').nfsHaExportPath]" + "nfsByoIpExportPath": "[parameters('lampCommon').nfsByoIpExportPath]", + "nfsHaLbIP": "[parameters('lampCommon').nfsHaLbIP]", + "nfsHaExportPath": "[parameters('lampCommon').nfsHaExportPath]" } } }, diff --git a/nested/webvmss.json b/nested/webvmss.json index b24b567..af5edc2 100644 --- a/nested/webvmss.json +++ b/nested/webvmss.json @@ -2,9 +2,9 @@ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { - "moodleCommon": { + "lampCommon": { "metadata": { - "description": "Common Moodle values" + "description": "Common LAMP values" }, "type": "object" }, @@ -25,8 +25,8 @@ { "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2017-06-01", - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').vmssdStorageAccounttName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').vmssdStorageAccounttName]", "kind": "Storage", "sku": { "name": "Standard_LRS" @@ -36,10 +36,10 @@ "type": "Microsoft.Compute/virtualMachineScaleSets", "apiVersion": "2017-03-30", "dependsOn": [ - "[concat('Microsoft.Storage/storageAccounts/', parameters('moodleCommon').vmssdStorageAccounttName)]" + "[concat('Microsoft.Storage/storageAccounts/', parameters('lampCommon').vmssdStorageAccounttName)]" ], - "location": "[parameters('moodleCommon').location]", - "name": "[parameters('moodleCommon').vmssName]", + "location": "[parameters('lampCommon').location]", + "name": "[parameters('lampCommon').vmssName]", "properties": { "overprovision": true, "upgradePolicy": { @@ -49,18 +49,18 @@ "extensionProfile": { "extensions": [ { - "name": "setup_moodle", + "name": "setup_lamp", "properties": { "autoUpgradeMinorVersion": true, "publisher": "Microsoft.Azure.Extensions", "settings": { "fileUris": [ "[variables('scriptUri')]", - "[parameters('moodleCommon').commonFunctionsScriptUri]" + "[parameters('lampCommon').commonFunctionsScriptUri]" ] }, "protectedSettings":{ - "commandToExecute": "[concat('bash ', parameters('moodleCommon').webServerSetupScriptFilename, ' ', parameters('moodleCommon').moodleOnAzureConfigsJsonPath)]" + "commandToExecute": "[concat('bash ', parameters('lampCommon').webServerSetupScriptFilename, ' ', parameters('lampCommon').lampOnAzureConfigsJsonPath)]" }, "type": "CustomScript", "typeHandlerVersion": "2.0" @@ -86,34 +86,34 @@ } ], "primary": true, - "enableAcceleratedNetworking": "[parameters('moodleCommon').enableAccelNwForOtherVmsSwitch]" + "enableAcceleratedNetworking": "[parameters('lampCommon').enableAccelNwForOtherVmsSwitch]" } } ] }, "osProfile": { - "adminUsername": "[parameters('moodleCommon').sshUsername]", - "computerNamePrefix": "[parameters('moodleCommon').vmssName]", - "customData": "[base64(concat('#cloud-config\nwrite_files:\n- encoding: b64\n content: ', base64(string(parameters('vmSetupParamsObj'))), '\n owner: root:root\n path: ', parameters('moodleCommon').moodleOnAzureConfigsJsonPath, '\n permissions: ', variables('singleQuote'), '0400', variables('singleQuote')))]", + "adminUsername": "[parameters('lampCommon').sshUsername]", + "computerNamePrefix": "[parameters('lampCommon').vmssName]", + "customData": "[base64(concat('#cloud-config\nwrite_files:\n- encoding: b64\n content: ', base64(string(parameters('vmSetupParamsObj'))), '\n owner: root:root\n path: ', parameters('lampCommon').lampOnAzureConfigsJsonPath, '\n permissions: ', variables('singleQuote'), '0400', variables('singleQuote')))]", "linuxConfiguration": { "disablePasswordAuthentication": true, "ssh": { "publicKeys": [ { - "path": "[concat('/home/', parameters('moodleCommon').sshUsername, '/.ssh/authorized_keys')]", - "keyData": "[parameters('moodleCommon').sshPublicKey]" + "path": "[concat('/home/', parameters('lampCommon').sshUsername, '/.ssh/authorized_keys')]", + "keyData": "[parameters('lampCommon').sshPublicKey]" } ] } } }, "storageProfile": { - "imageReference": "[parameters('moodleCommon').osType]", + "imageReference": "[parameters('lampCommon').osType]", "osDisk": { "caching": "ReadOnly", "createOption": "FromImage", "managedDisk": { - "storageAccountType": "[parameters('moodleCommon').osDiskStorageType]" + "storageAccountType": "[parameters('lampCommon').osDiskStorageType]" } } } @@ -121,7 +121,7 @@ }, "sku": { "capacity": 1, - "name": "[parameters('moodleCommon').autoscaleVmSku]", + "name": "[parameters('lampCommon').autoscaleVmSku]", "tier": "Standard" }, "tags": { @@ -132,9 +132,9 @@ "type": "Microsoft.Insights/autoscaleSettings", "apiVersion": "2015-04-01", "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachineScaleSets/', parameters('moodleCommon').vmssName)]" + "[concat('Microsoft.Compute/virtualMachineScaleSets/', parameters('lampCommon').vmssName)]" ], - "location": "[parameters('moodleCommon').location]", + "location": "[parameters('lampCommon').location]", "name": "autoscalewad", "properties": { "enabled": true, @@ -142,9 +142,9 @@ "profiles": [ { "capacity": { - "default": "[parameters('moodleCommon').autoscaleVmCountMin]", - "maximum": "[parameters('moodleCommon').autoscaleVmCountMax]", - "minimum": "[parameters('moodleCommon').autoscaleVmCountMin]" + "default": "[parameters('lampCommon').autoscaleVmCountMin]", + "maximum": "[parameters('lampCommon').autoscaleVmCountMax]", + "minimum": "[parameters('lampCommon').autoscaleVmCountMin]" }, "name": "Profile1", "rules": [ @@ -195,28 +195,28 @@ ], "variables": { "singleQuote": "'", - "dstorID": "[resourceId('Microsoft.Storage/storageAccounts',parameters('moodleCommon').vmssdStorageAccounttName)]", - "extBeID": "[concat(variables('extLbID'),'/backendAddressPools/',parameters('moodleCommon').extBeName)]", - "extFeID": "[concat(variables('extLbID'),'/frontendIPConfigurations/',parameters('moodleCommon').extFeName)]", - "extLbID": "[resourceId('Microsoft.Network/loadBalancers',parameters('moodleCommon').lbName)]", - "pipID": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('moodleCommon').lbPipName)]", - "scriptUri": "[concat(parameters('moodleCommon').scriptLocation,parameters('moodleCommon').webServerSetupScriptFilename,parameters('moodleCommon').artifactsSasToken)]", - "vmssID": "[resourceId('Microsoft.Compute/virtualMachineScaleSets',parameters('moodleCommon').vmssName)]", - "webvmss1NIC": "[concat('Microsoft.Compute/virtualMachineScaleSets/', parameters('moodleCommon').vmssName, '/virtualMachines/0/networkInterfaces/vmssnic')]", - "appGwID": "[resourceId('Microsoft.Network/applicationGateways', parameters('moodleCommon').appGwName)]", - "appGwBePoolId": "[concat(variables('appGwID'), '/backendAddressPools/', parameters('moodleCommon').appGwBePoolName)]", + "dstorID": "[resourceId('Microsoft.Storage/storageAccounts',parameters('lampCommon').vmssdStorageAccounttName)]", + "extBeID": "[concat(variables('extLbID'),'/backendAddressPools/',parameters('lampCommon').extBeName)]", + "extFeID": "[concat(variables('extLbID'),'/frontendIPConfigurations/',parameters('lampCommon').extFeName)]", + "extLbID": "[resourceId('Microsoft.Network/loadBalancers',parameters('lampCommon').lbName)]", + "pipID": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('lampCommon').lbPipName)]", + "scriptUri": "[concat(parameters('lampCommon').scriptLocation,parameters('lampCommon').webServerSetupScriptFilename,parameters('lampCommon').artifactsSasToken)]", + "vmssID": "[resourceId('Microsoft.Compute/virtualMachineScaleSets',parameters('lampCommon').vmssName)]", + "webvmss1NIC": "[concat('Microsoft.Compute/virtualMachineScaleSets/', parameters('lampCommon').vmssName, '/virtualMachines/0/networkInterfaces/vmssnic')]", + "appGwID": "[resourceId('Microsoft.Network/applicationGateways', parameters('lampCommon').appGwName)]", + "appGwBePoolId": "[concat(variables('appGwID'), '/backendAddressPools/', parameters('lampCommon').appGwBePoolName)]", "lbBePoolArray": [ { "id": "[variables('extBeID')]" } ], - "lbBePoolArrayTakeCount": "[if(equals(parameters('moodleCommon').httpsTermination, 'AppGw'), 0, 1)]", + "lbBePoolArrayTakeCount": "[if(equals(parameters('lampCommon').httpsTermination, 'AppGw'), 0, 1)]", "appGwBePoolArray": [ { "id": "[variables('appGwBePoolId')]" } ], - "appGwBePoolArrayTakeCount": "[if(equals(parameters('moodleCommon').httpsTermination, 'AppGw'), 1, 0)]" + "appGwBePoolArrayTakeCount": "[if(equals(parameters('lampCommon').httpsTermination, 'AppGw'), 1, 0)]" }, "outputs": { "webvm1IP": { diff --git a/package.json b/package.json deleted file mode 100644 index 5705382..0000000 --- a/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "azure-moodle", - "version": "1.0.0", - "description": "A package file for developer depenedencies when testing templates", - "scripts": { - "test": "grunt test" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/Moodle.git" - }, - "author": "Catalyst IT", - "license": "GPL V3", - "bugs": { - "url": "https://github.com/Azure/Moodle/issues" - }, - "homepage": "https://github.com/Azure/Moodle#readme", - "devDependencies": { - "grunt": "^0.4.5", - "grunt-contrib-jshint": "^0.11.3", - "load-grunt-tasks": "^3.3.0" - } -} diff --git a/scripts/install_elastic.sh b/scripts/install_elastic.sh deleted file mode 100644 index 999a44c..0000000 --- a/scripts/install_elastic.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash -# Custom Script for Linux - -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -esClusterName=$1 -elasticvm1ip=$2 -elasticvm2ip=$3 -elasticvm3ip=$4 - -echo $esClusterName >> /tmp/vars.txt -echo $elasticvm1ip >> /tmp/vars.txt -echo $elasticvm2ip >> /tmp/vars.txt -echo $elasticvm3ip >> /tmp/vars.txt - -{ - - # make sure the system does automatic update - sudo apt-get -y update - sudo apt-get -y install unattended-upgrades - - # configure elastic search repository & install elastic search - wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - - echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list - sudo apt-get -y update - sudo apt-get -y install elasticsearch=5.5.0 - - # install the required packages - sudo apt-get install -y openjdk-8-jre openjdk-8-jdk default-jre default-jdk - - # Configure elasticsearch - cat < /etc/elasticsearch/elasticsearch.yml -# ======================== Elasticsearch Configuration ========================= -# -# NOTE: Elasticsearch comes with reasonable defaults for most settings. -# Before you set out to tweak and tune the configuration, make sure you -# understand what are you trying to accomplish and the consequences. -# -# The primary way of configuring a node is via this file. This template lists -# the most important settings you may want to configure for a production cluster. -# -# Please consult the documentation for further information on configuration options: -# https://www.elastic.co/guide/en/elasticsearch/reference/index.html -# -# ---------------------------------- Cluster ----------------------------------- -# -# Use a descriptive name for your cluster: -# -cluster.name: ${esClusterName} -# -# ------------------------------------ Node ------------------------------------ -# -# Use a descriptive name for the node: -# -node.name: \${HOSTNAME} -# -# Add custom attributes to the node: -# -#node.attr.rack: r1 -# -# ----------------------------------- Paths ------------------------------------ -# -# Path to directory where to store the data (separate multiple locations by comma): -# -#path.data: /path/to/data -# -# Path to log files: -# -#path.logs: /path/to/logs -# -# ----------------------------------- Memory ----------------------------------- -# -# Lock the memory on startup: -# -#bootstrap.memory_lock: true -# -# Make sure that the heap size is set to about half the memory available -# on the system and that the owner of the process is allowed to use this -# limit. -# -# Elasticsearch performs poorly when the system is swapping the memory. -# -# ---------------------------------- Network ----------------------------------- -# -# Set the bind address to a specific IP (IPv4 or IPv6): -# -network.host: [_eth0_, _local_] -# -# Set a custom port for HTTP: -# -#http.port: 9200 -# -# For more information, consult the network module documentation. -# -# --------------------------------- Discovery ---------------------------------- -# -# Pass an initial list of hosts to perform discovery when new node is started: -# The default list of hosts is ["127.0.0.1", "[::1]"] -# -discovery.zen.ping.unicast.hosts: ["$elasticvm1ip", "$elasticvm2ip", "$elasticvm3ip"] -# -# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): -# -discovery.zen.minimum_master_nodes: 3 -# -# For more information, consult the zen discovery module documentation. -# -# ---------------------------------- Gateway ----------------------------------- -# -# Block initial recovery after a full cluster restart until N nodes are started: -# -#gateway.recover_after_nodes: 3 -# -# For more information, consult the gateway module documentation. -# -# ---------------------------------- Various ----------------------------------- -# -# Require explicit names when deleting indices: -# -#action.destructive_requires_name: true -EOF - - service elasticsearch restart - -} > /tmp/setup.log diff --git a/scripts/install_gluster.sh b/scripts/install_gluster.sh index dbb229a..c21ae2e 100644 --- a/scripts/install_gluster.sh +++ b/scripts/install_gluster.sh @@ -35,8 +35,9 @@ RAIDPARTITION="/dev/md1p1" BLACKLIST="/dev/sda|/dev/sdb" # make sure the system does automatic update -sudo apt-get -y update -sudo apt-get -y install unattended-upgrades +# TODO: ENSURE THIS IS CONFIGURED CORRECTLY +apt-get -y update +apt-get -y install unattended-upgrades { check_os() { @@ -74,7 +75,7 @@ sudo apt-get -y install unattended-upgrades if [ $_RET -eq 1 ]; then echo "installing mdadm" - sudo apt-get -y -q install mdadm + apt-get -y -q install mdadm fi echo "Creating raid0" udevadm control --stop-exec-queue diff --git a/scripts/install_tika.sh b/scripts/install_tika.sh deleted file mode 100644 index 82d3db5..0000000 --- a/scripts/install_tika.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -# Custom Script for Linux - -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -tikavmip=$1 - -echo $tikavmip >> /tmp/vars.txt - -{ - - # make sure the system does automatic update - sudo apt-get -y update - sudo apt-get -y install unattended-upgrades - - # download apache tika server - sudo wget -q http://mirrors.ocf.berkeley.edu/apache/tika/tika-server-1.18.jar --directory-prefix=/usr/share/java/ - - # install the required packages - sudo apt-get install -y openjdk-8-jre openjdk-8-jdk default-jre default-jdk - - # Configure tika - cat < /etc/systemd/system/tika-server.service -[Unit] -Description = Java Service -After network.target = tika-server.service - -[Service] -Type = forking -ExecStart = /usr/local/bin/tika-server start -ExecStop = /usr/local/bin/tika-server stop -ExecReload = /usr/local/bin/tika-server reload - -[Install] -WantedBy=multi-user.target -EOF - - chmod 777 /etc/systemd/system/tika-server.service - - cat < /usr/local/bin/tika-server -#!/bin/sh -SERVICE_NAME=tika-server -PATH_TO_JAR=/usr/share/java/tika-server-1.18.jar -PID_PATH_NAME=/var/run/tika-server-pid -case \$1 in - start) - echo "Starting \$SERVICE_NAME ..." - if [ ! -f \$PID_PATH_NAME ]; then - nohup java -jar \$PATH_TO_JAR --host=$tikavmip --port=9998 >> /var/log/tika-server.out 2>&1& - echo \$! > \$PID_PATH_NAME - echo "\$SERVICE_NAME started ..." - else - echo "\$SERVICE_NAME is already running ..." - fi - ;; - stop) - if [ -f \$PID_PATH_NAME ]; then - PID=\$(cat $PID_PATH_NAME); - echo "\$SERVICE_NAME stoping ..." - kill \$PID; - echo "\$SERVICE_NAME stopped ..." - rm \$PID_PATH_NAME - else - echo "\$SERVICE_NAME is not running ..." - fi - ;; - restart) - if [ -f \$PID_PATH_NAME ]; then - PID=\$(cat $PID_PATH_NAME); - echo "\$SERVICE_NAME stopping ..."; - kill \$PID; - echo "\$SERVICE_NAME stopped ..."; - rm \$PID_PATH_NAME - echo "\$SERVICE_NAME starting ..." - nohup java -jar \$PATH_TO_JAR --host=$tikavmip --port=9998 >> /var/log/tika-server.out 2>&1& - echo \$! > \$PID_PATH_NAME - echo "\$SERVICE_NAME started ..." - else - echo "\$SERVICE_NAME is not running ..." - fi - ;; -esac -EOF - chmod +x /usr/local/bin/tika-server - systemctl enable tika-server.service - systemctl start tika-server.service -} > /tmp/setup.log diff --git a/scripts/install_moodle.sh b/scripts/setup_controller.sh similarity index 61% rename from scripts/install_moodle.sh rename to scripts/setup_controller.sh index d4ff0c4..343e4d1 100644 --- a/scripts/install_moodle.sh +++ b/scripts/setup_controller.sh @@ -24,125 +24,78 @@ set -ex #parameters { - moodle_on_azure_configs_json_path=${1} + lamp_on_azure_configs_json_path=${1} . ./helper_functions.sh - get_setup_params_from_configs_json $moodle_on_azure_configs_json_path || exit 99 + get_setup_params_from_configs_json $lamp_on_azure_configs_json_path || exit 99 - echo $moodleVersion >> /tmp/vars.txt echo $glusterNode >> /tmp/vars.txt echo $glusterVolume >> /tmp/vars.txt echo $siteFQDN >> /tmp/vars.txt echo $httpsTermination >> /tmp/vars.txt echo $dbIP >> /tmp/vars.txt - echo $moodledbname >> /tmp/vars.txt - echo $moodledbuser >> /tmp/vars.txt - echo $moodledbpass >> /tmp/vars.txt echo $adminpass >> /tmp/vars.txt echo $dbadminlogin >> /tmp/vars.txt echo $dbadminloginazure >> /tmp/vars.txt echo $dbadminpass >> /tmp/vars.txt echo $storageAccountName >> /tmp/vars.txt echo $storageAccountKey >> /tmp/vars.txt - echo $azuremoodledbuser >> /tmp/vars.txt echo $redisDns >> /tmp/vars.txt echo $redisAuth >> /tmp/vars.txt - echo $elasticVm1IP >> /tmp/vars.txt - echo $installO365pluginsSwitch >> /tmp/vars.txt echo $dbServerType >> /tmp/vars.txt echo $fileServerType >> /tmp/vars.txt echo $mssqlDbServiceObjectiveName >> /tmp/vars.txt echo $mssqlDbEdition >> /tmp/vars.txt echo $mssqlDbSize >> /tmp/vars.txt - echo $installObjectFsSwitch >> /tmp/vars.txt - echo $installGdprPluginsSwitch >> /tmp/vars.txt echo $thumbprintSslCert >> /tmp/vars.txt echo $thumbprintCaCert >> /tmp/vars.txt - echo $searchType >> /tmp/vars.txt - echo $azureSearchKey >> /tmp/vars.txt - echo $azureSearchNameHost >> /tmp/vars.txt - echo $tikaVmIP >> /tmp/vars.txt echo $nfsByoIpExportPath >> /tmp/vars.txt check_fileServerType_param $fileServerType # make sure system does automatic updates and fail2ban - sudo apt-get -y update - sudo apt-get -y install unattended-upgrades fail2ban + export DEBIAN_FRONTEND=noninteractive + apt-get -y update + # TODO: ENSURE THIS IS CONFIGURED CORRECTLY + apt-get -y install unattended-upgrades fail2ban config_fail2ban # create gluster, nfs or Azure Files mount point mkdir -p /azlamp - export DEBIAN_FRONTEND=noninteractive - if [ $fileServerType = "gluster" ]; then # configure gluster repository & install gluster client - sudo add-apt-repository ppa:gluster/glusterfs-3.10 -y >> /tmp/apt1.log + add-apt-repository ppa:gluster/glusterfs-3.10 -y >> /tmp/apt1.log elif [ $fileServerType = "nfs" ]; then # configure NFS server and export setup_raid_disk_and_filesystem /azlamp /dev/md1 /dev/md1p1 configure_nfs_server_and_export /azlamp fi - sudo apt-get -y update >> /tmp/apt2.log - sudo apt-get -y --force-yes install rsyslog git >> /tmp/apt3.log + apt-get -y update >> /tmp/apt2.log + apt-get -y --force-yes install rsyslog git >> /tmp/apt3.log if [ $fileServerType = "gluster" ]; then - sudo apt-get -y --force-yes install glusterfs-client >> /tmp/apt3.log + apt-get -y --force-yes install glusterfs-client >> /tmp/apt3.log elif [ "$fileServerType" = "azurefiles" ]; then - sudo apt-get -y --force-yes install cifs-utils >> /tmp/apt3.log + apt-get -y --force-yes install cifs-utils >> /tmp/apt3.log fi if [ $dbServerType = "mysql" ]; then - sudo apt-get -y --force-yes install mysql-client >> /tmp/apt3.log + apt-get -y --force-yes install mysql-client >> /tmp/apt3.log elif [ "$dbServerType" = "postgres" ]; then - #sudo apt-get -y --force-yes install postgresql-client >> /tmp/apt3.log + #apt-get -y --force-yes install postgresql-client >> /tmp/apt3.log # Get a new version of Postgres to match Azure version (default Xenial postgresql-client version--previous line--is 9.5) # Note that this was done after create_db, but before pg_dump cron job setup (no idea why). If this change # causes any pgres install issue, consider reverting this ordering change... add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - + wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - apt-get update apt-get install -y postgresql-client-9.6 fi - if [ "$installObjectFsSwitch" = "true" -o "$fileServerType" = "azurefiles" ]; then - # install azure cli & setup container - echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ wheezy main" | \ - sudo tee /etc/apt/sources.list.d/azure-cli.list - - curl -L https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - >> /tmp/apt4.log - sudo apt-get -y install apt-transport-https >> /tmp/apt4.log - sudo apt-get -y update > /dev/null - sudo apt-get -y install azure-cli >> /tmp/apt4.log - - az storage container create \ - --name objectfs \ - --account-name $storageAccountName \ - --account-key $storageAccountKey \ - --public-access off \ - --fail-on-exist >> /tmp/wabs.log - - az storage container policy create \ - --account-name $storageAccountName \ - --account-key $storageAccountKey \ - --container-name objectfs \ - --name readwrite \ - --start $(date --date="1 day ago" +%F) \ - --expiry $(date --date="2199-01-01" +%F) \ - --permissions rw >> /tmp/wabs.log - - sas=$(az storage container generate-sas \ - --account-name $storageAccountName \ - --account-key $storageAccountKey \ - --name objectfs \ - --policy readwrite \ - --output tsv) - fi - if [ $fileServerType = "gluster" ]; then # mount gluster files system echo -e '\n\rInstalling GlusterFS on '$glusterNode':/'$glusterVolume '/azlamp\n\r' @@ -158,24 +111,22 @@ set -ex fi # install pre-requisites - sudo apt-get install -y --fix-missing python-software-properties unzip + apt-get install -y --fix-missing python-software-properties unzip # install the entire stack - sudo apt-get -y --force-yes install nginx php-fpm varnish >> /tmp/apt5a.log - sudo apt-get -y --force-yes install php php-cli php-curl php-zip >> /tmp/apt5b.log + apt-get -y --force-yes install nginx php-fpm php php-cli php-curl php-zip >> /tmp/apt5.log # LAMP requirements - sudo apt-get -y update > /dev/null - sudo apt-get install -y --force-yes graphviz aspell php-common php-soap php-json php-redis > /tmp/apt6.log - sudo apt-get install -y --force-yes php-bcmath php-gd php-xmlrpc php-intl php-xml php-bz2 php-pear php-mbstring php-dev mcrypt >> /tmp/apt6.log + apt-get -y update > /dev/null + apt-get install -y --force-yes php-common php-soap php-json php-redis php-bcmath php-gd php-xmlrpc php-intl php-xml php-bz2 php-pear php-mbstring php-dev mcrypt >> /tmp/apt6.log PhpVer=$(get_php_version) if [ $dbServerType = "mysql" ]; then - sudo apt-get install -y --force-yes php-mysql + apt-get install -y --force-yes php-mysql elif [ $dbServerType = "mssql" ]; then - sudo apt-get install -y libapache2-mod-php # Need this because install_php_mssql_driver tries to update apache2-mod-php settings always (which will fail without this) + apt-get install -y libapache2-mod-php # Need this because install_php_mssql_driver tries to update apache2-mod-php settings always (which will fail without this) install_php_mssql_driver else - sudo apt-get install -y --force-yes php-pgsql + apt-get install -y --force-yes php-pgsql fi # Set up initial LAMP dirs @@ -188,54 +139,46 @@ set -ex update_php_config_on_controller - # Remove the default site. Moodle is the only site we want + # Remove the default site rm -f /etc/nginx/sites-enabled/default # restart Nginx - sudo service nginx restart - - configure_varnish_on_controller - # Restart Varnish - systemctl daemon-reload - service varnish restart + systemctl restart nginx # Master config for syslog config_syslog_on_controller - service rsyslog restart + systemctl restart rsyslog # Turning off services we don't need the controller running - service nginx stop - service php${PhpVer}-fpm stop - service varnish stop - service varnishncsa stop - service varnishlog stop + systemctl stop nginx + systemctl stop php${PhpVer}-fpm if [ $fileServerType = "azurefiles" ]; then - # Delayed copy of moodle installation to the Azure Files share + # Delayed copy of azlamp installation to the Azure Files share # First rename azlamp directory to something else mv /azlamp /azlamp_old_delete_me - # Then create the moodle share + # Then create the azlamp share echo -e '\n\rCreating an Azure Files share for azlamp' create_azure_files_share azlamp $storageAccountName $storageAccountKey /tmp/wabs.log # Set up and mount Azure Files share. Must be done after nginx is installed because of www-data user/group echo -e '\n\rSetting up and mounting Azure Files share on //'$storageAccountName'.file.core.windows.net/azlamp on /azlamp\n\r' setup_and_mount_azure_files_share azlamp $storageAccountName $storageAccountKey # Move the local installation over to the Azure Files - echo -e '\n\rMoving locally installed moodle over to Azure Files' + echo -e '\n\rMoving locally installed azlamp over to Azure Files' cp -a /azlamp_old_delete_me/* /azlamp || true # Ignore case sensitive directory copy failure # rm -rf /azlamp_old_delete_me || true # Keep the files just in case fi # chmod /azlamp for Azure NetApp Files (its default is 770!) if [ $fileServerType = "nfs-byo" ]; then - sudo chmod +rx /azlamp + chmod +rx /azlamp fi create_last_modified_time_update_script run_once_last_modified_time_update_script - # Install scripts for LAMP gen. + # Install scripts for LAMP mkdir -p /azlamp/bin cp helper_functions.sh /azlamp/bin/utils.sh chmod +x /azlamp/bin/utils.sh @@ -252,12 +195,12 @@ while true do case \$VERSION in # Uncomment the following block when adding/removing sites. Change the parameters if needed (default should work for most cases). - # true (or anything else): htmlLocalCopySwitch, VMSS (or anything else): https termination, apache (or nginx): web server type + # true (or anything else): htmlLocalCopySwitch, VMSS (or anything else): https termination # Add another block with the next version number for any further site addition/removal. #1) # . /azlamp/bin/utils.sh - # reset_all_sites_on_vmss true VMSS apache + # reset_all_sites_on_vmss true VMSS #;; *) diff --git a/scripts/setup_nfs_ha.sh b/scripts/setup_nfs_ha.sh index d879d02..e77b558 100644 --- a/scripts/setup_nfs_ha.sh +++ b/scripts/setup_nfs_ha.sh @@ -141,7 +141,7 @@ function setup_corosync_and_pacemaker_for_nfs local drbd_resource_name=$3 # E.g., azmdlr0 local drbd_device_path=$4 # E.g., /dev/drbd0 local drbd_mount_point=$5 # E.g., /drbd - local nfs_export_path=$6 # E.g., /drbd/moodle + local nfs_export_path=$6 # E.g., /drbd/lamp local nfs_client_spec=$7 # E.g., * or 10.11.22.0/24 mv /etc/corosync/corosync.conf /etc/corosync/corosync.conf.orig || true diff --git a/scripts/setup_webserver.sh b/scripts/setup_webserver.sh index e951ba3..752d4ee 100644 --- a/scripts/setup_webserver.sh +++ b/scripts/setup_webserver.sh @@ -1,5 +1,3 @@ -# Custom Script for Linux - #!/bin/bash # The MIT License (MIT) @@ -24,18 +22,17 @@ set -ex -moodle_on_azure_configs_json_path=${1} +lamp_on_azure_configs_json_path=${1} . ./helper_functions.sh -get_setup_params_from_configs_json $moodle_on_azure_configs_json_path || exit 99 +get_setup_params_from_configs_json $lamp_on_azure_configs_json_path || exit 99 echo $glusterNode >> /tmp/vars.txt echo $glusterVolume >> /tmp/vars.txt echo $siteFQDN >> /tmp/vars.txt echo $httpsTermination >> /tmp/vars.txt echo $syslogServer >> /tmp/vars.txt -echo $webServerType >> /tmp/vars.txt echo $dbServerType >> /tmp/vars.txt echo $fileServerType >> /tmp/vars.txt echo $storageAccountName >> /tmp/vars.txt @@ -48,40 +45,28 @@ check_fileServerType_param $fileServerType { # make sure the system does automatic update - sudo apt-get -y update - sudo apt-get -y install unattended-upgrades + apt-get -y update + # TODO: ENSURE THIS IS CONFIGURED CORRECTLY + apt-get -y install unattended-upgrades # install pre-requisites - sudo apt-get -y install python-software-properties unzip rsyslog + apt-get -y install python-software-properties unzip rsyslog - sudo apt-get -y install postgresql-client mysql-client git + apt-get -y install postgresql-client mysql-client git if [ $fileServerType = "gluster" ]; then #configure gluster repository & install gluster client - sudo add-apt-repository ppa:gluster/glusterfs-3.10 -y - sudo apt-get -y update - sudo apt-get -y install glusterfs-client + add-apt-repository ppa:gluster/glusterfs-3.10 -y + apt-get -y update + apt-get -y install glusterfs-client elif [ "$fileServerType" = "azurefiles" ]; then - sudo apt-get -y install cifs-utils + apt-get -y install cifs-utils fi # install the base stack - sudo apt-get -y install varnish php php-cli php-curl php-zip php-pear php-mbstring php-dev mcrypt + apt-get -y install nginx php php-fpm php-cli php-curl php-zip php-pear php-mbstring php-dev mcrypt php-soap php-json php-redis php-bcmath php-gd php-pgsql php-mysql php-xmlrpc php-intl php-xml php-bz2 - if [ "$webServerType" = "nginx" -o "$httpsTermination" = "VMSS" ]; then - sudo apt-get -y install nginx - fi - - if [ "$webServerType" = "apache" ]; then - # install apache pacakges - sudo apt-get -y install apache2 libapache2-mod-php - else - # for nginx-only option - sudo apt-get -y install php-fpm - fi - - # Moodle requirements - sudo apt-get install -y graphviz aspell php-soap php-json php-redis php-bcmath php-gd php-pgsql php-mysql php-xmlrpc php-intl php-xml php-bz2 + # MSSQL if [ "$dbServerType" = "mssql" ]; then install_php_mssql_driver fi @@ -91,10 +76,10 @@ check_fileServerType_param $fileServerType if [ $fileServerType = "gluster" ]; then # Mount gluster fs for /azlamp - sudo mkdir -p /azlamp - sudo chown www-data /azlamp - sudo chmod 770 /azlamp - sudo echo -e 'Adding Gluster FS to /etc/fstab and mounting it' + mkdir -p /azlamp + chown www-data /azlamp + chmod 770 /azlamp + echo -e 'Adding Gluster FS to /etc/fstab and mounting it' setup_and_mount_gluster_share $glusterNode $glusterVolume /azlamp elif [ $fileServerType = "nfs" ]; then # mount NFS export (set up on controller VM--No HA) @@ -121,11 +106,10 @@ EOF local1.* @${syslogServer}:514 local2.* @${syslogServer}:514 EOF - service syslog restart + systemctl restart syslog - if [ "$webServerType" = "nginx" -o "$httpsTermination" = "VMSS" ]; then - # Build nginx config - cat < /etc/nginx/nginx.conf + # Build nginx config + cat < /etc/nginx/nginx.conf user www-data; worker_processes 2; pid /run/nginx.pid; @@ -135,8 +119,8 @@ events { } http { - sendfile on; + server_tokens off; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; @@ -165,29 +149,12 @@ http { gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; - gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; -EOF - if [ "$httpsTermination" != "None" ]; then - cat <> /etc/nginx/nginx.conf - map \$http_x_forwarded_proto \$fastcgi_https { - default \$https; - http ''; - https on; - } -EOF - fi - - cat <> /etc/nginx/nginx.conf - log_format moodle_combined '\$remote_addr - \$upstream_http_x_moodleuser [\$time_local] ' - '"\$request" \$status \$body_bytes_sent ' - '"\$http_referer" "\$http_user_agent"'; - + gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } EOF - fi # if [ "$webServerType" = "nginx" -o "$httpsTermination" = "VMSS" ]; # Set up html dir local copy if specified if [ "$htmlLocalCopySwitch" = "true" ]; then @@ -196,50 +163,35 @@ EOF setup_html_local_copy_cron_job fi - if [ "$webServerType" = "apache" ]; then - # Configure Apache/php - sed -i "s/Listen 80/Listen 81/" /etc/apache2/ports.conf - a2enmod rewrite && a2enmod remoteip && a2enmod headers - fi + config_all_sites_on_vmss $htmlLocalCopySwitch $httpsTermination - config_all_sites_on_vmss $htmlLocalCopySwitch $httpsTermination $webServerType - - # php config - if [ "$webServerType" = "apache" ]; then - PhpIni=/etc/php/${PhpVer}/apache2/php.ini - else - PhpIni=/etc/php/${PhpVer}/fpm/php.ini - fi - sed -i "s/memory_limit.*/memory_limit = 512M/" $PhpIni - sed -i "s/max_execution_time.*/max_execution_time = 18000/" $PhpIni - sed -i "s/max_input_vars.*/max_input_vars = 100000/" $PhpIni - sed -i "s/max_input_time.*/max_input_time = 600/" $PhpIni - sed -i "s/upload_max_filesize.*/upload_max_filesize = 1024M/" $PhpIni - sed -i "s/post_max_size.*/post_max_size = 1056M/" $PhpIni - sed -i "s/;opcache.use_cwd.*/opcache.use_cwd = 1/" $PhpIni - sed -i "s/;opcache.validate_timestamps.*/opcache.validate_timestamps = 1/" $PhpIni - sed -i "s/;opcache.save_comments.*/opcache.save_comments = 1/" $PhpIni - sed -i "s/;opcache.enable_file_override.*/opcache.enable_file_override = 0/" $PhpIni - sed -i "s/;opcache.enable.*/opcache.enable = 1/" $PhpIni - sed -i "s/;opcache.memory_consumption.*/opcache.memory_consumption = 256/" $PhpIni - sed -i "s/;opcache.max_accelerated_files.*/opcache.max_accelerated_files = 8000/" $PhpIni + # php config + PhpIni=/etc/php/${PhpVer}/fpm/php.ini + sed -i "s/memory_limit.*/memory_limit = 512M/" $PhpIni + sed -i "s/max_execution_time.*/max_execution_time = 18000/" $PhpIni + sed -i "s/max_input_vars.*/max_input_vars = 100000/" $PhpIni + sed -i "s/max_input_time.*/max_input_time = 600/" $PhpIni + sed -i "s/upload_max_filesize.*/upload_max_filesize = 1024M/" $PhpIni + sed -i "s/post_max_size.*/post_max_size = 1056M/" $PhpIni + sed -i "s/;opcache.use_cwd.*/opcache.use_cwd = 1/" $PhpIni + sed -i "s/;opcache.validate_timestamps.*/opcache.validate_timestamps = 1/" $PhpIni + sed -i "s/;opcache.save_comments.*/opcache.save_comments = 1/" $PhpIni + sed -i "s/;opcache.enable_file_override.*/opcache.enable_file_override = 0/" $PhpIni + sed -i "s/;opcache.enable.*/opcache.enable = 1/" $PhpIni + sed -i "s/;opcache.memory_consumption.*/opcache.memory_consumption = 256/" $PhpIni + sed -i "s/;opcache.max_accelerated_files.*/opcache.max_accelerated_files = 8000/" $PhpIni - # Remove the default site. Moodle is the only site we want - rm -f /etc/nginx/sites-enabled/default - if [ "$webServerType" = "apache" ]; then - rm -f /etc/apache2/sites-enabled/000-default.conf - fi + # Remove the default nginx site + rm -f /etc/nginx/sites-enabled/default - if [ "$webServerType" = "nginx" -o "$httpsTermination" = "VMSS" ]; then - # update startup script to wait for certificate in /azlamp mount - setup_azlamp_mount_dependency_for_systemd_service nginx || exit 1 - # restart Nginx - sudo service nginx restart - fi + # update startup script to wait for certificate in /azlamp mount + setup_azlamp_mount_dependency_for_systemd_service nginx || exit 1 - if [ "$webServerType" = "nginx" ]; then - # fpm config - overload this - cat < /etc/php/${PhpVer}/fpm/pool.d/www.conf + # restart nginx + systemctl restart nginx + + # fpm config - overload this + cat < /etc/php/${PhpVer}/fpm/pool.d/www.conf [www] user = www-data group = www-data @@ -253,267 +205,7 @@ pm.min_spare_servers = 20 pm.max_spare_servers = 30 EOF - # Restart fpm - service php${PhpVer}-fpm restart - fi - - if [ "$webServerType" = "apache" ]; then - if [ "$htmlLocalCopySwitch" != "true" ]; then - setup_azlamp_mount_dependency_for_systemd_service apache2 || exit 1 - fi - sudo service apache2 restart - fi - - # Configure varnish startup for 16.04 - VARNISHSTART="ExecStart=\/usr\/sbin\/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -f \/etc\/varnish\/moodle.vcl -S \/etc\/varnish\/secret -s malloc,1024m -p thread_pool_min=200 -p thread_pool_max=4000 -p thread_pool_add_delay=2 -p timeout_linger=100 -p timeout_idle=30 -p send_timeout=1800 -p thread_pools=4 -p http_max_hdr=512 -p workspace_backend=512k" - sed -i "s/^ExecStart.*/${VARNISHSTART}/" /lib/systemd/system/varnish.service - - # Configure varnish VCL for moodle - cat <> /etc/varnish/moodle.vcl -vcl 4.0; - -import std; -import directors; -backend default { - .host = "localhost"; - .port = "81"; - .first_byte_timeout = 3600s; - .connect_timeout = 600s; - .between_bytes_timeout = 600s; -} - -sub vcl_recv { - # Varnish does not support SPDY or HTTP/2.0 untill we upgrade to Varnish 5.0 - if (req.method == "PRI") { - return (synth(405)); - } - - if (req.restarts == 0) { - if (req.http.X-Forwarded-For) { - set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; - } else { - set req.http.X-Forwarded-For = client.ip; - } - } - - # Non-RFC2616 or CONNECT HTTP requests methods filtered. Pipe requests directly to backend - if (req.method != "GET" && - req.method != "HEAD" && - req.method != "PUT" && - req.method != "POST" && - req.method != "TRACE" && - req.method != "OPTIONS" && - req.method != "DELETE") { - return (pipe); - } - - # Varnish don't mess with healthchecks - if (req.url ~ "^/admin/tool/heartbeat" || req.url ~ "^/healthcheck.php") - { - return (pass); - } - - # Pipe requests to backup.php straight to backend - prevents problem with progress bar long polling 503 problem - # This is here because backup.php is POSTing to itself - Filter before !GET&&!HEAD - if (req.url ~ "^/backup/backup.php") - { - return (pipe); - } - - # Varnish only deals with GET and HEAD by default. If request method is not GET or HEAD, pass request to backend - if (req.method != "GET" && req.method != "HEAD") { - return (pass); - } - - ### Rules for Moodle and Totara sites ### - # Moodle doesn't require Cookie to serve following assets. Remove Cookie header from request, so it will be looked up. - if ( req.url ~ "^/altlogin/.+/.+\.(png|jpg|jpeg|gif|css|js|webp)$" || - req.url ~ "^/pix/.+\.(png|jpg|jpeg|gif)$" || - req.url ~ "^/theme/font.php" || - req.url ~ "^/theme/image.php" || - req.url ~ "^/theme/javascript.php" || - req.url ~ "^/theme/jquery.php" || - req.url ~ "^/theme/styles.php" || - req.url ~ "^/theme/yui" || - req.url ~ "^/lib/javascript.php/-1/" || - req.url ~ "^/lib/requirejs.php/-1/" - ) - { - set req.http.X-Long-TTL = "86400"; - unset req.http.Cookie; - return(hash); - } - - # Perform lookup for selected assets that we know are static but Moodle still needs a Cookie - if( req.url ~ "^/theme/.+\.(png|jpg|jpeg|gif|css|js|webp)" || - req.url ~ "^/lib/.+\.(png|jpg|jpeg|gif|css|js|webp)" || - req.url ~ "^/pluginfile.php/[0-9]+/course/overviewfiles/.+\.(?i)(png|jpg)$" - ) - { - # Set internal temporary header, based on which we will do things in vcl_backend_response - set req.http.X-Long-TTL = "86400"; - return (hash); - } - - # Serve requests to SCORM checknet.txt from varnish. Have to remove get parameters. Response body always contains "1" - if ( req.url ~ "^/lib/yui/build/moodle-core-checknet/assets/checknet.txt" ) - { - set req.url = regsub(req.url, "(.*)\?.*", "\1"); - unset req.http.Cookie; # Will go to hash anyway at the end of vcl_recv - set req.http.X-Long-TTL = "86400"; - return(hash); - } - - # Requests containing "Cookie" or "Authorization" headers will not be cached - if (req.http.Authorization || req.http.Cookie) { - return (pass); - } - - # Almost everything in Moodle correctly serves Cache-Control headers, if - # needed, which varnish will honor, but there are some which don't. Rather - # than explicitly finding them all and listing them here we just fail safe - # and don't cache unknown urls that get this far. - return (pass); -} - -sub vcl_backend_response { - # Happens after we have read the response headers from the backend. - # - # Here you clean the response headers, removing silly Set-Cookie headers - # and other mistakes your backend does. - - # We know these assest are static, let's set TTL >0 and allow client caching - if ( beresp.http.Cache-Control && bereq.http.X-Long-TTL && beresp.ttl < std.duration(bereq.http.X-Long-TTL + "s", 1s) && !beresp.http.WWW-Authenticate ) - { # If max-age < defined in X-Long-TTL header - set beresp.http.X-Orig-Pragma = beresp.http.Pragma; unset beresp.http.Pragma; - set beresp.http.X-Orig-Cache-Control = beresp.http.Cache-Control; - set beresp.http.Cache-Control = "public, max-age="+bereq.http.X-Long-TTL+", no-transform"; - set beresp.ttl = std.duration(bereq.http.X-Long-TTL + "s", 1s); - unset bereq.http.X-Long-TTL; - } - else if( !beresp.http.Cache-Control && bereq.http.X-Long-TTL && !beresp.http.WWW-Authenticate ) { - set beresp.http.X-Orig-Pragma = beresp.http.Pragma; unset beresp.http.Pragma; - set beresp.http.Cache-Control = "public, max-age="+bereq.http.X-Long-TTL+", no-transform"; - set beresp.ttl = std.duration(bereq.http.X-Long-TTL + "s", 1s); - unset bereq.http.X-Long-TTL; - } - else { # Don't touch headers if max-age > defined in X-Long-TTL header - unset bereq.http.X-Long-TTL; - } - - # Here we set X-Trace header, prepending it to X-Trace header received from backend. Useful for troubleshooting - if(beresp.http.x-trace && !beresp.was_304) { - set beresp.http.X-Trace = regsub(server.identity, "^([^.]+),?.*$", "\1")+"->"+regsub(beresp.backend.name, "^(.+)\((?:[0-9]{1,3}\.){3}([0-9]{1,3})\)","\1(\2)")+"->"+beresp.http.X-Trace; - } - else { - set beresp.http.X-Trace = regsub(server.identity, "^([^.]+),?.*$", "\1")+"->"+regsub(beresp.backend.name, "^(.+)\((?:[0-9]{1,3}\.){3}([0-9]{1,3})\)","\1(\2)"); - } - - # Gzip JS, CSS is done at the ngnix level doing it here dosen't respect the no buffer requsets - # if (beresp.http.content-type ~ "application/javascript.*" || beresp.http.content-type ~ "text") { - # set beresp.do_gzip = true; - #} -} - -sub vcl_deliver { - - # Revert back to original Cache-Control header before delivery to client - if (resp.http.X-Orig-Cache-Control) - { - set resp.http.Cache-Control = resp.http.X-Orig-Cache-Control; - unset resp.http.X-Orig-Cache-Control; - } - - # Revert back to original Pragma header before delivery to client - if (resp.http.X-Orig-Pragma) - { - set resp.http.Pragma = resp.http.X-Orig-Pragma; - unset resp.http.X-Orig-Pragma; - } - - # (Optional) X-Cache HTTP header will be added to responce, indicating whether object was retrieved from backend, or served from cache - if (obj.hits > 0) { - set resp.http.X-Cache = "HIT"; - } else { - set resp.http.X-Cache = "MISS"; - } - - # Set X-AuthOK header when totara/varnsih authentication succeeded - if (req.http.X-AuthOK) { - set resp.http.X-AuthOK = req.http.X-AuthOK; - } - - # If desired "Via: 1.1 Varnish-v4" response header can be removed from response - unset resp.http.Via; - unset resp.http.Server; - - return(deliver); -} - -sub vcl_backend_error { - # More comprehensive varnish error page. Display time, instance hostname, host header, url for easier troubleshooting. - set beresp.http.Content-Type = "text/html; charset=utf-8"; - set beresp.http.Retry-After = "5"; - synthetic( {" - - - - "} + beresp.status + " " + beresp.reason + {" - - -

Error "} + beresp.status + " " + beresp.reason + {"

-

"} + beresp.reason + {"

-

Guru Meditation:

-

Time: "} + now + {"

-

Node: "} + server.hostname + {"

-

Host: "} + bereq.http.host + {"

-

URL: "} + bereq.url + {"

-

XID: "} + bereq.xid + {"

-
-

Varnish cache server - - - "} ); - return (deliver); -} - -sub vcl_synth { - - #Redirect using '301 - Permanent Redirect', permanent redirect - if (resp.status == 851) { - set resp.http.Location = req.http.x-redir; - set resp.http.X-Varnish-Redirect = true; - set resp.status = 301; - return (deliver); - } - - #Redirect using '302 - Found', temporary redirect - if (resp.status == 852) { - set resp.http.Location = req.http.x-redir; - set resp.http.X-Varnish-Redirect = true; - set resp.status = 302; - return (deliver); - } - - #Redirect using '307 - Temporary Redirect', !GET&&!HEAD requests, dont change method on redirected requests - if (resp.status == 857) { - set resp.http.Location = req.http.x-redir; - set resp.http.X-Varnish-Redirect = true; - set resp.status = 307; - return (deliver); - } - - #Respond with 403 - Forbidden - if (resp.status == 863) { - set resp.http.X-Varnish-Error = true; - set resp.status = 403; - return (deliver); - } -} -EOF - - # Restart Varnish - systemctl daemon-reload - service varnish restart + # Restart php-fpm + systemctl restart php${PhpVer}-fpm } > /tmp/setup.log