Add compute node types and templates (#3446)

Signed-off-by: Modular Magician <magic-modules@google.com>
This commit is contained in:
The Magician 2019-04-22 15:32:58 -07:00 committed by emily
parent 9eff6af8f6
commit 8077953aa7
9 changed files with 866 additions and 0 deletions

View File

@ -0,0 +1,71 @@
package google
import (
"fmt"
"log"
"sort"
"time"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
)
func dataSourceGoogleComputeNodeTypes() *schema.Resource {
return &schema.Resource{
Read: dataSourceGoogleComputeNodeTypesRead,
Schema: map[string]*schema.Schema{
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"names": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}
func dataSourceGoogleComputeNodeTypesRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
zone, err := getZone(d, config)
if err != nil {
return fmt.Errorf("Please specify zone to get appropriate node types for zone. Unable to get zone: %s", err)
}
resp, err := config.clientCompute.NodeTypes.List(project, zone).Do()
if err != nil {
return err
}
nodeTypes := flattenComputeNodeTypes(resp.Items)
log.Printf("[DEBUG] Received Google Compute Regions: %q", nodeTypes)
d.Set("names", nodeTypes)
d.Set("project", project)
d.Set("zone", zone)
d.SetId(time.Now().UTC().String())
return nil
}
func flattenComputeNodeTypes(nodeTypes []*compute.NodeType) []string {
result := make([]string, len(nodeTypes), len(nodeTypes))
for i, nodeType := range nodeTypes {
result[i] = nodeType.Name
}
sort.Strings(result)
return result
}

View File

@ -0,0 +1,74 @@
package google
import (
"errors"
"fmt"
"strconv"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"regexp"
)
func TestAccDataSourceComputeNodeTypes_basic(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceComputeNodeTypes_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleComputeNodeTypes("data.google_compute_node_types.available"),
),
},
},
})
}
func testAccCheckGoogleComputeNodeTypes(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find node types data source: %s", n)
}
if rs.Primary.ID == "" {
return errors.New("node types data source ID not set.")
}
count, ok := rs.Primary.Attributes["names.#"]
if !ok {
return errors.New("can't find 'names' attribute")
}
cnt, err := strconv.Atoi(count)
if err != nil {
return errors.New("failed to read number of node types")
}
if cnt < 1 {
return fmt.Errorf("expected at least one node type, got %d", cnt)
}
for i := 0; i < cnt; i++ {
idx := fmt.Sprintf("names.%d", i)
v, ok := rs.Primary.Attributes[idx]
if !ok {
return fmt.Errorf("expected %q, version not found", idx)
}
if !regexp.MustCompile(`-[0-9]+-[0-9]+$`).MatchString(v) {
return fmt.Errorf("unexpected type format for %q, value is %v", idx, v)
}
}
return nil
}
}
var testAccDataSourceComputeNodeTypes_basic = `
data "google_compute_node_types" "available" {
zone = "us-central1-a"
}
`

View File

@ -93,6 +93,7 @@ func Provider() terraform.ResourceProvider {
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
"google_compute_network": dataSourceGoogleComputeNetwork(),
"google_compute_node_types": dataSourceGoogleComputeNodeTypes(),
"google_compute_regions": dataSourceGoogleComputeRegions(),
"google_compute_region_instance_group": dataSourceGoogleComputeRegionInstanceGroup(),
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),

View File

@ -33,6 +33,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{
"google_compute_image": resourceComputeImage(),
"google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(),
"google_compute_network": resourceComputeNetwork(),
"google_compute_node_template": resourceComputeNodeTemplate(),
"google_compute_region_autoscaler": resourceComputeRegionAutoscaler(),
"google_compute_region_disk": resourceComputeRegionDisk(),
"google_compute_route": resourceComputeRoute(),

View File

@ -0,0 +1,431 @@
// ----------------------------------------------------------------------------
//
// *** 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"
"time"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
)
func resourceComputeNodeTemplate() *schema.Resource {
return &schema.Resource{
Create: resourceComputeNodeTemplateCreate,
Read: resourceComputeNodeTemplateRead,
Delete: resourceComputeNodeTemplateDelete,
Importer: &schema.ResourceImporter{
State: resourceComputeNodeTemplateImport,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(240 * time.Second),
Delete: schema.DefaultTimeout(240 * time.Second),
},
Schema: map[string]*schema.Schema{
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"node_affinity_labels": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"node_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"node_type_flexibility"},
},
"node_type_flexibility": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cpus": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"memory": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"local_ssd": {
Type: schema.TypeString,
Computed: true,
},
},
},
ConflictsWith: []string{"node_type"},
},
"region": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"creation_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"self_link": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceComputeNodeTemplateCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
obj := make(map[string]interface{})
descriptionProp, err := expandComputeNodeTemplateDescription(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
}
nameProp, err := expandComputeNodeTemplateName(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
}
nodeAffinityLabelsProp, err := expandComputeNodeTemplateNodeAffinityLabels(d.Get("node_affinity_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("node_affinity_labels"); !isEmptyValue(reflect.ValueOf(nodeAffinityLabelsProp)) && (ok || !reflect.DeepEqual(v, nodeAffinityLabelsProp)) {
obj["nodeAffinityLabels"] = nodeAffinityLabelsProp
}
nodeTypeProp, err := expandComputeNodeTemplateNodeType(d.Get("node_type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("node_type"); !isEmptyValue(reflect.ValueOf(nodeTypeProp)) && (ok || !reflect.DeepEqual(v, nodeTypeProp)) {
obj["nodeType"] = nodeTypeProp
}
nodeTypeFlexibilityProp, err := expandComputeNodeTemplateNodeTypeFlexibility(d.Get("node_type_flexibility"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("node_type_flexibility"); !isEmptyValue(reflect.ValueOf(nodeTypeFlexibilityProp)) && (ok || !reflect.DeepEqual(v, nodeTypeFlexibilityProp)) {
obj["nodeTypeFlexibility"] = nodeTypeFlexibilityProp
}
regionProp, err := expandComputeNodeTemplateRegion(d.Get("region"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) {
obj["region"] = regionProp
}
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates")
if err != nil {
return err
}
log.Printf("[DEBUG] Creating new NodeTemplate: %#v", obj)
res, err := sendRequestWithTimeout(config, "POST", url, obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating NodeTemplate: %s", err)
}
// Store the ID now
id, err := replaceVars(d, config, "{{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
}
op := &compute.Operation{}
err = Convert(res, op)
if err != nil {
return err
}
waitErr := computeOperationWaitTime(
config.clientCompute, op, project, "Creating NodeTemplate",
int(d.Timeout(schema.TimeoutCreate).Minutes()))
if waitErr != nil {
// The resource didn't actually create
d.SetId("")
return fmt.Errorf("Error waiting to create NodeTemplate: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating NodeTemplate %q: %#v", d.Id(), res)
return resourceComputeNodeTemplateRead(d, meta)
}
func resourceComputeNodeTemplateRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
if err != nil {
return err
}
res, err := sendRequest(config, "GET", url, nil)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeNodeTemplate %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 NodeTemplate: %s", err)
}
if err := d.Set("creation_timestamp", flattenComputeNodeTemplateCreationTimestamp(res["creationTimestamp"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("description", flattenComputeNodeTemplateDescription(res["description"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("name", flattenComputeNodeTemplateName(res["name"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("node_affinity_labels", flattenComputeNodeTemplateNodeAffinityLabels(res["nodeAffinityLabels"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("node_type", flattenComputeNodeTemplateNodeType(res["nodeType"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("node_type_flexibility", flattenComputeNodeTemplateNodeTypeFlexibility(res["nodeTypeFlexibility"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("region", flattenComputeNodeTemplateRegion(res["region"], d)); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil {
return fmt.Errorf("Error reading NodeTemplate: %s", err)
}
return nil
}
func resourceComputeNodeTemplateDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
if err != nil {
return err
}
var obj map[string]interface{}
log.Printf("[DEBUG] Deleting NodeTemplate %q", d.Id())
res, err := sendRequestWithTimeout(config, "DELETE", url, obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return handleNotFoundError(err, d, "NodeTemplate")
}
project, err := getProject(d, config)
if err != nil {
return err
}
op := &compute.Operation{}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Deleting NodeTemplate",
int(d.Timeout(schema.TimeoutDelete).Minutes()))
if err != nil {
return err
}
log.Printf("[DEBUG] Finished deleting NodeTemplate %q: %#v", d.Id(), res)
return nil
}
func resourceComputeNodeTemplateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/regions/(?P<region>[^/]+)/nodeTemplates/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<region>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config); err != nil {
return nil, err
}
// Replace import id for the resource id
id, err := replaceVars(d, config, "{{name}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
return []*schema.ResourceData{d}, nil
}
func flattenComputeNodeTemplateCreationTimestamp(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateDescription(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateName(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateNodeAffinityLabels(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateNodeType(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateNodeTypeFlexibility(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["cpus"] =
flattenComputeNodeTemplateNodeTypeFlexibilityCpus(original["cpus"], d)
transformed["memory"] =
flattenComputeNodeTemplateNodeTypeFlexibilityMemory(original["memory"], d)
transformed["local_ssd"] =
flattenComputeNodeTemplateNodeTypeFlexibilityLocalSsd(original["localSsd"], d)
return []interface{}{transformed}
}
func flattenComputeNodeTemplateNodeTypeFlexibilityCpus(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateNodeTypeFlexibilityMemory(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateNodeTypeFlexibilityLocalSsd(v interface{}, d *schema.ResourceData) interface{} {
return v
}
func flattenComputeNodeTemplateRegion(v interface{}, d *schema.ResourceData) interface{} {
if v == nil {
return v
}
return NameFromSelfLinkStateFunc(v)
}
func expandComputeNodeTemplateDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateNodeAffinityLabels(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
}
func expandComputeNodeTemplateNodeType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateNodeTypeFlexibility(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{})
transformedCpus, err := expandComputeNodeTemplateNodeTypeFlexibilityCpus(original["cpus"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedCpus); val.IsValid() && !isEmptyValue(val) {
transformed["cpus"] = transformedCpus
}
transformedMemory, err := expandComputeNodeTemplateNodeTypeFlexibilityMemory(original["memory"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMemory); val.IsValid() && !isEmptyValue(val) {
transformed["memory"] = transformedMemory
}
transformedLocalSsd, err := expandComputeNodeTemplateNodeTypeFlexibilityLocalSsd(original["local_ssd"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedLocalSsd); val.IsValid() && !isEmptyValue(val) {
transformed["localSsd"] = transformedLocalSsd
}
return transformed, nil
}
func expandComputeNodeTemplateNodeTypeFlexibilityCpus(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateNodeTypeFlexibilityMemory(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateNodeTypeFlexibilityLocalSsd(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeNodeTemplateRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true)
if err != nil {
return nil, fmt.Errorf("Invalid value for region: %s", err)
}
return f.RelativeLink(), nil
}

View File

@ -0,0 +1,93 @@
// ----------------------------------------------------------------------------
//
// *** 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 TestAccComputeNodeTemplate_nodeTemplateBasicExample(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: testAccCheckComputeNodeTemplateDestroy,
Steps: []resource.TestStep{
{
Config: testAccComputeNodeTemplate_nodeTemplateBasicExample(context),
},
{
ResourceName: "google_compute_node_template.template",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccComputeNodeTemplate_nodeTemplateBasicExample(context map[string]interface{}) string {
return Nprintf(`
data "google_compute_node_types" "central1a" {
zone = "us-central1-a"
}
resource "google_compute_node_template" "template" {
name = "soletenant-tmpl-%{random_suffix}"
region = "us-central1"
node_affinity_labels = {
foo = "baz"
}
node_type = "${data.google_compute_node_types.central1a.names[0]}"
}
`, context)
}
func testAccCheckComputeNodeTemplateDestroy(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
if rs.Type != "google_compute_node_template" {
continue
}
if strings.HasPrefix(name, "data.") {
continue
}
config := testAccProvider.Meta().(*Config)
url, err := replaceVarsForTest(rs, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
if err != nil {
return err
}
_, err = sendRequest(config, "GET", url, nil)
if err == nil {
return fmt.Errorf("ComputeNodeTemplate still exists at %s", url)
}
}
return nil
}

View File

@ -0,0 +1,44 @@
---
layout: "google"
page_title: "Google: google_compute_node_types"
sidebar_current: "docs-google-datasource-compute-node-types"
description: |-
Provides list of available Google Compute Engine node types for
sole-tenant nodes.
---
# google\_compute\_node\_types
Provides available node types for Compute Engine sole-tenant nodes in a zone
for a given project. For more information, see [the official documentation](https://cloud.google.com/compute/docs/nodes/#types) and [API](https://cloud.google.com/compute/docs/reference/rest/v1/nodeTypes).
## Example Usage
```hcl
data "google_compute_node_types" "central1b" {
zone = "us-central1-b"
}
resource "google_compute_node_template" "tmpl" {
name = "terraform-test-tmpl"
region = "us-central1"
node_type = "${data.google_compute_node_types.types.names[0]}"
}
```
## Argument Reference
The following arguments are supported:
* `zone` (Optional) - The zone to list node types for. Should be in zone of intended node groups and region of referencing node template. If `zone` is not specified, the provider-level zone must be set and is used
instead.
* `project` (Optional) - ID of the project to list available node types for.
Should match the project the nodes of this type will be deployed to.
Defaults to the project that the provider is authenticated with.
## Attributes Reference
The following attributes are exported:
* `names` - A list of node types available in the given zone and project.

View File

@ -0,0 +1,144 @@
---
# ----------------------------------------------------------------------------
#
# *** 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_compute_node_template"
sidebar_current: "docs-google-compute-node-template"
description: |-
Represents a NodeTemplate resource.
---
# google\_compute\_node\_template
Represents a NodeTemplate resource. Node templates specify properties
for creating sole-tenant nodes, such as node type, vCPU and memory
requirments, node affinity labels, and region.
To get more information about NodeTemplate, see:
* [API documentation](https://cloud.google.com/compute/docs/reference/rest/v1/nodeTemplates)
* How-to Guides
* [Sole-Tenant Nodes](https://cloud.google.com/compute/docs/nodes/)
<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=node_template_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 - Node Template Basic
```hcl
data "google_compute_node_types" "central1a" {
zone = "us-central1-a"
}
resource "google_compute_node_template" "template" {
name = "soletenant-tmpl"
region = "us-central1"
node_affinity_labels = {
foo = "baz"
}
node_type = "${data.google_compute_node_types.central1a.names[0]}"
}
```
## Argument Reference
The following arguments are supported:
- - -
* `description` -
(Optional)
An optional textual description of the resource.
* `name` -
(Optional)
Name of the resource.
* `node_affinity_labels` -
(Optional)
Labels to use for node affinity, which will be used in
instance scheduling.
* `node_type` -
(Optional)
Node type to use for nodes group that are created from this template.
Only one of nodeTypeFlexibility and nodeType can be specified.
* `node_type_flexibility` -
(Optional)
Flexible properties for the desired node type. Node groups that
use this node template will create nodes of a type that matches
these properties. Only one of nodeTypeFlexibility and nodeType can
be specified. Structure is documented below.
* `region` -
(Optional)
Region where nodes using the node template will be created.
If it is not provided, the provider region is used.
* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.
The `node_type_flexibility` block supports:
* `cpus` -
(Optional)
Number of virtual CPUs to use.
* `memory` -
(Optional)
Physical memory available to the node, defined in MB.
* `local_ssd` -
Use local SSD
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are exported:
* `creation_timestamp` -
Creation timestamp in RFC3339 text format.
* `self_link` - The URI of the created resource.
## Timeouts
This resource provides the following
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
- `create` - Default is 4 minutes.
- `delete` - Default is 4 minutes.
## Import
NodeTemplate can be imported using any of these accepted formats:
```
$ terraform import google_compute_node_template.default projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}
$ terraform import google_compute_node_template.default {{project}}/{{region}}/{{name}}
$ terraform import google_compute_node_template.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.

View File

@ -84,6 +84,9 @@
<li<%= sidebar_current("docs-google-datasource-project-services") %>>
<a href="/docs/providers/google/d/google_project_services.html">google_project_services</a>
</li>
<li<%= sidebar_current("docs-google-datasource-compute-node-types") %>>
<a href="/docs/providers/google/d/google_compute_node_types.html">google_compute_node_types</a>
</li>
<li<%= sidebar_current("docs-google-datasource-compute-regions") %>>
<a href="/docs/providers/google/d/google_compute_regions.html">google_compute_regions</a>
</li>
@ -407,6 +410,10 @@
<a href="/docs/providers/google/r/compute_interconnect_attachment.html">google_compute_interconnect_attachment</a>
</li>
<li<%= sidebar_current("docs-google-compute-node-template") %>>
<a href="/docs/providers/google/r/compute_node_template.html">google_compute_node_template</a>
</li>
<li<%= sidebar_current("docs-google-compute-network-x") %>>
<a href="/docs/providers/google/r/compute_network.html">google_compute_network</a>
</li>