From 5d2fee04b273282248efc9d1a1ecb3402e900a8f Mon Sep 17 00:00:00 2001 From: vijayrajah Date: Mon, 20 Apr 2020 16:59:13 +0530 Subject: [PATCH] builder/azure: enable boot Diagnostics (#9053) * enable boot Diagnostics --- builder/azure/arm/config.go | 6 + builder/azure/arm/config.hcl2spec.go | 2 + builder/azure/arm/template_factory.go | 7 + ...stVirtualMachineDeployment14.approved.json | 181 ++++++++++++++++++ builder/azure/arm/template_factory_test.go | 31 +++ .../azure/common/template/template_builder.go | 16 ++ .../builder/azure/arm/Config-not-required.mdx | 5 + 7 files changed, 248 insertions(+) create mode 100644 builder/azure/arm/template_factory_test.TestVirtualMachineDeployment14.approved.json diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 71d509536..7c1e831db 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -383,6 +383,12 @@ type Config struct { // `virtual_network_name` is not allowed. AllowedInboundIpAddresses []string `mapstructure:"allowed_inbound_ip_addresses"` + // Specify storage to store Boot Diagnostics -- Enabling this option + // will create 2 Files in the specified storage account. (serial console log & screehshot file) + // once the build is completed, it has to be removed manually. + // see [here](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/boot-diagnostics) for more info + BootDiagSTGAccount string `mapstructure:"boot_diag_storage_account" required:"false"` + // specify custom azure resource names during build limited to max 10 charcters // this will set the prefix for the resources. The actuall resource names will be // `custom_resource_build_prefix` + resourcetype + 5 character random alphanumeric string diff --git a/builder/azure/arm/config.hcl2spec.go b/builder/azure/arm/config.hcl2spec.go index 3d3dceb84..d6e9f885e 100644 --- a/builder/azure/arm/config.hcl2spec.go +++ b/builder/azure/arm/config.hcl2spec.go @@ -69,6 +69,7 @@ type FlatConfig struct { AdditionalDiskSize []int32 `mapstructure:"disk_additional_size" required:"false" cty:"disk_additional_size"` DiskCachingType *string `mapstructure:"disk_caching_type" required:"false" cty:"disk_caching_type"` AllowedInboundIpAddresses []string `mapstructure:"allowed_inbound_ip_addresses" cty:"allowed_inbound_ip_addresses"` + BootDiagSTGAccount *string `mapstructure:"boot_diag_storage_account" required:"false" cty:"boot_diag_storage_account"` CustomResourcePrefix *string `mapstructure:"custom_resource_build_prefix" required:"false" cty:"custom_resource_build_prefix"` Type *string `mapstructure:"communicator" cty:"communicator"` PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"` @@ -185,6 +186,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "disk_additional_size": &hcldec.AttrSpec{Name: "disk_additional_size", Type: cty.List(cty.Number), Required: false}, "disk_caching_type": &hcldec.AttrSpec{Name: "disk_caching_type", Type: cty.String, Required: false}, "allowed_inbound_ip_addresses": &hcldec.AttrSpec{Name: "allowed_inbound_ip_addresses", Type: cty.List(cty.String), Required: false}, + "boot_diag_storage_account": &hcldec.AttrSpec{Name: "boot_diag_storage_account", Type: cty.String, Required: false}, "custom_resource_build_prefix": &hcldec.AttrSpec{Name: "custom_resource_build_prefix", Type: cty.String, Required: false}, "communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false}, "pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false}, diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index fbd3fe8e9..5680f1003 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -127,6 +127,13 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) } } + if config.BootDiagSTGAccount != "" { + err = builder.SetBootDiagnostics(config.BootDiagSTGAccount) + if err != nil { + return nil, err + } + } + builder.SetTags(&config.AzureTags) doc, _ := builder.ToJSON() return createDeploymentParameters(*doc, params) diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment14.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment14.approved.json new file mode 100644 index 000000000..1b80997a0 --- /dev/null +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment14.approved.json @@ -0,0 +1,181 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dataDiskName": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "nicName": { + "type": "string" + }, + "nsgName": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "publicIPAddressName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[parameters('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "https://diagstgaccnt.blob.core.windows.net" + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "id": "" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "name": "[parameters('osDiskName')]", + "osType": "Linux" + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "networkSecurityGroupsApiVersion": "2019-04-01", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "[parameters('subnetName')]", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "[parameters('virtualNetworkName')]", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.go b/builder/azure/arm/template_factory_test.go index 7c465a791..82b9b1cc9 100644 --- a/builder/azure/arm/template_factory_test.go +++ b/builder/azure/arm/template_factory_test.go @@ -473,6 +473,37 @@ func TestVirtualMachineDeployment13(t *testing.T) { } } +// Ensure the VM template is correct when building with bootdiagnostics +func TestVirtualMachineDeployment14(t *testing.T) { + config := map[string]interface{}{ + "location": "ignore", + "subscription_id": "ignore", + "os_type": constants.Target_Linux, + "communicator": "none", + "custom_managed_image_resource_group_name": "CustomManagedImageResourceGroupName", + "custom_managed_image_name": "CustomManagedImageName", + "managed_image_name": "ManagedImageName", + "managed_image_resource_group_name": "ManagedImageResourceGroupName", + "boot_diag_storage_account": "diagstgaccnt", + } + + var c Config + _, err := c.Prepare(config, getPackerConfiguration()) + if err != nil { + t.Fatal(err) + } + + deployment, err := GetVirtualMachineDeployment(&c) + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) + if err != nil { + t.Fatal(err) + } +} + // Ensure the link values are not set, and the concrete values are set. func TestKeyVaultDeployment00(t *testing.T) { var c Config diff --git a/builder/azure/common/template/template_builder.go b/builder/azure/common/template/template_builder.go index 651f7c00a..fdd298e57 100644 --- a/builder/azure/common/template/template_builder.go +++ b/builder/azure/common/template/template_builder.go @@ -357,6 +357,22 @@ func (s *TemplateBuilder) SetTags(tags *map[string]*string) error { return nil } +func (s *TemplateBuilder) SetBootDiagnostics(diagSTG string) error { + + resource, err := s.getResourceByType(resourceVirtualMachine) + if err != nil { + return err + } + + t := true + stg := fmt.Sprintf("https://%s.blob.core.windows.net", diagSTG) + + resource.Properties.DiagnosticsProfile.BootDiagnostics.Enabled = &t + resource.Properties.DiagnosticsProfile.BootDiagnostics.StorageURI = &stg + + return nil +} + func (s *TemplateBuilder) ToJSON() (*string, error) { bs, err := json.MarshalIndent(s.template, jsonPrefix, jsonIndent) diff --git a/website/pages/partials/builder/azure/arm/Config-not-required.mdx b/website/pages/partials/builder/azure/arm/Config-not-required.mdx index 816dd12ce..09bf761c5 100644 --- a/website/pages/partials/builder/azure/arm/Config-not-required.mdx +++ b/website/pages/partials/builder/azure/arm/Config-not-required.mdx @@ -234,6 +234,11 @@ Providing `allowed_inbound_ip_addresses` in combination with `virtual_network_name` is not allowed. +- `boot_diag_storage_account` (string) - Specify storage to store Boot Diagnostics -- Enabling this option + will create 2 Files in the specified storage account. (serial console log & screehshot file) + once the build is completed, it has to be removed manually. + see [here](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/boot-diagnostics) for more info + - `custom_resource_build_prefix` (string) - specify custom azure resource names during build limited to max 10 charcters this will set the prefix for the resources. The actuall resource names will be `custom_resource_build_prefix` + resourcetype + 5 character random alphanumeric string