Add 'vm' template function

This commit is contained in:
Paul Meyer 2019-10-04 18:59:11 +00:00
parent f72c4ec7a3
commit 19a3502b36
3 changed files with 87 additions and 1 deletions

View File

@ -115,6 +115,7 @@ type Builder struct {
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.ctx.Funcs = azcommon.TemplateFuncs
b.config.ctx.Funcs["vm"] = CreateVMMetadataTemplateFunc()
err := config.Decode(&b.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &b.config.ctx,
@ -129,6 +130,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
},
},
}, raws...)
if err != nil {
return nil, err
}
var errs *packer.MultiError
var warns []string

View File

@ -0,0 +1,37 @@
package chroot
import (
"fmt"
"sync"
"github.com/hashicorp/packer/builder/azure/common/client"
)
// CreateVMMetadataTemplateFunc returns a template function that retrieves VM metadata. VM metadata is retrieved only once and reused for all executions of the function.
func CreateVMMetadataTemplateFunc() func(string) (string, error) {
var data *client.ComputeInfo
var dataErr error
once := sync.Once{}
return func(key string) (string, error) {
once.Do(func() {
data, dataErr = client.DefaultMetadataClient.GetComputeInfo()
})
if dataErr != nil {
return "", dataErr
}
switch key {
case "name":
return data.Name, nil
case "subscription_id":
return data.SubscriptionID, nil
case "resource_group":
return data.ResourceGroupName, nil
case "location":
return data.Location, nil
case "resource_id":
return data.ResourceID(), nil
default:
return "", fmt.Errorf("unknown metadata key: %s (supported: name, subscription_id, resource_group, location, resource_id)", key)
}
}
}

View File

@ -101,7 +101,52 @@ mounts `/prod` and `/dev`:
- The mount directory.
## Example
## Additional template function
Because this builder runs on an Azure VM, there is an additional template function
available called `vm`, which returns the following VM metadata:
- name
- subscription_id
- resource_group
- location
- resource_id
This function can be used in the configuration templates, for example, use
```
"{{ vm `subscription_id` }}"
```
to fill in the subscription ID of the VM in any of the configuration options.
## Examples
Here are some examples using this builder.
### Using a VM with a Managed Identity
On a VM with a system-assigned managed identity that has the contributor role
on its own resource group, the following config can be used to create an
updated Debian image:
``` json
{
"builders": [{
"type": "azure-chroot",
"command_wrapper": "sudo {{.Command}}",
"image_resource_id": "/subscriptions/{{vm `subscription_id`}}/resourceGroups/{{vm `resource_group`}}/providers/Microsoft.Compute/images/MyDebianOSImage-{{timestamp}}",
"source": "credativ:Debian:9:latest"
}],
"provisioners": [{
"inline": [
"apt-get update",
"apt-get upgrade -y"
],
"inline_shebang": "/bin/sh -x",
"type": "shell"
}]
}
```
### Using a Service Principal
Here is an example that creates a Debian image with updated packages. Specify
all environment variables (`ARM_CLIENT_ID`, `ARM_CLIENT_SECRET`,
`ARM_SUBSCRIPTION_ID`) to use a service principal.