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  }`