diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index e79a92e64..28cc1d280 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -31,6 +31,7 @@ type Config struct { MachineType string `mapstructure:"machine_type"` Metadata map[string]string `mapstructure:"metadata"` Network string `mapstructure:"network"` + Address string `mapstructure:"address"` Preemptible bool `mapstructure:"preemptible"` SourceImage string `mapstructure:"source_image"` SourceImageProjectId string `mapstructure:"source_image_project_id"` diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index 6a9c3d651..495c1e092 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -47,6 +47,7 @@ type InstanceConfig struct { Metadata map[string]string Name string Network string + Address string Preemptible bool Tags []string Zone string diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index b1e4d8d45..91d04255f 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -13,6 +13,7 @@ import ( "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" "google.golang.org/api/compute/v1" + "strings" ) // driverGCE is a Driver implementation that actually talks to GCE. @@ -214,6 +215,23 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { return nil, err } + // If given a regional ip, get it + accessconfig := compute.AccessConfig{ + Name: "AccessConfig created by Packer", + Type: "ONE_TO_ONE_NAT", + } + + if c.Address != "" { + d.ui.Message(fmt.Sprintf("Looking up address: %s", c.Address)) + region_url := strings.Split(zone.Region, "/") + region := region_url[len(region_url)-1] + address, err := d.service.Addresses.Get(d.projectId, region, c.Address).Do() + if err != nil { + return nil, err + } + accessconfig.NatIP = address.Address + } + // Build up the metadata metadata := make([]*compute.MetadataItems, len(c.Metadata)) for k, v := range c.Metadata { @@ -247,10 +265,7 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { NetworkInterfaces: []*compute.NetworkInterface{ &compute.NetworkInterface{ AccessConfigs: []*compute.AccessConfig{ - &compute.AccessConfig{ - Name: "AccessConfig created by Packer", - Type: "ONE_TO_ONE_NAT", - }, + &accessconfig, }, Network: network.SelfLink, }, diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index 891072438..f3f16a09f 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -59,6 +59,7 @@ func (s *StepCreateInstance) Run(state multistep.StateBag) multistep.StepAction Metadata: config.getInstanceMetadata(sshPublicKey), Name: name, Network: config.Network, + Address: config.Address, Preemptible: config.Preemptible, Tags: config.Tags, Zone: config.Zone, diff --git a/website/source/docs/builders/googlecompute.html.markdown b/website/source/docs/builders/googlecompute.html.markdown index fe45ee01b..cebb1d484 100644 --- a/website/source/docs/builders/googlecompute.html.markdown +++ b/website/source/docs/builders/googlecompute.html.markdown @@ -118,6 +118,9 @@ builder. Not required if you run Packer on a GCE instance with a service account. Instructions for creating file or using service accounts are above. +- `address` (string) - The name of a pre-allocated static external IP address. + Note, must be the name and not the actual IP address. + - `disk_size` (integer) - The size of the disk in GB. This defaults to `10`, which is 10GB.