Skip to content

Instantly share code, notes, and snippets.

@rcarmo
Last active August 7, 2016 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rcarmo/01116f3ee7cefeb99b0a24b203516b36 to your computer and use it in GitHub Desktop.
Save rcarmo/01116f3ee7cefeb99b0a24b203516b36 to your computer and use it in GitHub Desktop.
Minimal Azure Cluster Templates
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"prefix": {
"type": "string",
"defaultValue": "master",
"metadata": {
"description": "Master node(s) name prefix"
}
},
"masterCount": {
"type": "int",
"defaultValue": 1,
"metadata": {
"description": "Master count"
},
"allowedValues": [
1,
3
]
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_DS2_v2",
"metadata": {
"description": "Master instance size"
},
"allowedValues": [
"Standard_DS1_v2",
"Standard_DS2_v2",
"Standard_DS3_v2",
"Standard_DS4_v2",
"Standard_F1",
"Standard_F2"
]
},
"adminUsername": {
"type": "string",
"defaultValue": "cluster",
"metadata": {
"description": "Admin username on all VMs."
}
},
"adminPublicKey": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "ssh public key for connecting to VMs."
}
},
"customData": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Base64 encoded, multi-line string to pass to Ubuntu cloud-init"
}
},
"nsgName": {
"type": "string",
"defaultValue": "masters"
},
"asFDCount": {
"type": "int",
"defaultValue": 3,
"metadata": {
"description": "Availability Set Fault Domains"
}
},
"asUDCount": {
"type": "int",
"defaultValue": 5,
"metadata": {
"description": "Availability Set Update Domains"
}
},
"saType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Premium_LRS"
]
},
"publicIpAddressType": {
"type": "string",
"defaultValue": "Dynamic"
}
},
"variables": {
"saName": "[toLower(substring(concat(parameters('prefix'), 'sa', uniqueString(resourceGroup().id)), 0, 11))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('saName')]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"accountType": "[parameters('saType')]"
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"name": "cluster",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.0.0.0/8"
]
},
"subnets": [
{
"name": "masters",
"properties": {
"addressPrefix": "10.1.0.0/16"
}
},
{
"name": "agents",
"properties": {
"addressPrefix": "10.2.0.0/16"
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"copy": {
"name": "masters",
"count": "[parameters('masterCount')]"
},
"name": "[concat(parameters('prefix'),copyIndex())]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"osProfile": {
"computerName": "[concat(parameters('prefix'),copyIndex())]",
"adminUsername": "[parameters('adminUsername')]",
"customData": "[parameters('customData')]",
"linuxConfiguration": {
"disablePasswordAuthentication": "true",
"ssh": {
"publicKeys": [
{
"path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
"keyData": "[parameters('adminPublicKey')]"
}
]
}
}
},
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04.0-LTS",
"version": "latest"
},
"osDisk": {
"name": "[concat(parameters('prefix'),copyIndex())]",
"vhd": {
"uri": "[concat('https', '://', variables('saName'), '.blob.core.windows.net', concat('/vhds/', 'osdisk', copyIndex(),'.vhd'))]"
},
"createOption": "FromImage"
},
"dataDisks": []
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('prefix'),copyIndex()))]"
}
]
},
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets', 'masters')]"
}
},
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', parameters('prefix'), copyIndex())]",
"[concat('Microsoft.Compute/availabilitySets/', 'masters')]",
"[concat('Microsoft.Storage/storageAccounts/', variables('saName'))]"
]
},
{
"type": "Microsoft.Compute/availabilitySets",
"name": "masters",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"platformFaultDomainCount": "[parameters('asFDCount')]",
"platformUpdateDomainCount": "[parameters('asUDCount')]"
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"copy": {
"name": "clusterMasterNetworkInterfaces",
"count": "[parameters('masterCount')]"
},
"name": "[concat(parameters('prefix'),copyIndex())]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": {
"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', 'cluster'), '/subnets/', 'masters')]"
},
"privateIPAllocationMethod": "Static",
"privateIPAddress": "[concat('10.1.0.',add(10,copyIndex()))]",
"publicIpAddress": {
"id": "[resourceId('Microsoft.Network/publicIpAddresses', concat(parameters('prefix'), copyIndex()))]"
}
}
}
],
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', concat(parameters('prefix'), copyIndex()))]"
}
},
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', 'cluster')]",
"[concat('Microsoft.Network/publicIpAddresses/', parameters('prefix'), copyIndex())]",
"[concat('Microsoft.Network/networkSecurityGroups/', parameters('prefix'), copyIndex())]"
]
},
{
"type": "Microsoft.Network/publicIPAddresses",
"name": "[concat(parameters('prefix'), copyIndex())]",
"copy": {
"name": "clusterMasterPublicIPAddresses",
"count": "[parameters('masterCount')]"
},
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"publicIpAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[concat(resourceGroup().name, '-', parameters('prefix'), copyIndex())]"
}
}
},
{
"type": "Microsoft.Network/networkSecurityGroups",
"copy": {
"name": "clusterMasterNetworkSecurityGroup",
"count": "[parameters('masterCount')]"
},
"name": "[concat(parameters('prefix'), copyIndex())]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"securityRules": [
{
"name": "default-allow-ssh",
"properties": {
"priority": 1000,
"sourceAddressPrefix": "*",
"protocol": "Tcp",
"destinationPortRange": "22",
"access": "Allow",
"direction": "Inbound",
"sourcePortRange": "*",
"destinationAddressPrefix": "*"
}
},
{
"name": "default-allow-http",
"properties": {
"priority": 1001,
"sourceAddressPrefix": "*",
"protocol": "Tcp",
"destinationPortRange": "80",
"access": "Allow",
"direction": "Inbound",
"sourcePortRange": "*",
"destinationAddressPrefix": "*"
}
},
{
"name": "default-allow-https",
"properties": {
"priority": 1002,
"sourceAddressPrefix": "*",
"protocol": "Tcp",
"destinationPortRange": "443",
"access": "Allow",
"direction": "Inbound",
"sourcePortRange": "*",
"destinationAddressPrefix": "*"
}
},
{
"name": "default-allow-managment-http",
"properties": {
"priority": 1003,
"sourceAddressPrefix": "*",
"protocol": "Tcp",
"destinationPortRange": "8080",
"access": "Allow",
"direction": "Inbound",
"sourcePortRange": "*",
"destinationAddressPrefix": "*"
}
}
]
}
}
]
}
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmSku": {
"type": "string",
"defaultValue": "Standard_DS1_v2",
"metadata": {
"description": "Size of VMs in the VM Scale Set."
}
},
"saType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Premium_LRS"
]
},
"vmssName": {
"type": "string",
"defaultValue": "agents"
},
"agentCount": {
"type": "int",
"metadata": {
"description": "Number of VM instances (100 or less)."
},
"defaultValue": 2,
"minValue": 1,
"maxValue": 100
},
"adminUsername": {
"type": "string",
"defaultValue": "cluster",
"metadata": {
"description": "Admin username on all VMs."
}
},
"adminPublicKey": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "ssh public key for connecting to VMs."
}
},
"customData": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Base64 encoded, multi-line string to pass to Ubuntu cloud-init"
}
}
},
"variables": {
"saCount": 5,
"saNameArray": [
"[concat(toLower(substring(concat(parameters('vmssName'), 'sa', uniqueString(resourceGroup().id)), 0, 11)), '0')]",
"[concat(toLower(substring(concat(parameters('vmssName'), 'sa', uniqueString(resourceGroup().id)), 0, 11)), '1')]",
"[concat(toLower(substring(concat(parameters('vmssName'), 'sa', uniqueString(resourceGroup().id)), 0, 11)), '2')]",
"[concat(toLower(substring(concat(parameters('vmssName'), 'sa', uniqueString(resourceGroup().id)), 0, 11)), '3')]",
"[concat(toLower(substring(concat(parameters('vmssName'), 'sa', uniqueString(resourceGroup().id)), 0, 11)), '4')]"
],
"natStartPort": 50000,
"natEndPort": 50099,
"natBackendPort": 22
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('saNameArray')[copyIndex()]]",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"copy": {
"name": "storageLoop",
"count": "[variables('saCount')]"
},
"properties": {
"accountType": "[parameters('saType')]"
}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"name": "[parameters('vmssName')]",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"properties": {
"publicIPAllocationMethod": "Dynamic",
"dnsSettings": {
"domainNameLabel": "[concat(resourceGroup().name, '-', parameters('vmssName'),'-lb')]"
}
}
},
{
"type": "Microsoft.Network/loadBalancers",
"name": "[parameters('vmssName')]",
"location": "[resourceGroup().location]",
"apiVersion": "2015-06-15",
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/',parameters('vmssName'))]"
],
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"properties": {
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('vmssName'))]"
}
}
}
],
"backendAddressPools": [
{
"name": "backendPool"
}
],
"inboundNatPools": [
{
"name": "natPool",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/loadBalancers',parameters('vmssName')),'/frontendIPConfigurations/loadBalancerFrontEnd')]"
},
"protocol": "tcp",
"frontendPortRangeStart": "[variables('natStartPort')]",
"frontendPortRangeEnd": "[variables('natEndPort')]",
"backendPort": "[variables('natBackendPort')]"
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[parameters('vmssName')]",
"location": "[resourceGroup().location]",
"apiVersion": "2016-03-30",
"dependsOn": [
"storageLoop",
"[concat('Microsoft.Network/loadBalancers/', parameters('vmssName'))]"
],
"sku": {
"name": "[parameters('vmSku')]",
"tier": "Standard",
"capacity": "[parameters('agentCount')]"
},
"properties": {
"overprovision": "false",
"upgradePolicy": {
"mode": "Manual"
},
"virtualMachineProfile": {
"osProfile": {
"computerNamePrefix": "[parameters('vmssName')]",
"adminUsername": "[parameters('adminUsername')]",
"customData": "[parameters('customData')]",
"linuxConfiguration": {
"disablePasswordAuthentication": "true",
"ssh": {
"publicKeys": [
{
"path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
"keyData": "[parameters('adminPublicKey')]"
}
]
}
}
},
"storageProfile": {
"osDisk": {
"vhdContainers": [
"[concat('https://', variables('saNameArray')[0], '.blob.core.windows.net/', 'vhds')]",
"[concat('https://', variables('saNameArray')[1], '.blob.core.windows.net/', 'vhds')]",
"[concat('https://', variables('saNameArray')[2], '.blob.core.windows.net/', 'vhds')]",
"[concat('https://', variables('saNameArray')[3], '.blob.core.windows.net/', 'vhds')]",
"[concat('https://', variables('saNameArray')[4], '.blob.core.windows.net/', 'vhds')]"
],
"name": "osdisk.vhd",
"caching": "ReadOnly",
"createOption": "FromImage"
},
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04.0-LTS",
"version": "latest"
}
},
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "[parameters('vmssName')]",
"properties": {
"primary": "true",
"ipConfigurations": [
{
"name": "[concat(parameters('vmssName'),'IpConfig')]",
"properties": {
"subnet": {
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/virtualNetworks/', 'cluster', '/subnets/', 'agents')]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', parameters('vmssName'), '/backendAddressPools/', 'backendPool')]"
}
],
"loadBalancerInboundNatPools": [
{
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', parameters('vmssName'), '/inboundNatPools/', 'natPool')]"
}
]
}
}
]
}
}
]
}
}
}
}
]
}
from IPython.display import HTML
import azurerm, re, json
def as_html(items):
return HTML("<table>" + ''.join(map(lambda x: "<tr><td>%s</td></tr>" % x, items)) + "</table>")
def format_subscription(args):
return '<a href="https://portal.azure.com/#asset/Microsoft_Azure_Billing/Subscription/%(id)s">%(displayName)s</a>' % args
def format_resource_group(args):
return '<a href="https://portal.azure.com/#resource%(id)s">%(name)s</a>&nbsp;%(location)s' % args
class Struct(dict):
"""An object that recursively builds itself from a dict or JSON string and allows easy access to attributes"""
def __init__(self, obj):
if isinstance(obj, str) or isinstance(obj, unicode):
try:
obj = json.loads(obj)
except:
pass
if isinstance(obj, dict) or isinstance(obj, Struct):
dict.__init__(self, obj)
for k, v in obj.iteritems():
if isinstance(v, dict):
self.__dict__[k] = Struct(v)
elif isinstance(v, list):
r = []
for i in v:
if not (isinstance(i, dict) or isinstance(i, list) or isinstance(i, Struct)):
r.append(i)
else:
r.append(Struct(i))
self.__dict__[k] = r
else:
self.__dict__[k] = v
elif isinstance(obj, list):
dict.__init__(self)
r = []
for i in obj:
if not (isinstance(i, dict) or isinstance(i, list) or isinstance(i, Struct)):
r.append(i)
else:
r.append(Struct(i))
self.__dict__[k] = r
def __dir__(self):
return self.__dict__.keys()
def __getattr__(self, attr):
try:
return Struct(self.__dict__[attr])
except KeyError:
return None
#raise AttributeError(attr)
def __getitem__(self, key):
try:
return Struct(self.__dict__[key])
except KeyError:
return None
#raise AttributeError(attr)
def __setitem__(self, key, value):
super(Struct, self).__setitem__(key, value)
self.__dict__[key] = value
def __setattr__(self, attr, value):
self.__setitem__(attr, value)
def __str__(self):
return json.dumps(self.__dict__,indent=2)
def __repr__(self):
return self.__str__()
from azurerm.restfns import do_delete, do_get, do_put
from azurerm.settings import azure_rm_endpoint, BASE_API
# https://msdn.microsoft.com/en-us/library/azure/dn790518.aspx
def list_deployment_operations(access_token, subscription_id, resource_group, deployment_name):
endpoint = ''.join([azure_rm_endpoint,
'/subscriptions/', subscription_id,
'/resourcegroups/', resource_group,
'/providers/Microsoft.Resources/deployments/', deployment_name,
'/operations',
'?api-version=', BASE_API])
return do_get(endpoint, access_token)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment