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

Add accelerators workstation config resource #5991

Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions .changelog/8490.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
workstations: added `accelerators` field to `google_workstations_workstation_config` resource(beta)
```
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,84 @@ resource "google_workstations_workstation_config" "default" {
`, context)
}

func TestAccWorkstationsWorkstationConfig_workstationConfigAcceleratorsExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
CheckDestroy: testAccCheckWorkstationsWorkstationConfigDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccWorkstationsWorkstationConfig_workstationConfigAcceleratorsExample(context),
},
{
ResourceName: "google_workstations_workstation_config.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"workstation_config_id", "workstation_cluster_id", "location"},
},
},
})
}

func testAccWorkstationsWorkstationConfig_workstationConfigAcceleratorsExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_compute_network" "default" {
provider = google-beta
name = "tf-test-workstation-cluster%{random_suffix}"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "default" {
provider = google-beta
name = "tf-test-workstation-cluster%{random_suffix}"
ip_cidr_range = "10.0.0.0/24"
region = "us-central1"
network = google_compute_network.default.name
}

resource "google_workstations_workstation_cluster" "default" {
provider = google-beta
workstation_cluster_id = "tf-test-workstation-cluster%{random_suffix}"
network = google_compute_network.default.id
subnetwork = google_compute_subnetwork.default.id
location = "us-central1"

labels = {
"label" = "key"
}

annotations = {
label-one = "value-one"
}
}

resource "google_workstations_workstation_config" "default" {
provider = google-beta
workstation_config_id = "tf-test-workstation-config%{random_suffix}"
workstation_cluster_id = google_workstations_workstation_cluster.default.workstation_cluster_id
location = "us-central1"

host {
gce_instance {
machine_type = "n1-standard-2"
boot_disk_size_gb = 35
disable_public_ip_addresses = true
accelerators {
type = "nvidia-tesla-p100"
count = "1"
}
}
}
}
`, context)
}

func TestAccWorkstationsWorkstationConfig_workstationConfigEncryptionKeyExample(t *testing.T) {
t.Parallel()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ If the encryption key is revoked, the workstation session will automatically be
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"accelerators": {
Type: schema.TypeList,
Optional: true,
Description: `An accelerator card attached to the instance.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"count": {
Type: schema.TypeInt,
Required: true,
Description: `Number of accelerator cards exposed to the instance.`,
},
"type": {
Type: schema.TypeString,
Required: true,
Description: `Type of accelerator resource to attach to the instance, for example, "nvidia-tesla-p100".`,
},
},
},
},
"boot_disk_size_gb": {
Type: schema.TypeInt,
Computed: true,
Expand Down Expand Up @@ -925,6 +944,8 @@ func flattenWorkstationsWorkstationConfigHostGceInstance(v interface{}, d *schem
flattenWorkstationsWorkstationConfigHostGceInstanceShieldedInstanceConfig(original["shieldedInstanceConfig"], d, config)
transformed["confidential_instance_config"] =
flattenWorkstationsWorkstationConfigHostGceInstanceConfidentialInstanceConfig(original["confidentialInstanceConfig"], d, config)
transformed["accelerators"] =
flattenWorkstationsWorkstationConfigHostGceInstanceAccelerators(original["accelerators"], d, config)
return []interface{}{transformed}
}
func flattenWorkstationsWorkstationConfigHostGceInstanceMachineType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
Expand Down Expand Up @@ -1021,6 +1042,46 @@ func flattenWorkstationsWorkstationConfigHostGceInstanceConfidentialInstanceConf
return []interface{}{transformed}
}

func flattenWorkstationsWorkstationConfigHostGceInstanceAccelerators(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) 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{}{
"type": flattenWorkstationsWorkstationConfigHostGceInstanceAcceleratorsType(original["type"], d, config),
"count": flattenWorkstationsWorkstationConfigHostGceInstanceAcceleratorsCount(original["count"], d, config),
})
}
return transformed
}
func flattenWorkstationsWorkstationConfigHostGceInstanceAcceleratorsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenWorkstationsWorkstationConfigHostGceInstanceAcceleratorsCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenWorkstationsWorkstationConfigPersistentDirectories(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -1352,6 +1413,13 @@ func expandWorkstationsWorkstationConfigHostGceInstance(v interface{}, d tpgreso
transformed["confidentialInstanceConfig"] = transformedConfidentialInstanceConfig
}

transformedAccelerators, err := expandWorkstationsWorkstationConfigHostGceInstanceAccelerators(original["accelerators"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAccelerators); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["accelerators"] = transformedAccelerators
}

return transformed, nil
}

Expand Down Expand Up @@ -1447,6 +1515,43 @@ func expandWorkstationsWorkstationConfigHostGceInstanceConfidentialInstanceConfi
return v, nil
}

func expandWorkstationsWorkstationConfigHostGceInstanceAccelerators(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
if raw == nil {
continue
}
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedType, err := expandWorkstationsWorkstationConfigHostGceInstanceAcceleratorsType(original["type"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedType); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["type"] = transformedType
}

transformedCount, err := expandWorkstationsWorkstationConfigHostGceInstanceAcceleratorsCount(original["count"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedCount); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["count"] = transformedCount
}

req = append(req, transformed)
}
return req, nil
}

func expandWorkstationsWorkstationConfigHostGceInstanceAcceleratorsType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandWorkstationsWorkstationConfigHostGceInstanceAcceleratorsCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandWorkstationsWorkstationConfigPersistentDirectories(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
Expand Down
73 changes: 73 additions & 0 deletions website/docs/r/workstations_workstation_config.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,64 @@ resource "google_workstations_workstation_config" "default" {
}
}
```
<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=workstation_config_accelerators&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 - Workstation Config Accelerators


```hcl
resource "google_compute_network" "default" {
provider = google-beta
name = "workstation-cluster"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "default" {
provider = google-beta
name = "workstation-cluster"
ip_cidr_range = "10.0.0.0/24"
region = "us-central1"
network = google_compute_network.default.name
}

resource "google_workstations_workstation_cluster" "default" {
provider = google-beta
workstation_cluster_id = "workstation-cluster"
network = google_compute_network.default.id
subnetwork = google_compute_subnetwork.default.id
location = "us-central1"

labels = {
"label" = "key"
}

annotations = {
label-one = "value-one"
}
}

resource "google_workstations_workstation_config" "default" {
provider = google-beta
workstation_config_id = "workstation-config"
workstation_cluster_id = google_workstations_workstation_cluster.default.workstation_cluster_id
location = "us-central1"

host {
gce_instance {
machine_type = "n1-standard-2"
boot_disk_size_gb = 35
disable_public_ip_addresses = true
accelerators {
type = "nvidia-tesla-p100"
count = "1"
}
}
}
}
```
<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=workstation_config_encryption_key&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%;">
Expand Down Expand Up @@ -540,6 +598,11 @@ The following arguments are supported:
A set of Compute Engine Confidential VM instance options.
Structure is [documented below](#nested_confidential_instance_config).

* `accelerators` -
(Optional)
An accelerator card attached to the instance.
Structure is [documented below](#nested_accelerators).


<a name="nested_shielded_instance_config"></a>The `shielded_instance_config` block supports:

Expand All @@ -561,6 +624,16 @@ The following arguments are supported:
(Optional)
Whether the instance has confidential compute enabled.

<a name="nested_accelerators"></a>The `accelerators` block supports:

* `type` -
(Required)
Type of accelerator resource to attach to the instance, for example, "nvidia-tesla-p100".

* `count` -
(Required)
Number of accelerator cards exposed to the instance.

<a name="nested_persistent_directories"></a>The `persistent_directories` block supports:

* `mount_path` -
Expand Down