├── README.md ├── acs ├── README.md ├── acsdcos.json ├── acsswarm.json ├── acswindows.json ├── cluster.parameters.json └── images │ ├── chronos-docker.png │ ├── chronos-ui.png │ ├── chronos.png │ ├── completed-hello-world.png │ ├── dockercomposescale.png │ ├── dockercomposescalewindows.png │ ├── dockerinfo.png │ ├── dockerinfowindows.png │ ├── dockerps.png │ ├── dockerpswindows.png │ ├── marathon-docker.png │ ├── marathon-newapp-status.png │ ├── marathon-newapp.png │ ├── mesos-agents.png │ ├── mesos-completed-tasks.png │ ├── mesos-frameworks.png │ ├── mesos-webui.png │ ├── mesos.png │ ├── portal-publicipaddresses.png │ ├── portal-resourcegroups.png │ ├── swarm-framework.png │ ├── swarm.png │ ├── swarmbrowser.png │ ├── swarmbrowserwindows.png │ └── swarmwindows.png ├── attachedDisks ├── README.md ├── azure.json ├── azure.parameters.json ├── azure.workaround.json ├── cloudinit.yml ├── gen-oneline-customdata.py ├── gen-oneline-customdata.yaml.py └── workaround.sh ├── availabilitySet ├── README.md ├── azuredeploy.json └── deployVM0.ps1 ├── bool-inline ├── README.md ├── azuredeploy.json └── inline.json ├── bool ├── README.md └── azuredeploy.json ├── cservice ├── README.md ├── azuredeploy.json ├── azuredeploy.parameters.json ├── deployVM0.ps1 ├── images │ ├── chronos-docker.png │ ├── chronos-ui.png │ ├── chronos.png │ ├── completed-hello-world.png │ ├── dockercomposescale.png │ ├── dockerinfo.png │ ├── dockerps.png │ ├── marathon-docker.png │ ├── marathon-newapp-status.png │ ├── marathon-newapp.png │ ├── mesos-agents.png │ ├── mesos-completed-tasks.png │ ├── mesos-frameworks.png │ ├── mesos-webui.png │ ├── mesos.png │ ├── portal-publicipaddresses.png │ ├── portal-resourcegroups.png │ ├── swarm-framework.png │ ├── swarm.png │ └── swarmbrowser.png └── swarm.json ├── dynamicNATRules ├── README.md ├── azuredeploy.json └── azuredeploy.parameters.json ├── exerciseStgNetCmp ├── README.md ├── azuredeploy.json └── azuredeploy.parameters.json ├── files-nas └── README.md ├── fuse-nas └── README.md ├── gaexercise ├── logfileexists │ ├── README.md │ └── azuredeploy.json └── nologfileexists │ ├── README.md │ └── azuredeploy.json ├── ignitedemo ├── avere-cache.json ├── avere-sustainedload.json ├── direct-nocache.json └── job.json ├── linuxvm ├── README.md ├── azuredeploy.json └── azuredeploy.parameters.json ├── mesos-marathon-vmss ├── README.md ├── cluster.parameters.json ├── deployVM0.ps1 ├── images │ ├── chronos-docker.png │ ├── chronos-ui.png │ ├── chronos.png │ ├── completed-hello-world.png │ ├── dockercomposescale.png │ ├── dockercomposescalewindows.png │ ├── dockerinfo.png │ ├── dockerinfowindows.png │ ├── dockerps.png │ ├── dockerpswindows.png │ ├── marathon-docker.png │ ├── marathon-newapp-status.png │ ├── marathon-newapp.png │ ├── mesos-agents.png │ ├── mesos-completed-tasks.png │ ├── mesos-frameworks.png │ ├── mesos-webui.png │ ├── mesos.png │ ├── portal-publicipaddresses.png │ ├── portal-resourcegroups.png │ ├── swarm-framework.png │ ├── swarm.png │ ├── swarmbrowser.png │ ├── swarmbrowserwindows.png │ └── swarmwindows.png ├── mesos-cluster-with-linux-jumpbox.json ├── mesos-cluster-with-no-jumpbox.json ├── mesos-cluster-with-windows-jumpbox.json ├── metadata.json ├── parts │ ├── Install-ContainerHost-And-Join-Swarm.ps1 │ ├── base-swarm-template.json │ ├── base-swarm-windows-template.json │ ├── base-template.json │ ├── base-template.parameters.json │ ├── configure-mesos-cluster.sh │ ├── configure-swarm-cluster.sh │ ├── configure-ubuntu.sh │ ├── fragment-linux-jumpbox.json │ ├── fragment-windows-agent-diagnostics-extension.json │ ├── fragment-windows-jumpbox.json │ ├── gen-arm-templates.py │ ├── gen-singleline-ps.py │ ├── nginx.conf │ ├── prettyPrintAzureTemplate.py │ ├── simple-web.ps1 │ ├── simplest-web.ps1 │ └── vmsizes-storage-account-mappings.json ├── swarm-cluster-with-no-jumpbox.json ├── swarm-cluster-with-windows-no-diagnostics.json └── swarm-cluster-with-windows.json ├── mesos-marathon ├── README.md ├── cluster.parameters.json ├── deployVM0.ps1 ├── images │ ├── chronos-docker.png │ ├── chronos-ui.png │ ├── chronos.png │ ├── completed-hello-world.png │ ├── dockercomposescale.png │ ├── dockerinfo.png │ ├── dockerps.png │ ├── marathon-docker.png │ ├── marathon-newapp-status.png │ ├── marathon-newapp.png │ ├── mesos-agents.png │ ├── mesos-completed-tasks.png │ ├── mesos-frameworks.png │ ├── mesos-webui.png │ ├── mesos.png │ ├── portal-publicipaddresses.png │ ├── portal-resourcegroups.png │ ├── swarm-framework.png │ ├── swarm.png │ └── swarmbrowser.png ├── mesos-cluster-with-linux-jumpbox.json ├── mesos-cluster-with-no-jumpbox.json ├── mesos-cluster-with-windows-jumpbox.json ├── metadata.json ├── parts │ ├── base-swarm-template.json │ ├── base-template.json │ ├── base-template.parameters.json │ ├── configure-mesos-cluster.sh │ ├── configure-swarm-cluster.sh │ ├── configure-ubuntu.sh │ ├── fragment-linux-jumpbox.json │ ├── fragment-windows-jumpbox.json │ ├── gen-arm-templates.py │ └── nginx.conf └── swarm-cluster-with-no-jumpbox.json ├── mesos-vmss ├── CS_VMSS.json ├── cluster.parameters.json ├── deployVM0.ps1 └── mesos-cluster.json ├── nicscaling ├── README.md └── azuredeploy.json ├── reliableCustomScriptExtension ├── README.md ├── gen-oneline-customdata.py ├── helloworld.sh └── reliableCustomScript.json ├── simplelinux-attachblankdisk ├── FixDiskFailure.ps1 ├── README.md ├── attachDetachLUN.ps1 ├── attachLUN.ps1 ├── attachLUN0-9.ps1 ├── attachLUN1-9.ps1 ├── azuredeploy.json ├── cluster.parameters.json ├── copydisks.ps1 ├── deployVM0.ps1 ├── detachAllDisks.ps1 └── detachLUN.ps1 ├── simplelinux ├── README.md ├── azuredeploy.json ├── cluster.parameters.json └── deployVM0.ps1 ├── simplemultilinux-swapdisks ├── README.md ├── azuredeploy.json ├── cluster.parameters.json ├── deployVM0.ps1 ├── findr.sh └── scandrives.sh ├── simplemultilinux ├── README.md ├── azuredeploy.json ├── cluster.parameters.json └── deployVM0.ps1 ├── simplewindows-customdata ├── README.md ├── azuredeploy.json ├── cluster.parameters.json ├── gen-oneline-customdata.py ├── gen-ps-launcher-template-vars.py ├── helloworld.ps1 └── launcher.ps1 ├── simplewindows ├── README.md └── azuredeploy.json ├── stgscaling ├── README.md └── azuredeploy.json ├── swarm ├── README.md ├── cluster.parameters.json ├── configure-swarm-cluster.sh ├── gen-oneline-customdata.py └── swarm.json ├── vnet ├── README.md ├── azuredeploy.json └── azuredeploy.parameters.json └── windowsvm ├── README.md └── azuredeploy.json /README.md: -------------------------------------------------------------------------------- 1 | This contains experimental Azure templates and code. 2 | 3 | Enjoy! 4 | 5 | Test String -------------------------------------------------------------------------------- /acs/acsdcos.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "dnsNamePrefix": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Sets the Domain name prefix for the cluster. The concatenation of the domain name and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 9 | } 10 | }, 11 | "agentCount": { 12 | "type": "int", 13 | "defaultValue": 1, 14 | "metadata": { 15 | "description": "The number of Mesos agents for the cluster. This value can be from 1 to 40" 16 | }, 17 | "minValue":1, 18 | "maxValue":100 19 | }, 20 | "agentVMSize": { 21 | "type": "string", 22 | "defaultValue": "Standard_D2_v2", 23 | "allowedValues": [ 24 | "Standard_A0", "Standard_A1", "Standard_A2", "Standard_A3", "Standard_A4", "Standard_A5", 25 | "Standard_A6", "Standard_A7", "Standard_A8", "Standard_A9", "Standard_A10", "Standard_A11", 26 | "Standard_D1", "Standard_D2", "Standard_D3", "Standard_D4", 27 | "Standard_D11", "Standard_D12", "Standard_D13", "Standard_D14", 28 | "Standard_D1_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", 29 | "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", 30 | "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", 31 | "Standard_DS1", "Standard_DS2", "Standard_DS3", "Standard_DS4", 32 | "Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14", 33 | "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5" 34 | ], 35 | "metadata": { 36 | "description": "The size of the Virtual Machine." 37 | } 38 | }, 39 | "linuxAdminUsername": { 40 | "type": "string", 41 | "defaultValue": "azureuser", 42 | "metadata": { 43 | "description": "User name for the Linux Virtual Machines." 44 | } 45 | }, 46 | "orchestratorType": { 47 | "type": "string", 48 | "defaultValue": "DCOS", 49 | "allowedValues": [ 50 | "Swarm", 51 | "DCOS" 52 | ], 53 | "metadata": { 54 | "description": "The type of orchestrator used to manage the applications on the cluster." 55 | } 56 | }, 57 | "masterCount": { 58 | "type": "int", 59 | "defaultValue": 1, 60 | "allowedValues": [ 61 | 1, 62 | 3, 63 | 5 64 | ], 65 | "metadata": { 66 | "description": "The number of Mesos masters for the cluster." 67 | } 68 | }, 69 | "sshRSAPublicKey": { 70 | "type": "string", 71 | "metadata": { 72 | "description": "Configure all linux machines with the SSH RSA public key string. Your key should include three parts, for example 'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm'" 73 | } 74 | } 75 | }, 76 | "variables": { 77 | "adminUsername":"[parameters('linuxAdminUsername')]", 78 | "agentCount":"[parameters('agentCount')]", 79 | "agentsEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'agents')]", 80 | "agentVMSize":"[parameters('agentVMSize')]", 81 | "masterCount":"[parameters('masterCount')]", 82 | "mastersEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'mgmt')]", 83 | "orchestratorType":"[parameters('orchestratorType')]", 84 | "sshRSAPublicKey":"[parameters('sshRSAPublicKey')]" 85 | }, 86 | "resources": [ 87 | { 88 | "apiVersion": "2016-03-30", 89 | "type": "Microsoft.ContainerService/containerServices", 90 | "location": "[resourceGroup().location]", 91 | "name":"[concat('containerservice-',resourceGroup().name)]", 92 | "properties": { 93 | "orchestratorProfile": { 94 | "orchestratorType": "[variables('orchestratorType')]" 95 | }, 96 | "masterProfile": { 97 | "count": "[variables('masterCount')]", 98 | "dnsPrefix": "[variables('mastersEndpointDNSNamePrefix')]" 99 | }, 100 | "agentPoolProfiles": [ 101 | { 102 | "name": "agentpools", 103 | "count": "[variables('agentCount')]", 104 | "vmSize": "[variables('agentVMSize')]", 105 | "dnsPrefix": "[variables('agentsEndpointDNSNamePrefix')]" 106 | } 107 | ], 108 | "linuxProfile": { 109 | "adminUsername": "[variables('adminUsername')]", 110 | "ssh": { 111 | "publicKeys": [ 112 | { 113 | "keyData": "[variables('sshRSAPublicKey')]" 114 | } 115 | ] 116 | } 117 | } 118 | } 119 | } 120 | ], 121 | "outputs": { 122 | "masterFQDN": { 123 | "type": "string", 124 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn]" 125 | }, 126 | "sshMaster0": { 127 | "type": "string", 128 | "value": "[concat('ssh ', variables('adminUsername'), '@', reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn, ' -A -p 2200')]" 129 | }, 130 | "agentFQDN": { 131 | "type": "string", 132 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).agentPoolProfiles[0].fqdn]" 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /acs/acsswarm.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "dnsNamePrefix": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Sets the Domain name prefix for the cluster. The concatenation of the domain name and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 9 | } 10 | }, 11 | "agentCount": { 12 | "type": "int", 13 | "defaultValue": 1, 14 | "metadata": { 15 | "description": "The number of Mesos agents for the cluster. This value can be from 1 to 40" 16 | }, 17 | "minValue":1, 18 | "maxValue":100 19 | }, 20 | "agentVMSize": { 21 | "type": "string", 22 | "defaultValue": "Standard_D2_v2", 23 | "allowedValues": [ 24 | "Standard_A0", "Standard_A1", "Standard_A2", "Standard_A3", "Standard_A4", "Standard_A5", 25 | "Standard_A6", "Standard_A7", "Standard_A8", "Standard_A9", "Standard_A10", "Standard_A11", 26 | "Standard_D1", "Standard_D2", "Standard_D3", "Standard_D4", 27 | "Standard_D11", "Standard_D12", "Standard_D13", "Standard_D14", 28 | "Standard_D1_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", 29 | "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", 30 | "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", 31 | "Standard_DS1", "Standard_DS2", "Standard_DS3", "Standard_DS4", 32 | "Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14", 33 | "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5" 34 | ], 35 | "metadata": { 36 | "description": "The size of the Virtual Machine." 37 | } 38 | }, 39 | "linuxAdminUsername": { 40 | "type": "string", 41 | "defaultValue": "azureuser", 42 | "metadata": { 43 | "description": "User name for the Linux Virtual Machines." 44 | } 45 | }, 46 | "orchestratorType": { 47 | "type": "string", 48 | "defaultValue": "Swarm", 49 | "allowedValues": [ 50 | "Swarm", 51 | "DCOS" 52 | ], 53 | "metadata": { 54 | "description": "The type of orchestrator used to manage the applications on the cluster." 55 | } 56 | }, 57 | "masterCount": { 58 | "type": "int", 59 | "defaultValue": 1, 60 | "allowedValues": [ 61 | 1, 62 | 3, 63 | 5 64 | ], 65 | "metadata": { 66 | "description": "The number of Mesos masters for the cluster." 67 | } 68 | }, 69 | "sshRSAPublicKey": { 70 | "type": "string", 71 | "metadata": { 72 | "description": "Configure all linux machines with the SSH RSA public key string. Your key should include three parts, for example 'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm'" 73 | } 74 | } 75 | }, 76 | "variables": { 77 | "adminUsername":"[parameters('linuxAdminUsername')]", 78 | "agentCount":"[parameters('agentCount')]", 79 | "agentsEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'agents')]", 80 | "agentVMSize":"[parameters('agentVMSize')]", 81 | "masterCount":"[parameters('masterCount')]", 82 | "mastersEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'mgmt')]", 83 | "orchestratorType":"[parameters('orchestratorType')]", 84 | "sshRSAPublicKey":"[parameters('sshRSAPublicKey')]" 85 | }, 86 | "resources": [ 87 | { 88 | "apiVersion": "2016-03-30", 89 | "type": "Microsoft.ContainerService/containerServices", 90 | "location": "[resourceGroup().location]", 91 | "name":"[concat('containerservice-',resourceGroup().name)]", 92 | "properties": { 93 | "orchestratorProfile": { 94 | "orchestratorType": "[variables('orchestratorType')]" 95 | }, 96 | "masterProfile": { 97 | "count": "[variables('masterCount')]", 98 | "dnsPrefix": "[variables('mastersEndpointDNSNamePrefix')]" 99 | }, 100 | "agentPoolProfiles": [ 101 | { 102 | "name": "agentpools", 103 | "count": "[variables('agentCount')]", 104 | "vmSize": "[variables('agentVMSize')]", 105 | "dnsPrefix": "[variables('agentsEndpointDNSNamePrefix')]" 106 | } 107 | ], 108 | "linuxProfile": { 109 | "adminUsername": "[variables('adminUsername')]", 110 | "ssh": { 111 | "publicKeys": [ 112 | { 113 | "keyData": "[variables('sshRSAPublicKey')]" 114 | } 115 | ] 116 | } 117 | } 118 | } 119 | } 120 | ], 121 | "outputs": { 122 | "masterFQDN": { 123 | "type": "string", 124 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn]" 125 | }, 126 | "sshMaster0": { 127 | "type": "string", 128 | "value": "[concat('ssh ', variables('adminUsername'), '@', reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn, ' -A -p 2200')]" 129 | }, 130 | "agentFQDN": { 131 | "type": "string", 132 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).agentPoolProfiles[0].fqdn]" 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /acs/acswindows.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "dnsNamePrefix": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Sets the Domain name prefix for the cluster. The concatenation of the domain name and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 9 | } 10 | }, 11 | "agentCount": { 12 | "type": "int", 13 | "defaultValue": 1, 14 | "metadata": { 15 | "description": "The number of Mesos agents for the cluster." 16 | }, 17 | "minValue":1, 18 | "maxValue":100 19 | }, 20 | "agentVMSize": { 21 | "type": "string", 22 | "defaultValue": "Standard_D2_v2", 23 | "allowedValues": [ 24 | "Standard_A0", "Standard_A1", "Standard_A2", "Standard_A3", "Standard_A4", "Standard_A5", 25 | "Standard_A6", "Standard_A7", "Standard_A8", "Standard_A9", "Standard_A10", "Standard_A11", 26 | "Standard_D1", "Standard_D2", "Standard_D3", "Standard_D4", 27 | "Standard_D11", "Standard_D12", "Standard_D13", "Standard_D14", 28 | "Standard_D1_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", 29 | "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", 30 | "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", 31 | "Standard_DS1", "Standard_DS2", "Standard_DS3", "Standard_DS4", 32 | "Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14", 33 | "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5" 34 | ], 35 | "metadata": { 36 | "description": "The size of the Virtual Machine." 37 | } 38 | }, 39 | "linuxAdminUsername": { 40 | "type": "string", 41 | "defaultValue": "azureuser", 42 | "metadata": { 43 | "description": "User name for the Linux Virtual Machines." 44 | } 45 | }, 46 | "orchestratorType": { 47 | "type": "string", 48 | "defaultValue": "Swarm", 49 | "allowedValues": [ 50 | "Swarm" 51 | ], 52 | "metadata": { 53 | "description": "The type of orchestrator used to manage the applications on the cluster." 54 | } 55 | }, 56 | "masterCount": { 57 | "type": "int", 58 | "defaultValue": 1, 59 | "allowedValues": [ 60 | 1, 61 | 3, 62 | 5 63 | ], 64 | "metadata": { 65 | "description": "The number of Mesos masters for the cluster." 66 | } 67 | }, 68 | "sshRSAPublicKey": { 69 | "type": "string", 70 | "metadata": { 71 | "description": "Configure all linux machines with the SSH RSA public key string. Your key should include three parts, for example 'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm'" 72 | } 73 | }, 74 | "windowsAdminPassword": { 75 | "type": "securestring", 76 | "defaultValue": "", 77 | "metadata": { 78 | "description": "Password for the Windows Jumpbox Virtual Machine." 79 | } 80 | } 81 | }, 82 | "variables": { 83 | "adminUsername":"[parameters('linuxAdminUsername')]", 84 | "adminPassword":"[parameters('windowsAdminPassword')]", 85 | "agentCount":"[parameters('agentCount')]", 86 | "agentsEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'agents')]", 87 | "agentVMSize":"[parameters('agentVMSize')]", 88 | "masterCount":"[parameters('masterCount')]", 89 | "mastersEndpointDNSNamePrefix":"[concat(parameters('dnsNamePrefix'),'mgmt')]", 90 | "orchestratorType":"Swarm", 91 | "sshRSAPublicKey":"[parameters('sshRSAPublicKey')]" 92 | }, 93 | "resources": [ 94 | { 95 | "apiVersion": "2016-03-30", 96 | "type": "Microsoft.ContainerService/containerServices", 97 | "location": "[resourceGroup().location]", 98 | "name":"[concat('containerservice-',resourceGroup().name)]", 99 | "properties": { 100 | "orchestratorProfile": { 101 | "orchestratorType": "[variables('orchestratorType')]" 102 | }, 103 | "masterProfile": { 104 | "count": "[variables('masterCount')]", 105 | "dnsPrefix": "[variables('mastersEndpointDNSNamePrefix')]" 106 | }, 107 | "agentPoolProfiles": [ 108 | { 109 | "name": "agentpools", 110 | "count": "[variables('agentCount')]", 111 | "vmSize": "[variables('agentVMSize')]", 112 | "dnsPrefix": "[variables('agentsEndpointDNSNamePrefix')]", 113 | "osType": "Windows" 114 | } 115 | ], 116 | "windowsProfile": { 117 | "adminUsername": "[variables('adminUsername')]", 118 | "adminPassword": "[variables('adminPassword')]" 119 | }, 120 | "diagnosticsProfile": { 121 | "vmDiagnostics": { 122 | "enabled": false 123 | } 124 | }, 125 | "linuxProfile": { 126 | "adminUsername": "[variables('adminUsername')]", 127 | "ssh": { 128 | "publicKeys": [ 129 | { 130 | "keyData": "[variables('sshRSAPublicKey')]" 131 | } 132 | ] 133 | } 134 | } 135 | } 136 | } 137 | ], 138 | "outputs": { 139 | "masterFQDN": { 140 | "type": "string", 141 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn]" 142 | }, 143 | "sshMaster0": { 144 | "type": "string", 145 | "value": "[concat('ssh ', variables('adminUsername'), '@', reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).masterProfile.fqdn, ' -A -p 2200')]" 146 | }, 147 | "agentFQDN": { 148 | "type": "string", 149 | "value": "[reference(concat('Microsoft.ContainerService/containerServices/', 'containerservice-', resourceGroup().name)).agentPoolProfiles[0].fqdn]" 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /acs/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "dnsNamePrefix": { 3 | "value": "anhowe0407b" 4 | }, 5 | "agentCount": { 6 | "value": 1 7 | }, 8 | "agentVMSize": { 9 | "value": "Standard_D1" 10 | }, 11 | "orchestratorType": { 12 | "value": "SwarmPreview" 13 | }, 14 | "masterCount": { 15 | "value": 3 16 | }, 17 | "sshRSAPublicKey": { 18 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /acs/images/chronos-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/chronos-docker.png -------------------------------------------------------------------------------- /acs/images/chronos-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/chronos-ui.png -------------------------------------------------------------------------------- /acs/images/chronos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/chronos.png -------------------------------------------------------------------------------- /acs/images/completed-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/completed-hello-world.png -------------------------------------------------------------------------------- /acs/images/dockercomposescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockercomposescale.png -------------------------------------------------------------------------------- /acs/images/dockercomposescalewindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockercomposescalewindows.png -------------------------------------------------------------------------------- /acs/images/dockerinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockerinfo.png -------------------------------------------------------------------------------- /acs/images/dockerinfowindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockerinfowindows.png -------------------------------------------------------------------------------- /acs/images/dockerps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockerps.png -------------------------------------------------------------------------------- /acs/images/dockerpswindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/dockerpswindows.png -------------------------------------------------------------------------------- /acs/images/marathon-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/marathon-docker.png -------------------------------------------------------------------------------- /acs/images/marathon-newapp-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/marathon-newapp-status.png -------------------------------------------------------------------------------- /acs/images/marathon-newapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/marathon-newapp.png -------------------------------------------------------------------------------- /acs/images/mesos-agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/mesos-agents.png -------------------------------------------------------------------------------- /acs/images/mesos-completed-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/mesos-completed-tasks.png -------------------------------------------------------------------------------- /acs/images/mesos-frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/mesos-frameworks.png -------------------------------------------------------------------------------- /acs/images/mesos-webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/mesos-webui.png -------------------------------------------------------------------------------- /acs/images/mesos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/mesos.png -------------------------------------------------------------------------------- /acs/images/portal-publicipaddresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/portal-publicipaddresses.png -------------------------------------------------------------------------------- /acs/images/portal-resourcegroups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/portal-resourcegroups.png -------------------------------------------------------------------------------- /acs/images/swarm-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/swarm-framework.png -------------------------------------------------------------------------------- /acs/images/swarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/swarm.png -------------------------------------------------------------------------------- /acs/images/swarmbrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/swarmbrowser.png -------------------------------------------------------------------------------- /acs/images/swarmbrowserwindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/swarmbrowserwindows.png -------------------------------------------------------------------------------- /acs/images/swarmwindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/acs/images/swarmwindows.png -------------------------------------------------------------------------------- /attachedDisks/README.md: -------------------------------------------------------------------------------- 1 | # Cloud Init erases attached disks 2 | 3 | This template demonstrates the erasure of an attached disk created by cloudinit. The cloudinit yaml is in `cloudinit.yml` 4 | 5 | Edit the parameters and deploy the file. 6 | 7 | To repro the erasing disk: 8 | 1. once deployed `sudo touch /foo/bar/hello` 9 | 2. `sudo ls /foo/bar` and notice the file `hello` exists 10 | 3. `sudo reboot` 11 | 4. once rebooted, `sudo ls /foo/bar` and notice the file is missing 12 | 13 | A similar repro happens when attaching an existing disk to a VM. 14 | 15 | This is because of the following bug: https://bugs.launchpad.net/cloud-init/+bug/1692093. 16 | 17 | The workaround to this problem is captured in workaround.sh and works the disk is preserved on reboot. -------------------------------------------------------------------------------- /attachedDisks/azure.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "newStorageAccountName": { 3 | "value": "anhowe0519g" 4 | }, 5 | "dnsNameForPublicIP": { 6 | "value": "anhowe0519g" 7 | }, 8 | "sshKeyData": { 9 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /attachedDisks/cloudinit.yml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | 3 | disk_setup: 4 | /dev/sdc: 5 | table_type: gpt 6 | layout: true 7 | overwrite: false 8 | 9 | fs_setup: 10 | - label: etcd_disk 11 | filesystem: ext4 12 | device: /dev/sdc1 13 | extra_opts: 14 | - "-F" 15 | - "-E" 16 | - "lazy_itable_init=1,lazy_journal_init=1" 17 | 18 | mounts: 19 | - - /dev/sdc1 20 | - /foo/bar -------------------------------------------------------------------------------- /attachedDisks/gen-oneline-customdata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import StringIO 6 | import sys 7 | 8 | def buildYMLFile(files): 9 | clusterYamlFile="""#cloud-config 10 | 11 | runcmd: 12 | - /opt/azure/workaround.sh 13 | 14 | write_files: 15 | %s 16 | """ 17 | writeFileBlock=""" - encoding: gzip 18 | content: !!binary | 19 | %s 20 | path: /opt/azure/%s 21 | permissions: "0744" 22 | """ 23 | filelines="" 24 | for encodeFile in files: 25 | # read the script file 26 | with open(encodeFile) as f: 27 | content = f.read() 28 | compressedbuffer=StringIO.StringIO() 29 | 30 | # gzip the script file 31 | with gzip.GzipFile(fileobj=compressedbuffer, mode='wb') as f: 32 | f.write(content) 33 | b64GzipStream=base64.b64encode(compressedbuffer.getvalue()) 34 | filelines=filelines+(writeFileBlock % (b64GzipStream,encodeFile)) 35 | 36 | return clusterYamlFile % (filelines) 37 | 38 | def convertToOneArmTemplateLine(clusterYamlFile): 39 | # remove the \r\n 40 | oneline="\\n".join(clusterYamlFile.split("\n")) 41 | oneline='\\"'.join(oneline.split('"')) 42 | return oneline 43 | 44 | def usage(): 45 | print 46 | print " usage: %s file1 file2 file3 . . ." % os.path.basename(sys.argv[0]) 47 | print 48 | print " builds a one line custom data entry for writing one or" 49 | print " more files to /opt/azure" 50 | 51 | if __name__ == "__main__": 52 | if len(sys.argv)==1: 53 | usage() 54 | sys.exit(1) 55 | 56 | files = sys.argv[1:] 57 | for file in files: 58 | if not os.path.exists(file): 59 | print "Error: file %s does not exist" 60 | sys.exit(2) 61 | 62 | # build the yml file for cluster 63 | yml = buildYMLFile(files) 64 | 65 | # convert yml file to one line 66 | oneline = convertToOneArmTemplateLine(yml) 67 | print '"customData": "[base64(\'%s\')]"' % (oneline) 68 | -------------------------------------------------------------------------------- /attachedDisks/gen-oneline-customdata.yaml.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import StringIO 6 | import sys 7 | 8 | def convertToOneArmTemplateLine(clusterYamlFile): 9 | # remove the \r\n 10 | oneline="\\n".join(clusterYamlFile.split("\n")) 11 | oneline='\\"'.join(oneline.split('"')) 12 | return oneline 13 | 14 | def usage(): 15 | print 16 | print " usage: %s file1" % os.path.basename(sys.argv[0]) 17 | print 18 | print " builds a one line custom data entry from the yaml file" 19 | print " more files to /opt/azure" 20 | 21 | if __name__ == "__main__": 22 | if len(sys.argv)!=2: 23 | usage() 24 | sys.exit(1) 25 | 26 | file = sys.argv[1] 27 | 28 | yml="" 29 | with open(file,'r') as f: 30 | yml = f.read() 31 | 32 | # convert yml file to one line 33 | oneline = convertToOneArmTemplateLine(yml) 34 | print '"customData": "[base64(\'%s\')]"' % (oneline) 35 | -------------------------------------------------------------------------------- /attachedDisks/workaround.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | DISK=/dev/sdc 4 | PARTITION=${DISK}1 5 | MOUNTPOINT=/var/lib/etcddisk 6 | udevadm settle 7 | mkdir -p $MOUNTPOINT 8 | mount | grep $MOUNTPOINT 9 | if [ $? -eq 0 ] 10 | then 11 | echo "disk is already mounted" 12 | exit 0 13 | fi 14 | # fill /etc/fstab 15 | grep "/dev/sdc1" /etc/fstab 16 | if [ $? -ne 0 ] 17 | then 18 | echo "$PARTITION $MOUNTPOINT auto defaults,nofail 0 2" >> /etc/fstab 19 | fi 20 | # check if partition exists 21 | ls $PARTITION 22 | if [ $? -ne 0 ] 23 | then 24 | # partition does not exist 25 | /sbin/sgdisk --new 1 $DISK 26 | /sbin/mkfs.ext4 $PARTITION -L etcd_disk -F -E lazy_itable_init=1,lazy_journal_init=1 27 | fi 28 | mount $MOUNTPOINT -------------------------------------------------------------------------------- /availabilitySet/README.md: -------------------------------------------------------------------------------- 1 | # A resource from each of Storage, Network, and Compute 2 | 3 | This verifies a network, storage, and compute resource can be created. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /availabilitySet/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { }, 5 | "variables": { }, 6 | "resources": [ 7 | { 8 | "type": "Microsoft.Compute/availabilitySets", 9 | "name": "avail-set", 10 | "apiVersion": "2015-06-15", 11 | "location": "[resourceGroup().location]", 12 | "properties": {} 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /availabilitySet/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $deployName="anhowe0304asc" 3 | $RGName=$deployName 4 | $locName="Southcentral US" 5 | $templateFile= "azuredeploy.json" 6 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 7 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateFile $templateFile 8 | -------------------------------------------------------------------------------- /bool-inline/README.md: -------------------------------------------------------------------------------- 1 | # Demonstratre concatenation 2 | 3 | This Microsoft Azure template demonstrates concatenation via an inline template. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /bool-inline/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "sampleString": { 6 | "type": "string", 7 | "defaultValue": "hello", 8 | "metadata": { 9 | "description": "This is a sample string" 10 | } 11 | }, 12 | "sampleInt": { 13 | "type": "int", 14 | "defaultValue": 5, 15 | "metadata": { 16 | "description": "This is a sample int" 17 | } 18 | }, 19 | "sampleBool": { 20 | "type": "bool", 21 | "defaultValue": false, 22 | "metadata": { 23 | "description": "This is a sample bool" 24 | } 25 | } 26 | }, 27 | "variables": { 28 | }, 29 | "resources": [ 30 | { 31 | "apiVersion": "2015-01-01", 32 | "type": "Microsoft.Resources/deployments", 33 | "name": "createVariables", 34 | "dependsOn": [], 35 | "properties": { 36 | "mode": "Incremental", 37 | "templateLink": { 38 | "uri": "https://raw.githubusercontent.com/anhowe/scratch/master/bool-inline/inline.json", 39 | "contentVersion": "1.0.0.0" 40 | }, 41 | "parameters": { 42 | "sampleString": { 43 | "value": "[parameters('sampleString')]" 44 | }, 45 | "sampleInt": { 46 | "value": "[parameters('sampleInt')]" 47 | }, 48 | "sampleBool": { 49 | "value": "[parameters('sampleBool')]" 50 | } 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /bool-inline/inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json# ", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "sampleString": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "This is a sample string" 9 | } 10 | }, 11 | "sampleInt": { 12 | "type": "int", 13 | "metadata": { 14 | "description": "This is a sample int" 15 | } 16 | }, 17 | "sampleBool": { 18 | "type": "bool", 19 | "metadata": { 20 | "description": "This is a sample bool" 21 | } 22 | } 23 | }, 24 | "variables": { 25 | "concatString": "[concat('samplestring',parameters('sampleString'))]", 26 | "concatInt": "[concat('sampleint', parameters('sampleInt'))]", 27 | "sampleBool1": "[parameters('sampleBool')]" 28 | }, 29 | "resources": [ 30 | { 31 | "type": "Microsoft.Storage/storageAccounts", 32 | "name": "anhowe0902oms", 33 | "apiVersion": "2015-05-01-preview", 34 | "location": "Standard_GRS", 35 | "properties": { 36 | "accountType": "[variables('storageAccountType')]" 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /bool/README.md: -------------------------------------------------------------------------------- 1 | # Demonstratre concatenation 2 | 3 | This Microsoft Azure template demonstrates concatenation. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /bool/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "sampleString": { 6 | "type": "string", 7 | "defaultValue": "hello", 8 | "metadata": { 9 | "description": "This is a sample string" 10 | } 11 | }, 12 | "sampleInt": { 13 | "type": "int", 14 | "defaultValue": 5, 15 | "metadata": { 16 | "description": "This is a sample int" 17 | } 18 | }, 19 | "sampleBool": { 20 | "type": "bool", 21 | "defaultValue": false, 22 | "metadata": { 23 | "description": "This is a sample bool" 24 | } 25 | } 26 | }, 27 | "variables": { 28 | "concatString": "[concat('samplestring',parameters('sampleString'))]", 29 | "concatInt": "[concat('sampleint', parameters('sampleInt'))]", 30 | "concatBool": "[concat('samplebool', parameters('sampleBool'))]" 31 | }, 32 | "resources": [ 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /cservice/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminUsername": { 6 | "type": "string", 7 | "defaultValue": "azureuser", 8 | "metadata": { 9 | "description": "User name for the Virtual Machine." 10 | } 11 | }, 12 | "adminPassword": { 13 | "type": "securestring", 14 | "metadata": { 15 | "description": "Password for the Virtual Machine." 16 | } 17 | }, 18 | "jumpboxOS": { 19 | "type": "string", 20 | "defaultValue": "Windows", 21 | "allowedValues": [ 22 | "Windows", 23 | "Linux" 24 | ], 25 | "metadata": { 26 | "description": "The size of the Virtual Machine. Allowable machine values are 1 core (A1), 2 core (A2), 4 core (A3), 8 core (A4)." 27 | } 28 | }, 29 | "jumpboxEndpointDNSNamePrefix": { 30 | "type": "string", 31 | "metadata": { 32 | "description": "Sets the Domain name label for the jumpbox. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 33 | } 34 | }, 35 | "managementEndpointDNSNamePrefix": { 36 | "type": "string", 37 | "metadata": { 38 | "description": "Sets the Domain name label for the container service. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 39 | } 40 | }, 41 | "applicationEndpointDNSNamePrefix": { 42 | "type": "string", 43 | "metadata": { 44 | "description": "Sets the Domain name label for the application. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 45 | } 46 | }, 47 | "agentCount": { 48 | "type": "int", 49 | "defaultValue": 1, 50 | "metadata": { 51 | "description": "The number of Mesos agents for the cluster. This value can be from 1 to 100" 52 | }, 53 | "allowedValues": [ 54 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 55 | 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 56 | 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60, 57 | 61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 58 | 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 59 | ] 60 | }, 61 | "masterCount": { 62 | "type": "int", 63 | "defaultValue": 1, 64 | "allowedValues": [ 65 | 1, 66 | 3, 67 | 5 68 | ], 69 | "metadata": { 70 | "description": "The number of Mesos masters for the cluster." 71 | } 72 | }, 73 | "agentVMSize": { 74 | "type": "string", 75 | "defaultValue": "Standard_A1", 76 | "allowedValues": [ 77 | "Standard_A1", 78 | "Standard_A2", 79 | "Standard_A3", 80 | "Standard_A4" 81 | ], 82 | "metadata": { 83 | "description": "The size of the Virtual Machine. Allowable machine values are 1 core (A1), 2 core (A2), 4 core (A3), 8 core (A4)." 84 | } 85 | }, 86 | "sshRSAPublicKey": { 87 | "type": "string", 88 | "defaultValue": "disabled", 89 | "metadata": { 90 | "description": "Configure all linux machines with the SSH rsa public key string. Use 'disabled' to not configure access with SSH rsa public key." 91 | } 92 | } 93 | }, 94 | "variables": {}, 95 | "resources": [ 96 | { 97 | "apiVersion": "2015-11-01-preview", 98 | "type": "Microsoft.ContainerService/containerServices", 99 | "location": "[resourceGroup().location]", 100 | "name":"[concat('containerservice-',resourceGroup().name)]", 101 | "properties": { 102 | "orchestratorProfile": { 103 | "orchestratorType": "Mesos" 104 | }, 105 | "masterProfile": { 106 | "count": "[parameters('masterCount')]", 107 | "dnsPrefix": "[parameters('managementEndpointDNSNamePrefix')]" 108 | }, 109 | "agentPoolProfiles": [ 110 | { 111 | "name": "agentpools", 112 | "count": "[parameters('agentCount')]", 113 | "vmSize": "[parameters('agentVMSize')]", 114 | "dnsPrefix": "[parameters('applicationEndpointDNSNamePrefix')]" 115 | } 116 | ], 117 | "osProfile": { 118 | "adminUsername": "[parameters('adminUsername')]", 119 | "adminPassword": "[parameters('adminPassword')]", 120 | "linuxConfiguration": { 121 | "ssh": { 122 | "publicKeys": [ 123 | { 124 | "keyData": "[parameters('sshRSAPublicKey')]" 125 | } 126 | ] 127 | } 128 | } 129 | }, 130 | "jumpboxProfile": { 131 | "osType": "[parameters('jumpboxOS')]", 132 | "dnsPrefix": "[parameters('jumpboxEndpointDNSNamePrefix')]" 133 | } 134 | } 135 | } 136 | ] 137 | } 138 | -------------------------------------------------------------------------------- /cservice/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "adminUsername": { 3 | "value": "azureuser" 4 | }, 5 | "adminPassword": { 6 | "value": "password1234$" 7 | }, 8 | "jumpboxEndpointDNSNamePrefix": { 9 | "value": "Windows" 10 | }, 11 | "jumpboxEndpointDNSNamePrefix": { 12 | "value": "anhowe1116b" 13 | }, 14 | "managementEndpointDNSNamePrefix": { 15 | "value": "anhowemgmt1116b" 16 | }, 17 | "applicationEndpointDNSNamePrefix": { 18 | "value": "anhoweapp1116b" 19 | }, 20 | "agentCount": { 21 | "value": 3 22 | }, 23 | "masterCount": { 24 | "value": 3 25 | }, 26 | "agentVMSize" : { 27 | "value": "Standard_A1" 28 | }, 29 | "sshRSAPublicKey": { 30 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cservice/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $deployName="anhowe1116b" 2 | $RGName=$deployName 3 | $locName="Japan East" 4 | $templateFile= "azuredeploy.json" 5 | $templateParameterFile= "azuredeploy.parameters.json" 6 | Switch-AzureMode -Name AzureResourceManager 7 | New-AzureResourceGroup -Name $RGName -Location $locName -Force 8 | 9 | echo New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateFile $templateFile 10 | New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 11 | -------------------------------------------------------------------------------- /cservice/images/chronos-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/chronos-docker.png -------------------------------------------------------------------------------- /cservice/images/chronos-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/chronos-ui.png -------------------------------------------------------------------------------- /cservice/images/chronos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/chronos.png -------------------------------------------------------------------------------- /cservice/images/completed-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/completed-hello-world.png -------------------------------------------------------------------------------- /cservice/images/dockercomposescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/dockercomposescale.png -------------------------------------------------------------------------------- /cservice/images/dockerinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/dockerinfo.png -------------------------------------------------------------------------------- /cservice/images/dockerps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/dockerps.png -------------------------------------------------------------------------------- /cservice/images/marathon-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/marathon-docker.png -------------------------------------------------------------------------------- /cservice/images/marathon-newapp-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/marathon-newapp-status.png -------------------------------------------------------------------------------- /cservice/images/marathon-newapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/marathon-newapp.png -------------------------------------------------------------------------------- /cservice/images/mesos-agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/mesos-agents.png -------------------------------------------------------------------------------- /cservice/images/mesos-completed-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/mesos-completed-tasks.png -------------------------------------------------------------------------------- /cservice/images/mesos-frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/mesos-frameworks.png -------------------------------------------------------------------------------- /cservice/images/mesos-webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/mesos-webui.png -------------------------------------------------------------------------------- /cservice/images/mesos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/mesos.png -------------------------------------------------------------------------------- /cservice/images/portal-publicipaddresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/portal-publicipaddresses.png -------------------------------------------------------------------------------- /cservice/images/portal-resourcegroups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/portal-resourcegroups.png -------------------------------------------------------------------------------- /cservice/images/swarm-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/swarm-framework.png -------------------------------------------------------------------------------- /cservice/images/swarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/swarm.png -------------------------------------------------------------------------------- /cservice/images/swarmbrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/cservice/images/swarmbrowser.png -------------------------------------------------------------------------------- /cservice/swarm.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminUsername": { 6 | "type": "string", 7 | "defaultValue": "azureuser", 8 | "metadata": { 9 | "description": "User name for the Virtual Machine." 10 | } 11 | }, 12 | "managementEndpointDNSNamePrefix": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "Sets the Domain name label for the container service. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 16 | } 17 | }, 18 | "applicationEndpointDNSNamePrefix": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Sets the Domain name label for the application. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address." 22 | } 23 | }, 24 | "agentCount": { 25 | "type": "int", 26 | "defaultValue": 1, 27 | "metadata": { 28 | "description": "The number of Mesos agents for the cluster. This value can be from 1 to 100" 29 | }, 30 | "allowedValues": [ 31 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 32 | 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 33 | 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60, 34 | 61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, 35 | 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 36 | ] 37 | }, 38 | "masterCount": { 39 | "type": "int", 40 | "defaultValue": 1, 41 | "allowedValues": [ 42 | 1, 43 | 3, 44 | 5 45 | ], 46 | "metadata": { 47 | "description": "The number of Mesos masters for the cluster." 48 | } 49 | }, 50 | "agentVMSize": { 51 | "type": "string", 52 | "defaultValue": "Standard_A1", 53 | "allowedValues": [ 54 | "Standard_A1", 55 | "Standard_A2", 56 | "Standard_A3", 57 | "Standard_A4" 58 | ], 59 | "metadata": { 60 | "description": "The size of the Virtual Machine. Allowable machine values are 1 core (A1), 2 core (A2), 4 core (A3), 8 core (A4)." 61 | } 62 | }, 63 | "sshRSAPublicKey": { 64 | "type": "string", 65 | "defaultValue": "disabled", 66 | "metadata": { 67 | "description": "Configure all linux machines with the SSH rsa public key string. Use 'disabled' to not configure access with SSH rsa public key." 68 | } 69 | } 70 | }, 71 | "variables": {}, 72 | "resources": [ 73 | { 74 | "apiVersion": "2015-11-01-preview", 75 | "type": "Microsoft.ContainerService/containerServices", 76 | "location": "[resourceGroup().location]", 77 | "name":"[concat('containerservice-',resourceGroup().name)]", 78 | "properties": { 79 | "orchestratorProfile": { 80 | "orchestratorType": "Swarm" 81 | }, 82 | "masterProfile": { 83 | "count": "[parameters('masterCount')]", 84 | "dnsPrefix": "[parameters('managementEndpointDNSNamePrefix')]" 85 | }, 86 | "agentPoolProfiles": [ 87 | { 88 | "name": "agentpools", 89 | "count": "[parameters('agentCount')]", 90 | "vmSize": "[parameters('agentVMSize')]", 91 | "dnsPrefix": "[parameters('applicationEndpointDNSNamePrefix')]" 92 | } 93 | ], 94 | "osProfile": { 95 | "adminUsername": "[parameters('adminUsername')]", 96 | "linuxConfiguration": { 97 | "ssh": { 98 | "publicKeys": [ 99 | { 100 | "keyData": "[parameters('sshRSAPublicKey')]" 101 | } 102 | ] 103 | } 104 | } 105 | } 106 | } 107 | } 108 | ] 109 | } 110 | -------------------------------------------------------------------------------- /dynamicNATRules/README.md: -------------------------------------------------------------------------------- 1 | # Dynamic NAT Rules 2 | 3 | This Microsoft Azure template demonstrates dynamic NAT rules. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dynamicNATRules/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "dnsName": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Unique DNS Name prefix for the cluster." 9 | } 10 | } 11 | }, 12 | "variables": { 13 | "managementPublicIPAddrName": "lb-nodes-ip", 14 | "virtualNetworkName": "vnet", 15 | "subnetNameNode": "subnet-nodes", 16 | "addressPrefix":"10.0.0.0/16", 17 | "subnetPrefixNode": "10.0.2.0/24", 18 | "subnetRefNode": "[concat(resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName')),'/subnets/',variables('subnetNameNode'))]", 19 | "nsgName": "node-nsg", 20 | "nsgID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('nsgName'))]", 21 | "nodesLbName": "nodes", 22 | "nodesLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('nodesLbName'))]", 23 | "nodesLbIPConfigName": "NodesLBFrontEnd", 24 | "nodesLbIPConfigID": "[concat(variables('nodesLbID'),'/frontendIPConfigurations/', variables('nodesLbIPConfigName'))]", 25 | "nodesLbBackendPoolName": "node-pool", 26 | "agentNodeCount": 3, 27 | "vmNameNode": "agent1" 28 | }, 29 | "resources": [ 30 | { 31 | "apiVersion": "2015-06-15", 32 | "type": "Microsoft.Network/publicIPAddresses", 33 | "name": "[variables('managementPublicIPAddrName')]", 34 | "location": "[resourceGroup().location]", 35 | "properties": { 36 | "publicIPAllocationMethod": "Dynamic", 37 | "dnsSettings": { 38 | "domainNameLabel": "[parameters('dnsName')]" 39 | } 40 | } 41 | }, 42 | { 43 | "apiVersion": "2015-06-15", 44 | "type": "Microsoft.Network/virtualNetworks", 45 | "name": "[variables('virtualNetworkName')]", 46 | "location": "[resourceGroup().location]", 47 | "dependsOn": [ 48 | "[variables('nsgID')]" 49 | ], 50 | "properties": { 51 | "addressSpace": { 52 | "addressPrefixes": [ 53 | "[variables('addressPrefix')]" 54 | ] 55 | }, 56 | "subnets": [ 57 | { 58 | "name": "[variables('subnetNameNode')]", 59 | "properties": { 60 | "addressPrefix": "[variables('subnetPrefixNode')]", 61 | "networkSecurityGroup": { 62 | "id": "[variables('nsgID')]" 63 | } 64 | } 65 | } 66 | ] 67 | } 68 | }, 69 | { 70 | "apiVersion": "2015-06-15", 71 | "type": "Microsoft.Network/networkSecurityGroups", 72 | "name": "[variables('nsgName')]", 73 | "location": "[resourceGroup().location]", 74 | "properties": { 75 | "securityRules": [ 76 | { 77 | "name": "ssh", 78 | "properties": { 79 | "description": "SSH", 80 | "protocol": "Tcp", 81 | "sourcePortRange": "*", 82 | "destinationPortRange": "22", 83 | "sourceAddressPrefix": "*", 84 | "destinationAddressPrefix": "*", 85 | "access": "Allow", 86 | "priority": 200, 87 | "direction": "Inbound" 88 | } 89 | } 90 | ] 91 | } 92 | }, 93 | { 94 | "apiVersion": "2015-06-15", 95 | "type": "Microsoft.Network/networkInterfaces", 96 | "name": "[concat(variables('vmNameNode'), copyIndex(1), '-nic')]", 97 | "location": "[resourceGroup().location]", 98 | "copy": { 99 | "name": "nicLoopNode", 100 | "count": "[variables('agentNodeCount')]" 101 | }, 102 | "dependsOn": [ 103 | "[concat('Microsoft.Network/loadBalancers/', variables('nodesLbName'))]", 104 | "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", 105 | "[concat('Microsoft.Network/loadBalancers/', variables('nodesLbName'), '/inboundNatRules/', 'SSH-', variables('vmNameNode'), copyIndex(1))]" 106 | ], 107 | "properties": { 108 | "ipConfigurations": [ 109 | { 110 | "name": "ipConfigNode", 111 | "properties": { 112 | "privateIPAllocationMethod": "Static", 113 | "privateIPAddress": "[concat('10.0.2.', copyIndex(51))]", 114 | "subnet": { 115 | "id": "[variables('subnetRefNode')]" 116 | }, 117 | "loadBalancerBackendAddressPools": [ 118 | { 119 | "id": "[concat(variables('nodesLbID'), '/backendAddressPools/', variables('nodesLbBackendPoolName'))]" 120 | } 121 | ], 122 | "loadBalancerInboundNatRules": [ 123 | { 124 | "id": "[concat(variables('nodesLbID'),'/inboundNatRules/SSH-',variables('vmNameNode'),copyindex(1))]" 125 | } 126 | ] 127 | } 128 | } 129 | ] 130 | } 131 | }, 132 | { 133 | "apiVersion": "2015-06-15", 134 | "name": "[variables('nodesLbName')]", 135 | "type": "Microsoft.Network/loadBalancers", 136 | "location": "[resourceGroup().location]", 137 | "dependsOn": [ 138 | "[concat('Microsoft.Network/publicIPAddresses/', variables('managementPublicIPAddrName'))]" 139 | ], 140 | "properties": { 141 | "frontendIPConfigurations": [ 142 | { 143 | "name": "[variables('nodesLbIPConfigName')]", 144 | "properties": { 145 | "publicIPAddress": { 146 | "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('managementPublicIPAddrName'))]" 147 | } 148 | } 149 | } 150 | ], 151 | "backendAddressPools": [ 152 | { 153 | "name": "[variables('nodesLbBackendPoolName')]" 154 | } 155 | ], 156 | "probes": [], 157 | "loadBalancingRules": [] 158 | } 159 | }, 160 | { 161 | "apiVersion": "2015-06-15", 162 | "type": "Microsoft.Network/loadBalancers/inboundNatRules", 163 | "name": "[concat(variables('nodesLbName'), '/', 'SSH-', variables('vmNameNode'), copyIndex(1))]", 164 | "location": "[resourceGroup().location]", 165 | "copy": { 166 | "name": "lbLoopNode", 167 | "count": "[variables('agentNodeCount')]" 168 | }, 169 | "dependsOn": [ 170 | "[concat('Microsoft.Network/loadBalancers/', variables('nodesLbName'))]" 171 | ], 172 | "properties": { 173 | "frontendIPConfiguration": { 174 | "id": "[variables('nodesLbIPConfigID')]" 175 | }, 176 | "protocol": "tcp", 177 | "frontendPort": "[copyIndex(1)]", 178 | "backendPort": 22, 179 | "enableFloatingIP": false 180 | } 181 | } 182 | ] 183 | } 184 | -------------------------------------------------------------------------------- /dynamicNATRules/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "dnsName": { 6 | "value": "containerservice-anhowe920d" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /exerciseStgNetCmp/README.md: -------------------------------------------------------------------------------- 1 | # A resource from each of Storage, Network, and Compute 2 | 3 | This verifies a network, storage, and compute resource can be created. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /exerciseStgNetCmp/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "newStorageAccountName": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Unique name for a new storage account where the VM disks will be stored." 9 | } 10 | }, 11 | "dnsName": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Unique DNS Name prefix for the cluster." 15 | } 16 | } 17 | }, 18 | "variables": { }, 19 | "resources": [ 20 | { 21 | "type": "Microsoft.Storage/storageAccounts", 22 | "name": "[parameters('newStorageAccountName')]", 23 | "apiVersion": "2015-05-01-preview", 24 | "location": "[resourceGroup().location]", 25 | "properties": { 26 | "accountType": "Standard_LRS" 27 | } 28 | }, 29 | { 30 | "type": "Microsoft.Compute/availabilitySets", 31 | "name": "avail-set", 32 | "apiVersion": "2015-06-15", 33 | "location": "[resourceGroup().location]", 34 | "properties": {} 35 | }, 36 | { 37 | "apiVersion": "2015-06-15", 38 | "type": "Microsoft.Network/publicIPAddresses", 39 | "name": "lb-nodes-ip", 40 | "location": "[resourceGroup().location]", 41 | "properties": { 42 | "publicIPAllocationMethod": "Dynamic", 43 | "dnsSettings": { 44 | "domainNameLabel": "[parameters('dnsName')]" 45 | } 46 | } 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /exerciseStgNetCmp/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "newStorageAccountName": { 6 | "value": "samplestg920f" 7 | }, 8 | "dnsName": { 9 | "value": "sampledns920f" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /files-nas/README.md: -------------------------------------------------------------------------------- 1 | # Moved 2 | 3 | Moved here: https://github.com/anhowe/azure-util/tree/master/nfsfiler-storagebackend -------------------------------------------------------------------------------- /fuse-nas/README.md: -------------------------------------------------------------------------------- 1 | # Moved 2 | 3 | Moved here: https://github.com/anhowe/azure-util/tree/master/nfsfiler-storagebackend -------------------------------------------------------------------------------- /gaexercise/logfileexists/README.md: -------------------------------------------------------------------------------- 1 | # Demonstratre concatenation 2 | 3 | This Microsoft Azure template demonstrates that the log file exists. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /gaexercise/nologfileexists/README.md: -------------------------------------------------------------------------------- 1 | # Demonstratre concatenation 2 | 3 | This Microsoft Azure template demonstrates that the log file exists. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ignitedemo/avere-cache.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobId": { 3 | "value": "avere-cache-cold" 4 | }, 5 | "poolId": { 6 | "value": "pool1" 7 | }, 8 | "adminUsername": { 9 | "value": "azureuser" 10 | }, 11 | "frameStart": { 12 | "value": 0 13 | }, 14 | "frameEnd": { 15 | "value": 499 16 | }, 17 | "frameStep": { 18 | "value": 1 19 | }, 20 | "mayaProjectPath": { 21 | "value": "/nfs/southeastasiavfxt/scenes/autodeskWallOfDScene" 22 | }, 23 | "sceneFile": { 24 | "value": "/nfs/southeastasiavfxt/scenes/autodeskWallOfDScene/scenes/SEQ001/SHOT001/anim/versions/SEQ001_SHOT001_anim_v010_Imported.ma" 25 | }, 26 | "imagesOutputBasePath": { 27 | "value": "/nfs/southeastasiavfxt/images" 28 | }, 29 | "renderScriptPath": { 30 | "value": "/nfs/southeastasiavfxt/src/render8gb.sh" 31 | }, 32 | "debugPath": { 33 | "value": "/nfs/southeastasiavfxt/debug" 34 | }, 35 | "additionalFlags": { 36 | "value": " -fnc name.#.ext " 37 | } 38 | } -------------------------------------------------------------------------------- /ignitedemo/avere-sustainedload.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobId": { 3 | "value": "avere-sustained-load" 4 | }, 5 | "poolId": { 6 | "value": "pool1" 7 | }, 8 | "adminUsername": { 9 | "value": "azureuser" 10 | }, 11 | "frameStart": { 12 | "value": 0 13 | }, 14 | "frameEnd": { 15 | "value": 4999 16 | }, 17 | "frameStep": { 18 | "value": 1 19 | }, 20 | "mayaProjectPath": { 21 | "value": "/nfs/southeastasiavfxt/scenes/autodeskWallOfDScene" 22 | }, 23 | "sceneFile": { 24 | "value": "/nfs/southeastasiavfxt/scenes/autodeskWallOfDScene/scenes/SEQ001/SHOT001/anim/versions/SEQ001_SHOT001_anim_v010_Imported.ma" 25 | }, 26 | "imagesOutputBasePath": { 27 | "value": "/nfs/southeastasiavfxt/images" 28 | }, 29 | "renderScriptPath": { 30 | "value": "/nfs/southeastasiavfxt/src/render8gb-sustained.sh" 31 | }, 32 | "debugPath": { 33 | "value": "/nfs/southeastasiavfxt/debug" 34 | }, 35 | "additionalFlags": { 36 | "value": " -fnc name.#.ext " 37 | } 38 | } -------------------------------------------------------------------------------- /ignitedemo/direct-nocache.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobId": { 3 | "value": "direct-nocache" 4 | }, 5 | "poolId": { 6 | "value": "pool1" 7 | }, 8 | "adminUsername": { 9 | "value": "azureuser" 10 | }, 11 | "frameStart": { 12 | "value": 0 13 | }, 14 | "frameEnd": { 15 | "value": 499 16 | }, 17 | "frameStep": { 18 | "value": 1 19 | }, 20 | "mayaProjectPath": { 21 | "value": "/nfs/southeastasia/scenes/autodeskWallOfDScene" 22 | }, 23 | "sceneFile": { 24 | "value": "/nfs/southeastasia/scenes/autodeskWallOfDScene/scenes/SEQ001/SHOT001/anim/versions/SEQ001_SHOT001_anim_v010_Imported.ma" 25 | }, 26 | "imagesOutputBasePath": { 27 | "value": "/nfs/southeastasia/images" 28 | }, 29 | "renderScriptPath": { 30 | "value": "/nfs/southeastasia/src/render8gb.sh" 31 | }, 32 | "debugPath": { 33 | "value": "/nfs/southeastasia/debug" 34 | }, 35 | "additionalFlags": { 36 | "value": " -fnc name.#.ext " 37 | } 38 | } -------------------------------------------------------------------------------- /ignitedemo/job.json: -------------------------------------------------------------------------------- 1 | { 2 | "templateMetadata": { 3 | "description": "Application template for working with Maya and Arnold on CentOS." 4 | }, 5 | "parameters": { 6 | "jobId": { 7 | "type": "string", 8 | "metadata": { 9 | "description": "The unique name of the job." 10 | } 11 | }, 12 | "poolId": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "The ID of the pool where the job runs." 16 | } 17 | }, 18 | "adminUsername": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Admin username on the batch VMs." 22 | } 23 | }, 24 | "frameStart": { 25 | "type": "int", 26 | "defaultValue": 1, 27 | "metadata": { 28 | "description": "Index of the first frame to render." 29 | } 30 | }, 31 | "frameEnd": { 32 | "type": "int", 33 | "defaultValue": 1, 34 | "metadata": { 35 | "description": "Index of the last frame to render." 36 | } 37 | }, 38 | "frameStep": { 39 | "type": "int", 40 | "defaultValue": 1, 41 | "metadata": { 42 | "description": "Incremental step in frame sequeunce." 43 | } 44 | }, 45 | "maxTasksPerNode": { 46 | "type": "int", 47 | "defaultValue": 1, 48 | "metadata": { 49 | "description": "The number of tasks per node." 50 | } 51 | }, 52 | "mayaProjectPath": { 53 | "type": "string", 54 | "metadata": { 55 | "description": "The maya project path used to load the scene file." 56 | } 57 | }, 58 | "sceneFile": { 59 | "type": "string", 60 | "metadata": { 61 | "description": "The path to the Maya scene file." 62 | } 63 | }, 64 | "imagesOutputBasePath": { 65 | "type": "string", 66 | "metadata": { 67 | "description": "The rendered frames output base directory." 68 | } 69 | }, 70 | "renderScriptPath": { 71 | "type": "string", 72 | "metadata": { 73 | "description": "The render script location." 74 | } 75 | }, 76 | "debugPath": { 77 | "type": "string", 78 | "metadata": { 79 | "description": "The debug path location." 80 | } 81 | }, 82 | "additionalFlags": { 83 | "type": "string", 84 | "defaultValue": " ", 85 | "metadata": { 86 | "description": "Any additional flags to pass to the renderer. Example: -of png" 87 | } 88 | } 89 | }, 90 | "job": { 91 | "type": "Microsoft.Batch/batchAccounts/jobs", 92 | "properties": { 93 | "id": "[parameters('jobId')]", 94 | "poolInfo": { 95 | "poolId": "[parameters('poolId')]" 96 | }, 97 | "taskFactory": { 98 | "type": "parametricSweep", 99 | "parameterSets": [ 100 | { 101 | "start": "[parameters('frameStart')]", 102 | "end": "[parameters('frameEnd')]", 103 | "step": "[parameters('frameStep')]" 104 | } 105 | ], 106 | "repeatTask": { 107 | "displayName": "Frame {0}", 108 | "userIdentity": { 109 | "userName": "[parameters('adminUsername')]" 110 | }, 111 | "commandLine": "/bin/bash -c '/bin/bash [parameters('renderScriptPath')] ; err=$? ; exit $err'", 112 | "constraints": { 113 | "maxTaskRetryCount":5 114 | }, 115 | "environmentSettings": [ 116 | { 117 | "name": "FLEXLM_TIMEOUT", 118 | "value": "5000000" 119 | }, 120 | { 121 | "name": "FRAME_START", 122 | "value": "{0}" 123 | }, 124 | { 125 | "name": "FRAME_END", 126 | "value": "{0}" 127 | }, 128 | { 129 | "name": "MAYA_PROJECT_PATH", 130 | "value": "[parameters('mayaProjectPath')]" 131 | }, 132 | { 133 | "name": "SCENE_FILE", 134 | "value": "[parameters('sceneFile')]" 135 | }, 136 | { 137 | "name": "IMAGES_OUTPUT_BASE_PATH", 138 | "value": "[parameters('imagesOutputBasePath')]" 139 | }, 140 | { 141 | "name": "DEBUG_PATH", 142 | "value": "[parameters('debugPath')]" 143 | }, 144 | { 145 | "name": "ADDITIONAL_FLAGS", 146 | "value": "[parameters('additionalFlags')]" 147 | }, 148 | { 149 | "name": "MAX_TASKS_PER_NODE", 150 | "value": "[parameters('maxTasksPerNode')]" 151 | } 152 | ] 153 | } 154 | }, 155 | "onAllTasksComplete": "terminateJob" 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /linuxvm/README.md: -------------------------------------------------------------------------------- 1 | # Linux VM that takes SSH key 2 | 3 | This demonstrates a Linux VM that takes an SSH Key and Password. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /linuxvm/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "newStorageAccountName": { 6 | "value": "anhowe922a" 7 | }, 8 | "dnsNameForPublicIP": { 9 | "value": "anhowe922a" 10 | }, 11 | "adminPassword": { 12 | "value": "password1234$" 13 | }, 14 | "sshKeyData": { 15 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjsySy7dmJk5w1/WBxC1MfYRHvUycHscaC/LvmH2vIOOckP1/BVEBENrDzP+YC21EK65AS+3/sFdIHYaYu4Cc3tMYkS/7CQYN/mrkJH3HZ24HoLpReMsHfjE/EfYwkVOhms5KRMwbU+1NCdykBizTp1Aibv5hhPX9BYTaigoUOWMcWL9dszSBGz3KLQxGM7ddOe1dn7FC5HP6YBtYtd5g41KKxJDcIfoPQfLcPEPuZ1TpbHo6Y9+PCufx/JIT4E1l11sziGab3ZkdKjPM8Rj99r1hopuZq/FASx3yNbYtTDMhsAZQYL4npE6j/kPYJ/LJx+N3hz2j1/XtDsNHYBWHl azureuser@c1master1" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "windowsAdminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "jumpboxEndpointDNSNamePrefix": { 6 | "value": "anhowejb21h" 7 | }, 8 | "masterEndpointDNSNamePrefix": { 9 | "value": "anhowemgmt21h" 10 | }, 11 | "agentEndpointDNSNamePrefix": { 12 | "value": "anhoweapp21h" 13 | }, 14 | "agentCount": { 15 | "value": 3 16 | }, 17 | "masterCount": { 18 | "value": 3 19 | }, 20 | "agentVMSize" : { 21 | "value": "Standard_A2" 22 | }, 23 | "sshRSAPublicKey": { 24 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $deployName="anhowe21h" 3 | $RGName=$deployName 4 | $locName="SouthEast Asia" 5 | #$locName="East US2" 6 | #$locName="West US" 7 | #$locName="Brazil South" 8 | #$locName="Central US" 9 | #$locName="East US" 10 | #$locName="SouthCentral US" 11 | #$locName="Japan East" 12 | #$locName="Japan West" 13 | #$locName="West Europe" 14 | #$locName="North Europe" 15 | #$locName="NorthCentral US" 16 | #$templateFile= "mesos-cluster-with-linux-jumpbox.json" 17 | #$templateFile= "mesos-cluster-with-windows-jumpbox.json" 18 | #$templateFile= "mesos-cluster-with-no-jumpbox.json" 19 | $templateFile= "swarm-cluster-with-no-jumpbox.json" 20 | $templateParameterFile= "cluster.parameters.json" 21 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 22 | 23 | echo New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateFile $templateFile 24 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 25 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/chronos-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/chronos-docker.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/chronos-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/chronos-ui.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/chronos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/chronos.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/completed-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/completed-hello-world.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockercomposescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockercomposescale.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockercomposescalewindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockercomposescalewindows.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockerinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockerinfo.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockerinfowindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockerinfowindows.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockerps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockerps.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/dockerpswindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/dockerpswindows.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/marathon-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/marathon-docker.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/marathon-newapp-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/marathon-newapp-status.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/marathon-newapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/marathon-newapp.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/mesos-agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/mesos-agents.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/mesos-completed-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/mesos-completed-tasks.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/mesos-frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/mesos-frameworks.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/mesos-webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/mesos-webui.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/mesos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/mesos.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/portal-publicipaddresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/portal-publicipaddresses.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/portal-resourcegroups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/portal-resourcegroups.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/swarm-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/swarm-framework.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/swarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/swarm.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/swarmbrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/swarmbrowser.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/swarmbrowserwindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/swarmbrowserwindows.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/images/swarmwindows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon-vmss/images/swarmwindows.png -------------------------------------------------------------------------------- /mesos-marathon-vmss/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemDisplayName": "Create a Marathon/Chronos/Swarm enabled Mesos cluster", 3 | "description": "This template creates a Docker capable Apache Mesos cluster with Marathon, Chronos, and Swarm on a configurable number of nodes.", 4 | "summary": "Create a Docker capable Apache Mesos cluster on Microsoft Azure with the Marathon/Chronos/Swarm frameworks.", 5 | "githubUsername": "anhowe", 6 | "dateUpdated": "2015-10-26" 7 | } 8 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/base-template.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "windowsAdminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "jumpboxEndpointDNSNamePrefix": { 6 | "value": "swarmjb1122g" 7 | }, 8 | "masterEndpointDNSNamePrefix": { 9 | "value": "swarmmgmt1122g" 10 | }, 11 | "agentEndpointDNSNamePrefix": { 12 | "value": "swarmapp1122g" 13 | }, 14 | "agentCount": { 15 | "value": 3 16 | }, 17 | "masterCount": { 18 | "value": 3 19 | }, 20 | "agentVMSize" : { 21 | "value": "Standard_A1" 22 | }, 23 | "sshRSAPublicKey": { 24 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/fragment-linux-jumpbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "2015-06-15", 3 | "type": "Microsoft.Network/publicIPAddresses", 4 | "name": "[variables('jumpboxPublicIPAddressName')]", 5 | "location": "[resourceGroup().location]", 6 | "properties": { 7 | "publicIPAllocationMethod": "Dynamic", 8 | "dnsSettings": { 9 | "domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]" 10 | } 11 | } 12 | }, 13 | { 14 | "apiVersion": "2015-06-15", 15 | "type": "Microsoft.Network/networkSecurityGroups", 16 | "name": "[variables('jumpboxNSGName')]", 17 | "location": "[resourceGroup().location]", 18 | "properties": { 19 | "securityRules": [ 20 | { 21 | "name": "ssh", 22 | "properties": { 23 | "description": "Allow SSH", 24 | "protocol": "Tcp", 25 | "sourcePortRange": "*", 26 | "destinationPortRange": "22", 27 | "sourceAddressPrefix": "*", 28 | "destinationAddressPrefix": "*", 29 | "access": "Allow", 30 | "priority": 200, 31 | "direction": "Inbound" 32 | } 33 | } 34 | ] 35 | } 36 | }, 37 | { 38 | "apiVersion": "2015-06-15", 39 | "type": "Microsoft.Network/networkInterfaces", 40 | "name": "[concat(variables('jumpboxVMName'), '-nic')]", 41 | "location": "[resourceGroup().location]", 42 | "dependsOn": [ 43 | "[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]", 44 | "[variables('vnetID')]", 45 | "[variables('jumpboxNSGID')]" 46 | ], 47 | "properties": { 48 | "networkSecurityGroup": { 49 | "id": "[variables('jumpboxNSGID')]" 50 | }, 51 | "ipConfigurations": [ 52 | { 53 | "name": "ipConfig", 54 | "properties": { 55 | "privateIPAllocationMethod": "Static", 56 | "privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], variables('jumpboxAddr'))]", 57 | "publicIPAddress": { 58 | "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]" 59 | }, 60 | "subnet": { 61 | "id": "[variables('masterSubnetRef')]" 62 | } 63 | } 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "apiVersion": "2015-06-15", 70 | "type": "Microsoft.Compute/virtualMachines", 71 | "name": "[variables('jumpboxVMName')]", 72 | "location": "[resourceGroup().location]", 73 | "dependsOn": [ 74 | "[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]", 75 | "[variables('masterStorageAccountName')]" 76 | ], 77 | "properties": { 78 | "hardwareProfile": { 79 | "vmSize": "[variables('jumpboxVMSize')]" 80 | }, 81 | "osProfile": { 82 | "computername": "[variables('jumpboxVMName')]", 83 | "adminUsername": "[variables('adminUsername')]", 84 | "adminPassword": "[variables('adminPassword')]", 85 | "customData": "[base64('#jumpboxLinuxCustomDataInstallYaml')]", 86 | "linuxConfiguration": "[variables('linuxConfiguration')]" 87 | }, 88 | "storageProfile": { 89 | "imageReference": { 90 | "publisher": "[variables('linuxPublisher')]", 91 | "offer": "[variables('linuxOffer')]", 92 | "sku": "[variables('linuxSku')]", 93 | "version": "[variables('linuxVersion')]" 94 | }, 95 | "osDisk": { 96 | "name": "[concat(variables('jumpboxVMName'),'-osdisk')]", 97 | "vhd": { 98 | "uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]" 99 | }, 100 | "caching": "ReadWrite", 101 | "createOption": "FromImage" 102 | } 103 | }, 104 | "networkProfile": { 105 | "networkInterfaces": [ 106 | { 107 | "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]" 108 | } 109 | ] 110 | } 111 | } 112 | }, 113 | { 114 | "type": "Microsoft.Compute/virtualMachines/extensions", 115 | "name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]", 116 | "apiVersion": "2015-06-15", 117 | "location": "[resourceGroup().location]", 118 | "dependsOn": [ 119 | "[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]" 120 | ], 121 | "properties": { 122 | "publisher": "Microsoft.OSTCExtensions", 123 | "type": "CustomScriptForLinux", 124 | "typeHandlerVersion": "1.4", 125 | "settings": { 126 | "commandToExecute": "[variables('jumpboxLinuxCustomScript')]" 127 | } 128 | } 129 | }, 130 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/fragment-windows-agent-diagnostics-extension.json: -------------------------------------------------------------------------------- 1 | , 2 | { 3 | "name": "AzureDiagnostic", 4 | "properties": 5 | { 6 | "publisher": "Microsoft.Azure.Diagnostics", 7 | "type": "IaaSDiagnostics", 8 | "typeHandlerVersion": "1.5", 9 | "autoUpgradeMinorVersion": true, 10 | "settings": { 11 | "xmlCfg": "[base64(concat(variables('windowswadcfgxstart'), variables('agentVMNamePrefix'), variables('windowswadcfgxend')))]", 12 | "StorageAccount": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]" 13 | }, 14 | "protectedSettings": { 15 | "storageAccountName": "[variables(concat('diagnosticsStorageAccountName', '-', variables('enableVMDiagnostics')))]", 16 | "storageAccountKey": "[listKeys(variables('accountid'), variables('storageApiVersion')).key1]" 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/fragment-windows-jumpbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "2015-06-15", 3 | "type": "Microsoft.Network/publicIPAddresses", 4 | "name": "[variables('jumpboxPublicIPAddressName')]", 5 | "location": "[resourceGroup().location]", 6 | "properties": { 7 | "publicIPAllocationMethod": "Dynamic", 8 | "dnsSettings": { 9 | "domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]" 10 | } 11 | } 12 | }, 13 | { 14 | "apiVersion": "2015-06-15", 15 | "type": "Microsoft.Network/networkSecurityGroups", 16 | "name": "[variables('jumpboxNSGName')]", 17 | "location": "[resourceGroup().location]", 18 | "properties": { 19 | "securityRules": [ 20 | { 21 | "name": "ssh", 22 | "properties": { 23 | "description": "Allow RDP", 24 | "protocol": "Tcp", 25 | "sourcePortRange": "*", 26 | "destinationPortRange": "3389", 27 | "sourceAddressPrefix": "*", 28 | "destinationAddressPrefix": "*", 29 | "access": "Allow", 30 | "priority": 200, 31 | "direction": "Inbound" 32 | } 33 | } 34 | ] 35 | } 36 | }, 37 | { 38 | "apiVersion": "2015-06-15", 39 | "type": "Microsoft.Network/networkInterfaces", 40 | "name": "[concat(variables('jumpboxVMName'), '-nic')]", 41 | "location": "[resourceGroup().location]", 42 | "dependsOn": [ 43 | "[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]", 44 | "[variables('vnetID')]", 45 | "[variables('jumpboxNSGID')]" 46 | ], 47 | "properties": { 48 | "networkSecurityGroup": { 49 | "id": "[variables('jumpboxNSGID')]" 50 | }, 51 | "ipConfigurations": [ 52 | { 53 | "name": "ipConfig", 54 | "properties": { 55 | "privateIPAllocationMethod": "Static", 56 | "privateIPAddress": "[concat(split(variables('masterAddressPrefix'),'0/24')[0], variables('jumpboxAddr'))]", 57 | "publicIPAddress": { 58 | "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]" 59 | }, 60 | "subnet": { 61 | "id": "[variables('masterSubnetRef')]" 62 | } 63 | } 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "apiVersion": "2015-06-15", 70 | "type": "Microsoft.Compute/virtualMachines", 71 | "name": "[variables('jumpboxVMName')]", 72 | "location": "[resourceGroup().location]", 73 | "dependsOn": [ 74 | "[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]", 75 | "[variables('masterStorageAccountName')]" 76 | ], 77 | "properties": { 78 | "hardwareProfile": { 79 | "vmSize": "[variables('jumpboxVMSize')]" 80 | }, 81 | "osProfile": { 82 | "computername": "[variables('jumpboxVMName')]", 83 | "adminUsername": "[variables('windowsAdminUsername')]", 84 | "adminPassword": "[variables('windowsAdminPassword')]" 85 | }, 86 | "storageProfile": { 87 | "imageReference": { 88 | "publisher": "[variables('windowsJumpboxPublisher')]", 89 | "offer": "[variables('windowsJumpboxOffer')]", 90 | "sku": "[variables('windowsJumpboxSku')]", 91 | "version": "latest" 92 | }, 93 | "osDisk": { 94 | "name": "[concat(variables('jumpboxVMName'),'-osdisk')]", 95 | "vhd": { 96 | "uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]" 97 | }, 98 | "caching": "ReadWrite", 99 | "createOption": "FromImage" 100 | } 101 | }, 102 | "networkProfile": { 103 | "networkInterfaces": [ 104 | { 105 | "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]" 106 | } 107 | ] 108 | } 109 | } 110 | }, 111 | { 112 | "type": "Microsoft.Compute/virtualMachines/extensions", 113 | "name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]", 114 | "apiVersion": "2015-06-15", 115 | "location": "[resourceGroup().location]", 116 | "dependsOn": [ 117 | "[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]" 118 | ], 119 | "properties": { 120 | "publisher": "Microsoft.Compute", 121 | "type": "CustomScriptExtension", 122 | "typeHandlerVersion": "1.4", 123 | "settings": { 124 | "commandToExecute": "[variables('jumpboxWindowsCustomScript')]" 125 | } 126 | } 127 | }, 128 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/gen-singleline-ps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import re 6 | import StringIO 7 | import sys 8 | 9 | # goal "commandToExecute": "[variables('jumpboxWindowsCustomScript')]" 10 | 11 | def convertToOneArmTemplateLine(file): 12 | with open(file) as f: 13 | content = f.read() 14 | 15 | oneline="" 16 | lines = content.split("\n") 17 | for line in lines: 18 | if (line.find("{") == -1 and line.find("}") == -1) or (line.find("{") > -1 and line.find("}") > -1): 19 | oneline=oneline + " ; " + line 20 | else: 21 | oneline=oneline + line 22 | 23 | oneline="'".join(oneline.split('"')) 24 | 25 | codeRegEx=re.compile(r".arguments\s*=\s*'([^']*)'\s*;") 26 | matchArray=codeRegEx.findall(oneline) 27 | if len(matchArray)>1: 28 | print oneline 29 | raise AssertionError, "incorrect number of matches" 30 | argumentList='' 31 | if len(matchArray) == 1: 32 | argumentList = matchArray[0] 33 | oneline=codeRegEx.sub('',oneline) 34 | 35 | return oneline,argumentList 36 | 37 | def usage(): 38 | print 39 | print " usage: %s file1" % os.path.basename(sys.argv[0]) 40 | print 41 | print " builds a one line string to send to commandToExecute" 42 | 43 | if __name__ == "__main__": 44 | if len(sys.argv)!=2: 45 | usage() 46 | sys.exit(1) 47 | 48 | file = sys.argv[1] 49 | if not os.path.exists(file): 50 | print "Error: file %s does not exist" 51 | sys.exit(2) 52 | 53 | # build the yml file for cluster 54 | oneline, argumentList = convertToOneArmTemplateLine(file) 55 | 56 | print 'powershell.exe -ExecutionPolicy Unrestricted -command "%s"' % oneline 57 | #print '"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -command \\"%s\\""' % (oneline) 58 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/nginx.conf: -------------------------------------------------------------------------------- 1 | error_log stderr; 2 | 3 | events { 4 | worker_connections 1024; 5 | } 6 | 7 | env COREOS_PUBLIC_IPV4; 8 | 9 | http { 10 | access_log /var/log/nginx/access.log; 11 | error_log /var/log/nginx/error.log; 12 | 13 | lua_package_path '$prefix/conf/?.lua;;'; 14 | 15 | include mime.types; 16 | default_type application/octet-stream; 17 | 18 | sendfile on; 19 | keepalive_timeout 65; 20 | 21 | # use mesos-dns 22 | resolver 127.0.0.1; 23 | 24 | server { 25 | listen 80 default_server; 26 | server_name dcos.*; 27 | root /opt/mesosphere/active/dcos-ui/usr; 28 | 29 | location = /mesos { 30 | rewrite ^/mesos$ $scheme://$http_host/mesos/ permanent; 31 | } 32 | location ~ ^/mesos/(?.*)$ { 33 | proxy_set_header Host $http_host; 34 | proxy_set_header Accept-Encoding ""; 35 | subs_filter_types application/json; 36 | subs_filter [a-zA-Z0-9-]+:8080 $host/marathon/ rg; 37 | subs_filter [a-zA-Z0-9-]+:4400 $host/chronos/ rg; 38 | # instead of using upstream we must force a re-resolve, 39 | # in case leader changes 40 | proxy_pass http://leader.mesos:5050/$url$is_args$args; 41 | } 42 | 43 | location = /static { 44 | rewrite ^/static$ $scheme://$http_host/mesos/static/ permanent; 45 | } 46 | location /static/ { 47 | proxy_set_header Host $http_host; 48 | # instead of using upstream we must force a re-resolve, 49 | # in case leader changes 50 | proxy_pass http://leader.mesos:5050$uri$is_args$args; 51 | proxy_set_header Accept-Encoding ""; 52 | subs_filter_types application/x-javascript; 53 | subs_filter "'//' + host + '/" "'//$host/mesosredir/' + host + '/" g; 54 | } 55 | 56 | location = /files { 57 | rewrite ^/files$ $scheme://$http_host/mesos/files/ permanent; 58 | } 59 | location /files/ { 60 | proxy_set_header Host $http_host; 61 | # instead of using upstream we must force a re-resolve, 62 | # in case leader changes 63 | proxy_pass http://leader.mesos:5050$uri$is_args$args; 64 | } 65 | 66 | location ~ ^/mesosredir/[^/]+:80(?.*)$ { 67 | rewrite ^/mesosredir/.*$ $url last; 68 | } 69 | 70 | location ~ ^/mesosredir/(?[^/]+)(?.*)$ { 71 | set $slaveaddr ''; 72 | 73 | more_clear_input_headers Accept-Encoding; 74 | rewrite ^/mesosredir/.*$ $url break; 75 | rewrite_by_lua_file conf/slavehostname.lua; 76 | 77 | proxy_set_header Host $http_host; 78 | proxy_set_header X-Real-IP $remote_addr; 79 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 80 | proxy_set_header X-Forwarded-Proto $scheme; 81 | 82 | proxy_pass http://$slaveaddr; 83 | } 84 | 85 | location ~ ^/slave/(?[0-9a-zA-Z-]+)(?.*)$ { 86 | set $slaveaddr ''; 87 | 88 | more_clear_input_headers Accept-Encoding; 89 | rewrite ^/slave/[0-9a-zA-Z-]+/.*$ $url break; 90 | rewrite_by_lua_file conf/slave.lua; 91 | 92 | proxy_set_header Host $http_host; 93 | proxy_set_header X-Real-IP $remote_addr; 94 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 95 | proxy_set_header X-Forwarded-Proto $scheme; 96 | 97 | proxy_pass http://$slaveaddr; 98 | } 99 | 100 | location ~ ^/service/(?[0-9a-zA-Z-.]+)/?(?.*) { 101 | set $serviceurl ''; 102 | 103 | more_clear_input_headers Accept-Encoding; 104 | rewrite ^/service/[0-9a-zA-Z-.]+/?.*$ /$url break; 105 | rewrite_by_lua_file conf/service.lua; 106 | 107 | proxy_set_header Host $http_host; 108 | proxy_set_header X-Real-IP $remote_addr; 109 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 110 | proxy_set_header X-Forwarded-Proto $scheme; 111 | 112 | proxy_pass $serviceurl; 113 | proxy_redirect http://$host/service/$serviceid/ /service/$serviceid/; 114 | proxy_redirect http://$host/ /service/$serviceid/; 115 | proxy_redirect / /service/$serviceid/; 116 | } 117 | 118 | location /metadata { 119 | content_by_lua_file conf/metadata.lua; 120 | } 121 | 122 | location /dcos-metadata/ { 123 | alias /opt/mesosphere/active/dcos-metadata/etc/; 124 | } 125 | 126 | location = /marathon { 127 | rewrite ^/marathon$ $scheme://$http_host/marathon/ permanent; 128 | } 129 | # TODO(cmaloney): Make the Web UI work in a subdirectory. 130 | location ~ ^/marathon/(.*) { 131 | proxy_set_header Host $http_host; 132 | proxy_pass http://master.mesos:8080/$1$is_args$args; 133 | } 134 | 135 | location = /chronos { 136 | rewrite ^/chronos$ $scheme://$http_host/chronos/ permanent; 137 | } 138 | location ~ ^/chronos/(.*) { 139 | proxy_set_header Host $http_host; 140 | proxy_pass http://master.mesos:4400/$1$is_args$args; 141 | } 142 | 143 | location /pkgpanda/active.buildinfo.full.json { 144 | add_header Cache-Control "no-cache"; 145 | alias /opt/mesosphere/active.buildinfo.full.json; 146 | } 147 | 148 | location = /mesos_dns { 149 | rewrite ^/mesos_dns$ $scheme://$http_host/mesos_dns/ permanent; 150 | } 151 | location ~ ^/mesos_dns/(.*) { 152 | proxy_set_header Host $http_host; 153 | proxy_pass http://master.mesos:8123/$1$is_args$args; 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/prettyPrintAzureTemplate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import sys 4 | import json 5 | 6 | def jsonLines(jsonFile): 7 | with open(jsonFile) as f: 8 | content = f.read() 9 | return content 10 | 11 | def prettyPrintAndSort(jsonLines): 12 | jsonContent = json.loads(jsonLines) 13 | return json.dumps(jsonContent, sort_keys=True, indent=2).__str__() 14 | 15 | def translateJson(jsonContent, translateParams, reverseTranslate): 16 | for a, b in translateParams: 17 | if reverseTranslate: 18 | jsonContent=jsonContent.replace(b, a) 19 | else: 20 | jsonContent=jsonContent.replace(a, b) 21 | return jsonContent 22 | 23 | def usage(programName): 24 | print "usage: %s AZURE_TEMPLATE_FILE" % (programName) 25 | 26 | if __name__ == "__main__": 27 | if len(sys.argv) != 2: 28 | print "Error: incorrect number of elements" 29 | print 30 | usage(sys.argv[0]) 31 | jsonFile=sys.argv[1] 32 | 33 | if not(os.path.exists(jsonFile)) or not(os.path.isfile(jsonFile)): 34 | print "Error: %s is not a valid json file" 35 | print 36 | usage(sys.argv[0]) 37 | 38 | # read the lines of the file 39 | jsonLines = jsonLines(jsonFile) 40 | 41 | translateParams = [ 42 | ["parameters", "dparameters"], 43 | ["variables", "eparameters"], 44 | ["resources", "fresources"], 45 | ["outputs", "zoutputs"] 46 | ] 47 | 48 | # translate the outer parameters 49 | jsonLines = translateJson(jsonLines, translateParams, False) 50 | 51 | # pretty print and sort 52 | prettyPrintLines = prettyPrintAndSort(jsonLines) 53 | 54 | # translate the parameters back 55 | prettyPrintLines = translateJson(prettyPrintLines, translateParams, True) 56 | 57 | # print the string 58 | print prettyPrintLines 59 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/simple-web.ps1: -------------------------------------------------------------------------------- 1 | <#code used from https://gist.github.com/wagnerandrade/5424431#> 2 | $ip = (Get-NetIPAddress | where {$_.IPAddress -Like '*.*.*.*'})[0].IPAddress 3 | $url = "http://"+$ip+":80/" 4 | $listener = New-Object System.Net.HttpListener 5 | $listener.Prefixes.Add($url) 6 | $listener.Start() 7 | $callerCounts = @{} 8 | 9 | Write-Host('Listening at {0}...' -f $url) 10 | 11 | while ($listener.IsListening) { 12 | $context = $listener.GetContext() 13 | $requestUrl = $context.Request.Url 14 | $clientIP = $context.Request.RemoteEndPoint.Address 15 | $response = $context.Response 16 | 17 | Write-Host '' 18 | Write-Host('> {0}' -f $requestUrl) 19 | 20 | $count = 1 21 | $k=$callerCounts.Get_Item($clientIP) 22 | if ($k -ne $null) { $count += $k } 23 | $callerCounts.Set_Item($clientIP, $count) 24 | $header="

Windows Container Web Server

" 25 | $callerCountsString="" 26 | $callerCounts.Keys | % { $callerCountsString+='

IP {0} callerCount {1} ' -f $_,$callerCounts.Item($_) } 27 | $footer="" 28 | $content='{0}{1}{2}' -f $header,$callerCountsString,$footer 29 | Write-Output $content 30 | $buffer = [System.Text.Encoding]::UTF8.GetBytes($content) 31 | $response.ContentLength64 = $buffer.Length 32 | $response.OutputStream.Write($buffer, 0, $buffer.Length) 33 | $response.Close() 34 | 35 | $responseStatus = $response.StatusCode 36 | Write-Host('< {0}' -f $responseStatus) 37 | } 38 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/simplest-web.ps1: -------------------------------------------------------------------------------- 1 | <#code used from https://gist.github.com/wagnerandrade/5424431#> 2 | $ip = (Get-NetIPAddress | where {$_.IPAddress -Like '*.*.*.*'})[0].IPAddress 3 | $url = 'http://{0}:80/' -f $ip 4 | $listener = New-Object System.Net.HttpListener 5 | $listener.Prefixes.Add($url) 6 | $listener.Start() 7 | 8 | Write-Host('Listening at {0}...' -f $url) 9 | 10 | while ($listener.IsListening) { 11 | $context = $listener.GetContext() 12 | $requestUrl = $context.Request.Url 13 | $clientIP = $context.Request.RemoteEndPoint.Address 14 | $response = $context.Response 15 | Write-Host '' 16 | Write-Host('> {0}' -f $requestUrl) 17 | $content='

helloworld

' 18 | Write-Output $content 19 | $buffer = [System.Text.Encoding]::UTF8.GetBytes($content) 20 | $response.ContentLength64 = $buffer.Length 21 | $response.OutputStream.Write($buffer, 0, $buffer.Length) 22 | $response.Close() 23 | $responseStatus = $response.StatusCode 24 | Write-Host('< {0}' -f $responseStatus) 25 | } 26 | -------------------------------------------------------------------------------- /mesos-marathon-vmss/parts/vmsizes-storage-account-mappings.json: -------------------------------------------------------------------------------- 1 | "vmSizesMap": { 2 | "Standard_A0": { 3 | "storageAccountType":"Standard_LRS" 4 | }, 5 | "Standard_A1": { 6 | "storageAccountType":"Standard_LRS" 7 | }, 8 | "Standard_A2": { 9 | "storageAccountType":"Standard_LRS" 10 | }, 11 | "Standard_A3": { 12 | "storageAccountType":"Standard_LRS" 13 | }, 14 | "Standard_A4": { 15 | "storageAccountType":"Standard_LRS" 16 | }, 17 | "Standard_A5": { 18 | "storageAccountType":"Standard_LRS" 19 | }, 20 | "Standard_A6": { 21 | "storageAccountType":"Standard_LRS" 22 | }, 23 | "Standard_A7": { 24 | "storageAccountType":"Standard_LRS" 25 | }, 26 | "Standard_A8": { 27 | "storageAccountType":"Standard_LRS" 28 | }, 29 | "Standard_A9": { 30 | "storageAccountType":"Standard_LRS" 31 | }, 32 | "Standard_A10": { 33 | "storageAccountType":"Standard_LRS" 34 | }, 35 | "Standard_A11": { 36 | "storageAccountType":"Standard_LRS" 37 | }, 38 | "Standard_D1": { 39 | "storageAccountType":"Standard_LRS" 40 | }, 41 | "Standard_D2": { 42 | "storageAccountType":"Standard_LRS" 43 | }, 44 | "Standard_D3": { 45 | "storageAccountType":"Standard_LRS" 46 | }, 47 | "Standard_D4": { 48 | "storageAccountType":"Standard_LRS" 49 | }, 50 | "Standard_D11": { 51 | "storageAccountType":"Standard_LRS" 52 | }, 53 | "Standard_D12": { 54 | "storageAccountType":"Standard_LRS" 55 | }, 56 | "Standard_D13": { 57 | "storageAccountType":"Standard_LRS" 58 | }, 59 | "Standard_D14": { 60 | "storageAccountType":"Standard_LRS" 61 | }, 62 | "Standard_D1_v2": { 63 | "storageAccountType":"Standard_LRS" 64 | }, 65 | "Standard_D2_v2": { 66 | "storageAccountType":"Standard_LRS" 67 | }, 68 | "Standard_D3_v2": { 69 | "storageAccountType":"Standard_LRS" 70 | }, 71 | "Standard_D4_v2": { 72 | "storageAccountType":"Standard_LRS" 73 | }, 74 | "Standard_D5_v2": { 75 | "storageAccountType":"Standard_LRS" 76 | }, 77 | "Standard_D11_v2": { 78 | "storageAccountType":"Standard_LRS" 79 | }, 80 | "Standard_D12_v2": { 81 | "storageAccountType":"Standard_LRS" 82 | }, 83 | "Standard_D13_v2": { 84 | "storageAccountType":"Standard_LRS" 85 | }, 86 | "Standard_D14_v2": { 87 | "storageAccountType":"Standard_LRS" 88 | }, 89 | "Standard_G1": { 90 | "storageAccountType":"Standard_LRS" 91 | }, 92 | "Standard_G2": { 93 | "storageAccountType":"Standard_LRS" 94 | }, 95 | "Standard_G3": { 96 | "storageAccountType":"Standard_LRS" 97 | }, 98 | "Standard_G4": { 99 | "storageAccountType":"Standard_LRS" 100 | }, 101 | "Standard_G5": { 102 | "storageAccountType":"Standard_LRS" 103 | }, 104 | "Standard_DS1": { 105 | "storageAccountType":"Premium_LRS" 106 | }, 107 | "Standard_DS2": { 108 | "storageAccountType":"Premium_LRS" 109 | }, 110 | "Standard_DS3": { 111 | "storageAccountType":"Premium_LRS" 112 | }, 113 | "Standard_DS4": { 114 | "storageAccountType":"Premium_LRS" 115 | }, 116 | "Standard_DS11": { 117 | "storageAccountType":"Premium_LRS" 118 | }, 119 | "Standard_DS12": { 120 | "storageAccountType":"Premium_LRS" 121 | }, 122 | "Standard_DS13": { 123 | "storageAccountType":"Premium_LRS" 124 | }, 125 | "Standard_DS14": { 126 | "storageAccountType":"Premium_LRS" 127 | }, 128 | "Standard_GS1": { 129 | "storageAccountType":"Premium_LRS" 130 | }, 131 | "Standard_GS2": { 132 | "storageAccountType":"Premium_LRS" 133 | }, 134 | "Standard_GS3": { 135 | "storageAccountType":"Premium_LRS" 136 | }, 137 | "Standard_GS4": { 138 | "storageAccountType":"Premium_LRS" 139 | }, 140 | "Standard_GS5": { 141 | "storageAccountType":"Premium_LRS" 142 | } 143 | } -------------------------------------------------------------------------------- /mesos-marathon/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "windowsAdminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "jumpboxEndpointDNSNamePrefix": { 6 | "value": "swarmjb1122g" 7 | }, 8 | "masterEndpointDNSNamePrefix": { 9 | "value": "swarmmgmt1122g" 10 | }, 11 | "agentEndpointDNSNamePrefix": { 12 | "value": "swarmapp1122g" 13 | }, 14 | "agentCount": { 15 | "value": 3 16 | }, 17 | "masterCount": { 18 | "value": 3 19 | }, 20 | "agentVMSize" : { 21 | "value": "Standard_A1" 22 | }, 23 | "sshRSAPublicKey": { 24 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mesos-marathon/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $randomString = [System.Guid]::NewGuid().GetHashCode().ToString("X") 2 | 3 | #$templateFile= "mesos-cluster-with-linux-jumpbox.json" 4 | #$templateFile= "mesos-cluster-with-windows-jumpbox.json" 5 | $templateFile= "mesos-cluster-with-no-jumpbox.json" 6 | #$templateFile= "swarm-cluster-with-no-jumpbox.json" 7 | #$templateParameterFile= "cluster.parameters.json" 8 | 9 | $deployName="$env:USERNAME$randomString" 10 | $RGName=$deployName 11 | $locName="East US 2" 12 | 13 | Switch-AzureMode -Name AzureResourceManager 14 | New-AzureResourceGroup -Name $RGName -Location $locName -Force 15 | 16 | $templateParameters = @{ windowsAdminPassword="password1234$"; 17 | jumpboxEndpointDNSNamePrefix="testjumpbox$randomString"; 18 | masterEndpointDNSNamePrefix="testmaster$randomString"; 19 | masterCount=1; 20 | agentEndpointDNSNamePrefix="testagent$randomString"; 21 | agentCount=1; 22 | agentVMSize="Standard_A1"; 23 | sshRSAPublicKey="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 24 | } 25 | 26 | echo New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterObject $templateParameters -TemplateFile $templateFile 27 | New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterObject $templateParameters -TemplateFile $templateFile 28 | 29 | #echo New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 30 | #New-AzureResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 31 | -------------------------------------------------------------------------------- /mesos-marathon/images/chronos-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/chronos-docker.png -------------------------------------------------------------------------------- /mesos-marathon/images/chronos-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/chronos-ui.png -------------------------------------------------------------------------------- /mesos-marathon/images/chronos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/chronos.png -------------------------------------------------------------------------------- /mesos-marathon/images/completed-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/completed-hello-world.png -------------------------------------------------------------------------------- /mesos-marathon/images/dockercomposescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/dockercomposescale.png -------------------------------------------------------------------------------- /mesos-marathon/images/dockerinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/dockerinfo.png -------------------------------------------------------------------------------- /mesos-marathon/images/dockerps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/dockerps.png -------------------------------------------------------------------------------- /mesos-marathon/images/marathon-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/marathon-docker.png -------------------------------------------------------------------------------- /mesos-marathon/images/marathon-newapp-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/marathon-newapp-status.png -------------------------------------------------------------------------------- /mesos-marathon/images/marathon-newapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/marathon-newapp.png -------------------------------------------------------------------------------- /mesos-marathon/images/mesos-agents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/mesos-agents.png -------------------------------------------------------------------------------- /mesos-marathon/images/mesos-completed-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/mesos-completed-tasks.png -------------------------------------------------------------------------------- /mesos-marathon/images/mesos-frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/mesos-frameworks.png -------------------------------------------------------------------------------- /mesos-marathon/images/mesos-webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/mesos-webui.png -------------------------------------------------------------------------------- /mesos-marathon/images/mesos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/mesos.png -------------------------------------------------------------------------------- /mesos-marathon/images/portal-publicipaddresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/portal-publicipaddresses.png -------------------------------------------------------------------------------- /mesos-marathon/images/portal-resourcegroups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/portal-resourcegroups.png -------------------------------------------------------------------------------- /mesos-marathon/images/swarm-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/swarm-framework.png -------------------------------------------------------------------------------- /mesos-marathon/images/swarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/swarm.png -------------------------------------------------------------------------------- /mesos-marathon/images/swarmbrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anhowe/scratch/a8864bb0de845b506f9cf150ea25759ea6032683/mesos-marathon/images/swarmbrowser.png -------------------------------------------------------------------------------- /mesos-marathon/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemDisplayName": "Create a Marathon/Chronos/Swarm enabled Mesos cluster", 3 | "description": "This template creates a Docker capable Apache Mesos cluster with Marathon, Chronos, and Swarm on a configurable number of nodes.", 4 | "summary": "Create a Docker capable Apache Mesos cluster on Microsoft Azure with the Marathon/Chronos/Swarm frameworks.", 5 | "githubUsername": "anhowe", 6 | "dateUpdated": "2015-10-26" 7 | } 8 | -------------------------------------------------------------------------------- /mesos-marathon/parts/base-template.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "windowsAdminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "jumpboxEndpointDNSNamePrefix": { 6 | "value": "swarmjb1122g" 7 | }, 8 | "masterEndpointDNSNamePrefix": { 9 | "value": "swarmmgmt1122g" 10 | }, 11 | "agentEndpointDNSNamePrefix": { 12 | "value": "swarmapp1122g" 13 | }, 14 | "agentCount": { 15 | "value": 3 16 | }, 17 | "masterCount": { 18 | "value": 3 19 | }, 20 | "agentVMSize" : { 21 | "value": "Standard_A1" 22 | }, 23 | "sshRSAPublicKey": { 24 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mesos-marathon/parts/fragment-linux-jumpbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "2015-06-15", 3 | "type": "Microsoft.Network/publicIPAddresses", 4 | "name": "[variables('jumpboxPublicIPAddressName')]", 5 | "location": "[resourceGroup().location]", 6 | "properties": { 7 | "publicIPAllocationMethod": "Dynamic", 8 | "dnsSettings": { 9 | "domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]" 10 | } 11 | } 12 | }, 13 | { 14 | "apiVersion": "2015-06-15", 15 | "type": "Microsoft.Network/networkSecurityGroups", 16 | "name": "[variables('jumpboxNSGName')]", 17 | "location": "[resourceGroup().location]", 18 | "properties": { 19 | "securityRules": [ 20 | { 21 | "name": "ssh", 22 | "properties": { 23 | "description": "Allow SSH", 24 | "protocol": "Tcp", 25 | "sourcePortRange": "*", 26 | "destinationPortRange": "22", 27 | "sourceAddressPrefix": "*", 28 | "destinationAddressPrefix": "*", 29 | "access": "Allow", 30 | "priority": 200, 31 | "direction": "Inbound" 32 | } 33 | } 34 | ] 35 | } 36 | }, 37 | { 38 | "apiVersion": "2015-06-15", 39 | "type": "Microsoft.Network/networkInterfaces", 40 | "name": "[concat(variables('jumpboxVMName'), '-nic')]", 41 | "location": "[resourceGroup().location]", 42 | "dependsOn": [ 43 | "[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]", 44 | "[variables('vnetID')]", 45 | "[variables('jumpboxNSGID')]" 46 | ], 47 | "properties": { 48 | "networkSecurityGroup": { 49 | "id": "[variables('jumpboxNSGID')]" 50 | }, 51 | "ipConfigurations": [ 52 | { 53 | "name": "ipConfig", 54 | "properties": { 55 | "privateIPAllocationMethod": "Static", 56 | "privateIPAddress": "[concat(split(variables('subnetPrefix'),'0/18')[0], variables('jumpboxAddr'))]", 57 | "publicIPAddress": { 58 | "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]" 59 | }, 60 | "subnet": { 61 | "id": "[variables('subnetRef')]" 62 | } 63 | } 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "apiVersion": "2015-06-15", 70 | "type": "Microsoft.Compute/virtualMachines", 71 | "name": "[variables('jumpboxVMName')]", 72 | "location": "[resourceGroup().location]", 73 | "dependsOn": [ 74 | "[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]", 75 | "[variables('masterStorageAccountName')]" 76 | ], 77 | "properties": { 78 | "hardwareProfile": { 79 | "vmSize": "[variables('jumpboxVMSize')]" 80 | }, 81 | "osProfile": { 82 | "computername": "[variables('jumpboxVMName')]", 83 | "adminUsername": "[variables('adminUsername')]", 84 | "adminPassword": "[variables('adminPassword')]", 85 | "customData": "[base64('#jumpboxLinuxCustomDataInstallYaml')]", 86 | "linuxConfiguration": "[variables('linuxConfiguration')]" 87 | }, 88 | "storageProfile": { 89 | "imageReference": { 90 | "publisher": "[variables('linuxPublisher')]", 91 | "offer": "[variables('linuxOffer')]", 92 | "sku": "[variables('linuxSku')]", 93 | "version": "[variables('linuxVersion')]" 94 | }, 95 | "osDisk": { 96 | "name": "[concat(variables('jumpboxVMName'),'-osdisk')]", 97 | "vhd": { 98 | "uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]" 99 | }, 100 | "caching": "ReadWrite", 101 | "createOption": "FromImage" 102 | } 103 | }, 104 | "networkProfile": { 105 | "networkInterfaces": [ 106 | { 107 | "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]" 108 | } 109 | ] 110 | } 111 | } 112 | }, 113 | { 114 | "type": "Microsoft.Compute/virtualMachines/extensions", 115 | "name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]", 116 | "apiVersion": "2015-06-15", 117 | "location": "[resourceGroup().location]", 118 | "dependsOn": [ 119 | "[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]" 120 | ], 121 | "properties": { 122 | "publisher": "Microsoft.OSTCExtensions", 123 | "type": "CustomScriptForLinux", 124 | "typeHandlerVersion": "1.3", 125 | "settings": { 126 | "commandToExecute": "[variables('jumpboxLinuxCustomScript')]" 127 | } 128 | } 129 | }, 130 | -------------------------------------------------------------------------------- /mesos-marathon/parts/fragment-windows-jumpbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "2015-06-15", 3 | "type": "Microsoft.Network/publicIPAddresses", 4 | "name": "[variables('jumpboxPublicIPAddressName')]", 5 | "location": "[resourceGroup().location]", 6 | "properties": { 7 | "publicIPAllocationMethod": "Dynamic", 8 | "dnsSettings": { 9 | "domainNameLabel": "[variables('jumpboxEndpointDNSNamePrefix')]" 10 | } 11 | } 12 | }, 13 | { 14 | "apiVersion": "2015-06-15", 15 | "type": "Microsoft.Network/networkSecurityGroups", 16 | "name": "[variables('jumpboxNSGName')]", 17 | "location": "[resourceGroup().location]", 18 | "properties": { 19 | "securityRules": [ 20 | { 21 | "name": "ssh", 22 | "properties": { 23 | "description": "Allow RDP", 24 | "protocol": "Tcp", 25 | "sourcePortRange": "*", 26 | "destinationPortRange": "3389", 27 | "sourceAddressPrefix": "*", 28 | "destinationAddressPrefix": "*", 29 | "access": "Allow", 30 | "priority": 200, 31 | "direction": "Inbound" 32 | } 33 | } 34 | ] 35 | } 36 | }, 37 | { 38 | "apiVersion": "2015-06-15", 39 | "type": "Microsoft.Network/networkInterfaces", 40 | "name": "[concat(variables('jumpboxVMName'), '-nic')]", 41 | "location": "[resourceGroup().location]", 42 | "dependsOn": [ 43 | "[concat('Microsoft.Network/publicIPAddresses/', variables('jumpboxPublicIPAddressName'))]", 44 | "[variables('vnetID')]", 45 | "[variables('jumpboxNSGID')]" 46 | ], 47 | "properties": { 48 | "networkSecurityGroup": { 49 | "id": "[variables('jumpboxNSGID')]" 50 | }, 51 | "ipConfigurations": [ 52 | { 53 | "name": "ipConfig", 54 | "properties": { 55 | "privateIPAllocationMethod": "Static", 56 | "privateIPAddress": "[concat(split(variables('subnetPrefix'),'0/18')[0], variables('jumpboxAddr'))]", 57 | "publicIPAddress": { 58 | "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('jumpboxPublicIPAddressName'))]" 59 | }, 60 | "subnet": { 61 | "id": "[variables('subnetRef')]" 62 | } 63 | } 64 | } 65 | ] 66 | } 67 | }, 68 | { 69 | "apiVersion": "2015-06-15", 70 | "type": "Microsoft.Compute/virtualMachines", 71 | "name": "[variables('jumpboxVMName')]", 72 | "location": "[resourceGroup().location]", 73 | "dependsOn": [ 74 | "[concat('Microsoft.Network/networkInterfaces/', variables('jumpboxVMName'), '-nic')]", 75 | "[variables('masterStorageAccountName')]" 76 | ], 77 | "properties": { 78 | "hardwareProfile": { 79 | "vmSize": "[variables('jumpboxVMSize')]" 80 | }, 81 | "osProfile": { 82 | "computername": "[variables('jumpboxVMName')]", 83 | "adminUsername": "[variables('windowsAdminUsername')]", 84 | "adminPassword": "[variables('windowsAdminPassword')]" 85 | }, 86 | "storageProfile": { 87 | "imageReference": { 88 | "publisher": "[variables('windowsJumpboxPublisher')]", 89 | "offer": "[variables('windowsJumpboxOffer')]", 90 | "sku": "[variables('windowsJumpboxSku')]", 91 | "version": "latest" 92 | }, 93 | "osDisk": { 94 | "name": "[concat(variables('jumpboxVMName'),'-osdisk')]", 95 | "vhd": { 96 | "uri": "[concat('http://', variables('masterStorageAccountName'), '.blob.core.windows.net/vhds/', variables('jumpboxVMName'), '-osdisk.vhd')]" 97 | }, 98 | "caching": "ReadWrite", 99 | "createOption": "FromImage" 100 | } 101 | }, 102 | "networkProfile": { 103 | "networkInterfaces": [ 104 | { 105 | "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('jumpboxVMName'), '-nic'))]" 106 | } 107 | ] 108 | } 109 | } 110 | }, 111 | { 112 | "type": "Microsoft.Compute/virtualMachines/extensions", 113 | "name": "[concat(variables('jumpboxVMName'),'/installcustomscript')]", 114 | "apiVersion": "2015-06-15", 115 | "location": "[resourceGroup().location]", 116 | "dependsOn": [ 117 | "[concat('Microsoft.Compute/virtualMachines/', variables('jumpboxVMName'))]" 118 | ], 119 | "properties": { 120 | "publisher": "Microsoft.Compute", 121 | "type": "CustomScriptExtension", 122 | "typeHandlerVersion": "1.4", 123 | "settings": { 124 | "commandToExecute": "[variables('jumpboxWindowsCustomScript')]" 125 | } 126 | } 127 | }, 128 | -------------------------------------------------------------------------------- /mesos-marathon/parts/nginx.conf: -------------------------------------------------------------------------------- 1 | error_log stderr; 2 | 3 | events { 4 | worker_connections 1024; 5 | } 6 | 7 | env COREOS_PUBLIC_IPV4; 8 | 9 | http { 10 | access_log /var/log/nginx/access.log; 11 | error_log /var/log/nginx/error.log; 12 | 13 | lua_package_path '$prefix/conf/?.lua;;'; 14 | 15 | include mime.types; 16 | default_type application/octet-stream; 17 | 18 | sendfile on; 19 | keepalive_timeout 65; 20 | 21 | # use mesos-dns 22 | resolver 127.0.0.1; 23 | 24 | server { 25 | listen 80 default_server; 26 | server_name dcos.*; 27 | root /opt/mesosphere/active/dcos-ui/usr; 28 | 29 | location = /mesos { 30 | rewrite ^/mesos$ $scheme://$http_host/mesos/ permanent; 31 | } 32 | location ~ ^/mesos/(?.*)$ { 33 | proxy_set_header Host $http_host; 34 | proxy_set_header Accept-Encoding ""; 35 | subs_filter_types application/json; 36 | subs_filter [a-z0-9-]+:8080 $host/marathon/ rg; 37 | subs_filter [a-z0-9-]+:4400 $host/chronos/ rg; 38 | # instead of using upstream we must force a re-resolve, 39 | # in case leader changes 40 | proxy_pass http://leader.mesos:5050/$url$is_args$args; 41 | } 42 | 43 | location = /static { 44 | rewrite ^/static$ $scheme://$http_host/mesos/static/ permanent; 45 | } 46 | location /static/ { 47 | proxy_set_header Host $http_host; 48 | # instead of using upstream we must force a re-resolve, 49 | # in case leader changes 50 | proxy_pass http://leader.mesos:5050$uri$is_args$args; 51 | proxy_set_header Accept-Encoding ""; 52 | subs_filter_types application/x-javascript; 53 | subs_filter "'//' + host + '/" "'//$host/mesosredir/' + host + '/" g; 54 | } 55 | 56 | location = /files { 57 | rewrite ^/files$ $scheme://$http_host/mesos/files/ permanent; 58 | } 59 | location /files/ { 60 | proxy_set_header Host $http_host; 61 | # instead of using upstream we must force a re-resolve, 62 | # in case leader changes 63 | proxy_pass http://leader.mesos:5050$uri$is_args$args; 64 | } 65 | 66 | location ~ ^/mesosredir/[^/]+:80(?.*)$ { 67 | rewrite ^/mesosredir/.*$ $url last; 68 | } 69 | 70 | location ~ ^/mesosredir/(?[^/]+)(?.*)$ { 71 | set $slaveaddr ''; 72 | 73 | more_clear_input_headers Accept-Encoding; 74 | rewrite ^/mesosredir/.*$ $url break; 75 | rewrite_by_lua_file conf/slavehostname.lua; 76 | 77 | proxy_set_header Host $http_host; 78 | proxy_set_header X-Real-IP $remote_addr; 79 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 80 | proxy_set_header X-Forwarded-Proto $scheme; 81 | 82 | proxy_pass http://$slaveaddr; 83 | } 84 | 85 | location ~ ^/slave/(?[0-9a-zA-Z-]+)(?.*)$ { 86 | set $slaveaddr ''; 87 | 88 | more_clear_input_headers Accept-Encoding; 89 | rewrite ^/slave/[0-9a-zA-Z-]+/.*$ $url break; 90 | rewrite_by_lua_file conf/slave.lua; 91 | 92 | proxy_set_header Host $http_host; 93 | proxy_set_header X-Real-IP $remote_addr; 94 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 95 | proxy_set_header X-Forwarded-Proto $scheme; 96 | 97 | proxy_pass http://$slaveaddr; 98 | } 99 | 100 | location ~ ^/service/(?[0-9a-zA-Z-.]+)/?(?.*) { 101 | set $serviceurl ''; 102 | 103 | more_clear_input_headers Accept-Encoding; 104 | rewrite ^/service/[0-9a-zA-Z-.]+/?.*$ /$url break; 105 | rewrite_by_lua_file conf/service.lua; 106 | 107 | proxy_set_header Host $http_host; 108 | proxy_set_header X-Real-IP $remote_addr; 109 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 110 | proxy_set_header X-Forwarded-Proto $scheme; 111 | 112 | proxy_pass $serviceurl; 113 | proxy_redirect http://$host/service/$serviceid/ /service/$serviceid/; 114 | proxy_redirect http://$host/ /service/$serviceid/; 115 | proxy_redirect / /service/$serviceid/; 116 | } 117 | 118 | location /metadata { 119 | content_by_lua_file conf/metadata.lua; 120 | } 121 | 122 | location /dcos-metadata/ { 123 | alias /opt/mesosphere/active/dcos-metadata/etc/; 124 | } 125 | 126 | location = /marathon { 127 | rewrite ^/marathon$ $scheme://$http_host/marathon/ permanent; 128 | } 129 | # TODO(cmaloney): Make the Web UI work in a subdirectory. 130 | location ~ ^/marathon/(.*) { 131 | proxy_set_header Host $http_host; 132 | proxy_pass http://master.mesos:8080/$1$is_args$args; 133 | } 134 | 135 | location = /chronos { 136 | rewrite ^/chronos$ $scheme://$http_host/chronos/ permanent; 137 | } 138 | location ~ ^/chronos/(.*) { 139 | proxy_set_header Host $http_host; 140 | proxy_pass http://master.mesos:4400/$1$is_args$args; 141 | } 142 | 143 | location /pkgpanda/active.buildinfo.full.json { 144 | add_header Cache-Control "no-cache"; 145 | alias /opt/mesosphere/active.buildinfo.full.json; 146 | } 147 | 148 | location = /mesos_dns { 149 | rewrite ^/mesos_dns$ $scheme://$http_host/mesos_dns/ permanent; 150 | } 151 | location ~ ^/mesos_dns/(.*) { 152 | proxy_set_header Host $http_host; 153 | proxy_pass http://master.mesos:8123/$1$is_args$args; 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /mesos-vmss/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "masterEndpointDNSNamePrefix": { 3 | "value": "aaajmgmt0115c" 4 | }, 5 | "agentEndpointDNSNamePrefix": { 6 | "value": "aaajapp0115c" 7 | }, 8 | "agentCount": { 9 | "value": 3 10 | }, 11 | "masterCount": { 12 | "value": 3 13 | }, 14 | "agentVMSize" : { 15 | "value": "Standard_A2" 16 | }, 17 | "sshRSAPublicKey": { 18 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /mesos-vmss/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $deployName="aaajmgmt0115c" 3 | $RGName=$deployName 4 | $locName="East Asia" 5 | $templateFile= "mesos-cluster.json" 6 | $templateParameterFile= "cluster.parameters.json" 7 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 8 | 9 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 10 | -------------------------------------------------------------------------------- /nicscaling/README.md: -------------------------------------------------------------------------------- 1 | # Dynamic NAT Rules 2 | 3 | The nic scaling project allows to scale to 12,800 nodes. This is because 200 ips are allocated per each of the 64 octets on the subnet of 10.0.0.0/18 (10.0.0.0..10.0.63.255). 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /nicscaling/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": {}, 5 | "variables": { 6 | "virtualNetworkName": "VNET", 7 | "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]", 8 | "subnetName": "Subnet", 9 | "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", 10 | "addressPrefix": "10.0.0.0/16", 11 | "subnetPrefix": "10.0.0.0/18", 12 | "nodesPerIPv4Octet": 200, 13 | "ipv4OctetOffset": 50, 14 | "agentVMNamePrefix": "agent", 15 | "agentCount": 220 16 | }, 17 | "resources": [ 18 | { 19 | "apiVersion": "2015-06-15", 20 | "type": "Microsoft.Network/virtualNetworks", 21 | "name": "[variables('virtualNetworkName')]", 22 | "location": "[resourceGroup().location]", 23 | "dependsOn": [], 24 | "properties": { 25 | "addressSpace": { 26 | "addressPrefixes": [ 27 | "[variables('addressPrefix')]" 28 | ] 29 | }, 30 | "subnets": [ 31 | { 32 | "name": "[variables('subnetName')]", 33 | "properties": { 34 | "addressPrefix": "[variables('subnetPrefix')]" 35 | } 36 | } 37 | ] 38 | } 39 | }, 40 | { 41 | "apiVersion": "2015-06-15", 42 | "type": "Microsoft.Network/networkInterfaces", 43 | "name": "[concat(variables('agentVMNamePrefix'), copyIndex(1), '-nic')]", 44 | "dependsOn": [ 45 | "[variables('vnetID')]" 46 | ], 47 | "location": "[resourceGroup().location]", 48 | "copy": { 49 | "name": "nicLoopNode", 50 | "count": "[variables('agentCount')]" 51 | }, 52 | "properties": { 53 | "ipConfigurations": [ 54 | { 55 | "name": "ipConfigNode", 56 | "properties": { 57 | "privateIPAllocationMethod": "Static", 58 | "privateIPAddress": "[concat(split(variables('subnetPrefix'),'0.0/18')[0], div(copyIndex(),variables('nodesPerIPv4Octet')), '.', add(mod(copyIndex(),variables('nodesPerIPv4Octet')), variables('ipv4OctetOffset')))]", 59 | "subnet": { 60 | "id": "[variables('subnetRef')]" 61 | } 62 | } 63 | } 64 | ] 65 | } 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /reliableCustomScriptExtension/gen-oneline-customdata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import StringIO 6 | import sys 7 | 8 | def buildYMLFile(files): 9 | clusterYamlFile="""#cloud-config 10 | 11 | write_files: 12 | %s 13 | """ 14 | writeFileBlock=""" - encoding: gzip 15 | content: !!binary | 16 | %s 17 | path: /opt/azure/%s 18 | permissions: "0744" 19 | """ 20 | filelines="" 21 | for encodeFile in files: 22 | # read the script file 23 | with open(encodeFile) as f: 24 | content = f.read() 25 | compressedbuffer=StringIO.StringIO() 26 | 27 | # gzip the script file 28 | with gzip.GzipFile(fileobj=compressedbuffer, mode='wb') as f: 29 | f.write(content) 30 | b64GzipStream=base64.b64encode(compressedbuffer.getvalue()) 31 | filelines=filelines+(writeFileBlock % (b64GzipStream,encodeFile)) 32 | 33 | return clusterYamlFile % (filelines) 34 | 35 | def convertToOneArmTemplateLine(clusterYamlFile): 36 | # remove the \r\n 37 | oneline="\\n".join(clusterYamlFile.split("\n")) 38 | oneline='\\"'.join(oneline.split('"')) 39 | return oneline 40 | 41 | def usage(): 42 | print 43 | print " usage: %s file1 file2 file3 . . ." % os.path.basename(sys.argv[0]) 44 | print 45 | print " builds a one line custom data entry for writing one or" 46 | print " more files to /opt/azure" 47 | 48 | if __name__ == "__main__": 49 | if len(sys.argv)==1: 50 | usage() 51 | sys.exit(1) 52 | 53 | files = sys.argv[1:] 54 | for file in files: 55 | if not os.path.exists(file): 56 | print "Error: file %s does not exist" 57 | sys.exit(2) 58 | 59 | # build the yml file for cluster 60 | yml = buildYMLFile(files) 61 | 62 | # convert yml file to one line 63 | oneline = convertToOneArmTemplateLine(yml) 64 | print '"customData": "[base64(\'%s\')]"' % (oneline) 65 | -------------------------------------------------------------------------------- /reliableCustomScriptExtension/helloworld.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ####################################### 4 | # wait for network to become ready 5 | ####################################### 6 | ensureAzureNetwork() 7 | { 8 | VMNAME=`hostname` 9 | # ensure the host name is resolvable 10 | hostResolveHealthy=1 11 | for i in {1..120}; do 12 | host $VMNAME 13 | if [ $? -eq 0 ] 14 | then 15 | # hostname has been found continue 16 | hostResolveHealthy=0 17 | echo "the host name resolves" 18 | break 19 | fi 20 | sleep 1 21 | done 22 | if [ $hostResolveHealthy -ne 0 ] 23 | then 24 | echo "host name does not resolve, aborting install" 25 | exit 1 26 | fi 27 | 28 | # ensure the network works 29 | networkHealthy=1 30 | for i in {1..12}; do 31 | wget -O/dev/null http://bing.com 32 | if [ $? -eq 0 ] 33 | then 34 | # hostname has been found continue 35 | networkHealthy=0 36 | echo "the network is healthy" 37 | break 38 | fi 39 | sleep 10 40 | done 41 | if [ $networkHealthy -ne 0 ] 42 | then 43 | echo "the network is not healthy, cannot download from bing, aborting install" 44 | ifconfig 45 | ip a 46 | exit 2 47 | fi 48 | # ensure the hostname -i works 49 | networkHealthy=1 50 | for i in {1..120}; do 51 | hostname -i 52 | if [ $? -eq 0 ] 53 | then 54 | # hostname has been found continue 55 | networkHealthy=0 56 | echo "the network is healthy" 57 | break 58 | fi 59 | sleep 1 60 | done 61 | if [ $networkHealthy -ne 0 ] 62 | then 63 | echo "the network is not healthy, cannot resolve ip address, aborting install" 64 | ifconfig 65 | ip a 66 | exit 2 67 | fi 68 | # ensure hostname -f works 69 | networkHealthy=1 70 | for i in {1..120}; do 71 | hostname -f 72 | if [ $? -eq 0 ] 73 | then 74 | # hostname has been found continue 75 | networkHealthy=0 76 | echo "the network is healthy" 77 | break 78 | fi 79 | sleep 1 80 | done 81 | if [ $networkHealthy -ne 0 ] 82 | then 83 | echo "the network is not healthy, cannot resolve hostname, aborting install" 84 | ifconfig 85 | ip a 86 | exit 2 87 | fi 88 | } 89 | ensureAzureNetwork 90 | 91 | ####################################### 92 | # run the main program 93 | ####################################### 94 | echo hello world 95 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/FixDiskFailure.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [string] 16 | [ValidateNotNullOrEmpty()] 17 | $vmName = "linuxvm" 18 | ) 19 | 20 | Set-AzureRmContext -SubscriptionId $SubscriptionId 21 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 22 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 23 | 24 | # starting attach / detach in an endless while loop 25 | Write-Output(Get-Date) 26 | Write-Output("({0}) getting vm" -f $counter) 27 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 28 | $vm.Tags["Fix"] = "me" 29 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 30 | $vm.Tags.Remove("Name") 31 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 32 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 33 | Write-Output(Get-Date) 34 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/README.md: -------------------------------------------------------------------------------- 1 | # Attach Blank Disks 2 | The template demonstrates attaching a blank disk using power shell. 3 | 4 | # Attach / Detach Disks causing a failed VM 5 | Here is how to repro the issue described here https://github.com/CatalystCode/azure-flocker-driver/issues/15: 6 | 7 | 1. Deploy the template https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fsimplelinux-attachblankdisk%2Fazuredeploy.json 8 | 9 | 2. go to https://resources.azure.com and for this new VM write down the RGName, storageaccountname, and your subscriptionid to use for the commands below. 10 | 11 | 3. run `CreateDataDisks.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 12 | 13 | 4. in 3 separate powershell windows run the following 3 commands 14 | 1. `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 1` 15 | 2. `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 2` 16 | 3. `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 3` 17 | 18 | 5. Watch for errors in the above scripts. Notice that retrying the failed script fixes the VM provisioning state. 19 | 20 | # LUN 0 issues 21 | 22 | The following article (https://blogs.msdn.microsoft.com/igorpag/2014/10/23/azure-storage-secrets-and-linux-io-optimizations/) says that each SCSI Host Linux must have a disk start at LUN0. This is part of the SCSI spec and how the Linux Kernel is implemented. 23 | 24 | Here are some repros to try to see the impact of the LUN0 issue: 25 | 26 | 1. Deploy the template https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fanhowe%2Fscratch%2Fmaster%2Fsimplelinux-attachblankdisk%2Fazuredeploy.json 27 | 28 | 2. go to https://resources.azure.com and for this new VM write down the RGName, storageaccountname, and your subscriptionid to use for the commands below. 29 | 30 | 3. run `CreateDataDisks.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -DiskCount 10` 31 | 32 | 4. start fresh by running `detachAllDisks.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 33 | 34 | 5. SSH to Linux machine, and type `sudo apt-get install lsscsi`, then `sudo lsscsi` and observe only /dev/sr0 (cdrom), /dev/sda (os), and /dev/sdb (ephemeral disk) 35 | 36 | 6. attach disks from lun0 to lun9 37 | 1. `attachLUN0-9.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 38 | 2. on the linux machine, type `sudo lsscsi`, and observe 10 disks. 39 | 40 | 7. start fresh 41 | 1. `detachAllDisks.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 42 | 2. on the linux machine, type `sudo lsscsi`, and observe only the 3 original devices sr0, sda, and sdb 43 | 44 | 8. attach disks from lun1 to lun9 45 | 1. `attachLUN1-9.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 46 | 2. on the linux machine, type `sudo lsscsi`, and observe 7 disks! 47 | 3. to see all disks `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 0` 48 | 4. on the linux machine, type `sudo lsscsi`, and observe 10 disks! 49 | 50 | 9. start fresh 51 | 1. `detachAllDisks.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 52 | 2. on the linux machine, type `sudo lsscsi`, and observe only the 3 original devices sr0, sda, and sdb 53 | 54 | 10. attach disks from lun0 to lun9, remove disk at lun0, add disk at lun10, then add disk at lun0 55 | 1. `attachLUN0-9.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME` 56 | 2. on the linux machine, type `sudo lsscsi`, and observe 10 disks. 57 | 3. `detachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 0` 58 | 4. on the linux machine, type `sudo lsscsi`, and observe 9 disks. 59 | 5. attach disk 10 `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 10` 60 | 6. on the linux machine, type `sudo lsscsi`, and observe only 9 disks. The tenth disk is missing. 61 | 7. attach disk 0 `attachLUN.ps1 -SubscriptionId SUBSCRIPTIONID -StorageAccountName STORAGEACCOUNT -RGName RESOURCGROUPNAME -Lun 0` 62 | 8. on the linux machine, type `sudo lsscsi`, and observe 11 disks. Everything is correct now that the disk at LUN0 has returned. 63 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/attachDetachLUN.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [int] 16 | $Lun, 17 | 18 | [string] 19 | [ValidateNotNullOrEmpty()] 20 | $ContainerName="datadisk", 21 | 22 | [string] 23 | [ValidateNotNullOrEmpty()] 24 | $vmName = "linuxvm" 25 | ) 26 | 27 | $diskName = "datadisk{0}" -f $lun 28 | $targetVhd = "https://{0}.blob.core.windows.net/{1}/dataDisk{2}.vhd" -f $StorageAccountName, $ContainerName, $lun 29 | 30 | Set-AzureRmContext -SubscriptionId $SubscriptionId 31 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 32 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 33 | 34 | # starting attach / detach in an endless while loop 35 | Write-Output(Get-Date) 36 | $counter=0 37 | while($true) 38 | { 39 | $counter++ 40 | Write-Output("({0}) getting vm" -f $counter) 41 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 42 | Write-Output("({0}) attaching disk at LUN {1}" -f $counter, $lun) 43 | Add-AzureRmVMDataDisk -VM $vm -Name $diskName -VhdUri $targetVhd -LUN $lun -Caching ReadWrite -CreateOption Attach -DiskSizeInGB $null 44 | Write-Output("({0}) updating Azure VM (add)" -f $counter) 45 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 46 | if ($result -ne $null) 47 | { 48 | Write-Output(Get-Date) 49 | Write-Output("UpdateStatus (add): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 50 | } 51 | 52 | Write-Output("({0}) dettaching disk at LUN {1}" -f $counter, $lun) 53 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 54 | Remove-AzureRmVMDataDisk -VM $vm -Name $diskName 55 | Write-Output("({0}) updating Azure VM (remove)" -f $counter) 56 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 57 | if ($result -ne $null) 58 | { 59 | Write-Output(Get-Date) 60 | Write-Output("UpdateStatus (remove): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 61 | } 62 | if($result -ne $null -and ($result.StatusCode -ne "OK" -or $result.Status -ne "Succeeded")) 63 | { 64 | break 65 | } 66 | } 67 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 68 | Write-Output("failed after {0} attempts" -f $counter) 69 | Write-Output(Get-Date) 70 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/attachLUN.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [int] 16 | $Lun, 17 | 18 | [string] 19 | [ValidateNotNullOrEmpty()] 20 | $ContainerName="datadisk", 21 | 22 | [string] 23 | [ValidateNotNullOrEmpty()] 24 | $vmName = "linuxvm" 25 | ) 26 | 27 | $diskName = "datadisk{0}" -f $lun 28 | $targetVhd = "https://{0}.blob.core.windows.net/{1}/dataDisk{2}.vhd" -f $StorageAccountName, $ContainerName, $lun 29 | 30 | Set-AzureRmContext -SubscriptionId $SubscriptionId 31 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 32 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 33 | 34 | # starting attach / detach in an endless while loop 35 | Write-Output(Get-Date) 36 | 37 | Write-Output("({0}) getting vm" -f $counter) 38 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 39 | Write-Output("({0}) attaching disk at LUN {1}" -f $counter, $lun) 40 | Add-AzureRmVMDataDisk -VM $vm -Name $diskName -VhdUri $targetVhd -LUN $lun -Caching ReadWrite -CreateOption Attach -DiskSizeInGB $null 41 | Write-Output("({0}) updating Azure VM (add)" -f $counter) 42 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 43 | if ($result -ne $null) 44 | { 45 | Write-Output(Get-Date) 46 | Write-Output("UpdateStatus (add): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 47 | } 48 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 49 | Write-Output(Get-Date) 50 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/attachLUN0-9.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [string] 16 | [ValidateNotNullOrEmpty()] 17 | $ContainerName="datadisk", 18 | 19 | [string] 20 | [ValidateNotNullOrEmpty()] 21 | $vmName = "linuxvm" 22 | ) 23 | 24 | Set-AzureRmContext -SubscriptionId $SubscriptionId 25 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 26 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 27 | 28 | # starting attach / detach in an endless while loop 29 | Write-Output(Get-Date) 30 | Write-Output("({0}) getting vm" -f $counter) 31 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 32 | 33 | $DiskCount=10 34 | For ($i=0; $i -lt $DiskCount; $i++) 35 | { 36 | $diskName = "datadisk{0}" -f $i 37 | $targetVhd = "https://{0}.blob.core.windows.net/{1}/dataDisk{2}.vhd" -f $StorageAccountName, $ContainerName, $i 38 | Write-Output("({0}) attaching disk at LUN {1}" -f $counter, $i) 39 | Add-AzureRmVMDataDisk -VM $vm -Name $diskName -VhdUri $targetVhd -LUN $i -Caching ReadWrite -CreateOption Attach -DiskSizeInGB $null 40 | } 41 | Write-Output("({0}) updating Azure VM (add)" -f $counter) 42 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 43 | if ($result -ne $null) 44 | { 45 | Write-Output(Get-Date) 46 | Write-Output("UpdateStatus (add): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 47 | } 48 | 49 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 50 | Write-Output(Get-Date) 51 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/attachLUN1-9.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [string] 16 | [ValidateNotNullOrEmpty()] 17 | $ContainerName="datadisk", 18 | 19 | [string] 20 | [ValidateNotNullOrEmpty()] 21 | $vmName = "linuxvm" 22 | ) 23 | 24 | Set-AzureRmContext -SubscriptionId $SubscriptionId 25 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 26 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 27 | 28 | # starting attach / detach in an endless while loop 29 | Write-Output(Get-Date) 30 | Write-Output("({0}) getting vm" -f $counter) 31 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 32 | 33 | $DiskCount=10 34 | For ($i=1; $i -lt $DiskCount; $i++) 35 | { 36 | $diskName = "datadisk{0}" -f $i 37 | $targetVhd = "https://{0}.blob.core.windows.net/{1}/dataDisk{2}.vhd" -f $StorageAccountName, $ContainerName, $i 38 | Write-Output("({0}) attaching disk at LUN {1}" -f $counter, $i) 39 | Add-AzureRmVMDataDisk -VM $vm -Name $diskName -VhdUri $targetVhd -LUN $i -Caching ReadWrite -CreateOption Attach -DiskSizeInGB $null 40 | } 41 | Write-Output("({0}) updating Azure VM (add)" -f $counter) 42 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 43 | if ($result -ne $null) 44 | { 45 | Write-Output(Get-Date) 46 | Write-Output("UpdateStatus (add): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 47 | } 48 | 49 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 50 | Write-Output(Get-Date) 51 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "masterEndpointDNSNamePrefix": { 3 | "value": "anhowe0622b" 4 | }, 5 | "sshRSAPublicKey": { 6 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/copydisks.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [int] 16 | $DiskCount=3, 17 | 18 | [string] 19 | [ValidateNotNullOrEmpty()] 20 | $ContainerName="datadisk", 21 | 22 | [string] 23 | [ValidateNotNullOrEmpty()] 24 | $vmName = "linuxvm", 25 | 26 | [string] 27 | [ValidateNotNullOrEmpty()] 28 | $srcDataDisk = "dataDisk0.vhd" 29 | ) 30 | 31 | Set-AzureRmContext -SubscriptionId $SubscriptionId 32 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 33 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 34 | 35 | # upload the images 36 | # good article on copying between accounts: https://www.opsgility.com/blog/windows-azure-powershell-reference-guide/copying-vhds-blobs-between-storage-accounts/ 37 | #$blob1 = Start-AzureStorageBlobCopy -srcUri $ubuntuSAS -DestContainer $ContainerName -DestBlob $ubuntudailyBlob -DestContext $destContext 38 | # https://ooyprplqchmsk.blob.core.windows.net/dd2/dataDisk0.vhd 39 | For ($i=1; $i -le $DiskCount; $i++) 40 | { 41 | $destblob="dataDisk{0}.vhd" -f $i 42 | $blob1 = Start-AzureStorageBlobCopy -SrcContainer $ContainerName -SrcBlob $srcDataDisk -SrcContext $destContext -DestContainer $ContainerName -DestBlob $destblob -DestContext $destContext 43 | $status = $blob1 | Get-AzureStorageBlobCopyState 44 | While($status.Status -eq "Pending"){ 45 | $status = $blob1 | Get-AzureStorageBlobCopyState 46 | Start-Sleep 10 47 | $status 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $SubscriptionId="b52fce95-de5f-4b37-afca-db203a5d0b6a" 3 | Set-AzureRmContext -SubscriptionId $SubscriptionId 4 | $deployName="anhowe0622b" 5 | $RGName=$deployName 6 | $locName="West US" 7 | $templateFile= "azuredeploy.json" 8 | $templateParameterFile= "cluster.parameters.json" 9 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 10 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 11 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/detachAllDisks.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [string] 16 | [ValidateNotNullOrEmpty()] 17 | $vmName = "linuxvm" 18 | ) 19 | 20 | Set-AzureRmContext -SubscriptionId $SubscriptionId 21 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 22 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 23 | 24 | # starting attach / detach in an endless while loop 25 | Write-Output(Get-Date) 26 | Write-Output("({0}) getting vm" -f $counter) 27 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 28 | 29 | $DiskCount=16 30 | For ($i=$DiskCount; $i -ge 0; $i--) 31 | { 32 | $diskName = "datadisk{0}" -f $i 33 | Remove-AzureRmVMDataDisk -VM $vm -Name $diskName 34 | } 35 | 36 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 37 | if ($result -ne $null) 38 | { 39 | Write-Output(Get-Date) 40 | Write-Output("UpdateStatus (remove): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 41 | } 42 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 43 | Write-Output(Get-Date) 44 | -------------------------------------------------------------------------------- /simplelinux-attachblankdisk/detachLUN.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="Standard")] 2 | param( 3 | [string] 4 | [ValidateNotNullOrEmpty()] 5 | $SubscriptionId, 6 | 7 | [string] 8 | [ValidateNotNullOrEmpty()] 9 | $StorageAccountName, 10 | 11 | [string] 12 | [ValidateNotNullOrEmpty()] 13 | $RGname, 14 | 15 | [int] 16 | $Lun, 17 | 18 | [string] 19 | [ValidateNotNullOrEmpty()] 20 | $ContainerName="datadisk", 21 | 22 | [string] 23 | [ValidateNotNullOrEmpty()] 24 | $vmName = "linuxvm" 25 | ) 26 | 27 | $diskName = "datadisk{0}" -f $lun 28 | $targetVhd = "https://{0}.blob.core.windows.net/{1}/dataDisk{2}.vhd" -f $StorageAccountName, $ContainerName, $lun 29 | 30 | Set-AzureRmContext -SubscriptionId $SubscriptionId 31 | $storageKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -StorageAccountName $StorageAccountName).Key1 32 | $destContext=New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey 33 | 34 | # starting attach / detach in an endless while loop 35 | Write-Output(Get-Date) 36 | 37 | Write-Output("({0}) getting vm" -f $counter) 38 | $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 39 | Write-Output("({0}) attaching disk at LUN {1}" -f $counter, $lun) 40 | Remove-AzureRmVMDataDisk -VM $vm -Name $diskName 41 | Write-Output("({0}) updating Azure VM (remove)" -f $counter) 42 | $result=Update-AzureRmVM -ResourceGroupName $rgName -VM $vm 43 | if ($result -ne $null) 44 | { 45 | Write-Output(Get-Date) 46 | Write-Output("UpdateStatus (add): {0}, {1}, {2}, {3}, {4}" -f $result.StatusCode,$result.Status, $result.RequestId,$result.Error,$result.ErrorText) 47 | } 48 | Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName 49 | Write-Output(Get-Date) 50 | -------------------------------------------------------------------------------- /simplelinux/README.md: -------------------------------------------------------------------------------- 1 | # Boot a simple windows VM 2 | 3 | This demonstrates booting a simple windows VM. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /simplelinux/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminPassword": { 6 | "type": "securestring", 7 | "metadata": { 8 | "description": "Password for the Virtual Machine." 9 | } 10 | }, 11 | "masterEndpointDNSNamePrefix": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." 15 | } 16 | }, 17 | "sshRSAPublicKey": { 18 | "type": "string", 19 | "defaultValue": "", 20 | "metadata": { 21 | "description": "SSH public key used for auth to all Linux machines. Not Required. If not set, you must provide a password key." 22 | } 23 | } 24 | }, 25 | "variables": { 26 | "adminPassword": "[parameters('adminPassword')]", 27 | "masterEndpointDNSNamePrefix": "[parameters('masterEndpointDNSNamePrefix')]", 28 | "sshRSAPublicKey": "[parameters('sshRSAPublicKey')]", 29 | "newStorageAccountName": "[concat(uniqueString(variables('masterEndpointDNSNamePrefix')))]", 30 | "adminUsername": "azureuser", 31 | "osImagePublisher": "CoreOS", 32 | "osImageOffer": "CoreOS", 33 | "osImageSKU": "Beta", 34 | "osImageVersion": "latest", 35 | "nicName": "myVMNic", 36 | "addressPrefix": "10.0.0.0/16", 37 | "subnetName": "Subnet", 38 | "subnetPrefix": "10.0.0.0/24", 39 | "storageAccountType": "Standard_LRS", 40 | "publicIPAddressName": "myPublicIP", 41 | "publicIPAddressType": "Dynamic", 42 | "vmName": "linuxvm", 43 | "vmSize": "Standard_D2", 44 | "virtualNetworkName": "MyVNET", 45 | "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]", 46 | "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", 47 | "sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]" 48 | }, 49 | "resources": [ 50 | { 51 | "type": "Microsoft.Storage/storageAccounts", 52 | "name": "[variables('newStorageAccountName')]", 53 | "apiVersion": "2015-06-15", 54 | "location": "[resourceGroup().location]", 55 | "properties": { 56 | "accountType": "[variables('storageAccountType')]" 57 | } 58 | }, 59 | { 60 | "apiVersion": "2015-06-15", 61 | "type": "Microsoft.Network/publicIPAddresses", 62 | "name": "[variables('publicIPAddressName')]", 63 | "location": "[resourceGroup().location]", 64 | "properties": { 65 | "publicIPAllocationMethod": "[variables('publicIPAddressType')]", 66 | "dnsSettings": { 67 | "domainNameLabel": "[variables('masterEndpointDNSNamePrefix')]" 68 | } 69 | } 70 | }, 71 | { 72 | "apiVersion": "2015-06-15", 73 | "type": "Microsoft.Network/virtualNetworks", 74 | "name": "[variables('virtualNetworkName')]", 75 | "location": "[resourceGroup().location]", 76 | "properties": { 77 | "addressSpace": { 78 | "addressPrefixes": [ 79 | "[variables('addressPrefix')]" 80 | ] 81 | }, 82 | "subnets": [ 83 | { 84 | "name": "[variables('subnetName')]", 85 | "properties": { 86 | "addressPrefix": "[variables('subnetPrefix')]" 87 | } 88 | } 89 | ] 90 | } 91 | }, 92 | { 93 | "apiVersion": "2015-06-15", 94 | "type": "Microsoft.Network/networkInterfaces", 95 | "name": "[variables('nicName')]", 96 | "location": "[resourceGroup().location]", 97 | "dependsOn": [ 98 | "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", 99 | "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" 100 | ], 101 | "properties": { 102 | "ipConfigurations": [ 103 | { 104 | "name": "ipconfig1", 105 | "properties": { 106 | "privateIPAllocationMethod": "Dynamic", 107 | "publicIPAddress": { 108 | "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]" 109 | }, 110 | "subnet": { 111 | "id": "[variables('subnetRef')]" 112 | } 113 | } 114 | } 115 | ] 116 | } 117 | }, 118 | { 119 | "apiVersion": "2015-06-15", 120 | "type": "Microsoft.Compute/virtualMachines", 121 | "name": "[variables('vmName')]", 122 | "location": "[resourceGroup().location]", 123 | "dependsOn": [ 124 | "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]", 125 | "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 126 | ], 127 | "properties": { 128 | "hardwareProfile": { 129 | "vmSize": "[variables('vmSize')]" 130 | }, 131 | "osProfile": { 132 | "computername": "[variables('vmName')]", 133 | "adminUsername": "[variables('adminUsername')]", 134 | "adminPassword": "[variables('adminPassword')]", 135 | "linuxConfiguration": { 136 | "ssh": { 137 | "publicKeys": [ 138 | { 139 | "path": "[variables('sshKeyPath')]", 140 | "keyData": "[variables('sshRSAPublicKey')]" 141 | } 142 | ] 143 | } 144 | } 145 | }, 146 | "storageProfile": { 147 | "imageReference": { 148 | "publisher": "[variables('osImagePublisher')]", 149 | "offer": "[variables('osImageOffer')]", 150 | "sku": "[variables('osImageSKU')]", 151 | "version": "[variables('osImageVersion')]" 152 | }, 153 | "osDisk": { 154 | "name": "osdisk", 155 | "vhd": { 156 | "uri": "[concat('http://',variables('newStorageAccountName'),'.blob.core.windows.net/vhds/osdisk.vhd')]" 157 | }, 158 | "caching": "ReadWrite", 159 | "createOption": "FromImage" 160 | } 161 | }, 162 | "networkProfile": { 163 | "networkInterfaces": [ 164 | { 165 | "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]" 166 | } 167 | ] 168 | }, 169 | "diagnosticsProfile": { 170 | "bootDiagnostics": { 171 | "enabled": "true", 172 | "storageUri": "[concat('http://',variables('newStorageAccountName'),'.blob.core.windows.net')]" 173 | } 174 | } 175 | } 176 | } 177 | ] 178 | } 179 | -------------------------------------------------------------------------------- /simplelinux/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "adminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "masterEndpointDNSNamePrefix": { 6 | "value": "anhowe0304coreos" 7 | }, 8 | "sshRSAPublicKey": { 9 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /simplelinux/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $deployName="anhowe0304coreos" 3 | $RGName=$deployName 4 | $locName="West US" 5 | $templateFile= "azuredeploy.json" 6 | $templateParameterFile= "cluster.parameters.json" 7 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 8 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 9 | -------------------------------------------------------------------------------- /simplemultilinux-swapdisks/README.md: -------------------------------------------------------------------------------- 1 | # Multi Node Linux Cluster 2 | 3 | This demonstrates booting multiple linux machines and shows how to setup an experiment to cause the OS drive to land on SDB1. 4 | 5 | 6 | 7 | 8 | 9 | # Repro to swap disks 10 | 11 | 1. deploy the templateFile using your CLI or clicking deploy to portal above. Choose one of the multi core machines 12 | 13 | 2. SSH to the first machine on port 2200 (second machine is on port 2201, 3rd on port 2202, and so on) 14 | 15 | 3. You need to place your private key in /home/azureuser/.ssh 16 | 1. `mkdir .ssh` 17 | 2. `cd .ssh` 18 | 3. `vi id_rsa` to edit your file and paste in the contents of your private key 19 | 4. `chmod 600 ~/.ssh/id_rsa` 20 | 21 | 4. paste in the contents of `scandrives.sh` and `findr.sh` into `/home/azureuser` 22 | 23 | 5. `chmod +x /home/azureuser/scandrives.sh` 24 | 25 | 6. `chmod +x /home/azureuser/findr.sh` 26 | 27 | 7. `findr.sh` 28 | 29 | 8. wait until the script breaks out with a repro. 30 | 31 | # Repro to show /etc/fstab gets written incorrectly 32 | 33 | 1. deploy the templateFile using your CLI or clicking deploy to portal above. Choose one of the multi core machines 34 | 35 | 2. SSH to the first machine on port 2200 (second machine is on port 2201, 3rd on port 2202, and so on) 36 | 37 | 3. You need to place your private key in /home/azureuser/.ssh 38 | 1. `mkdir .ssh` 39 | 2. `cd .ssh` 40 | 3. `vi id_rsa` to edit your file and paste in the contents of your private key 41 | 4. `chmod 600 ~/.ssh/id_rsa` 42 | 43 | 4. paste in the contents of `scandrives.sh` into `/home/azureuser` 44 | 45 | 5. `chmod +x /home/azureuser/scandrives.sh` 46 | 47 | 6. `./scandrives.sh --get-fstab` to see the values in /etc/fstab of all machines, and observe /dev/disk/azure/resource-part1 refers to /mount 48 | 49 | 7. (steps 1-7 must be done within first 10 minutes after cluster has deployed) './scandrives.sh --reboot-nodes' to reboot all machines 50 | 51 | 8. after 30 seconds `./scandrives.sh --get-fstab` and notice how all /etc/fstab files have been re-written and /dev/sdb1 refers to /mount 52 | 53 | # Repro to get NTFS mounted ephemeral disk 54 | 55 | 1. deploy the templateFile using your CLI or clicking deploy to portal above. Choose at least 20 machines with 16.04.0-LTS. 56 | 57 | 2. SSH to the first machine on port 2200 (second machine is on port 2201, 3rd on port 2202, and so on) 58 | 59 | 3. You need to place your private key in /home/azureuser/.ssh 60 | 1. `mkdir .ssh` 61 | 2. `cd .ssh` 62 | 3. `vi id_rsa` to edit your file and paste in the contents of your private key 63 | 4. `chmod 600 ~/.ssh/id_rsa` 64 | 65 | 4. paste in the contents of `scandrives.sh` and `findr.sh` into `/home/azureuser` 66 | 67 | 5. `chmod +x /home/azureuser/scandrives.sh` 68 | 69 | 6. `./scandrives.sh --get-mounts | grep fuse` - this may show an NTFS mounted drive 70 | 71 | 7. Edit the template to choose a different VM Size, and re-deploy 72 | 73 | 8. once deployed, run `./scandrives.sh --get-mounts | grep fuse` to show the NTFS mounted drives 74 | -------------------------------------------------------------------------------- /simplemultilinux-swapdisks/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "masterEndpointDNSNamePrefix": { 3 | "value": "anhowe0803b" 4 | }, 5 | "sshRSAPublicKey": { 6 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 7 | }, 8 | "vmCount": { 9 | "value": 50 10 | }, 11 | "vmSize" : { 12 | "value": "Standard_D1_v2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /simplemultilinux-swapdisks/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $SubscriptionId="b52fce95-de5f-4b37-afca-db203a5d0b6a" 3 | Set-AzureRmContext -SubscriptionId $SubscriptionId 4 | $deployName="anhowe0714a" 5 | $RGName=$deployName 6 | #$locName="East US" 7 | #$locName="brazilsouth" 8 | #$locName="West US" 9 | $locName="East US2" 10 | $templateFile= "azuredeploy.json" 11 | $templateParameterFile= "cluster.parameters.json" 12 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 13 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 14 | -------------------------------------------------------------------------------- /simplemultilinux-swapdisks/findr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this script will continously reboot all machines on the cluster until the 4 | # drives swap on at least 1 machine. 5 | 6 | date 7 | while true; do 8 | if /home/azureuser/scandrives.sh --get-mounts | grep -q sdb 9 | then 10 | echo "hit found" 11 | date 12 | break 13 | fi 14 | /home/azureuser/scandrives.sh --reboot-nodes > /dev/null 15 | sleep 30 16 | done 17 | /home/azureuser/scandrives.sh --get-mounts 18 | -------------------------------------------------------------------------------- /simplemultilinux-swapdisks/scandrives.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROGNAME=${0##*/} 4 | AZUREUSER=azureuser 5 | 6 | usage() 7 | { 8 | cat << EO 9 | Usage: $PROGNAME [options] 10 | 11 | Manage the cluster. 12 | 13 | Options: 14 | 15 | Cluster Management 16 | --get-fstab cat output of /etc/fstab 17 | --get-mounts get device of / and /mnt 18 | --reboot-nodes reboot all nodes (except this one) 19 | 20 | Other 21 | --help show this output 22 | EO 23 | } 24 | 25 | if [ $# -eq 0 ]; then 26 | usage 27 | exit 1 28 | fi 29 | 30 | ARGS=$(getopt -s bash -o h --longoptions help,get-fstab,get-mounts,reboot-nodes --name $PROGNAME -- "$@") 31 | 32 | if [ $? -ne 0 ] ; then 33 | usage 34 | exit 1 35 | fi 36 | 37 | eval set -- "$ARGS" 38 | 39 | GETFSTAB=false 40 | GETMOUNTS=false 41 | REBOOTNODES=false 42 | 43 | while true; do 44 | case $1 in 45 | -h|--help) 46 | usage 47 | exit 0 48 | ;; 49 | 50 | --get-fstab) 51 | shift 52 | GETFSTAB=true 53 | ;; 54 | 55 | --get-mounts) 56 | shift 57 | GETMOUNTS=true 58 | ;; 59 | 60 | --reboot-nodes) 61 | shift 62 | REBOOTNODES=true 63 | ;; 64 | 65 | --) 66 | shift 67 | break 68 | ;; 69 | 70 | *) 71 | echo "ERROR: invalid argument or missing parameter for $1" 72 | usage 73 | exit 1 74 | esac 75 | done 76 | 77 | installTools() { 78 | type pssh > /dev/null 2>&1 79 | if [ $? -ne 0 ] ; then 80 | sudo apt-get update && sudo apt-get install -y wget python ssh nmap 81 | sudo wget https://parallel-ssh.googlecode.com/files/pssh-2.3.1.tar.gz -O /tmp/pssh.tar.gz 82 | sudo tar xvf /tmp/pssh.tar.gz --directory /tmp 83 | cd /tmp/pssh-2.3.1 && sudo python setup.py install && cd - 84 | sudo rm -rf /tmp/* 85 | fi 86 | } 87 | installTools 88 | 89 | getnodes() { 90 | if [ -e .nodes ] ; then 91 | cat .nodes 92 | else 93 | local -a arr=() 94 | RESULTS="$(nmap -sn 10.0.0.0/25 | grep report | awk '{print $5}')" 95 | while read -r line ; do 96 | arr=("${arr[@]}" "$line") 97 | done <<< "$RESULTS" 98 | local nodesString=$(declare -p arr | sed -e 's/^declare -a arr=//' | tee .nodes) 99 | local -a nodes=() 100 | eval "declare -a nodes=${nodesString}" 101 | for node in "${nodes[@]}"; do 102 | `ssh-keyscan -H $node >> ~/.ssh/known_hosts` 103 | done 104 | echo $nodesString 105 | fi 106 | } 107 | 108 | get-fstab() { 109 | local nodesString="$(getnodes)" 110 | local -a nodes=() 111 | eval "declare -a nodes=${nodesString}" 112 | 113 | for node in "${nodes[@]}"; do 114 | hostString="$hostString -H $AZUREUSER@$node" 115 | done 116 | pssh -i $hostString "ls -l /etc/fstab && sudo cat /etc/fstab" 117 | } 118 | if [ "$GETFSTAB" = true ] ; then 119 | get-fstab 120 | exit 0 121 | fi 122 | 123 | get-mounts() { 124 | local nodesString="$(getnodes)" 125 | local -a nodes=() 126 | eval "declare -a nodes=${nodesString}" 127 | 128 | for node in "${nodes[@]}"; do 129 | hostString="$hostString -H $AZUREUSER@$node" 130 | done 131 | pssh -i $hostString "mount | grep -e ' on /mnt ' -e ' on / '" 132 | } 133 | if [ "$GETMOUNTS" = true ] ; then 134 | get-mounts 135 | exit 0 136 | fi 137 | 138 | reboot-nodes() { 139 | local nodesString="$(getnodes)" 140 | local -a nodes=() 141 | eval "declare -a nodes=${nodesString}" 142 | 143 | me=`hostname -i` 144 | 145 | for node in "${nodes[@]}"; do 146 | if [ "$node" != $me ] ; then 147 | hostString="$hostString -H $AZUREUSER@$node" 148 | fi 149 | done 150 | pssh -i $hostString "sudo shutdown -r now" 151 | } 152 | if [ "$REBOOTNODES" = true ] ; then 153 | reboot-nodes 154 | exit 0 155 | fi 156 | -------------------------------------------------------------------------------- /simplemultilinux/README.md: -------------------------------------------------------------------------------- 1 | # Boot a simple windows VM 2 | 3 | This demonstrates booting multiple linux. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /simplemultilinux/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "masterEndpointDNSNamePrefix": { 3 | "value": "anhowe0329m" 4 | }, 5 | "sshRSAPublicKey": { 6 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 7 | }, 8 | "vmCount": { 9 | "value": 20 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /simplemultilinux/deployVM0.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference="Continue" 2 | $deployName="anhowe0329m" 3 | $RGName=$deployName 4 | $locName="West US" 5 | $templateFile= "azuredeploy.json" 6 | $templateParameterFile= "cluster.parameters.json" 7 | New-AzureRmResourceGroup -Name $RGName -Location $locName -Force 8 | New-AzureRmResourceGroupDeployment -Name $deployName -ResourceGroupName $RGName -TemplateParameterFile $templateParameterFile -TemplateFile $templateFile 9 | -------------------------------------------------------------------------------- /simplewindows-customdata/README.md: -------------------------------------------------------------------------------- 1 | # Boot a simple windows VM with customData 2 | 3 | This demonstrates booting a simple windows VM using customData to deliver a powershell script for execution on the VM. This also deploys the custom script extension to execute the script. The script is gzipped and base64 encoded for most efficient delivery. 4 | 5 | 6 | 7 | 8 | 9 | Here are some notes: 10 | 11 | 1. Use the gen-ps-launcher-template-vars.py and launcher.ps1 to generate the template variables. Once generate, put these in the variables section of the template. The launcher will automatically unzip and launch the powershell in %SYSTEMDRIVE%\AzureData\CustomData.bin. 12 | 13 | 2. Use the gen-oneline-customdata.py to gzip the powershell script payload. This gzips the payload for most efficient delivery. Take the output from this and paste into the customData section of the Windows VM. 14 | 15 | The azuredeploy.json demonstrates the launcher and a sample powershell script. Once you deploy the VM and extension, you can confirm 16 | -------------------------------------------------------------------------------- /simplewindows-customdata/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "adminPassword": { 3 | "value": "password1234$" 4 | }, 5 | "masterEndpointDNSNamePrefix": { 6 | "value": "anhowe0409wing" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /simplewindows-customdata/gen-oneline-customdata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import StringIO 6 | import sys 7 | 8 | def CompressEncodeFile(file): 9 | # read the script file 10 | with open(file) as f: 11 | content = f.read() 12 | compressedbuffer=StringIO.StringIO() 13 | 14 | # gzip the script file 15 | with gzip.GzipFile(fileobj=compressedbuffer, mode='wb') as f: 16 | f.write(content) 17 | b64GzipStream=base64.b64encode(compressedbuffer.getvalue()) 18 | 19 | return b64GzipStream 20 | 21 | def usage(): 22 | print 23 | print " usage: %s file1" % os.path.basename(sys.argv[0]) 24 | print 25 | print " builds a one line custom data entry for writing a file" 26 | 27 | if __name__ == "__main__": 28 | if len(sys.argv)!=2: 29 | usage() 30 | sys.exit(1) 31 | 32 | file = sys.argv[1] 33 | if not os.path.exists(file): 34 | print "Error: file %s does not exist" 35 | sys.exit(2) 36 | 37 | # build the yml file for cluster 38 | oneline = CompressEncodeFile(file) 39 | 40 | print '"customData": "%s"' % (oneline) 41 | -------------------------------------------------------------------------------- /simplewindows-customdata/gen-ps-launcher-template-vars.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import re 6 | import StringIO 7 | import sys 8 | 9 | # goal "commandToExecute": "[variables('jumpboxWindowsCustomScript')]" 10 | 11 | def convertToOneArmTemplateLine(file): 12 | with open(file) as f: 13 | content = f.read() 14 | 15 | oneline=" ; ".join(content.split("\n")) 16 | oneline="'".join(oneline.split('"')) 17 | 18 | codeRegEx=re.compile(r".arguments\s*=\s*'([^']*)'\s*;") 19 | matchArray=codeRegEx.findall(oneline) 20 | if len(matchArray)>1: 21 | print oneline 22 | raise AssertionError, "incorrect number of matches" 23 | argumentList='' 24 | if len(matchArray) == 1: 25 | argumentList = matchArray[0] 26 | oneline=codeRegEx.sub('',oneline) 27 | 28 | return oneline,argumentList 29 | 30 | def usage(): 31 | print 32 | print " usage: %s file1" % os.path.basename(sys.argv[0]) 33 | print 34 | print " builds a one line string to send to commandToExecute" 35 | 36 | if __name__ == "__main__": 37 | if len(sys.argv)!=2: 38 | usage() 39 | sys.exit(1) 40 | 41 | file = sys.argv[1] 42 | if not os.path.exists(file): 43 | print "Error: file %s does not exist" 44 | sys.exit(2) 45 | 46 | # build the yml file for cluster 47 | oneline, argumentList = convertToOneArmTemplateLine(file) 48 | 49 | print "copy/paste the following rows into your templates variables and use" 50 | print "[variables('windowsCustomScript')] as the commandToExecute in your" 51 | print "custom script extension" 52 | print 53 | print '"windowsCustomScriptArguments": "$arguments = \'%s\' ; ",' % (argumentList) 54 | print '"windowsCustomScriptSuffix": "%s",' % (oneline) 55 | print '"windowsCustomScript": "[concat(\'powershell.exe -ExecutionPolicy Unrestricted -command \\"\', variables(\'windowsCustomScriptArguments\'), variables(\'windowsCustomScriptSuffix\'), \'\\"\')]",' 56 | #print '"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -command \\"%s\\""' % (oneline) 57 | -------------------------------------------------------------------------------- /simplewindows-customdata/helloworld.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(DefaultParameterSetName="HelloWorld")] 2 | param( 3 | [Parameter(ParameterSetName="HelloWorld", Mandatory=$true)] 4 | [string] 5 | [ValidateNotNullOrEmpty()] 6 | $FirstParameter 7 | ) 8 | 9 | $content = "hello world with parameter $FirstParameter" 10 | $outFile = "{0}\\AzureData\\hello.txt" -f $env:SYSTEMDRIVE 11 | Write-Output($outFile) 12 | $content | Out-File -FilePath $outFile -Encoding ascii 13 | Write-Output("hello world with parameter $FirstParameter") 14 | -------------------------------------------------------------------------------- /simplewindows-customdata/launcher.ps1: -------------------------------------------------------------------------------- 1 | $arguments = "-FirstParameter helloParameter" 2 | $inputFile = "%SYSTEMDRIVE%\\AzureData\\CustomData.bin" 3 | $outputFile = "%SYSTEMDRIVE%\\AzureData\\CustomDataSetupScript.ps1" 4 | $inputStream = New-Object System.IO.FileStream $inputFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read) 5 | $sr = New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream($inputStream, [System.IO.Compression.CompressionMode]::Decompress)) 6 | $sr.ReadToEnd() | Out-File($outputFile) 7 | Invoke-Expression("{0} {1}" -f $outputFile, $arguments) 8 | -------------------------------------------------------------------------------- /simplewindows/README.md: -------------------------------------------------------------------------------- 1 | # Boot a simple windows VM 2 | 3 | This demonstrates booting a simple windows VM. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /simplewindows/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminPassword": { 6 | "type": "securestring", 7 | "metadata": { 8 | "description": "Password for the Virtual Machine." 9 | } 10 | }, 11 | "masterEndpointDNSNamePrefix": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Unique DNS Name for the Public IP used to access the Virtual Machine." 15 | } 16 | } 17 | }, 18 | "variables": { 19 | "adminPassword": "[parameters('adminPassword')]", 20 | "masterEndpointDNSNamePrefix": "[parameters('masterEndpointDNSNamePrefix')]", 21 | "newStorageAccountName": "[concat(uniqueString(variables('masterEndpointDNSNamePrefix')))]", 22 | "adminUsername": "azureuser", 23 | "osImagePublisher": "MicrosoftVisualStudio", 24 | "osImageOffer": "VisualStudio", 25 | "osImageSKU": "VS-2015-Ent-AzureSDK-2.8-WS2012R2", 26 | "osImageVersion": "latest", 27 | "OSDiskName": "osdiskforwindowssimple", 28 | "nicName": "myVMNic", 29 | "addressPrefix": "10.0.0.0/16", 30 | "subnetName": "Subnet", 31 | "subnetPrefix": "10.0.0.0/24", 32 | "storageAccountType": "Standard_LRS", 33 | "publicIPAddressName": "myPublicIP", 34 | "publicIPAddressType": "Dynamic", 35 | "vmName": "MyWindowsVM", 36 | "vmSize": "Standard_D2", 37 | "virtualNetworkName": "MyVNET", 38 | "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]", 39 | "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]" 40 | }, 41 | "resources": [ 42 | { 43 | "type": "Microsoft.Storage/storageAccounts", 44 | "name": "[variables('newStorageAccountName')]", 45 | "apiVersion": "2015-06-15", 46 | "location": "[resourceGroup().location]", 47 | "properties": { 48 | "accountType": "[variables('storageAccountType')]" 49 | } 50 | }, 51 | { 52 | "apiVersion": "2015-06-15", 53 | "type": "Microsoft.Network/publicIPAddresses", 54 | "name": "[variables('publicIPAddressName')]", 55 | "location": "[resourceGroup().location]", 56 | "properties": { 57 | "publicIPAllocationMethod": "[variables('publicIPAddressType')]", 58 | "dnsSettings": { 59 | "domainNameLabel": "[variables('masterEndpointDNSNamePrefix')]" 60 | } 61 | } 62 | }, 63 | { 64 | "apiVersion": "2015-06-15", 65 | "type": "Microsoft.Network/virtualNetworks", 66 | "name": "[variables('virtualNetworkName')]", 67 | "location": "[resourceGroup().location]", 68 | "properties": { 69 | "addressSpace": { 70 | "addressPrefixes": [ 71 | "[variables('addressPrefix')]" 72 | ] 73 | }, 74 | "subnets": [ 75 | { 76 | "name": "[variables('subnetName')]", 77 | "properties": { 78 | "addressPrefix": "[variables('subnetPrefix')]" 79 | } 80 | } 81 | ] 82 | } 83 | }, 84 | { 85 | "apiVersion": "2015-06-15", 86 | "type": "Microsoft.Network/networkInterfaces", 87 | "name": "[variables('nicName')]", 88 | "location": "[resourceGroup().location]", 89 | "dependsOn": [ 90 | "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", 91 | "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" 92 | ], 93 | "properties": { 94 | "ipConfigurations": [ 95 | { 96 | "name": "ipconfig1", 97 | "properties": { 98 | "privateIPAllocationMethod": "Dynamic", 99 | "publicIPAddress": { 100 | "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]" 101 | }, 102 | "subnet": { 103 | "id": "[variables('subnetRef')]" 104 | } 105 | } 106 | } 107 | ] 108 | } 109 | }, 110 | { 111 | "apiVersion": "2015-06-15", 112 | "type": "Microsoft.Compute/virtualMachines", 113 | "name": "[variables('vmName')]", 114 | "location": "[resourceGroup().location]", 115 | "dependsOn": [ 116 | "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]", 117 | "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 118 | ], 119 | "properties": { 120 | "hardwareProfile": { 121 | "vmSize": "[variables('vmSize')]" 122 | }, 123 | "osProfile": { 124 | "computername": "[variables('vmName')]", 125 | "adminUsername": "[variables('adminUsername')]", 126 | "adminPassword": "[variables('adminPassword')]" 127 | }, 128 | "storageProfile": { 129 | "imageReference": { 130 | "publisher": "[variables('osImagePublisher')]", 131 | "offer": "[variables('osImageOffer')]", 132 | "sku": "[variables('osImageSKU')]", 133 | "version": "[variables('osImageVersion')]" 134 | }, 135 | "osDisk": { 136 | "name": "osdisk", 137 | "vhd": { 138 | "uri": "[concat('http://',variables('newStorageAccountName'),'.blob.core.windows.net/vhds/',variables('OSDiskName'),'.vhd')]" 139 | }, 140 | "caching": "ReadWrite", 141 | "createOption": "FromImage" 142 | } 143 | }, 144 | "networkProfile": { 145 | "networkInterfaces": [ 146 | { 147 | "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]" 148 | } 149 | ] 150 | }, 151 | "diagnosticsProfile": { 152 | "bootDiagnostics": { 153 | "enabled": "true", 154 | "storageUri": "[concat('http://',variables('newStorageAccountName'),'.blob.core.windows.net')]" 155 | } 156 | } 157 | } 158 | } 159 | ] 160 | } 161 | -------------------------------------------------------------------------------- /stgscaling/README.md: -------------------------------------------------------------------------------- 1 | # Scaling across 1296 storage accounts 2 | 3 | This enables scaling to 12960 vms by spreading across a 2 character prefix, where each prefix is 36 characters. 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /stgscaling/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": {}, 5 | "variables": { 6 | "newStorageAccountNamePrefix": "anhowe921e", 7 | "vmsPerStorageAccount": 20, 8 | "agentCount": 50, 9 | "storageAccountsCount": "[add(div(variables('agentCount'), variables('vmsPerStorageAccount')), mod(add(mod(variables('agentCount'), variables('vmsPerStorageAccount')),2), add(mod(variables('agentCount'), variables('vmsPerStorageAccount')),1)))]", 10 | "storageAccountType": "Standard_LRS", 11 | "storageAccountPrefix": [ 12 | "0","6","c","i","o","u","1","7","d","j","p","v", 13 | "2","8","e","k","q","w","3","9","f","l","r","x", 14 | "4","a","g","m","s","y","5","b","h","n","t","z" 15 | ], 16 | "storageAccountPrefixCount": "[length(variables('storageAccountPrefix'))]" 17 | }, 18 | "resources": [ 19 | { 20 | "type": "Microsoft.Storage/storageAccounts", 21 | "name": "[concat(variables('storageAccountPrefix')[mod(copyIndex(),variables('storageAccountPrefixCount'))],variables('storageAccountPrefix')[div(copyIndex(),variables('storageAccountPrefixCount'))],variables('newStorageAccountNamePrefix'),copyIndex(1))]", 22 | "apiVersion": "2015-05-01-preview", 23 | "location": "[resourceGroup().location]", 24 | "copy": { 25 | "name": "vmLoopNode", 26 | "count": "[variables('storageAccountsCount')]" 27 | }, 28 | "properties": { 29 | "accountType": "[variables('storageAccountType')]" 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /swarm/README.md: -------------------------------------------------------------------------------- 1 | # Mesos cluster with Marathon and Swarm 2 | 3 | This Microsoft Azure template creates an Docker Swarm cluster on a configurable number of agent machines. 4 | 5 | Access the cluster via SSH on port 2211 on masterFQDN. 6 | 7 | Portal Launch Button|Cluster Type 8 | --- | --- 9 | |Swarm 10 | -------------------------------------------------------------------------------- /swarm/cluster.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "jumpboxEndpointDNSNamePrefix": { 3 | "value": "swarmjb1122g" 4 | }, 5 | "masterEndpointDNSNamePrefix": { 6 | "value": "swarmmgmt1122g" 7 | }, 8 | "agentEndpointDNSNamePrefix": { 9 | "value": "swarmapp1122g" 10 | }, 11 | "agentCount": { 12 | "value": 3 13 | }, 14 | "masterCount": { 15 | "value": 3 16 | }, 17 | "agentVMSize" : { 18 | "value": "Standard_A1" 19 | }, 20 | "sshRSAPublicKey": { 21 | "value": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /swarm/configure-swarm-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################### 4 | # Configure Mesos One Box 5 | # 6 | # This installs the following components 7 | # - zookeepr 8 | # - mesos master 9 | # - marathon 10 | # - mesos agent 11 | ########################################################### 12 | 13 | set -x 14 | 15 | echo "starting mesos cluster configuration" 16 | date 17 | ps ax 18 | 19 | SWARM_VERSION="swarm:latest" 20 | ############# 21 | # Parameters 22 | ############# 23 | 24 | MASTERCOUNT=${1} 25 | MASTERPREFIX=${2} 26 | MASTERFIRSTADDR=${3} 27 | AZUREUSER=${4} 28 | VMNAME=`hostname` 29 | VMNUMBER=`echo $VMNAME | sed 's/.*[^0-9]\([0-9]\+\)*$/\1/'` 30 | VMPREFIX=`echo $VMNAME | sed 's/\(.*[^0-9]\)*[0-9]\+$/\1/'` 31 | BASESUBNET="10.0.0." 32 | 33 | echo "Master Count: $MASTERCOUNT" 34 | echo "Master Prefix: $MASTERPREFIX" 35 | echo "Master First Addr: $MASTERFIRSTADDR" 36 | echo "vmname: $VMNAME" 37 | echo "VMNUMBER: $VMNUMBER, VMPREFIX: $VMPREFIX" 38 | echo "BASESUBNET: $BASESUBNET" 39 | echo "AZUREUSER: $AZUREUSER" 40 | 41 | ################### 42 | # Common Functions 43 | ################### 44 | 45 | ensureAzureNetwork() 46 | { 47 | # ensure the host name is resolvable 48 | hostResolveHealthy=1 49 | for i in {1..120}; do 50 | host $VMNAME 51 | if [ $? -eq 0 ] 52 | then 53 | # hostname has been found continue 54 | hostResolveHealthy=0 55 | echo "the host name resolves" 56 | break 57 | fi 58 | sleep 1 59 | done 60 | if [ $hostResolveHealthy -ne 0 ] 61 | then 62 | echo "host name does not resolve, aborting install" 63 | exit 1 64 | fi 65 | 66 | # ensure the network works 67 | networkHealthy=1 68 | for i in {1..12}; do 69 | wget -O/dev/null http://bing.com 70 | if [ $? -eq 0 ] 71 | then 72 | # hostname has been found continue 73 | networkHealthy=0 74 | echo "the network is healthy" 75 | break 76 | fi 77 | sleep 10 78 | done 79 | if [ $networkHealthy -ne 0 ] 80 | then 81 | echo "the network is not healthy, aborting install" 82 | ifconfig 83 | ip a 84 | exit 2 85 | fi 86 | # ensure the host ip can resolve 87 | networkHealthy=1 88 | for i in {1..120}; do 89 | hostname -i 90 | if [ $? -eq 0 ] 91 | then 92 | # hostname has been found continue 93 | networkHealthy=0 94 | echo "the network is healthy" 95 | break 96 | fi 97 | sleep 1 98 | done 99 | if [ $networkHealthy -ne 0 ] 100 | then 101 | echo "the network is not healthy, cannot resolve ip address, aborting install" 102 | ifconfig 103 | ip a 104 | exit 2 105 | fi 106 | } 107 | ensureAzureNetwork 108 | HOSTADDR=`hostname -i` 109 | 110 | ismaster () 111 | { 112 | if [ "$MASTERPREFIX" == "$VMPREFIX" ] 113 | then 114 | return 0 115 | else 116 | return 1 117 | fi 118 | } 119 | if ismaster ; then 120 | echo "this node is a master" 121 | fi 122 | 123 | isagent() 124 | { 125 | if ismaster ; then 126 | return 1 127 | else 128 | return 0 129 | fi 130 | } 131 | if isagent ; then 132 | echo "this node is an agent" 133 | fi 134 | 135 | ###################### 136 | # resolve self in DNS 137 | ###################### 138 | 139 | echo "$HOSTADDR $VMNAME" | sudo tee -a /etc/hosts 140 | 141 | ################ 142 | # Install Docker 143 | ################ 144 | 145 | echo "Installing and configuring docker" 146 | 147 | time wget -qO- https://get.docker.com | sh 148 | sudo usermod -aG docker $AZUREUSER 149 | if isagent ; then 150 | # Start Docker and listen on :2375 (no auth, but in vnet) 151 | echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:2375"' | sudo tee /etc/default/docker 152 | fi 153 | 154 | echo "Installing docker compose" 155 | curl -L https://github.com/docker/compose/releases/download/1.5.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose 156 | chmod +x /usr/local/bin/docker-compose 157 | 158 | sudo service docker restart 159 | 160 | ensureDocker() 161 | { 162 | # ensure that docker is healthy 163 | dockerHealthy=1 164 | for i in {1..3}; do 165 | sudo docker info 166 | if [ $? -eq 0 ] 167 | then 168 | # hostname has been found continue 169 | dockerHealthy=0 170 | echo "Docker is healthy" 171 | sudo docker ps -a 172 | break 173 | fi 174 | sleep 10 175 | done 176 | if [ $dockerHealthy -ne 0 ] 177 | then 178 | echo "Docker is not healthy" 179 | fi 180 | } 181 | ensureDocker 182 | 183 | ############################################## 184 | # configure init rules restart all processes 185 | ############################################## 186 | 187 | consulstr() 188 | { 189 | consulargs="" 190 | for i in `seq 0 $((MASTERCOUNT-1))` ; 191 | do 192 | MASTEROCTET=`expr $MASTERFIRSTADDR + $i` 193 | IPADDR="${BASESUBNET}${MASTEROCTET}" 194 | 195 | if [ "$VMNUMBER" -eq "0" ] 196 | then 197 | consulargs="${consulargs}-bootstrap-expect $MASTERCOUNT " 198 | fi 199 | if [ "$VMNUMBER" -eq "$i" ] 200 | then 201 | consulargs="${consulargs}-advertise $IPADDR " 202 | else 203 | consulargs="${consulargs}-retry-join $IPADDR " 204 | fi 205 | done 206 | echo $consulargs 207 | } 208 | 209 | consulargs=$(consulstr) 210 | MASTEROCTET=`expr $MASTERFIRSTADDR + $VMNUMBER` 211 | VMIPADDR="${BASESUBNET}${MASTEROCTET}" 212 | MASTER0IPADDR="${BASESUBNET}${MASTERFIRSTADDR}" 213 | 214 | if ismaster ; then 215 | mkdir -p /data/consul 216 | echo "consul: 217 | image: \"progrium/consul\" 218 | command: -server -node $VMNAME $consulargs 219 | ports: 220 | - \"8300:8300\" 221 | - \"8301:8301\" 222 | - \"8301:8301/udp\" 223 | - \"8302:8302\" 224 | - \"8302:8302/udp\" 225 | - \"8400:8400\" 226 | - \"8500:8500\" 227 | volumes: 228 | - \"/data/consul:/data\" 229 | restart: \"always\" 230 | swarm: 231 | image: \"$SWARM_VERSION\" 232 | command: manage --replication --advertise $HOSTADDR:2375 consul://$MASTER0IPADDR:8500/nodes 233 | ports: 234 | - \"2375:2375\" 235 | links: 236 | - \"consul\" 237 | volumes: 238 | - \"/etc/docker:/etc/docker\" 239 | restart: \"always\" 240 | " > /opt/azure/containers/docker-compose.yml 241 | 242 | pushd /opt/azure/containers/ 243 | docker-compose up -d 244 | popd 245 | echo "completed starting docker swarm on the master" 246 | fi 247 | 248 | if isagent ; then 249 | echo "swarm: 250 | image: \"$SWARM_VERSION\" 251 | restart: \"always\" 252 | command: join --advertise=$HOSTADDR:2375 consul://$MASTER0IPADDR:8500/nodes 253 | " > /opt/azure/containers/docker-compose.yml 254 | 255 | pushd /opt/azure/containers/ 256 | docker-compose up -d 257 | popd 258 | echo "completed starting docker swarm on the agent" 259 | fi 260 | 261 | echo "processes at end of script" 262 | ps ax 263 | date 264 | echo "completed mesos cluster configuration" 265 | -------------------------------------------------------------------------------- /swarm/gen-oneline-customdata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import base64 3 | import os 4 | import gzip 5 | import StringIO 6 | import sys 7 | 8 | def buildYMLFile(files): 9 | clusterYamlFile="""#cloud-config 10 | 11 | write_files: 12 | %s 13 | """ 14 | writeFileBlock=""" - encoding: gzip 15 | content: !!binary | 16 | %s 17 | path: /opt/azure/%s 18 | permissions: "0744" 19 | """ 20 | filelines="" 21 | for encodeFile in files: 22 | # read the script file 23 | with open(encodeFile) as f: 24 | content = f.read() 25 | compressedbuffer=StringIO.StringIO() 26 | 27 | # gzip the script file 28 | with gzip.GzipFile(fileobj=compressedbuffer, mode='wb') as f: 29 | f.write(content) 30 | b64GzipStream=base64.b64encode(compressedbuffer.getvalue()) 31 | filelines=filelines+(writeFileBlock % (b64GzipStream,encodeFile)) 32 | 33 | return clusterYamlFile % (filelines) 34 | 35 | def convertToOneArmTemplateLine(clusterYamlFile): 36 | # remove the \r\n 37 | oneline="\\n".join(clusterYamlFile.split("\n")) 38 | oneline='\\"'.join(oneline.split('"')) 39 | return oneline 40 | 41 | def usage(): 42 | print 43 | print " usage: %s file1 file2 file3 . . ." % os.path.basename(sys.argv[0]) 44 | print 45 | print " builds a one line custom data entry for writing one or" 46 | print " more files to /opt/azure" 47 | 48 | if __name__ == "__main__": 49 | if len(sys.argv)==1: 50 | usage() 51 | sys.exit(1) 52 | 53 | files = sys.argv[1:] 54 | for file in files: 55 | if not os.path.exists(file): 56 | print "Error: file %s does not exist" 57 | sys.exit(2) 58 | 59 | # build the yml file for cluster 60 | yml = buildYMLFile(files) 61 | 62 | # convert yml file to one line 63 | oneline = convertToOneArmTemplateLine(yml) 64 | print '"customData": "[base64(\'%s\')]"' % (oneline) 65 | -------------------------------------------------------------------------------- /vnet/README.md: -------------------------------------------------------------------------------- 1 | # Virtual Network 2 | 3 | This template implements a virtual network and a subnet. The output parameters provide the names of the created resources and the subnet ID of the VNET. 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /vnet/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "uniqueName": { 6 | "type": "string", 7 | "defaultValue": "vnet1", 8 | "metadata": { 9 | "description": "The unique name used for resource names" 10 | } 11 | }, 12 | "addressPrefix": { 13 | "type": "string", 14 | "defaultValue": "10.0.0.0/16", 15 | "metadata": { 16 | "description": "The address prefix for the VNET." 17 | } 18 | }, 19 | "subnetPrefix": { 20 | "type": "string", 21 | "defaultValue": "10.0.0.0/24", 22 | "metadata": { 23 | "description": "The subnet prefix for the VNET." 24 | } 25 | } 26 | }, 27 | "variables": { 28 | "uniqueName": "[parameters('uniqueName')]", 29 | "addressPrefix": "[parameters('addressPrefix')]", 30 | "subnetPrefix": "[parameters('subnetPrefix')]", 31 | "virtualNetworkName": "[concat('vnet-',variables('uniqueName'))]", 32 | "subnetName": "[concat('subnet-',variables('uniqueName'))]" 33 | }, 34 | "resources": [ 35 | { 36 | "apiVersion": "2017-10-01", 37 | "type": "Microsoft.Network/virtualNetworks", 38 | "name": "[variables('virtualNetworkName')]", 39 | "location": "[resourceGroup().location]", 40 | "properties": { 41 | "addressSpace": { 42 | "addressPrefixes": [ 43 | "[variables('addressPrefix')]" 44 | ] 45 | }, 46 | "subnets": [ 47 | { 48 | "name": "[variables('subnetName')]", 49 | "properties": { 50 | "addressPrefix": "[variables('subnetPrefix')]" 51 | } 52 | } 53 | ] 54 | } 55 | } 56 | ], 57 | "outputs": { 58 | "RESOURCE_GROUP": { 59 | "type": "string", 60 | "value": "[resourceGroup().name]" 61 | }, 62 | "LOCATION": { 63 | "type": "string", 64 | "value": "[resourceGroup().location]" 65 | }, 66 | "NETWORK": { 67 | "type": "string", 68 | "value": "[variables('virtualNetworkName')]" 69 | }, 70 | "SUBNET": { 71 | "type": "string", 72 | "value": "[variables('subnetName')]" 73 | }, 74 | "SUBNET_ID": { 75 | "type": "string", 76 | "value": "[concat(resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName')),'/subnets/',variables('subnetName'))]" 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /vnet/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "uniquename": { 6 | "value": "GEN-UNIQUE" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /windowsvm/README.md: -------------------------------------------------------------------------------- 1 | # Scaling to 12800 static IP addresses using subnet 10.0.0.0/18 2 | 3 | This demonstrates updating registry during installation so that browser settings can be modified. 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------