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

[azurerm_batch_pool] - support for custom images with the storage_image_reference property #3530

Merged
merged 8 commits into from
Jul 4, 2019
32 changes: 23 additions & 9 deletions azurerm/helpers/azure/batch_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,31 @@ func ExpandBatchPoolImageReference(list []interface{}) (*batch.ImageReference, e
}

storageImageRef := list[0].(map[string]interface{})
imageRef := &batch.ImageReference{}

storageImageRefOffer := storageImageRef["offer"].(string)
storageImageRefPublisher := storageImageRef["publisher"].(string)
storageImageRefSku := storageImageRef["sku"].(string)
storageImageRefVersion := storageImageRef["version"].(string)
if storageImageRef["id"] != nil && storageImageRef["id"] != "" {
storageImageRefID := storageImageRef["id"].(string)
imageRef.ID = &storageImageRefID
}

if storageImageRef["offer"] != nil && storageImageRef["offer"] != "" {
storageImageRefOffer := storageImageRef["offer"].(string)
imageRef.Offer = &storageImageRefOffer
}

if storageImageRef["publisher"] != nil && storageImageRef["publisher"] != "" {
storageImageRefPublisher := storageImageRef["publisher"].(string)
imageRef.Publisher = &storageImageRefPublisher
}

if storageImageRef["sku"] != nil && storageImageRef["sku"] != "" {
storageImageRefSku := storageImageRef["sku"].(string)
imageRef.Sku = &storageImageRefSku
}

imageRef := &batch.ImageReference{
Offer: &storageImageRefOffer,
Publisher: &storageImageRefPublisher,
Sku: &storageImageRefSku,
Version: &storageImageRefVersion,
if storageImageRef["version"] != nil && storageImageRef["version"] != "" {
storageImageRefVersion := storageImageRef["version"].(string)
imageRef.Version = &storageImageRefVersion
}

return imageRef, nil
Expand Down
20 changes: 16 additions & 4 deletions azurerm/resource_arm_batch_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,34 +137,35 @@ func resourceArmBatchPool() *schema.Resource {
"id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
katbyte marked this conversation as resolved.
Show resolved Hide resolved
ValidateFunc: azure.ValidateResourceID,
},

"publisher": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"offer": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"sku": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validate.NoEmptyStrings,
},

"version": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},
Expand Down Expand Up @@ -382,6 +383,17 @@ func resourceArmBatchPoolCreate(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): %+v", poolName, resourceGroup, err)
}

if imageReference != nil {
// if an image reference ID is specified, the user wants use a custom image. This property is mutually exclusive with other properties.
if imageReference.ID != nil && (imageReference.Offer != nil || imageReference.Publisher != nil || imageReference.Sku != nil || imageReference.Version != nil) {
return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): Propeties version, offer, publish cannot be defined when using a custom image id", poolName, resourceGroup)
} else if imageReference.ID == nil && (imageReference.Offer == nil || imageReference.Publisher == nil || imageReference.Sku == nil || imageReference.Version == nil) {
return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): Propeties version, offer, publish and sku are mandatory when not using a custom image", poolName, resourceGroup)
}
} else {
return fmt.Errorf("Error creating Batch pool %q (Resource Group %q): image reference property can not be empty", poolName, resourceGroup)
}

if startTaskValue, startTaskOk := d.GetOk("start_task"); startTaskOk {
startTaskList := startTaskValue.([]interface{})
startTask, startTaskErr := azure.ExpandBatchPoolStartTask(startTaskList)
Expand Down
82 changes: 82 additions & 0 deletions azurerm/resource_arm_batch_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,36 @@ func TestAccAzureRMBatchPool_validateResourceFileHttpURLWithoutFilePath(t *testi
})
}

func TestAccAzureRMBatchPool_customImage(t *testing.T) {
resourceName := "azurerm_batch_pool.test"
ri := tf.AccRandTimeInt()
rs := acctest.RandString(4)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMBatchPoolDestroy,
Steps: []resource.TestStep{
{
Config: testaccAzureRMBatchPoolCustomImageConfiguration(ri, rs, testLocation()),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMBatchPoolExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "vm_size", "STANDARD_A1"),
resource.TestCheckResourceAttr(resourceName, "max_tasks_per_node", "2"),
resource.TestCheckResourceAttr(resourceName, "node_agent_sku_id", "batch.node.ubuntu 16.04"),
resource.TestCheckResourceAttr(resourceName, "account_name", fmt.Sprintf("testaccbatch%s", rs)),
resource.TestCheckResourceAttr(resourceName, "auto_scale.#", "0"),
resource.TestCheckResourceAttr(resourceName, "fixed_scale.#", "1"),
resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.target_dedicated_nodes", "2"),
resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.resize_timeout", "PT15M"),
resource.TestCheckResourceAttr(resourceName, "fixed_scale.0.target_low_priority_nodes", "0"),
resource.TestCheckResourceAttr(resourceName, "start_task.#", "0"),
),
},
},
})
}

func testCheckAzureRMBatchPoolExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
// Ensure we have enough information in state to look up in API
Expand Down Expand Up @@ -986,3 +1016,55 @@ resource "azurerm_batch_pool" "test" {

`, rInt, location, rString, rString, rString)
}

func testaccAzureRMBatchPoolCustomImageConfiguration(rInt int, rString string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "testaccRG-%d-batchpool"
location = "%s"
}

data "azurerm_image" "test" {
name = "ubuntu1604base-img"
resource_group_name = "batch-custom-img-rg"
}

resource "azurerm_storage_account" "test" {
name = "testaccsa%s"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_batch_account" "test" {
name = "testaccbatch%s"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
pool_allocation_mode = "BatchService"
storage_account_id = "${azurerm_storage_account.test.id}"

tags = {
env = "test"
}
}

resource "azurerm_batch_pool" "test" {
name = "testaccpool%s"
resource_group_name = "${azurerm_resource_group.test.name}"
account_name = "${azurerm_batch_account.test.name}"
display_name = "Test Acc Pool"
vm_size = "Standard_A1"
max_tasks_per_node = 2
node_agent_sku_id = "batch.node.ubuntu 16.04"

fixed_scale {
target_dedicated_nodes = 2
}

storage_image_reference {
id = "${data.azurerm_image.test.id}"
}
}
`, rInt, location, rString, rString, rString)
}
3 changes: 3 additions & 0 deletions examples/batch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ This example provisions the following Resources:
2. A [Storage Account](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics#azure-storage-account)
3. A [Batch Account](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics#account)
4. Two [Batch pools](https://docs.microsoft.com/en-us/azure/batch/batch-api-basics#pool): one with fixed scale and the other with auto-scale.
5. A [Batch pool that uses a custom VM image](https://docs.microsoft.com/en-us/azure/batch/batch-custom-images)

**Note:**: for point #5, it assumes that you have a VM image named `ubuntu1604base-img` in a resource group `batch-custom-img-rg` in the same Azure region than the one you are deploying the Azure Batch account. Check out the [documentation](https://docs.microsoft.com/en-us/azure/batch/batch-custom-images) for more information about how to create a custom VM image for Azure Batch.

## Usage

Expand Down
23 changes: 23 additions & 0 deletions examples/batch/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,26 @@ EOF
version = "latest"
}
}

data "azurerm_image" "image" {
katbyte marked this conversation as resolved.
Show resolved Hide resolved
name = "ubuntu1604base-img"
resource_group_name = "batch-custom-img-rg"
}

resource "azurerm_batch_pool" "customimg" {
name = "${var.prefix}-custom-img-pool"
resource_group_name = "${azurerm_resource_group.example.name}"
account_name = "${azurerm_batch_account.example.name}"
display_name = "Custom Img Pool"
vm_size = "Standard_A1"
node_agent_sku_id = "batch.node.ubuntu 16.04"

fixed_scale {
target_dedicated_nodes = 2
resize_timeout = "PT15M"
}

storage_image_reference {
id = "${data.azurerm_image.image.id}"
}
}
31 changes: 31 additions & 0 deletions website/docs/r/batch_pool.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,35 @@ EOF
}
```

## Example Usage with a Custom VM Image
katbyte marked this conversation as resolved.
Show resolved Hide resolved

It is also possible to use a custom VM image for an Azure Batch pool. The following assume that you have an image `ubuntu1604base-img` defined in a resource group `batch-custom-img-rg` in the same region than the Azure Batch account you are creating/updating.

```hcl
data "azurerm_image" "image" {
name = "ubuntu1604base-img"
resource_group_name = "batch-custom-img-rg"
}

resource "azurerm_batch_pool" "pool" {
name = "testaccpool"
resource_group_name = "${azurerm_resource_group.test.name}"
account_name = "${azurerm_batch_account.test.name}"
display_name = "Test Acc Pool Auto"
vm_size = "Standard_A1"
node_agent_sku_id = "batch.node.ubuntu 16.04"

fixed_scale {
target_dedicated_nodes = 2
resize_timeout = "PT15M"
}

storage_image_reference {
id = "${data.azurerm_image.image.id}"
}
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -120,6 +149,8 @@ The following arguments are supported:

* `storage_image_reference` - (Required) A `storage_image_reference` for the virtual machines that will compose the Batch pool.
katbyte marked this conversation as resolved.
Show resolved Hide resolved

~> **NOTE:** It's possible to reference a custom VM image for the pool by specifying it's `id` in the `id` property of the `storage_image_reference`. This property is mutually exclusive with other properties. The VM image should be in the same region that the batch pool you are about to create. See [official documentation](https://docs.microsoft.com/en-us/azure/batch/batch-custom-images) for more details.
katbyte marked this conversation as resolved.
Show resolved Hide resolved

* `display_name` - (Optional) Specifies the display name of the Batch pool.

* `max_tasks_per_node` - (Optional) Specifies the maximum number of tasks that can run concurrently on a single compute node in the pool. Defaults to `1`. Changing this forces a new resource to be created.
Expand Down