mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-07-01 07:42:40 +00:00
Add Cloud TPU Nodes (#3179)
Signed-off-by: Modular Magician <magic-modules@google.com>
This commit is contained in:
parent
17086fed49
commit
946f3b77c7
|
@ -145,6 +145,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
|
||||||
GeneratedSourceRepoResourcesMap,
|
GeneratedSourceRepoResourcesMap,
|
||||||
GeneratedSpannerResourcesMap,
|
GeneratedSpannerResourcesMap,
|
||||||
GeneratedStorageResourcesMap,
|
GeneratedStorageResourcesMap,
|
||||||
|
GeneratedTpuResourcesMap,
|
||||||
GeneratedMonitoringResourcesMap,
|
GeneratedMonitoringResourcesMap,
|
||||||
map[string]*schema.Resource{
|
map[string]*schema.Resource{
|
||||||
"google_app_engine_application": resourceAppEngineApplication(),
|
"google_app_engine_application": resourceAppEngineApplication(),
|
||||||
|
|
21
google/provider_tpu_gen.go
Normal file
21
google/provider_tpu_gen.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
|
var GeneratedTpuResourcesMap = map[string]*schema.Resource{
|
||||||
|
"google_tpu_node": resourceTpuNode(),
|
||||||
|
}
|
527
google/resource_tpu_node.go
Normal file
527
google/resource_tpu_node.go
Normal file
|
@ -0,0 +1,527 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// compareTpuNodeSchedulingConfig diff suppresses for the default
|
||||||
|
// scheduling, i.e. if preemptible is false, the API may either return no
|
||||||
|
// schedulingConfig or an empty schedulingConfig.
|
||||||
|
func compareTpuNodeSchedulingConfig(k, old, new string, d *schema.ResourceData) bool {
|
||||||
|
if k == "scheduling_config.0.preemptible" {
|
||||||
|
return old == "" && new == "false"
|
||||||
|
}
|
||||||
|
if k == "scheduling_config.#" {
|
||||||
|
o, n := d.GetChange("scheduling_config.0.preemptible")
|
||||||
|
return o.(bool) == n.(bool)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNode() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceTpuNodeCreate,
|
||||||
|
Read: resourceTpuNodeRead,
|
||||||
|
Update: resourceTpuNodeUpdate,
|
||||||
|
Delete: resourceTpuNodeDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: resourceTpuNodeImport,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: schema.DefaultTimeout(900 * time.Second),
|
||||||
|
Update: schema.DefaultTimeout(900 * time.Second),
|
||||||
|
Delete: schema.DefaultTimeout(900 * time.Second),
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"accelerator_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"cidr_block": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"tensorflow_version": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"zone": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||||
|
},
|
||||||
|
"scheduling_config": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
DiffSuppressFunc: compareTpuNodeSchedulingConfig,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"preemptible": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
DiffSuppressFunc: compareTpuNodeSchedulingConfig,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"network_endpoints": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"ip_address": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"service_account": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNodeCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
obj := make(map[string]interface{})
|
||||||
|
nameProp, err := expandTpuNodeName(d.Get("name"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||||
|
obj["name"] = nameProp
|
||||||
|
}
|
||||||
|
descriptionProp, err := expandTpuNodeDescription(d.Get("description"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||||
|
obj["description"] = descriptionProp
|
||||||
|
}
|
||||||
|
acceleratorTypeProp, err := expandTpuNodeAcceleratorType(d.Get("accelerator_type"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("accelerator_type"); !isEmptyValue(reflect.ValueOf(acceleratorTypeProp)) && (ok || !reflect.DeepEqual(v, acceleratorTypeProp)) {
|
||||||
|
obj["acceleratorType"] = acceleratorTypeProp
|
||||||
|
}
|
||||||
|
tensorflowVersionProp, err := expandTpuNodeTensorflowVersion(d.Get("tensorflow_version"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("tensorflow_version"); !isEmptyValue(reflect.ValueOf(tensorflowVersionProp)) && (ok || !reflect.DeepEqual(v, tensorflowVersionProp)) {
|
||||||
|
obj["tensorflowVersion"] = tensorflowVersionProp
|
||||||
|
}
|
||||||
|
networkProp, err := expandTpuNodeNetwork(d.Get("network"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("network"); !isEmptyValue(reflect.ValueOf(networkProp)) && (ok || !reflect.DeepEqual(v, networkProp)) {
|
||||||
|
obj["network"] = networkProp
|
||||||
|
}
|
||||||
|
cidrBlockProp, err := expandTpuNodeCidrBlock(d.Get("cidr_block"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("cidr_block"); !isEmptyValue(reflect.ValueOf(cidrBlockProp)) && (ok || !reflect.DeepEqual(v, cidrBlockProp)) {
|
||||||
|
obj["cidrBlock"] = cidrBlockProp
|
||||||
|
}
|
||||||
|
schedulingConfigProp, err := expandTpuNodeSchedulingConfig(d.Get("scheduling_config"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("scheduling_config"); !isEmptyValue(reflect.ValueOf(schedulingConfigProp)) && (ok || !reflect.DeepEqual(v, schedulingConfigProp)) {
|
||||||
|
obj["schedulingConfig"] = schedulingConfigProp
|
||||||
|
}
|
||||||
|
labelsProp, err := expandTpuNodeLabels(d.Get("labels"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
|
||||||
|
obj["labels"] = labelsProp
|
||||||
|
}
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://tpu.googleapis.com/v1/projects/{{project}}/locations/{{zone}}/nodes?nodeId={{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating new Node: %#v", obj)
|
||||||
|
res, err := sendRequestWithTimeout(config, "POST", url, obj, d.Timeout(schema.TimeoutCreate))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating Node: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the ID now
|
||||||
|
id, err := replaceVars(d, config, "{{project}}/{{zone}}/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error constructing id: %s", err)
|
||||||
|
}
|
||||||
|
d.SetId(id)
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
waitErr := tpuOperationWaitTime(
|
||||||
|
config, res, project, "Creating Node",
|
||||||
|
int(d.Timeout(schema.TimeoutCreate).Minutes()))
|
||||||
|
|
||||||
|
if waitErr != nil {
|
||||||
|
// The resource didn't actually create
|
||||||
|
d.SetId("")
|
||||||
|
return fmt.Errorf("Error waiting to create Node: %s", waitErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Finished creating Node %q: %#v", d.Id(), res)
|
||||||
|
|
||||||
|
return resourceTpuNodeRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNodeRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://tpu.googleapis.com/v1/projects/{{project}}/locations/{{zone}}/nodes/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := sendRequest(config, "GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return handleNotFoundError(err, d, fmt.Sprintf("TpuNode %q", d.Id()))
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Set("project", project); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.Set("name", flattenTpuNodeName(res["name"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("description", flattenTpuNodeDescription(res["description"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("accelerator_type", flattenTpuNodeAcceleratorType(res["acceleratorType"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("tensorflow_version", flattenTpuNodeTensorflowVersion(res["tensorflowVersion"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("network", flattenTpuNodeNetwork(res["network"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("cidr_block", flattenTpuNodeCidrBlock(res["cidrBlock"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("service_account", flattenTpuNodeServiceAccount(res["serviceAccount"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("scheduling_config", flattenTpuNodeSchedulingConfig(res["schedulingConfig"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("network_endpoints", flattenTpuNodeNetworkEndpoints(res["networkEndpoints"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("labels", flattenTpuNodeLabels(res["labels"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading Node: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNodeUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
d.Partial(true)
|
||||||
|
|
||||||
|
if d.HasChange("tensorflow_version") {
|
||||||
|
obj := make(map[string]interface{})
|
||||||
|
tensorflowVersionProp, err := expandTpuNodeTensorflowVersion(d.Get("tensorflow_version"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("tensorflow_version"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, tensorflowVersionProp)) {
|
||||||
|
obj["tensorflowVersion"] = tensorflowVersionProp
|
||||||
|
}
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://tpu.googleapis.com/v1/projects/{{project}}/locations/{{zone}}/nodes/{{name}}:reimage")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res, err := sendRequestWithTimeout(config, "POST", url, obj, d.Timeout(schema.TimeoutUpdate))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating Node %q: %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tpuOperationWaitTime(
|
||||||
|
config, res, project, "Updating Node",
|
||||||
|
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetPartial("tensorflow_version")
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Partial(false)
|
||||||
|
|
||||||
|
return resourceTpuNodeRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNodeDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://tpu.googleapis.com/v1/projects/{{project}}/locations/{{zone}}/nodes/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj map[string]interface{}
|
||||||
|
log.Printf("[DEBUG] Deleting Node %q", d.Id())
|
||||||
|
res, err := sendRequestWithTimeout(config, "DELETE", url, obj, d.Timeout(schema.TimeoutDelete))
|
||||||
|
if err != nil {
|
||||||
|
return handleNotFoundError(err, d, "Node")
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tpuOperationWaitTime(
|
||||||
|
config, res, project, "Deleting Node",
|
||||||
|
int(d.Timeout(schema.TimeoutDelete).Minutes()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Finished deleting Node %q: %#v", d.Id(), res)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceTpuNodeImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
config := meta.(*Config)
|
||||||
|
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/locations/(?P<zone>[^/]+)/nodes/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace import id for the resource id
|
||||||
|
id, err := replaceVars(d, config, "{{project}}/{{zone}}/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error constructing id: %s", err)
|
||||||
|
}
|
||||||
|
d.SetId(id)
|
||||||
|
|
||||||
|
return []*schema.ResourceData{d}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeName(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return NameFromSelfLinkStateFunc(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeDescription(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeAcceleratorType(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeTensorflowVersion(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeNetwork(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeCidrBlock(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeServiceAccount(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeSchedulingConfig(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
original := v.(map[string]interface{})
|
||||||
|
if len(original) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
transformed := make(map[string]interface{})
|
||||||
|
transformed["preemptible"] =
|
||||||
|
flattenTpuNodeSchedulingConfigPreemptible(original["preemptible"], d)
|
||||||
|
return []interface{}{transformed}
|
||||||
|
}
|
||||||
|
func flattenTpuNodeSchedulingConfigPreemptible(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeNetworkEndpoints(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
l := v.([]interface{})
|
||||||
|
transformed := make([]interface{}, 0, len(l))
|
||||||
|
for _, raw := range l {
|
||||||
|
original := raw.(map[string]interface{})
|
||||||
|
if len(original) < 1 {
|
||||||
|
// Do not include empty json objects coming back from the api
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
transformed = append(transformed, map[string]interface{}{
|
||||||
|
"ip_address": flattenTpuNodeNetworkEndpointsIpAddress(original["ipAddress"], d),
|
||||||
|
"port": flattenTpuNodeNetworkEndpointsPort(original["port"], d),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return transformed
|
||||||
|
}
|
||||||
|
func flattenTpuNodeNetworkEndpointsIpAddress(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeNetworkEndpointsPort(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
// Handles the string fixed64 format
|
||||||
|
if strVal, ok := v.(string); ok {
|
||||||
|
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
|
||||||
|
return intVal
|
||||||
|
} // let terraform core handle it if we can't convert the string to an int.
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenTpuNodeLabels(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeAcceleratorType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeTensorflowVersion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeNetwork(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeCidrBlock(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeSchedulingConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
l := v.([]interface{})
|
||||||
|
if len(l) == 0 || l[0] == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
raw := l[0]
|
||||||
|
original := raw.(map[string]interface{})
|
||||||
|
transformed := make(map[string]interface{})
|
||||||
|
|
||||||
|
transformedPreemptible, err := expandTpuNodeSchedulingConfigPreemptible(original["preemptible"], d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if val := reflect.ValueOf(transformedPreemptible); val.IsValid() && !isEmptyValue(val) {
|
||||||
|
transformed["preemptible"] = transformedPreemptible
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeSchedulingConfigPreemptible(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandTpuNodeLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
|
||||||
|
if v == nil {
|
||||||
|
return map[string]string{}, nil
|
||||||
|
}
|
||||||
|
m := make(map[string]string)
|
||||||
|
for k, val := range v.(map[string]interface{}) {
|
||||||
|
m[k] = val.(string)
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
143
google/resource_tpu_node_generated_test.go
Normal file
143
google/resource_tpu_node_generated_test.go
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccTpuNode_tpuNodeBasicExample(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
context := map[string]interface{}{
|
||||||
|
"random_suffix": acctest.RandString(10),
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckTpuNodeDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccTpuNode_tpuNodeBasicExample(context),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceName: "google_tpu_node.tpu",
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
ImportStateVerifyIgnore: []string{"zone"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccTpuNode_tpuNodeBasicExample(context map[string]interface{}) string {
|
||||||
|
return Nprintf(`
|
||||||
|
resource "google_tpu_node" "tpu" {
|
||||||
|
name = "test-tpu-%{random_suffix}"
|
||||||
|
zone = "us-central1-b"
|
||||||
|
|
||||||
|
accelerator_type = "v3-8"
|
||||||
|
tensorflow_version = "1.9"
|
||||||
|
cidr_block = "10.2.0.0/29"
|
||||||
|
}
|
||||||
|
`, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccTpuNode_tpuNodeFullExample(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
context := map[string]interface{}{
|
||||||
|
"random_suffix": acctest.RandString(10),
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckTpuNodeDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccTpuNode_tpuNodeFullExample(context),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceName: "google_tpu_node.tpu",
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
ImportStateVerifyIgnore: []string{"zone"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccTpuNode_tpuNodeFullExample(context map[string]interface{}) string {
|
||||||
|
return Nprintf(`
|
||||||
|
resource "google_compute_network" "tpu_network" {
|
||||||
|
name = "test-tpu-network-%{random_suffix}"
|
||||||
|
auto_create_subnetworks = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_tpu_node" "tpu" {
|
||||||
|
name = "test-tpu-%{random_suffix}"
|
||||||
|
zone = "us-central1-b"
|
||||||
|
|
||||||
|
accelerator_type = "v3-8"
|
||||||
|
|
||||||
|
cidr_block = "10.3.0.0/29"
|
||||||
|
tensorflow_version = "1.12"
|
||||||
|
|
||||||
|
description = "Terraform Google Provider test TPU"
|
||||||
|
network = "${google_compute_network.tpu_network.name}"
|
||||||
|
|
||||||
|
labels {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduling_config {
|
||||||
|
preemptible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckTpuNodeDestroy(s *terraform.State) error {
|
||||||
|
for name, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "google_tpu_node" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(name, "data.") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVarsForTest(rs, "https://tpu.googleapis.com/v1/projects/{{project}}/locations/{{zone}}/nodes/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sendRequest(config, "GET", url, nil)
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("TpuNode still exists at %s", url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
57
google/resource_tpu_node_test.go
Normal file
57
google/resource_tpu_node_test.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccTpuNode_tpuNodeBUpdateTensorFlowVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
nodeId := acctest.RandomWithPrefix("tf-test")
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckTpuNodeDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccTpuNode_tpuNodeTensorFlow(nodeId, "1.11"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceName: "google_tpu_node.tpu",
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
ImportStateVerifyIgnore: []string{"zone"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccTpuNode_tpuNodeTensorFlow(nodeId, "1.12"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceName: "google_tpu_node.tpu",
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
ImportStateVerifyIgnore: []string{"zone"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: cidr_block must not overlap with other existing TPU blocks
|
||||||
|
// Make sure if you change this value that it does not overlap with the
|
||||||
|
// autogenerated examples.
|
||||||
|
func testAccTpuNode_tpuNodeTensorFlow(nodeId, tensorFlowVer string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_tpu_node" "tpu" {
|
||||||
|
name = "%s"
|
||||||
|
zone = "us-central1-b"
|
||||||
|
|
||||||
|
accelerator_type = "v3-8"
|
||||||
|
tensorflow_version = "%s"
|
||||||
|
cidr_block = "10.1.0.0/29"
|
||||||
|
}
|
||||||
|
`, nodeId, tensorFlowVer)
|
||||||
|
}
|
46
google/tpu_operation.go
Normal file
46
google/tpu_operation.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TpuOperationWaiter struct {
|
||||||
|
Config *Config
|
||||||
|
CommonOperationWaiter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *TpuOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
|
if w == nil {
|
||||||
|
return nil, fmt.Errorf("Cannot query operation, it's unset or nil.")
|
||||||
|
}
|
||||||
|
// Returns the proper get.
|
||||||
|
url := fmt.Sprintf("https://tpu.googleapis.com/v1/%s", w.CommonOperationWaiter.Op.Name)
|
||||||
|
return sendRequest(w.Config, "GET", url, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tpuOperationWaitTime(config *Config, op map[string]interface{}, project, activity string, timeoutMinutes int) error {
|
||||||
|
if val, ok := op["name"]; !ok || val == "" {
|
||||||
|
// This was a synchronous call - there is no operation to wait for.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
w := &TpuOperationWaiter{
|
||||||
|
Config: config,
|
||||||
|
}
|
||||||
|
if err := w.CommonOperationWaiter.SetOp(op); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
|
}
|
196
website/docs/r/tpu_node.html.markdown
Normal file
196
website/docs/r/tpu_node.html.markdown
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
---
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This file is automatically generated by Magic Modules and manual
|
||||||
|
# changes will be clobbered when the file is regenerated.
|
||||||
|
#
|
||||||
|
# Please read more about how to change this file in
|
||||||
|
# .github/CONTRIBUTING.md.
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
layout: "google"
|
||||||
|
page_title: "Google: google_tpu_node"
|
||||||
|
sidebar_current: "docs-google-tpu-node"
|
||||||
|
description: |-
|
||||||
|
A Cloud TPU instance.
|
||||||
|
---
|
||||||
|
|
||||||
|
# google\_tpu\_node
|
||||||
|
|
||||||
|
A Cloud TPU instance.
|
||||||
|
|
||||||
|
|
||||||
|
To get more information about Node, see:
|
||||||
|
|
||||||
|
* [API documentation](https://cloud.google.com/tpu/docs/reference/rest/)
|
||||||
|
* How-to Guides
|
||||||
|
* [Official Documentation](https://cloud.google.com/tpu/docs/)
|
||||||
|
|
||||||
|
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
|
||||||
|
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=tpu_node_basic&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
|
||||||
|
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
## Example Usage - Tpu Node Basic
|
||||||
|
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
resource "google_tpu_node" "tpu" {
|
||||||
|
name = "test-tpu"
|
||||||
|
zone = "us-central1-b"
|
||||||
|
|
||||||
|
accelerator_type = "v3-8"
|
||||||
|
tensorflow_version = "1.9"
|
||||||
|
cidr_block = "10.2.0.0/29"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
|
||||||
|
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=tpu_node_full&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
|
||||||
|
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
## Example Usage - Tpu Node Full
|
||||||
|
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
resource "google_compute_network" "tpu_network" {
|
||||||
|
name = "test-tpu-network"
|
||||||
|
auto_create_subnetworks = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_tpu_node" "tpu" {
|
||||||
|
name = "test-tpu"
|
||||||
|
zone = "us-central1-b"
|
||||||
|
|
||||||
|
accelerator_type = "v3-8"
|
||||||
|
|
||||||
|
cidr_block = "10.3.0.0/29"
|
||||||
|
tensorflow_version = "1.12"
|
||||||
|
|
||||||
|
description = "Terraform Google Provider test TPU"
|
||||||
|
network = "${google_compute_network.tpu_network.name}"
|
||||||
|
|
||||||
|
labels {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduling_config {
|
||||||
|
preemptible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
|
||||||
|
* `name` -
|
||||||
|
(Required)
|
||||||
|
The immutable name of the TPU.
|
||||||
|
|
||||||
|
* `accelerator_type` -
|
||||||
|
(Required)
|
||||||
|
The type of hardware accelerators associated with this node.
|
||||||
|
|
||||||
|
* `tensorflow_version` -
|
||||||
|
(Required)
|
||||||
|
The version of Tensorflow running in the Node.
|
||||||
|
|
||||||
|
* `cidr_block` -
|
||||||
|
(Required)
|
||||||
|
The CIDR block that the TPU node will use when selecting an IP
|
||||||
|
address. This CIDR block must be a /29 block; the Compute Engine
|
||||||
|
networks API forbids a smaller block, and using a larger block would
|
||||||
|
be wasteful (a node can only consume one IP address).
|
||||||
|
Errors will occur if the CIDR block has already been used for a
|
||||||
|
currently existing TPU node, the CIDR block conflicts with any
|
||||||
|
subnetworks in the user's provided network, or the provided network
|
||||||
|
is peered with another network that is using that CIDR block.
|
||||||
|
|
||||||
|
* `zone` -
|
||||||
|
(Required)
|
||||||
|
The GCP location for the TPU.
|
||||||
|
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
|
||||||
|
* `description` -
|
||||||
|
(Optional)
|
||||||
|
The user-supplied description of the TPU. Maximum of 512 characters.
|
||||||
|
|
||||||
|
* `network` -
|
||||||
|
(Optional)
|
||||||
|
The name of a network to peer the TPU node to. It must be a
|
||||||
|
preexisting Compute Engine network inside of the project on which
|
||||||
|
this API has been activated. If none is provided, "default" will be
|
||||||
|
used.
|
||||||
|
|
||||||
|
* `scheduling_config` -
|
||||||
|
(Optional)
|
||||||
|
Sets the scheduling options for this TPU instance. Structure is documented below.
|
||||||
|
|
||||||
|
* `labels` -
|
||||||
|
(Optional)
|
||||||
|
Resource labels to represent user provided metadata.
|
||||||
|
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||||
|
If it is not provided, the provider project is used.
|
||||||
|
|
||||||
|
|
||||||
|
The `scheduling_config` block supports:
|
||||||
|
|
||||||
|
* `preemptible` -
|
||||||
|
(Optional)
|
||||||
|
Defines whether the TPU instance is preemptible.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
In addition to the arguments listed above, the following computed attributes are exported:
|
||||||
|
|
||||||
|
|
||||||
|
* `service_account` -
|
||||||
|
The service account used to run the tensor flow services within the
|
||||||
|
node. To share resources, including Google Cloud Storage data, with
|
||||||
|
the Tensorflow job running in the Node, this account must have
|
||||||
|
permissions to that data.
|
||||||
|
|
||||||
|
* `network_endpoints` -
|
||||||
|
The network endpoints where TPU workers can be accessed and sent work.
|
||||||
|
It is recommended that Tensorflow clients of the node first reach out
|
||||||
|
to the first (index 0) entry. Structure is documented below.
|
||||||
|
|
||||||
|
|
||||||
|
The `network_endpoints` block contains:
|
||||||
|
|
||||||
|
* `ip_address` -
|
||||||
|
The IP address of this network endpoint.
|
||||||
|
|
||||||
|
* `port` -
|
||||||
|
The port of this network endpoint.
|
||||||
|
|
||||||
|
## Timeouts
|
||||||
|
|
||||||
|
This resource provides the following
|
||||||
|
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
|
||||||
|
|
||||||
|
- `create` - Default is 15 minutes.
|
||||||
|
- `update` - Default is 15 minutes.
|
||||||
|
- `delete` - Default is 15 minutes.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
Node can be imported using any of these accepted formats:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_tpu_node.default projects/{{project}}/locations/{{zone}}/nodes/{{name}}
|
||||||
|
$ terraform import google_tpu_node.default {{project}}/{{zone}}/{{name}}
|
||||||
|
$ terraform import google_tpu_node.default {{name}}
|
||||||
|
```
|
||||||
|
|
||||||
|
-> If you're importing a resource with beta features, make sure to include `-provider=google-beta`
|
||||||
|
as an argument so that Terraform uses the correct provider to import your resource.
|
Loading…
Reference in New Issue
Block a user