Merge pull request #1 from ItalyPaleAle/azure-url

Updates to generalized architecture
This commit is contained in:
Alessandro (Ale) Segala 2019-02-07 14:02:25 -08:00 коммит произвёл GitHub
Родитель 2b95669ac8 5e0ec49cf5
Коммит a5e5b3d91d
53 изменённых файлов: 970 добавлений и 3074 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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']);

129
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 `<siteroot>/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 `<siteroot>/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.

Просмотреть файл

@ -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",

Просмотреть файл

@ -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."
}
}

Просмотреть файл

@ -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"

Просмотреть файл

@ -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",

Просмотреть файл

@ -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": [
{

Просмотреть файл

@ -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
```

Просмотреть файл

@ -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)

Просмотреть файл

@ -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
```

Просмотреть файл

@ -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 `<siteroot>/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

Просмотреть файл

@ -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)

Просмотреть файл

@ -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/<yoursitename>/`. 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/<your_moodle_site_fqdn>/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/<your_moodle_site_fqdn>/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/<your_moodle_site_fqdn>/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/<your_site_fqdn>/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/<your_moodle_site_fqdn>/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/<your_site_fqdn>/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/<your_moodle_site_fqdn>/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/<your_moodle_site_fqdn>/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/<your_moodle_site_fqdn>/nginx.key`: Your certificate's private key
- `/azlamp/certs/<your_moodle_site_fqdn>/nginx.crt`: Your combined signed certificate and trust chain certificate(s).
- `/azlamp/certs/<your_site_fqdn>/nginx.key`: Your certificate's private key
- `/azlamp/certs/<your_site_fqdn>/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

Просмотреть файл

@ -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]

Просмотреть файл

@ -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
```

Просмотреть файл

@ -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 `<siteroot>/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 `<siteroot>/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.

Просмотреть файл

@ -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 <key_vault_name> <resource_group_name> <azure_region> <secret_name> cert.pem key.pem chain.pem
```sh
bash $LAMP_AZURE_WORKSPACE/arm_template/etc/keyvault.sh <key_vault_name> <resource_group_name> <azure_region> <secret_name> cert.pem key.pem chain.pem
```
Make sure to set `<azure_region>` the same as the Azure region you'll be using to deploy the Moodle template.
Assign desired names for `<key_vault_name>`, `<resource_group_name>` (you can use an existing resource group) and `<secret_name>`.
`<secret_name>` is not very important in our deployment. Then you'll get outputs as follows:
Make sure to set `<azure_region>` the same as the Azure region you'll be using to deploy the template.
Assign desired names for `<key_vault_name>`, `<resource_group_name>` (you can use an existing resource group) and `<secret_name>`. `<secret_name>` 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 `<resource_group_name>`, `"mdl-kv"` for `<key_vault_name>`,
and `"mymoodlesitecert"` for `<secret_name>`. Note that `caCertKeyVaultURL` and `caCertThumbprint` will be empty
and `"mylampsitecert"` for `<secret_name>`. 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.

Просмотреть файл

@ -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

Просмотреть файл

@ -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"
}

Просмотреть файл

@ -1,5 +0,0 @@
{
"MOODLE_RG_NAME": "rgmoodlearm12",
"MOODLE_RG_LOCATION": "canadacentral",
"MOODLE_DEPLOYMENT_NAME": "MainDeployment"
}

Просмотреть файл

@ -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"
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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"
}
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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"

Просмотреть файл

@ -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'))]"
}
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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]"
}
}
],

Просмотреть файл

@ -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]"
}
}
],

Просмотреть файл

@ -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')]"
]
}
}

Просмотреть файл

@ -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"
}
}
}

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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'))]"
}

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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"
}
}
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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)]"
}
}

Просмотреть файл

@ -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]"
}
}
},

Просмотреть файл

@ -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": {

Просмотреть файл

@ -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"
}
}

Просмотреть файл

@ -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 <<EOF > /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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <<EOF > /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 <<EOF > /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

Просмотреть файл

@ -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
#;;
*)

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <<EOF > /etc/nginx/nginx.conf
# Build nginx config
cat <<EOF > /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 <<EOF >> /etc/nginx/nginx.conf
map \$http_x_forwarded_proto \$fastcgi_https {
default \$https;
http '';
https on;
}
EOF
fi
cat <<EOF >> /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 <<EOF > /etc/php/${PhpVer}/fpm/pool.d/www.conf
# restart nginx
systemctl restart nginx
# fpm config - overload this
cat <<EOF > /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 <<EOF >> /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( {"
<!DOCTYPE html>
<html>
<head>
<title>"} + beresp.status + " " + beresp.reason + {"</title>
</head>
<body>
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
<p>"} + beresp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>Time: "} + now + {"</p>
<p>Node: "} + server.hostname + {"</p>
<p>Host: "} + bereq.http.host + {"</p>
<p>URL: "} + bereq.url + {"</p>
<p>XID: "} + bereq.xid + {"</p>
<hr>
<p>Varnish cache server
</body>
</html>
"} );
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