Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support import in compute instance #873

Merged
merged 3 commits into from
Dec 19, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions google/resource_compute_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ func resourceComputeInstance() *schema.Resource {
Read: resourceComputeInstanceRead,
Update: resourceComputeInstanceUpdate,
Delete: resourceComputeInstanceDelete,
Importer: &schema.ResourceImporter{
State: resourceComputeInstanceImportState,
},

SchemaVersion: 6,
MigrateState: resourceComputeInstanceMigrateState,
Expand Down Expand Up @@ -738,12 +741,10 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error

md := flattenMetadataBeta(instance.Metadata)

if _, scriptExists := d.GetOk("metadata_startup_script"); scriptExists {
d.Set("metadata_startup_script", md["startup-script"])
// Note that here we delete startup-script from our metadata list. This is to prevent storing the startup-script
// as a value in the metadata since the config specifically tracks it under 'metadata_startup_script'
delete(md, "startup-script")
}
d.Set("metadata_startup_script", md["startup-script"])
// Note that here we delete startup-script from our metadata list. This is to prevent storing the startup-script
// as a value in the metadata since the config specifically tracks it under 'metadata_startup_script'
delete(md, "startup-script")

existingMetadata := d.Get("metadata").(map[string]interface{})

Expand Down Expand Up @@ -794,6 +795,7 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
// Set the tags fingerprint if there is one.
if instance.Tags != nil {
d.Set("tags_fingerprint", instance.Tags.Fingerprint)
d.Set("tags", convertStringArrToInterface(instance.Tags.Items))
}

if len(instance.Labels) > 0 {
Expand Down Expand Up @@ -859,6 +861,7 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
d.Set("self_link", ConvertSelfLinkToV1(instance.SelfLink))
d.Set("instance_id", fmt.Sprintf("%d", instance.Id))
d.Set("project", project)
d.Set("name", instance.Name)
d.SetId(instance.Name)

return nil
Expand Down Expand Up @@ -1239,6 +1242,20 @@ func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) err
return nil
}

func resourceComputeInstanceImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(d.Id(), "/")

if len(parts) != 3 {
return nil, fmt.Errorf("Invalid import id %q. Expecting {project}/{zone}/{instance_name}", d.Id())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be worth it to also allow users to just import by name and then rely on the provider-level project/zone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will refactor what we have done in some other resources to make it reusable and reuse it here. I wanted to keep that PR simple.

}

d.Set("project", parts[0])
d.Set("zone", parts[1])
d.SetId(parts[2])

return []*schema.ResourceData{d}, nil
}

func expandBootDisk(d *schema.ResourceData, config *Config, zone *compute.Zone, project string) (*computeBeta.AttachedDisk, error) {
disk := &computeBeta.AttachedDisk{
AutoDelete: d.Get("boot_disk.0.auto_delete").(bool),
Expand Down
95 changes: 95 additions & 0 deletions google/resource_compute_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ func TestAccComputeInstance_basic1(t *testing.T) {
testAccCheckComputeInstanceDisk(&instance, instanceName, true, true),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params", "create_timeout"},
},
},
})
}
Expand Down Expand Up @@ -246,6 +252,12 @@ func TestAccComputeInstance_attachedDisk(t *testing.T) {
testAccCheckComputeInstanceDisk(&instance, diskName, false, false),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -270,6 +282,12 @@ func TestAccComputeInstance_attachedDisk_sourceUrl(t *testing.T) {
testAccCheckComputeInstanceDisk(&instance, diskName, false, false),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand Down Expand Up @@ -347,6 +365,11 @@ func TestAccComputeInstance_bootDisk_source(t *testing.T) {
testAccCheckComputeInstanceBootDisk(&instance, diskName),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
},
},
})
}
Expand All @@ -371,6 +394,12 @@ func TestAccComputeInstance_bootDisk_sourceUrl(t *testing.T) {
testAccCheckComputeInstanceBootDisk(&instance, diskName),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand Down Expand Up @@ -418,6 +447,12 @@ func TestAccComputeInstance_scratchDisk(t *testing.T) {
testAccCheckComputeInstanceScratchDisk(&instance, []string{"NVME", "SCSI"}),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand Down Expand Up @@ -511,6 +546,12 @@ func TestAccComputeInstance_service_account(t *testing.T) {
"https://www.googleapis.com/auth/userinfo.email"),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -533,6 +574,12 @@ func TestAccComputeInstance_scheduling(t *testing.T) {
"google_compute_instance.foobar", &instance),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -556,6 +603,12 @@ func TestAccComputeInstance_subnet_auto(t *testing.T) {
testAccCheckComputeInstanceHasSubnet(&instance),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -579,6 +632,12 @@ func TestAccComputeInstance_subnet_custom(t *testing.T) {
testAccCheckComputeInstanceHasSubnet(&instance),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand Down Expand Up @@ -700,6 +759,12 @@ func TestAccComputeInstance_forceChangeMachineTypeManually(t *testing.T) {
),
ExpectNonEmptyPlan: true,
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params", "create_timeout"},
},
},
})
}
Expand All @@ -724,6 +789,12 @@ func TestAccComputeInstance_multiNic(t *testing.T) {
testAccCheckComputeInstanceHasMultiNic(&instance),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-central1-a", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -746,6 +817,12 @@ func TestAccComputeInstance_guestAccelerator(t *testing.T) {
testAccCheckComputeInstanceHasGuestAccelerator(&instance, "nvidia-tesla-k80", 1),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})

Expand All @@ -769,6 +846,12 @@ func TestAccComputeInstance_minCpuPlatform(t *testing.T) {
testAccCheckComputeInstanceHasMinCpuPlatform(&instance, "Intel Haswell"),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -791,6 +874,12 @@ func TestAccComputeInstance_primaryAliasIpRange(t *testing.T) {
testAccCheckComputeInstanceHasAliasIpRange(&instance, "", "/24"),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand All @@ -813,6 +902,12 @@ func TestAccComputeInstance_secondaryAliasIpRange(t *testing.T) {
testAccCheckComputeInstanceHasAliasIpRange(&instance, "inst-test-secondary", "172.16.0.0/24"),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
ImportStateVerifyIgnore: []string{"boot_disk.0.initialize_params"},
},
},
})
}
Expand Down
10 changes: 10 additions & 0 deletions website/docs/r/compute_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,13 @@ exported:
* `disk.0.disk_encryption_key_sha256` - The [RFC 4648 base64](https://tools.ietf.org/html/rfc4648#section-4)
encoded SHA-256 hash of the [customer-supplied encryption key]
(https://cloud.google.com/compute/docs/disks/customer-supplied-encryption) that protects this resource.

## Import

~> **Note:** The fields `boot_disk.0.initialize_params`, `boot_disk.0.disk_entryption_raw` and `attached_disk.*.disk_encryption_key_raw` cannot be imported automatically. The API doesn't return this information. You will need to update your state manually for this field after importing the resource.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make it extra clear, I'd say something like "If you are setting one of these fields in your config, you will need to update your state..." since not everybody is going to need to update their state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Will do


Instances can be imported using the `project`, `zone` and `name`, e.g.

```
$ terraform import google_compute_instance.default gcp-project/us-central1-a/test
```