Skip to content

Commit 23ab7ee

Browse files
authored
Merge pull request hashicorp#8147 from nwwebb/import-instance-template
provider/google: Support Import of 'google_compute_instance_template'
2 parents 900c0fd + fe5d7d1 commit 23ab7ee

3 files changed

Lines changed: 244 additions & 2 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package google
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform/helper/acctest"
7+
"github.com/hashicorp/terraform/helper/resource"
8+
)
9+
10+
func TestAccComputeInstanceTemplate_importBasic(t *testing.T) {
11+
resourceName := "google_compute_instance_template.foobar"
12+
13+
resource.Test(t, resource.TestCase{
14+
PreCheck: func() { testAccPreCheck(t) },
15+
Providers: testAccProviders,
16+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
17+
Steps: []resource.TestStep{
18+
resource.TestStep{
19+
Config: testAccComputeInstanceTemplate_basic,
20+
},
21+
22+
resource.TestStep{
23+
ResourceName: resourceName,
24+
ImportState: true,
25+
ImportStateVerify: true,
26+
},
27+
},
28+
})
29+
}
30+
31+
func TestAccComputeInstanceTemplate_importIp(t *testing.T) {
32+
resourceName := "google_compute_instance_template.foobar"
33+
34+
resource.Test(t, resource.TestCase{
35+
PreCheck: func() { testAccPreCheck(t) },
36+
Providers: testAccProviders,
37+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
38+
Steps: []resource.TestStep{
39+
resource.TestStep{
40+
Config: testAccComputeInstanceTemplate_ip,
41+
},
42+
43+
resource.TestStep{
44+
ResourceName: resourceName,
45+
ImportState: true,
46+
ImportStateVerify: true,
47+
},
48+
},
49+
})
50+
}
51+
52+
func TestAccComputeInstanceTemplate_importDisks(t *testing.T) {
53+
resourceName := "google_compute_instance_template.foobar"
54+
55+
resource.Test(t, resource.TestCase{
56+
PreCheck: func() { testAccPreCheck(t) },
57+
Providers: testAccProviders,
58+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
59+
Steps: []resource.TestStep{
60+
resource.TestStep{
61+
Config: testAccComputeInstanceTemplate_disks,
62+
},
63+
64+
resource.TestStep{
65+
ResourceName: resourceName,
66+
ImportState: true,
67+
ImportStateVerify: true,
68+
},
69+
},
70+
})
71+
}
72+
73+
func TestAccComputeInstanceTemplate_importSubnetAuto(t *testing.T) {
74+
resourceName := "google_compute_instance_template.foobar"
75+
network := "network-" + acctest.RandString(10)
76+
77+
resource.Test(t, resource.TestCase{
78+
PreCheck: func() { testAccPreCheck(t) },
79+
Providers: testAccProviders,
80+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
81+
Steps: []resource.TestStep{
82+
resource.TestStep{
83+
Config: testAccComputeInstanceTemplate_subnet_auto(network),
84+
},
85+
86+
resource.TestStep{
87+
ResourceName: resourceName,
88+
ImportState: true,
89+
ImportStateVerify: true,
90+
},
91+
},
92+
})
93+
}
94+
95+
func TestAccComputeInstanceTemplate_importSubnetCustom(t *testing.T) {
96+
resourceName := "google_compute_instance_template.foobar"
97+
98+
resource.Test(t, resource.TestCase{
99+
PreCheck: func() { testAccPreCheck(t) },
100+
Providers: testAccProviders,
101+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
102+
Steps: []resource.TestStep{
103+
resource.TestStep{
104+
Config: testAccComputeInstanceTemplate_subnet_custom,
105+
},
106+
107+
resource.TestStep{
108+
ResourceName: resourceName,
109+
ImportState: true,
110+
ImportStateVerify: true,
111+
},
112+
},
113+
})
114+
}

builtin/providers/google/resource_compute_instance_template.go

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package google
33
import (
44
"fmt"
55
"log"
6+
"strings"
67

78
"github.com/hashicorp/terraform/helper/resource"
89
"github.com/hashicorp/terraform/helper/schema"
@@ -15,6 +16,9 @@ func resourceComputeInstanceTemplate() *schema.Resource {
1516
Create: resourceComputeInstanceTemplateCreate,
1617
Read: resourceComputeInstanceTemplateRead,
1718
Delete: resourceComputeInstanceTemplateDelete,
19+
Importer: &schema.ResourceImporter{
20+
State: schema.ImportStatePassthrough,
21+
},
1822

1923
Schema: map[string]*schema.Schema{
2024
"name": &schema.Schema{
@@ -66,6 +70,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
6670
Type: schema.TypeBool,
6771
Optional: true,
6872
ForceNew: true,
73+
Computed: true,
6974
},
7075

7176
"device_name": &schema.Schema{
@@ -90,6 +95,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
9095
Type: schema.TypeString,
9196
Optional: true,
9297
ForceNew: true,
98+
Computed: true,
9399
},
94100

95101
"source_image": &schema.Schema{
@@ -102,12 +108,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
102108
Type: schema.TypeString,
103109
Optional: true,
104110
ForceNew: true,
111+
Computed: true,
105112
},
106113

107114
"mode": &schema.Schema{
108115
Type: schema.TypeString,
109116
Optional: true,
110117
ForceNew: true,
118+
Computed: true,
111119
},
112120

113121
"source": &schema.Schema{
@@ -120,6 +128,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
120128
Type: schema.TypeString,
121129
Optional: true,
122130
ForceNew: true,
131+
Computed: true,
123132
},
124133
},
125134
},
@@ -179,6 +188,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
179188
Type: schema.TypeString,
180189
Optional: true,
181190
ForceNew: true,
191+
Computed: true,
182192
},
183193

184194
"subnetwork": &schema.Schema{
@@ -215,6 +225,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
215225
Type: schema.TypeString,
216226
Optional: true,
217227
ForceNew: true,
228+
Computed: true,
218229
},
219230

220231
"region": &schema.Schema{
@@ -226,12 +237,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
226237
"scheduling": &schema.Schema{
227238
Type: schema.TypeList,
228239
Optional: true,
240+
Computed: true,
229241
ForceNew: true,
230242
Elem: &schema.Resource{
231243
Schema: map[string]*schema.Schema{
232244
"preemptible": &schema.Schema{
233245
Type: schema.TypeBool,
234246
Optional: true,
247+
Default: false,
235248
ForceNew: true,
236249
},
237250

@@ -245,6 +258,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
245258
"on_host_maintenance": &schema.Schema{
246259
Type: schema.TypeString,
247260
Optional: true,
261+
Computed: true,
248262
ForceNew: true,
249263
},
250264
},
@@ -476,6 +490,7 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
476490
instanceProperties.Scheduling = &compute.Scheduling{}
477491
instanceProperties.Scheduling.OnHostMaintenance = "MIGRATE"
478492

493+
// Depreciated fields
479494
if v, ok := d.GetOk("automatic_restart"); ok {
480495
instanceProperties.Scheduling.AutomaticRestart = v.(bool)
481496
}
@@ -570,9 +585,91 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
570585
return resourceComputeInstanceTemplateRead(d, meta)
571586
}
572587

588+
func flattenDisks(disks []*compute.AttachedDisk) []map[string]interface{} {
589+
result := make([]map[string]interface{}, 0, len(disks))
590+
for _, disk := range disks {
591+
diskMap := make(map[string]interface{})
592+
if disk.InitializeParams != nil {
593+
sourceImageUrl := strings.Split(disk.InitializeParams.SourceImage, "/")
594+
diskMap["source_image"] = sourceImageUrl[len(sourceImageUrl)-1]
595+
diskMap["disk_type"] = disk.InitializeParams.DiskType
596+
diskMap["disk_name"] = disk.InitializeParams.DiskName
597+
diskMap["disk_size_gb"] = disk.InitializeParams.DiskSizeGb
598+
}
599+
diskMap["auto_delete"] = disk.AutoDelete
600+
diskMap["boot"] = disk.Boot
601+
diskMap["device_name"] = disk.DeviceName
602+
diskMap["interface"] = disk.Interface
603+
diskMap["source"] = disk.Source
604+
diskMap["mode"] = disk.Mode
605+
diskMap["type"] = disk.Type
606+
result = append(result, diskMap)
607+
}
608+
return result
609+
}
610+
611+
func flattenNetworkInterfaces(networkInterfaces []*compute.NetworkInterface) ([]map[string]interface{}, string) {
612+
result := make([]map[string]interface{}, 0, len(networkInterfaces))
613+
region := ""
614+
for _, networkInterface := range networkInterfaces {
615+
networkInterfaceMap := make(map[string]interface{})
616+
if networkInterface.Network != "" {
617+
networkUrl := strings.Split(networkInterface.Network, "/")
618+
networkInterfaceMap["network"] = networkUrl[len(networkUrl)-1]
619+
}
620+
if networkInterface.Subnetwork != "" {
621+
subnetworkUrl := strings.Split(networkInterface.Subnetwork, "/")
622+
networkInterfaceMap["subnetwork"] = subnetworkUrl[len(subnetworkUrl)-1]
623+
region = subnetworkUrl[len(subnetworkUrl)-3]
624+
}
625+
626+
if networkInterface.AccessConfigs != nil {
627+
accessConfigsMap := make([]map[string]interface{}, 0, len(networkInterface.AccessConfigs))
628+
for _, accessConfig := range networkInterface.AccessConfigs {
629+
accessConfigMap := make(map[string]interface{})
630+
accessConfigMap["nat_ip"] = accessConfig.NatIP
631+
632+
accessConfigsMap = append(accessConfigsMap, accessConfigMap)
633+
}
634+
networkInterfaceMap["access_config"] = accessConfigsMap
635+
}
636+
result = append(result, networkInterfaceMap)
637+
}
638+
return result, region
639+
}
640+
641+
func flattenScheduling(scheduling *compute.Scheduling) ([]map[string]interface{}, bool) {
642+
result := make([]map[string]interface{}, 0, 1)
643+
schedulingMap := make(map[string]interface{})
644+
schedulingMap["automatic_restart"] = scheduling.AutomaticRestart
645+
schedulingMap["on_host_maintenance"] = scheduling.OnHostMaintenance
646+
schedulingMap["preemptible"] = scheduling.Preemptible
647+
result = append(result, schedulingMap)
648+
return result, scheduling.AutomaticRestart
649+
}
650+
651+
func flattenServiceAccounts(serviceAccounts []*compute.ServiceAccount) []map[string]interface{} {
652+
result := make([]map[string]interface{}, 0, len(serviceAccounts))
653+
for _, serviceAccount := range serviceAccounts {
654+
serviceAccountMap := make(map[string]interface{})
655+
serviceAccountMap["email"] = serviceAccount.Email
656+
serviceAccountMap["scopes"] = serviceAccount.Scopes
657+
658+
result = append(result, serviceAccountMap)
659+
}
660+
return result
661+
}
662+
663+
func flattenMetadata(metadata *compute.Metadata) map[string]string {
664+
metadataMap := make(map[string]string)
665+
for _, item := range metadata.Items {
666+
metadataMap[item.Key] = *item.Value
667+
}
668+
return metadataMap
669+
}
670+
573671
func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{}) error {
574672
config := meta.(*Config)
575-
576673
project, err := getProject(d, config)
577674
if err != nil {
578675
return err
@@ -603,6 +700,36 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{
603700
}
604701
d.Set("self_link", instanceTemplate.SelfLink)
605702
d.Set("name", instanceTemplate.Name)
703+
if instanceTemplate.Properties.Disks != nil {
704+
d.Set("disk", flattenDisks(instanceTemplate.Properties.Disks))
705+
}
706+
d.Set("description", instanceTemplate.Description)
707+
d.Set("machine_type", instanceTemplate.Properties.MachineType)
708+
d.Set("can_ip_forward", instanceTemplate.Properties.CanIpForward)
709+
if instanceTemplate.Properties.Metadata != nil {
710+
d.Set("metadata", flattenMetadata(instanceTemplate.Properties.Metadata))
711+
}
712+
d.Set("instance_description", instanceTemplate.Properties.Description)
713+
d.Set("project", project)
714+
if instanceTemplate.Properties.NetworkInterfaces != nil {
715+
networkInterfaces, region := flattenNetworkInterfaces(instanceTemplate.Properties.NetworkInterfaces)
716+
d.Set("network_interface", networkInterfaces)
717+
// region is where to look up the subnetwork if there is one attached to the instance template
718+
if region != "" {
719+
d.Set("region", region)
720+
}
721+
}
722+
if instanceTemplate.Properties.Scheduling != nil {
723+
scheduling, autoRestart := flattenScheduling(instanceTemplate.Properties.Scheduling)
724+
d.Set("scheduling", scheduling)
725+
d.Set("automatic_restart", autoRestart)
726+
}
727+
if instanceTemplate.Properties.Tags != nil {
728+
d.Set("tags", instanceTemplate.Properties.Tags.Items)
729+
}
730+
if instanceTemplate.Properties.ServiceAccounts != nil {
731+
d.Set("service_account", flattenServiceAccounts(instanceTemplate.Properties.ServiceAccounts))
732+
}
606733
return nil
607734
}
608735

website/source/docs/providers/google/r/compute_instance_template.html.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ The `scheduling` block supports:
226226
* `on_host_maintenance` - (Optional) Defines the maintenance behavior for this
227227
instance.
228228

229-
* `preemptible` - (Optional) Allows instance to be preempted. Read more on this
229+
* `preemptible` - (Optional) Allows instance to be preempted. This defaults to
230+
false. Read more on this
230231
[here](https://cloud.google.com/compute/docs/instances/preemptible).
231232

232233
## Attributes Reference

0 commit comments

Comments
 (0)