github.com/marksheahan/packer@v0.10.2-0.20160613200515-1acb2d6645a0/builder/azure/common/template/template_builder.go (about) 1 package template 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/Azure/azure-sdk-for-go/arm/compute" 8 "github.com/Azure/go-autorest/autorest/to" 9 "strings" 10 ) 11 12 const ( 13 jsonPrefix = "" 14 jsonIndent = " " 15 16 resourceVirtualMachine = "Microsoft.Compute/virtualMachines" 17 resourceKeyVaults = "Microsoft.KeyVault/vaults" 18 19 variableSshKeyPath = "sshKeyPath" 20 ) 21 22 type TemplateBuilder struct { 23 template *Template 24 } 25 26 func NewTemplateBuilder() (*TemplateBuilder, error) { 27 var t Template 28 29 err := json.Unmarshal([]byte(basicTemplate), &t) 30 if err != nil { 31 return nil, err 32 } 33 34 return &TemplateBuilder{ 35 template: &t, 36 }, nil 37 } 38 39 func (s *TemplateBuilder) BuildLinux(sshAuthorizedKey string) error { 40 resource, err := s.getResourceByType(resourceVirtualMachine) 41 if err != nil { 42 return err 43 } 44 45 profile := resource.Properties.OsProfile 46 profile.LinuxConfiguration = &compute.LinuxConfiguration{ 47 SSH: &compute.SSHConfiguration{ 48 PublicKeys: &[]compute.SSHPublicKey{ 49 compute.SSHPublicKey{ 50 Path: to.StringPtr(s.toVariable(variableSshKeyPath)), 51 KeyData: to.StringPtr(sshAuthorizedKey), 52 }, 53 }, 54 }, 55 } 56 57 return nil 58 } 59 60 func (s *TemplateBuilder) BuildWindows(keyVaultName, winRMCertificateUrl string) error { 61 resource, err := s.getResourceByType(resourceVirtualMachine) 62 if err != nil { 63 return err 64 } 65 66 profile := resource.Properties.OsProfile 67 68 profile.Secrets = &[]compute.VaultSecretGroup{ 69 compute.VaultSecretGroup{ 70 SourceVault: &compute.SubResource{ 71 ID: to.StringPtr(s.toResourceID(resourceKeyVaults, keyVaultName)), 72 }, 73 VaultCertificates: &[]compute.VaultCertificate{ 74 compute.VaultCertificate{ 75 CertificateStore: to.StringPtr("My"), 76 CertificateURL: to.StringPtr(winRMCertificateUrl), 77 }, 78 }, 79 }, 80 } 81 82 profile.WindowsConfiguration = &compute.WindowsConfiguration{ 83 ProvisionVMAgent: to.BoolPtr(true), 84 WinRM: &compute.WinRMConfiguration{ 85 Listeners: &[]compute.WinRMListener{ 86 compute.WinRMListener{ 87 Protocol: "https", 88 CertificateURL: to.StringPtr(winRMCertificateUrl), 89 }, 90 }, 91 }, 92 } 93 return nil 94 } 95 96 func (s *TemplateBuilder) SetMarketPlaceImage(publisher, offer, sku, version string) error { 97 resource, err := s.getResourceByType(resourceVirtualMachine) 98 if err != nil { 99 return err 100 } 101 102 profile := resource.Properties.StorageProfile 103 profile.ImageReference = &compute.ImageReference{ 104 Publisher: to.StringPtr(publisher), 105 Offer: to.StringPtr(offer), 106 Sku: to.StringPtr(sku), 107 Version: to.StringPtr(version), 108 } 109 110 return nil 111 } 112 113 func (s *TemplateBuilder) SetImageUrl(imageUrl string, osType compute.OperatingSystemTypes) error { 114 resource, err := s.getResourceByType(resourceVirtualMachine) 115 if err != nil { 116 return err 117 } 118 119 profile := resource.Properties.StorageProfile 120 profile.OsDisk.OsType = osType 121 profile.OsDisk.Image = &compute.VirtualHardDisk{ 122 URI: to.StringPtr(imageUrl), 123 } 124 125 return nil 126 } 127 128 func (s *TemplateBuilder) ToJSON() (*string, error) { 129 bs, err := json.MarshalIndent(s.template, jsonPrefix, jsonIndent) 130 131 if err != nil { 132 return nil, err 133 } 134 return to.StringPtr(string(bs)), err 135 } 136 137 func (s *TemplateBuilder) getResourceByType(t string) (*Resource, error) { 138 for _, x := range *s.template.Resources { 139 if strings.EqualFold(*x.Type, t) { 140 return &x, nil 141 } 142 } 143 144 return nil, fmt.Errorf("template: could not find a resource of type %s", t) 145 } 146 147 func (s *TemplateBuilder) toKeyVaultID(name string) string { 148 return s.toResourceID(resourceKeyVaults, name) 149 } 150 151 func (s *TemplateBuilder) toResourceID(id, name string) string { 152 return fmt.Sprintf("[resourceId(resourceGroup().name, '%s', '%s')]", id, name) 153 } 154 155 func (s *TemplateBuilder) toVariable(name string) string { 156 return fmt.Sprintf("[variables('%s')]", name) 157 } 158 159 const basicTemplate = `{ 160 "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", 161 "contentVersion": "1.0.0.0", 162 "parameters": { 163 "adminUsername": { 164 "type": "string" 165 }, 166 "adminPassword": { 167 "type": "string" 168 }, 169 "dnsNameForPublicIP": { 170 "type": "string" 171 }, 172 "osDiskName": { 173 "type": "string" 174 }, 175 "storageAccountBlobEndpoint": { 176 "type": "string" 177 }, 178 "vmSize": { 179 "type": "string" 180 }, 181 "vmName": { 182 "type": "string" 183 } 184 }, 185 "variables": { 186 "addressPrefix": "10.0.0.0/16", 187 "apiVersion": "2015-06-15", 188 "location": "[resourceGroup().location]", 189 "nicName": "packerNic", 190 "publicIPAddressName": "packerPublicIP", 191 "publicIPAddressType": "Dynamic", 192 "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", 193 "subnetName": "packerSubnet", 194 "subnetAddressPrefix": "10.0.0.0/24", 195 "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", 196 "virtualNetworkName": "packerNetwork", 197 "vmStorageAccountContainerName": "images", 198 "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" 199 }, 200 "resources": [ 201 { 202 "apiVersion": "[variables('apiVersion')]", 203 "type": "Microsoft.Network/publicIPAddresses", 204 "name": "[variables('publicIPAddressName')]", 205 "location": "[variables('location')]", 206 "properties": { 207 "publicIPAllocationMethod": "[variables('publicIPAddressType')]", 208 "dnsSettings": { 209 "domainNameLabel": "[parameters('dnsNameForPublicIP')]" 210 } 211 } 212 }, 213 { 214 "apiVersion": "[variables('apiVersion')]", 215 "type": "Microsoft.Network/virtualNetworks", 216 "name": "[variables('virtualNetworkName')]", 217 "location": "[variables('location')]", 218 "properties": { 219 "addressSpace": { 220 "addressPrefixes": [ 221 "[variables('addressPrefix')]" 222 ] 223 }, 224 "subnets": [ 225 { 226 "name": "[variables('subnetName')]", 227 "properties": { 228 "addressPrefix": "[variables('subnetAddressPrefix')]" 229 } 230 } 231 ] 232 } 233 }, 234 { 235 "apiVersion": "[variables('apiVersion')]", 236 "type": "Microsoft.Network/networkInterfaces", 237 "name": "[variables('nicName')]", 238 "location": "[variables('location')]", 239 "dependsOn": [ 240 "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", 241 "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" 242 ], 243 "properties": { 244 "ipConfigurations": [ 245 { 246 "name": "ipconfig", 247 "properties": { 248 "privateIPAllocationMethod": "Dynamic", 249 "publicIPAddress": { 250 "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" 251 }, 252 "subnet": { 253 "id": "[variables('subnetRef')]" 254 } 255 } 256 } 257 ] 258 } 259 }, 260 { 261 "apiVersion": "[variables('apiVersion')]", 262 "type": "Microsoft.Compute/virtualMachines", 263 "name": "[parameters('vmName')]", 264 "location": "[variables('location')]", 265 "dependsOn": [ 266 "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 267 ], 268 "properties": { 269 "hardwareProfile": { 270 "vmSize": "[parameters('vmSize')]" 271 }, 272 "osProfile": { 273 "computerName": "[parameters('vmName')]", 274 "adminUsername": "[parameters('adminUsername')]", 275 "adminPassword": "[parameters('adminPassword')]" 276 }, 277 "storageProfile": { 278 "osDisk": { 279 "name": "osdisk", 280 "vhd": { 281 "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" 282 }, 283 "caching": "ReadWrite", 284 "createOption": "FromImage" 285 } 286 }, 287 "networkProfile": { 288 "networkInterfaces": [ 289 { 290 "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" 291 } 292 ] 293 }, 294 "diagnosticsProfile": { 295 "bootDiagnostics": { 296 "enabled": false 297 } 298 } 299 } 300 } 301 ] 302 }`