diff --git a/README.md b/README.md index 86b51ee..23be06b 100644 --- a/README.md +++ b/README.md @@ -1 +1,10 @@ -# azure-templates \ No newline at end of file +# azure-templates + +### acs-swarm + +Installing swarm service via azure container service automation + + +### docker-swarm + +Installing swarm on VM cluster and way to deploy any software. acs deployment does not support running custom scripts after deployment. \ No newline at end of file diff --git a/docker-swarm/azuredeploy.json b/docker-swarm/azuredeploy.json new file mode 100644 index 0000000..eb2f6c4 --- /dev/null +++ b/docker-swarm/azuredeploy.json @@ -0,0 +1,642 @@ + +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "sshPublicKey": { + "type": "securestring", + "metadata": { + "description": "SSH public key for the Virtual Machines." + } + }, + "nodeCount": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Number of Swarm worker nodes in the cluster." + } + }, + "clusterName": { + "type": "string", + "defaultValue": "test-cluster", + "metadata": { + "description": "DNS prefix for the application" + } + }, + "installScript": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Installation script path" + } + }, + "installCommand": { + "type": "string", + "defaultValue": "sh installer.sh", + "metadata": { + "description": "Installation command" + } + } + }, + "variables": { + "masterCount": 1, + "adminUsername": "phagunbaya", + "vmNameMaster": "swarm-master-", + "vmNameNode": "swarm-node-", + "vmSizeMaster": "Standard_DS2_v2", + "vmSizeNode": "Standard_DS12_v2", + "availabilitySetMasters": "swarm-masters-set", + "availabilitySetNodes": "swarm-nodes-set", + "osImagePublisher": "Canonical", + "osImageOffer": "UbuntuServer", + "osImageSKU": "14.04.4-LTS", + "managementPublicIPAddrName": "swarm-lb-masters-ip", + "nodesPublicIPAddrName": "swarm-lb-nodes-ip", + "virtualNetworkName": "swarm-vnet", + "subnetNameMasters": "subnet-masters", + "subnetNameNodes": "subnet-nodes", + "addressPrefixMasters": "10.0.0.0/16", + "addressPrefixNodes": "192.168.0.0/16", + "subnetPrefixMasters": "10.0.0.0/24", + "subnetPrefixNodes": "192.168.0.0/24", + "subnetRefMaster": "[concat(resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName')),'/subnets/',variables('subnetNameMasters'))]", + "subnetRefNodes": "[concat(resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName')),'/subnets/',variables('subnetNameNodes'))]", + "mastersNsgName": "swarm-masters-firewall", + "nodesNsgName": "swarm-nodes-firewall", + "mastersNsgID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('mastersNsgName'))]", + "nodesNsgID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('nodesNsgName'))]", + "newStorageAccountName": "[uniqueString(resourceGroup().id, deployment().name)]", + "clusterFqdn": "[concat('swarm-',uniqueString(resourceGroup().id, deployment().name))]", + "storageAccountType": "Standard_LRS", + "vhdBlobContainer": "vhds", + "mastersLbName": "swarm-lb-masters", + "mastersLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('mastersLbName'))]", + "mastersLbIPConfigName": "MastersLBFrontEnd", + "mastersLbIPConfigID": "[concat(variables('mastersLbID'),'/frontendIPConfigurations/', variables('mastersLbIPConfigName'))]", + "mastersLbBackendPoolName": "swarm-masters-pool", + "nodesLbName": "swarm-lb-nodes", + "nodesLbID": "[resourceId('Microsoft.Network/loadBalancers',variables('nodesLbName'))]", + "nodesLbBackendPoolName": "swarm-nodes-pool", + "sshKeyPath": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]", + "consulServerArgs": [ + "-advertise 10.0.0.4 -bootstrap" + ] + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('newStorageAccountName')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "properties": { + "accountType": "[variables('storageAccountType')]" + } + }, + { + "type": "Microsoft.Compute/availabilitySets", + "name": "[variables('availabilitySetMasters')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "properties": {} + }, + { + "type": "Microsoft.Compute/availabilitySets", + "name": "[variables('availabilitySetNodes')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "properties": {} + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('managementPublicIPAddrName')]", + "location": "[resourceGroup().location]", + "properties": { + "publicIPAllocationMethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[concat(parameters('clusterName'), '-manage')]" + } + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('nodesPublicIPAddrName')]", + "location": "[resourceGroup().location]", + "properties": { + "publicIPAllocationMethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[parameters('clusterName')]" + } + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('virtualNetworkName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[variables('mastersNsgID')]", + "[variables('nodesNsgID')]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefixMasters')]", + "[variables('addressPrefixNodes')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetNameMasters')]", + "properties": { + "addressPrefix": "[variables('subnetPrefixMasters')]", + "networkSecurityGroup": { + "id": "[variables('mastersNsgID')]" + } + } + }, + { + "name": "[variables('subnetNameNodes')]", + "properties": { + "addressPrefix": "[variables('subnetPrefixNodes')]", + "networkSecurityGroup": { + "id": "[variables('nodesNsgID')]" + } + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkSecurityGroups", + "name": "[variables('mastersNsgName')]", + "location": "[resourceGroup().location]", + "properties": { + "securityRules": [ + { + "name": "ssh", + "properties": { + "description": "", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 1000, + "direction": "Inbound" + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkSecurityGroups", + "name": "[variables('nodesNsgName')]", + "location": "[resourceGroup().location]", + "properties": { + "securityRules": [ + { + "name": "AllowAny", + "properties": { + "description": "Swarm node ports need to be configured on the load balancer to be reachable", + "protocol": "*", + "sourcePortRange": "*", + "destinationPortRange": "*", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 1000, + "direction": "Inbound" + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkInterfaces", + "name": "[concat(variables('vmNameMaster'), copyIndex(), '-nic')]", + "location": "[resourceGroup().location]", + "copy": { + "name": "nicLoopMaster", + "count": "[variables('masterCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('mastersLbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Network/loadBalancers/', variables('mastersLbName'), '/inboundNatRules/', 'SSH-', variables('vmNameMaster'), copyIndex())]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipConfigMaster", + "properties": { + "privateIPAllocationMethod": "Static", + "privateIPAddress": "[concat('10.0.0.', copyIndex(4))]", + "subnet": { + "id": "[variables('subnetRefMaster')]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[concat(variables('mastersLbID'), '/backendAddressPools/', variables('mastersLbBackendPoolName'))]" + } + ], + "loadBalancerInboundNatRules": [ + { + "id": "[concat(variables('mastersLbID'),'/inboundNatRules/SSH-',variables('vmNameMaster'),copyindex())]" + } + ] + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "name": "[variables('mastersLbName')]", + "type": "Microsoft.Network/loadBalancers", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('managementPublicIPAddrName'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "[variables('mastersLbIPConfigName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('managementPublicIPAddrName'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('mastersLbBackendPoolName')]" + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/loadBalancers/inboundNatRules", + "name": "[concat(variables('mastersLbName'), '/', 'SSH-', variables('vmNameMaster'), copyIndex())]", + "location": "[resourceGroup().location]", + "copy": { + "name": "lbNatLoopMaster", + "count": "[variables('masterCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('mastersLbName'))]" + ], + "properties": { + "frontendIPConfiguration": { + "id": "[variables('mastersLbIPConfigID')]" + }, + "protocol": "tcp", + "frontendPort": "[copyIndex(2200)]", + "backendPort": 22, + "enableFloatingIP": false + } + }, + { + "apiVersion": "2015-06-15", + "name": "[variables('nodesLbName')]", + "type": "Microsoft.Network/loadBalancers", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('nodesPublicIPAddrName'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerFrontEnd", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('nodesPublicIPAddrName'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('nodesLbBackendPoolName')]" + } + ], + "loadBalancingRules": [ + { + "properties": { + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('nodesLbName')), '/frontendIpConfigurations/LoadBalancerFrontEnd')]" + }, + "backendAddressPool": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('nodesLbName')), '/backendAddressPools/', variables('nodesLbBackendPoolName'))]" + }, + "probe": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('nodesLbName')), '/probes/app-probe')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 8080, + "idleTimeoutInMinutes": 4 + }, + "name": "lbrule-app-port" + } + ], + "probes": [ + { + "properties": { + "protocol": "Tcp", + "port": 8080, + "path": "/ping", + "intervalInSeconds": 20, + "numberOfProbes": 2 + }, + "name": "app-probe" + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Network/networkInterfaces", + "name": "[concat(variables('vmNameNode'),copyIndex(), '-nic')]", + "location": "[resourceGroup().location]", + "copy": { + "name": "nicLoopNode", + "count": "[parameters('nodeCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('nodesLbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipConfigNode", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[variables('subnetRefNodes')]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[concat(variables('nodesLbID'), '/backendAddressPools/', variables('nodesLbBackendPoolName'))]" + } + ] + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Compute/virtualMachines", + "name": "[concat(variables('vmNameMaster'), copyIndex())]", + "location": "[resourceGroup().location]", + "copy": { + "name": "vmLoopMaster", + "count": "[variables('masterCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]", + "[concat('Microsoft.Network/networkInterfaces/', variables('vmNameMaster'), copyIndex(), '-nic')]", + "[concat('Microsoft.Compute/availabilitySets/', variables('availabilitySetMasters'))]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetMasters'))]" + }, + "hardwareProfile": { + "vmSize": "[variables('vmSizeMaster')]" + }, + "osProfile": { + "computerName": "[concat(variables('vmNameMaster'), copyIndex())]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": "true", + "ssh": { + "publicKeys": [ + { + "path": "[variables('sshKeyPath')]", + "keyData": "[parameters('sshPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('osImagePublisher')]", + "offer": "[variables('osImageOffer')]", + "sku": "[variables('osImageSKU')]", + "version": "latest" + }, + "osDisk": { + "name": "[concat(variables('vmNameMaster'), copyIndex(),'-osdisk')]", + "vhd": { + "uri": "[concat('http://', variables('newStorageAccountName'), '.blob.core.windows.net/', variables('vhdBlobContainer'), '/master-', copyIndex(), '-osdisk.vhd')]" + }, + "caching": "ReadWrite", + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('vmNameMaster'), copyIndex(), '-nic'))]" + } + ] + } + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Compute/virtualMachines", + "name": "[concat(variables('vmNameNode'), copyIndex())]", + "location": "[resourceGroup().location]", + "copy": { + "name": "vmLoopNode", + "count": "[parameters('nodeCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', variables('newStorageAccountName'))]", + "[concat('Microsoft.Network/networkInterfaces/', variables('vmNameNode'), copyIndex(), '-nic')]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetNodes'))]" + }, + "hardwareProfile": { + "vmSize": "[variables('vmSizeNode')]" + }, + "osProfile": { + "computerName": "[concat(variables('vmNameNode'), copyIndex())]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": "true", + "ssh": { + "publicKeys": [ + { + "path": "[variables('sshKeyPath')]", + "keyData": "[parameters('sshPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('osImagePublisher')]", + "offer": "[variables('osImageOffer')]", + "sku": "[variables('osImageSKU')]", + "version": "latest" + }, + "osDisk": { + "name": "[concat(variables('vmNameNode'), copyIndex(),'-osdisk')]", + "vhd": { + "uri": "[concat('http://', variables('newStorageAccountName'), '.blob.core.windows.net/', variables('vhdBlobContainer'), '/node-', copyIndex(), '-osdisk.vhd')]" + }, + "caching": "ReadWrite", + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('vmNameNode'), copyindex(), '-nic'))]" + } + ] + } + } + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(variables('vmNameMaster'), copyIndex(), '/DockerExtension')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "copy": { + "name": "extensionLoopMaster", + "count": "[variables('masterCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('vmNameMaster'), copyIndex())]" + ], + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "DockerExtension", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "settings": { + "compose": { + "consul": { + "image": "progrium/consul", + "command": "[concat('-server -node master', copyIndex(), ' ', variables('consulServerArgs')[copyIndex()])]", + "ports": [ + "8500:8500", + "8300:8300", + "8301:8301", + "8301:8301/udp", + "8302:8302", + "8302:8302/udp", + "8400:8400" + ], + "volumes": [ + "/data/consul:/data" + ], + "restart": "always" + }, + "swarm": { + "image": "swarm", + "command": "[concat('manage --advertise ', reference(concat(variables('vmNameMaster'), copyIndex(), '-nic')).ipConfigurations[0].properties.privateIPAddress, ':2375 --discovery-opt kv.path=docker/nodes consul://10.0.0.4:8500')]", + "ports": [ + "2375:2375" + ], + "links": [ + "consul" + ], + "volumes": [ + "/etc/docker:/etc/docker" + ], + "restart": "always" + } + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(variables('vmNameNode'), copyIndex(), '/DockerExtension')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "copy": { + "name": "extensionLoopNode", + "count": "[parameters('nodeCount')]" + }, + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('vmNameNode'), copyIndex())]" + ], + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "DockerExtension", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "settings": { + "docker": { + "port": "2375", + "options": [ + "--cluster-store=consul://10.0.0.4:8500", + "--cluster-advertise=eth0:2375" + ] + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(variables('vmNameMaster'), copyIndex(), '/software-installer')]", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "copy": { + "name": "extensionLoopInstaller", + "count": "[variables('masterCount')]" + }, + "dependsOn": [ + "extensionLoopNode" + ], + "properties": { + "publisher": "Microsoft.OSTCExtensions", + "type": "CustomScriptForLinux", + "typeHandlerVersion": "1.2", + "settings": { + "fileUris": [ + "[parameters('installScript')]" + ], + "commandToExecute": "[concat(parameters('installCommand'), ' ', resourceGroup().location, ' ', parameters('clusterName'))]" + } + } + } + ], + "outputs": { + "sshTunnelCmd": { + "type": "string", + "value": "[concat('ssh -L 2375:swarm-master-0:2375 -N ', variables('adminUsername'), '@', reference(variables('managementPublicIPAddrName')).dnsSettings.fqdn, ' -p 2200')]" + }, + "dockerCmd": { + "type": "string", + "value": "docker -H tcp://localhost:2375 info" + }, + "swarmNodesLoadBalancerAddress": { + "type": "string", + "value": "[reference(variables('nodesPublicIPAddrName')).dnsSettings.fqdn]" + }, + "sshMaster0": { + "type": "string", + "value": "[concat('ssh ', variables('adminUsername'), '@', reference(variables('managementPublicIPAddrName')).dnsSettings.fqdn, ' -A -p 2200')]" + } + } +} diff --git a/docker-swarm/azuredeploy.parameters.json b/docker-swarm/azuredeploy.parameters.json new file mode 100644 index 0000000..430a847 --- /dev/null +++ b/docker-swarm/azuredeploy.parameters.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "sshPublicKey": { + "value": "RSA key" + }, + "nodeCount": { + "value": 1 + }, + "clusterName": { + "value": "test-cluster-1" + }, + "installScript": { + "value": "https://raw.githubusercontent.com/phagunbaya/azure-templates/master/docker-swarm/installer.sh" + }, + "installCommand": { + "value": "sh installer.sh" + } + } +} \ No newline at end of file diff --git a/docker-swarm/installer.sh b/docker-swarm/installer.sh new file mode 100644 index 0000000..dd7b76d --- /dev/null +++ b/docker-swarm/installer.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "Your software installation script" + +# +# docker is available at docker -H tcp://0.0.0.0:2375 +#