diff --git a/builtin/providers/google/resource_compute_instance.go b/builtin/providers/google/resource_compute_instance.go index 380aac8da04e..8233815b335a 100644 --- a/builtin/providers/google/resource_compute_instance.go +++ b/builtin/providers/google/resource_compute_instance.go @@ -191,6 +191,12 @@ func resourceComputeInstance() *schema.Resource { ForceNew: true, }, + "metadata_startup_script": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "metadata": &schema.Schema{ Type: schema.TypeMap, Optional: true, @@ -469,13 +475,18 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err serviceAccounts = append(serviceAccounts, serviceAccount) } + metadata, err := resourceInstanceMetadata(d) + if err != nil { + return fmt.Errorf("Error creating metadata: %s", err) + } + // Create the instance information instance := compute.Instance{ CanIpForward: d.Get("can_ip_forward").(bool), Description: d.Get("description").(string), Disks: disks, MachineType: machineType.SelfLink, - Metadata: resourceInstanceMetadata(d), + Metadata: metadata, Name: d.Get("name").(string), NetworkInterfaces: networkInterfaces, Tags: resourceInstanceTags(d), @@ -662,7 +673,10 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err // If the Metadata has changed, then update that. if d.HasChange("metadata") { - metadata := resourceInstanceMetadata(d) + metadata, err := resourceInstanceMetadata(d) + if err != nil { + return fmt.Errorf("Error updating metadata: %s", err) + } op, err := config.clientCompute.Instances.SetMetadata( config.Project, zone, d.Id(), metadata).Do() if err != nil { @@ -781,9 +795,18 @@ func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) err return nil } -func resourceInstanceMetadata(d *schema.ResourceData) *compute.Metadata { +func resourceInstanceMetadata(d *schema.ResourceData) (*compute.Metadata, error) { m := &compute.Metadata{} - if mdMap := d.Get("metadata").(map[string]interface{}); len(mdMap) > 0 { + mdMap := d.Get("metadata").(map[string]interface{}) + _, mapScriptExists := mdMap["startup-script"] + dScript, dScriptExists := d.GetOk("metadata_startup_script") + if mapScriptExists && dScriptExists { + return nil, fmt.Errorf("Not allowed to have both metadata_startup_script and metadata.startup-script") + } + if dScriptExists { + mdMap["startup-script"] = dScript + } + if len(mdMap) > 0 { m.Items = make([]*compute.MetadataItems, 0, len(mdMap)) for key, val := range mdMap { m.Items = append(m.Items, &compute.MetadataItems{ @@ -797,7 +820,7 @@ func resourceInstanceMetadata(d *schema.ResourceData) *compute.Metadata { m.Fingerprint = d.Get("metadata_fingerprint").(string) } - return m + return m, nil } func resourceInstanceTags(d *schema.ResourceData) *compute.Tags { diff --git a/builtin/providers/google/resource_compute_instance_template.go b/builtin/providers/google/resource_compute_instance_template.go index f1d2f9bc320d..4069da10491d 100644 --- a/builtin/providers/google/resource_compute_instance_template.go +++ b/builtin/providers/google/resource_compute_instance_template.go @@ -331,7 +331,11 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac instanceProperties.Description = d.Get("instance_description").(string) instanceProperties.MachineType = d.Get("machine_type").(string) instanceProperties.Disks = buildDisks(d, meta) - instanceProperties.Metadata = resourceInstanceMetadata(d) + metadata, err := resourceInstanceMetadata(d) + if err != nil { + return err + } + instanceProperties.Metadata = metadata err, networks := buildNetworks(d, meta) if err != nil { return err diff --git a/builtin/providers/google/resource_compute_instance_test.go b/builtin/providers/google/resource_compute_instance_test.go index 70d0c5f2f8f4..3ae487a18c93 100644 --- a/builtin/providers/google/resource_compute_instance_test.go +++ b/builtin/providers/google/resource_compute_instance_test.go @@ -476,10 +476,10 @@ resource "google_compute_instance" "foobar" { metadata { foo = "bar" - } - metadata { baz = "qux" } + + metadata_startup_script = "echo Hello" }` const testAccComputeInstance_basic2 = ` diff --git a/website/source/docs/providers/google/r/compute_instance.html.markdown b/website/source/docs/providers/google/r/compute_instance.html.markdown index ae231a8c49cf..bf8add9e621b 100644 --- a/website/source/docs/providers/google/r/compute_instance.html.markdown +++ b/website/source/docs/providers/google/r/compute_instance.html.markdown @@ -44,6 +44,8 @@ resource "google_compute_instance" "default" { foo = "bar" } + metadata_startup_script = "echo hi > /test.txt" + service_account { scopes = ["userinfo-email", "compute-ro", "storage-ro"] } @@ -73,6 +75,12 @@ The following arguments are supported: * `metadata` - (Optional) Metadata key/value pairs to make available from within the instance. +* `metadata_startup_script` - (Optional) An alternative to using the + startup-script metadata key, except this one forces the instance to be + recreated (thus re-running the script) if it is changed. This replaces the + startup-script metadata key on the created instance and thus the two mechanisms + are not allowed to be used simultaneously. + * `network_interface` - (Required) Networks to attach to the instance. This can be specified multiple times for multiple networks. Structure is documented below.