builder/googlecompute: Support provisioning VM without external IP address

This change adds an `omit_external_ip` configuration property that, when true,
will cause no external IP address to be associated with the Google Compute
Engine VM provisioned to create an image. When using `omit_external_ip`, you
must also set the `use_internal_ip` configuration property to true.

Addresses #3296
This commit is contained in:
Evan Brown 2016-08-02 13:43:04 -07:00
parent 644b11805d
commit a5c598264f
5 changed files with 35 additions and 20 deletions

View File

@ -37,6 +37,7 @@ type Config struct {
MachineType string `mapstructure:"machine_type"`
Metadata map[string]string `mapstructure:"metadata"`
Network string `mapstructure:"network"`
OmitExternalIP bool `mapstructure:"omit_external_ip"`
Preemptible bool `mapstructure:"preemptible"`
RawStateTimeout string `mapstructure:"state_timeout"`
Region string `mapstructure:"region"`
@ -169,6 +170,14 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
}
if c.OmitExternalIP && c.Address != "" {
errs = packer.MultiErrorAppend(fmt.Errorf("you can not specify an external address when 'omit_external_ip' is true"))
}
if c.OmitExternalIP && !c.UseInternalIP {
errs = packer.MultiErrorAppend(fmt.Errorf("'use_internal_ip' must be true if 'omit_external_ip' is true"))
}
// Check for any errors.
if errs != nil && len(errs.Errors) > 0 {
return nil, nil, errs

View File

@ -53,6 +53,7 @@ type InstanceConfig struct {
Metadata map[string]string
Name string
Network string
OmitExternalIP bool
Preemptible bool
Region string
ServiceAccountEmail string

View File

@ -256,21 +256,24 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
subnetworkSelfLink = subnetwork.SelfLink
}
// 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
var accessconfig *compute.AccessConfig
// Use external IP if OmitExternalIP isn't set
if !c.OmitExternalIP {
accessconfig = &compute.AccessConfig{
Name: "AccessConfig created by Packer",
Type: "ONE_TO_ONE_NAT",
}
// If given a static IP, use it
if 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
}
accessconfig.NatIP = address.Address
}
// Build up the metadata
@ -307,11 +310,9 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
Name: c.Name,
NetworkInterfaces: []*compute.NetworkInterface{
&compute.NetworkInterface{
AccessConfigs: []*compute.AccessConfig{
&accessconfig,
},
Network: network.SelfLink,
Subnetwork: subnetworkSelfLink,
AccessConfigs: []*compute.AccessConfig{accessconfig},
Network: network.SelfLink,
Subnetwork: subnetworkSelfLink,
},
},
Scheduling: &compute.Scheduling{

View File

@ -25,7 +25,7 @@ func (config *Config) getImage() Image {
func (config *Config) getInstanceMetadata(sshPublicKey string) (map[string]string, error) {
instanceMetadata := make(map[string]string)
var err error
var err error
// Copy metadata from config.
for k, v := range config.Metadata {
@ -77,6 +77,7 @@ func (s *StepCreateInstance) Run(state multistep.StateBag) multistep.StepAction
Metadata: metadata,
Name: name,
Network: config.Network,
OmitExternalIP: config.OmitExternalIP,
Preemptible: config.Preemptible,
Region: config.Region,
ServiceAccountEmail: config.account.ClientEmail,

View File

@ -146,6 +146,9 @@ builder.
- `network` (string) - The Google Compute network to use for the
launched instance. Defaults to `"default"`.
- `omit_external_ip` (boolean) - If true, the instance will not have an external IP.
`use_internal_ip` must be true if this property is true.
- `preemptible` (boolean) - If true, launch a preembtible instance.
- `region` (string) - The region in which to launch the instance. Defaults to