-1

I have an application that is incompatible with the latest dot net framework coming with the latest Microsoft image. I want to use the older Microsoft image and exclude .net framework update.

Ask: I want my machines to be patched then if I choose the VMSS automatic update or roll-up; How can I make sure on every new instance I don't get that .net framework update (specific KB)

1 Answers1

0

If I understand the question, you have a scaleset that is created from a standard image. You apply the specific .Net framework. You then deploy your app.

Option 1: Simplest and Preferred - Edit app config file to use specific .Net Framework (so it works regardless of installed framework(s)). Below config will run your app under 2.0.50727 framework, regardless of patches.

<configuration>
   <startup>
      <supportedRuntime version="v2.0.50727"/>
   </startup>
</configuration

Option 2: I think you will need to create a OS VM with the configuration you want. Then periodically create a new image from that VM with the various patches. It is possible to maintain a baseline VM and create images from a clone. In this scenario, I think you really have a "Windows Update" issue in wanting to block a specific patch. Then re-image your scaleset from the resulting image. This template creates a VMSS from a specific iamge:

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string"
    },
    "vmssName": {
      "type": "string"
    },
    "vmSku": {
      "type": "string"
    },
    "adminUsername": {
      "type": "string"
    },
    "instanceCount": {
      "type": "string"
    },
    "singlePlacementGroup": {
      "type": "string"
    },
    "pipName": {
      "type": "string"
    },
    "pipLabel": {
      "type": "string"
    },
    "skuType": {
      "type": "string"
    },
    "ipAllocationMethod": {
      "type": "string"
    },
    "priority": {
      "type": "string"
    },
    "enableAcceleratedNetworking": {
      "type": "string"
    },
    "publicIpAddressPerInstance": {
      "type": "string"
    },
    "upgradeMode": {
      "type": "string"
    },
    "adminPassword": {
      "type": "securestring"
    },
    "spreadingAlgorithmPlatformFaultDomainCount": {
      "type": "string"
    },

    "diagnosticStorageAccount": {
      "type": "string"
    },

    //vNet
    "vnetResourceGroup": {
      "type": "string",
      "defaultValue": "xxxxx"
    },
    "vnetName": {
      "type": "string",
      "defaultValue": "xxxxx"
    },
    "vnetSubnetName": {
      "type": "string",
      "defaultValue": "xxxxx"
    },
    //vm OS Image
    "imageSubscription": {
      "type": "string",
      "defaultValue": "xxxxx-xxxx-xxxx-xxxx-xxxxx"
    },
    "imageResourceGroup": {
      "type": "string",
      "defaultValue": "xxxxx"
    },
    "imageName": {
      "type": "string",
      "defaultValue": "xxxxx_eastus_2019_11_21_18_21_29"
    },

    "domainName": {
      "type": "string",
      "defaultValue": "xxxxx.net"
    },
    "userName": {
      "type": "string",
      "defaultValue": "xxxxx",
      "metadata": {
        "description": "Do not use domainName here. domainName\\userName are concatenated at runtime."
      }
    },
    "userPassword": {
      "type": "securestring",
      "defaultValue": "xxxxxxxxxxxxxxxxxx"
    },
    "ouPath": {
      "type": "string",
      "defaultValue": "OU=xx,DC=xxx,DC=xxxx,DC=net",
      "metadata": {
        "description": "Fully qualified path works."
      }
    },
    "restart": {
      "type": "string",
      "defaultValue": "true",
      "metadata": {
        "description": "VM will restart, UNLESS account already esists in domain. This may impact a configuration sequence during deployment. This extension can remove the account when removing a machine from the domain, (according to the documentation)."
      }
    },
    "options": {
      "type": "string",
      "defaultValue": "3",
      "metadata": {
        "description": "Extension uses NetJoinDomain Win32 API. Options is a OR mask documented in url below. ie '3' = NETSETUP_JOIN_DOMAIN & NETSETUP_ACCT_CREATE. ",
        "url": "https://learn.microsoft.com/en-us/windows/win32/api/lmjoin/nf-lmjoin-netjoindomain"
      }
    },
    "forceUpdateTag": {
      "defaultValue": "[newGuid()]",
      "type": "string",
      "metadata": {
        "description": "Forces extension to deploy every time."
      }
    }

  },
  "variables": {
    "namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]",
    "networkApiVersion": "2018-01-01",
    "storageApiVersion": "2019-06-01",
    "computeApiVersion": "2019-03-01",
    "autoscaleApiVersion": "2015-04-01",
    "subnetRef": "[resourceId(parameters('vnetResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('vnetSubnetName') )]",
    "imageReferenceId": "[resourceId(  parameters('imageSubscription'), parameters('imageResourceGroup'), 'Microsoft.Compute/images', parameters('imageName') )]"
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachineScaleSets",
      "apiVersion": "[variables('computeApiVersion')]",
      "name": "[parameters('vmssName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
      ],
      "sku": {
        "name": "[parameters('vmSku')]",
        "tier": "Standard",
        "capacity": "[int(parameters('instanceCount'))]"
      },
      "identity": {
        "type": "SystemAssigned"
      },
      "properties": {
        "overprovision": true,
        "upgradePolicy": {
          "mode": "[parameters('upgradeMode')]"
        },
        "singlePlacementGroup": "[parameters('singlePlacementGroup')]",
        "virtualMachineProfile": {
          "extensionProfile": {
            "extensions": [
              {
                "type": "Microsoft.Compute/virtualMachines/extensions",
                "name": "[concat(parameters('vmssName'), '_joindomain')]",
                "properties": {
                  "publisher": "Microsoft.Compute",
                  "type": "JsonADDomainExtension",
                  "typeHandlerVersion": "1.3",
                  "autoUpgradeMinorVersion": true,
                  "forceUpdateTag": "[parameters('forceUpdateTag')]",
                  "settings": {
                    "Name": "[parameters('domainName')]",
                    "User": "[ concat( parameters('domainName'), '\u005c',  parameters('userName')  ) ]",
                    "OUPath": "[parameters('ouPath')]",
                    "Restart": "[parameters('restart')]",
                    "Options": "[parameters('options')]"
                  },
                  "protectedSettings": {
                    "Password": "[parameters('userPassword')]"
                  }
                }
              }
            ]
          },
          "storageProfile": {
            "imageReference": {
                 "id": "[variables('imageReferenceId')]"
            },            
            "osDisk": {
              "createOption": "FromImage",
              "caching": "ReadWrite"
            }
          },
          "priority": "[parameters('priority')]",
          "osProfile": {
            "computerNamePrefix": "[variables('namingInfix')]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]"
          },
          "networkProfile": {
            "networkInterfaceConfigurations": [
              {
                "name": "[concat(parameters('vmssName'), 'Nic')]",
                "properties": {
                  "primary": true,
                  "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]",
                  "ipConfigurations": [
                    {
                      "name": "[concat(parameters('vmssName'), 'IpConfig')]",
                      "properties": {
                        "subnet": {
                          "id": "[variables('subnetRef')]"
                        }
                      }
                    }
                  ],
                  "dnsSettings": {
                    "dnsServers": [
                      "xx.xx.xx.xx"
                    ]
                  }
                }
              }
            ]
          },
          "diagnosticsProfile": {
            "bootDiagnostics": {
              "enabled": true,
              "storageUri": "[reference(parameters('diagnosticStorageAccount'), variables('storageApiVersion')).primaryEndpoints.blob]"
            }
          }
        },
        "platformFaultDomainCount": "[int(parameters('spreadingAlgorithmPlatformFaultDomainCount'))]"
      }
    }
  ]
}
jlo-gmail
  • 4,453
  • 3
  • 37
  • 64