From 180a8a0e89695381c09d957a42091d95ab832be3 Mon Sep 17 00:00:00 2001 From: Neil Peterson Date: Thu, 14 Mar 2019 10:29:49 -0700 Subject: [PATCH 1/5] Added support for GPU resources on Linux containers --- azurerm/resource_arm_container_group.go | 48 ++++++++++++++++++++ azurerm/resource_arm_container_group_test.go | 12 ++++- website/docs/r/container_group.html.markdown | 12 ++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 0bdf5bd2dfaf..a727423e2af7 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -145,6 +145,28 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, + "gpu": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "gpu_count": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "gpu_sku": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + }, + }, + "port": { Type: schema.TypeInt, Optional: true, @@ -461,6 +483,22 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc }, } + if v, ok := data["gpu"]; ok { + gpu := v.([]interface{}) + for _, v := range gpu { + gpuCount := v.(map[string]interface{})["gpu_count"] + gpuSku := v.(map[string]interface{})["gpu_sku"] + + var gpus containerinstance.GpuResource + + gpus = containerinstance.GpuResource{ + Count: utils.Int32(int32(gpuCount.(int))), + Sku: containerinstance.GpuSku(gpuSku.(string)), + } + container.Resources.Requests.Gpu = &gpus + } + } + if v, ok := data["ports"].(*schema.Set); ok && len(v.List()) > 0 { var ports []containerinstance.ContainerPort for _, v := range v.List() { @@ -711,6 +749,16 @@ func flattenContainerGroupContainers(d *schema.ResourceData, containers *[]conta if v := resourceRequests.MemoryInGB; v != nil { containerConfig["memory"] = *v } + if v := resourceRequests.Gpu; v != nil { + gpus := make([]interface{}, 0) + gpu := make(map[string]interface{}) + + gpu["gpu_count"] = *v.Count + gpu["gpu_sku"] = v.Sku + gpus = append(gpus, gpu) + + containerConfig["gpu"] = gpus + } } } diff --git a/azurerm/resource_arm_container_group_test.go b/azurerm/resource_arm_container_group_test.go index a34bb971c7e8..3fde05a204ff 100644 --- a/azurerm/resource_arm_container_group_test.go +++ b/azurerm/resource_arm_container_group_test.go @@ -211,6 +211,9 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.%", "2"), resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.secureFoo", "secureBar"), resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.secureFoo1", "secureBar1"), + resource.TestCheckResourceAttr(resourceName, "container.0.gpu.#", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.gpu_count", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.gpu_sku", "K80"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.#", "1"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.0.mount_path", "/aci/logs"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.0.name", "logs"), @@ -560,7 +563,7 @@ resource "azurerm_container_group" "test" { ports { port = 80 protocol = "TCP" - } + } environment_variables = { "foo" = "bar" @@ -624,7 +627,12 @@ resource "azurerm_container_group" "test" { ports { port = 80 protocol = "TCP" - } + } + + gpu = { + gpu_count = 1 + gpu_sku = "K80" + } volume { name = "logs" diff --git a/website/docs/r/container_group.html.markdown b/website/docs/r/container_group.html.markdown index 363a451969b7..b5030269ccb8 100644 --- a/website/docs/r/container_group.html.markdown +++ b/website/docs/r/container_group.html.markdown @@ -55,7 +55,7 @@ resource "azurerm_container_group" "aci-helloworld" { } ports { port = 443 - protocol = "TCP" + protocol = "TCP" } environment_variables = { @@ -128,6 +128,10 @@ The `container` block supports: * `memory` - (Required) The required memory of the containers in GB. Changing this forces a new resource to be created. +~> **Note:** Gpu resources are currently only supported in Linux containers. + +* `gpu` - (Optional) Specify to deploy the container with a GPU resource. + * `ports` - (Optional) A set of public ports for the container. Changing this forces a new resource to be created. Set as documented in the `ports` block below. * `environment_variables` - (Optional) A list of environment variables to be set on the container. Specified as a map of name/value pairs. Changing this forces a new resource to be created. @@ -170,6 +174,12 @@ The `ports` block supports: * `protocol` - (Required) The network protocol associated with port. Possible values are `TCP` & `UDP`. +The `gpu` block supports: + +* `gpu_count` - (Required) The number of GPUs. Allowed values are 1, 2, or 4. + +* `gpu_sku` - (Required) The GPU SKU. Allowed values are K80, P100, or V100. + ## Attributes Reference The following attributes are exported: From 4d984c73aa67471b9449113a61efdbbb027860f7 Mon Sep 17 00:00:00 2001 From: Neil Peterson Date: Thu, 14 Mar 2019 11:22:25 -0700 Subject: [PATCH 2/5] Fixed linting issue: remove var --- azurerm/resource_arm_container_group.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 13ead72e25e6..4410d11bdba5 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -557,9 +557,7 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc gpuCount := v.(map[string]interface{})["gpu_count"] gpuSku := v.(map[string]interface{})["gpu_sku"] - var gpus containerinstance.GpuResource - - gpus = containerinstance.GpuResource{ + gpus := containerinstance.GpuResource{ Count: utils.Int32(int32(gpuCount.(int))), Sku: containerinstance.GpuSku(gpuSku.(string)), } From 325b98d16336b5f4269ee333142b65cc1ae57633 Mon Sep 17 00:00:00 2001 From: Neil Peterson Date: Sat, 16 Mar 2019 09:45:22 -0700 Subject: [PATCH 3/5] Addressed PR feedback --- azurerm/resource_arm_container_group.go | 40 +++++++++++++------- website/docs/r/container_group.html.markdown | 8 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 4410d11bdba5..da4dcde03d19 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -152,16 +152,26 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "gpu_count": { + "count": { Type: schema.TypeInt, Optional: true, ForceNew: true, + ValidateFunc: validate.IntInSlice([]int{ + 1, + 2, + 4, + }), }, - "gpu_sku": { + "sku": { Type: schema.TypeString, Optional: true, ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "K80", + "P100", + "V100", + }, false), }, }, }, @@ -552,14 +562,15 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc } if v, ok := data["gpu"]; ok { - gpu := v.([]interface{}) - for _, v := range gpu { - gpuCount := v.(map[string]interface{})["gpu_count"] - gpuSku := v.(map[string]interface{})["gpu_sku"] + gpus := v.([]interface{}) + for _, gpuRaw := range gpus { + v := gpuRaw.(map[string]interface{}) + gpuCount := int32(v["count"].(int)) + gpuSku := containerinstance.GpuSku(v["sku"].(string)) gpus := containerinstance.GpuResource{ - Count: utils.Int32(int32(gpuCount.(int))), - Sku: containerinstance.GpuSku(gpuSku.(string)), + Count: &gpuCount, + Sku: gpuSku, } container.Resources.Requests.Gpu = &gpus } @@ -815,16 +826,17 @@ func flattenContainerGroupContainers(d *schema.ResourceData, containers *[]conta if v := resourceRequests.MemoryInGB; v != nil { containerConfig["memory"] = *v } + + gpus := make([]interface{}, 0) if v := resourceRequests.Gpu; v != nil { - gpus := make([]interface{}, 0) gpu := make(map[string]interface{}) - - gpu["gpu_count"] = *v.Count - gpu["gpu_sku"] = v.Sku + if v.Count != nil { + gpu["count"] = *v.Count + } + gpu["sku"] = string(v.Sku) gpus = append(gpus, gpu) - - containerConfig["gpu"] = gpus } + containerConfig["gpu"] = gpus } } diff --git a/website/docs/r/container_group.html.markdown b/website/docs/r/container_group.html.markdown index 9ae0647633a7..47af628745d9 100644 --- a/website/docs/r/container_group.html.markdown +++ b/website/docs/r/container_group.html.markdown @@ -134,9 +134,9 @@ A `container` block supports: * `memory` - (Required) The required memory of the containers in GB. Changing this forces a new resource to be created. -~> **Note:** Gpu resources are currently only supported in Linux containers. +* `gpu` - (Optional) A `gpu` block as defined below. -* `gpu` - (Optional) Specify to deploy the container with a GPU resource. +~> **Note:** Gpu resources are currently only supported in Linux containers. * `ports` - (Optional) A set of public ports for the container. Changing this forces a new resource to be created. Set as documented in the `ports` block below. @@ -192,9 +192,9 @@ A `ports` block supports: A `gpu` block supports: -* `gpu_count` - (Required) The number of GPUs. Allowed values are 1, 2, or 4. +* `count` - (Required) The number of GPUs which should be assigned to this container. Allowed values are `1`, `2`, or `4`. -* `gpu_sku` - (Required) The GPU SKU. Allowed values are K80, P100, or V100. +* `sku` - (Required) The Sku which should be used for the GPU. Possible values are `K80`, `P100`, or `V100`. --- From 1ee3ec72300975ad3036098103367f6904d437a5 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Sun, 17 Mar 2019 18:32:51 +0100 Subject: [PATCH 4/5] Fixing the test assertion --- azurerm/resource_arm_container_group_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_container_group_test.go b/azurerm/resource_arm_container_group_test.go index 5b4f8e34baf3..39579009e745 100644 --- a/azurerm/resource_arm_container_group_test.go +++ b/azurerm/resource_arm_container_group_test.go @@ -212,8 +212,8 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.secureFoo", "secureBar"), resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.secureFoo1", "secureBar1"), resource.TestCheckResourceAttr(resourceName, "container.0.gpu.#", "1"), - resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.gpu_count", "1"), - resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.gpu_sku", "K80"), + resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.count", "1"), + resource.TestCheckResourceAttr(resourceName, "container.0.gpu.0.sku", "K80"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.#", "1"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.0.mount_path", "/aci/logs"), resource.TestCheckResourceAttr(resourceName, "container.0.volume.0.name", "logs"), From 273a294524535f7be7907de4cbecdf0dd2b43226 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Sun, 17 Mar 2019 18:48:22 +0100 Subject: [PATCH 5/5] fixing the argument names --- azurerm/resource_arm_container_group_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/azurerm/resource_arm_container_group_test.go b/azurerm/resource_arm_container_group_test.go index 39579009e745..3e189e649e60 100644 --- a/azurerm/resource_arm_container_group_test.go +++ b/azurerm/resource_arm_container_group_test.go @@ -690,12 +690,12 @@ resource "azurerm_container_group" "test" { ports { port = 80 protocol = "TCP" - } + } - gpu = { - gpu_count = 1 - gpu_sku = "K80" - } + gpu = { + count = 1 + sku = "K80" + } volume { name = "logs"