2017-03-03 21:12:00 +01:00
|
|
|
package azurerm
|
|
|
|
|
|
|
|
import (
|
2017-03-03 23:31:40 +01:00
|
|
|
"fmt"
|
2017-03-03 21:12:00 +01:00
|
|
|
"github.com/Azure/azure-sdk-for-go/arm/disk"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
"github.com/hashicorp/terraform/helper/validation"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
2017-03-03 23:31:40 +01:00
|
|
|
"strings"
|
2017-03-03 21:12:00 +01:00
|
|
|
)
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
func resourceArmManagedDisk() *schema.Resource {
|
2017-03-03 21:12:00 +01:00
|
|
|
return &schema.Resource{
|
2017-03-03 23:46:33 +01:00
|
|
|
Create: resourceArmManagedDiskCreate,
|
|
|
|
Read: resourceArmManagedDiskRead,
|
|
|
|
Update: resourceArmManagedDiskCreate,
|
|
|
|
Delete: resourceArmManagedDiskDelete,
|
2017-03-03 21:12:00 +01:00
|
|
|
Importer: &schema.ResourceImporter{
|
|
|
|
State: schema.ImportStatePassthrough,
|
|
|
|
},
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"name": {
|
2017-03-03 23:31:40 +01:00
|
|
|
Type: schema.TypeString,
|
2017-03-03 21:12:00 +01:00
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"location": locationSchema(),
|
|
|
|
|
|
|
|
"resource_group_name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"storage_account_type": {
|
2017-03-03 23:31:40 +01:00
|
|
|
Type: schema.TypeString,
|
2017-03-03 21:12:00 +01:00
|
|
|
Required: true,
|
|
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
|
|
string(disk.PremiumLRS),
|
|
|
|
string(disk.StandardLRS),
|
|
|
|
}, true),
|
|
|
|
},
|
|
|
|
|
|
|
|
"create_option": {
|
2017-03-03 23:31:40 +01:00
|
|
|
Type: schema.TypeString,
|
2017-03-03 21:12:00 +01:00
|
|
|
Required: true,
|
2017-03-04 04:33:04 +01:00
|
|
|
ForceNew: true,
|
2017-03-03 21:12:00 +01:00
|
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
|
|
string(disk.Import),
|
|
|
|
string(disk.Empty),
|
2017-03-04 04:33:04 +01:00
|
|
|
string(disk.Copy),
|
2017-03-03 21:12:00 +01:00
|
|
|
}, true),
|
|
|
|
},
|
|
|
|
|
2017-03-04 03:15:05 +01:00
|
|
|
"source_uri": {
|
2017-03-04 04:33:04 +01:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
Computed: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"source_resource_id": {
|
2017-03-03 21:12:00 +01:00
|
|
|
Type: schema.TypeString,
|
|
|
|
Optional: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"os_type": {
|
2017-03-03 23:31:40 +01:00
|
|
|
Type: schema.TypeString,
|
2017-03-03 21:12:00 +01:00
|
|
|
Optional: true,
|
|
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
|
|
string(disk.Windows),
|
|
|
|
string(disk.Linux),
|
|
|
|
}, true),
|
|
|
|
},
|
|
|
|
|
|
|
|
"disk_size_gb": {
|
2017-03-03 23:31:40 +01:00
|
|
|
Type: schema.TypeInt,
|
2017-03-04 03:15:05 +01:00
|
|
|
Optional: true,
|
2017-03-03 21:12:00 +01:00
|
|
|
ValidateFunc: validateDiskSizeGB,
|
|
|
|
},
|
|
|
|
|
|
|
|
"tags": tagsSchema(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateDiskSizeGB(v interface{}, k string) (ws []string, errors []error) {
|
|
|
|
value := v.(int)
|
|
|
|
if value < 1 || value > 1023 {
|
|
|
|
errors = append(errors, fmt.Errorf(
|
|
|
|
"The `disk_size_gb` can only be between 1 and 1023"))
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
func resourceArmManagedDiskCreate(d *schema.ResourceData, meta interface{}) error {
|
2017-03-03 21:12:00 +01:00
|
|
|
client := meta.(*ArmClient)
|
|
|
|
diskClient := client.diskClient
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
log.Printf("[INFO] preparing arguments for Azure ARM Managed Disk creation.")
|
2017-03-03 21:12:00 +01:00
|
|
|
|
|
|
|
name := d.Get("name").(string)
|
|
|
|
location := d.Get("location").(string)
|
|
|
|
resGroup := d.Get("resource_group_name").(string)
|
|
|
|
tags := d.Get("tags").(map[string]interface{})
|
|
|
|
expandedTags := expandTags(tags)
|
|
|
|
|
2017-03-03 23:31:40 +01:00
|
|
|
createDisk := disk.Model{
|
2017-03-03 21:12:00 +01:00
|
|
|
Name: &name,
|
|
|
|
Location: &location,
|
|
|
|
Tags: expandedTags,
|
|
|
|
}
|
|
|
|
|
|
|
|
storageAccountType := d.Get("storage_account_type").(string)
|
|
|
|
osType := d.Get("os_type").(string)
|
|
|
|
|
2017-03-03 23:31:40 +01:00
|
|
|
createDisk.Properties = &disk.Properties{
|
|
|
|
AccountType: disk.StorageAccountTypes(storageAccountType),
|
|
|
|
OsType: disk.OperatingSystemTypes(osType),
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
2017-03-04 03:15:05 +01:00
|
|
|
if v := d.Get("disk_size_gb"); v != 0 {
|
2017-03-03 23:31:40 +01:00
|
|
|
diskSize := int32(v.(int))
|
|
|
|
createDisk.Properties.DiskSizeGB = &diskSize
|
|
|
|
}
|
2017-03-03 21:12:00 +01:00
|
|
|
createOption := d.Get("create_option").(string)
|
|
|
|
|
|
|
|
creationData := &disk.CreationData{
|
|
|
|
CreateOption: disk.CreateOption(createOption),
|
|
|
|
}
|
|
|
|
|
2017-03-03 23:31:40 +01:00
|
|
|
if strings.EqualFold(createOption, string(disk.Import)) {
|
2017-03-04 03:15:05 +01:00
|
|
|
if sourceUri := d.Get("source_uri").(string); sourceUri != "" {
|
|
|
|
creationData.SourceURI = &sourceUri
|
2017-03-03 21:12:00 +01:00
|
|
|
} else {
|
2017-03-04 04:33:04 +01:00
|
|
|
return fmt.Errorf("[ERROR] source_uri must be specified when create_option is `%s`", disk.Import)
|
|
|
|
}
|
|
|
|
} else if strings.EqualFold(createOption, string(disk.Copy)) {
|
|
|
|
if sourceResourceId := d.Get("source_resource_id").(string); sourceResourceId != "" {
|
|
|
|
creationData.SourceResourceID = &sourceResourceId
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("[ERROR] source_resource_id must be specified when create_option is `%s`", disk.Copy)
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createDisk.CreationData = creationData
|
|
|
|
|
|
|
|
_, diskErr := diskClient.CreateOrUpdate(resGroup, name, createDisk, make(chan struct{}))
|
|
|
|
if diskErr != nil {
|
|
|
|
return diskErr
|
|
|
|
}
|
|
|
|
|
|
|
|
read, err := diskClient.Get(resGroup, name)
|
2017-03-03 23:31:40 +01:00
|
|
|
if err != nil {
|
2017-03-03 21:12:00 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if read.ID == nil {
|
2017-03-03 23:46:33 +01:00
|
|
|
return fmt.Errorf("[ERROR] Cannot read Managed Disk %s (resource group %s) ID", name, resGroup)
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(*read.ID)
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
return resourceArmManagedDiskRead(d, meta)
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
func resourceArmManagedDiskRead(d *schema.ResourceData, meta interface{}) error {
|
2017-03-03 21:12:00 +01:00
|
|
|
diskClient := meta.(*ArmClient).diskClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resGroup := id.ResourceGroup
|
|
|
|
name := id.Path["disks"]
|
|
|
|
|
|
|
|
resp, err := diskClient.Get(resGroup, name)
|
|
|
|
if err != nil {
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
d.SetId("")
|
|
|
|
return nil
|
|
|
|
}
|
2017-03-03 23:46:33 +01:00
|
|
|
return fmt.Errorf("[ERROR] Error making Read request on Azure Managed Disk %s (resource group %s): %s", name, resGroup, err)
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
d.Set("name", resp.Name)
|
|
|
|
d.Set("resource_group_name", resGroup)
|
|
|
|
d.Set("location", resp.Location)
|
|
|
|
|
|
|
|
if resp.Properties != nil {
|
2017-03-04 04:33:04 +01:00
|
|
|
m := flattenAzureRmManagedDiskProperties(resp.Properties)
|
|
|
|
d.Set("storage_account_type", m["storage_account_type"])
|
|
|
|
d.Set("disk_size_gb", m["disk_size_gb"])
|
|
|
|
if m["os_type"] != nil {
|
|
|
|
d.Set("os_type", m["os_type"])
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if resp.CreationData != nil {
|
2017-03-04 04:33:04 +01:00
|
|
|
m := flattenAzureRmManagedDiskCreationData(resp.CreationData)
|
|
|
|
d.Set("create_option", m["create_option"])
|
|
|
|
if m["source_uri"] != nil {
|
|
|
|
d.Set("source_uri", m["source_uri"])
|
|
|
|
}
|
|
|
|
if m["source_resource_id"] != nil {
|
|
|
|
d.Set("source_resource_id", m["source_resource_id"])
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
flattenAndSetTags(d, resp.Tags)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-03-03 23:46:33 +01:00
|
|
|
func resourceArmManagedDiskDelete(d *schema.ResourceData, meta interface{}) error {
|
2017-03-03 21:12:00 +01:00
|
|
|
diskClient := meta.(*ArmClient).diskClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resGroup := id.ResourceGroup
|
|
|
|
name := id.Path["disks"]
|
|
|
|
|
|
|
|
if _, err = diskClient.Delete(resGroup, name, make(chan struct{})); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-03-04 04:33:04 +01:00
|
|
|
func flattenAzureRmManagedDiskProperties(properties *disk.Properties) map[string]interface{} {
|
2017-03-03 21:12:00 +01:00
|
|
|
result := make(map[string]interface{})
|
2017-03-03 23:31:40 +01:00
|
|
|
result["storage_account_type"] = string(properties.AccountType)
|
2017-03-06 08:42:15 +01:00
|
|
|
if properties.DiskSizeGB != nil {
|
|
|
|
result["disk_size_gb"] = *properties.DiskSizeGB
|
|
|
|
}
|
2017-03-03 23:31:40 +01:00
|
|
|
if properties.OsType != "" {
|
|
|
|
result["os_type"] = string(properties.OsType)
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
2017-03-04 04:33:04 +01:00
|
|
|
return result
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
2017-03-04 04:33:04 +01:00
|
|
|
func flattenAzureRmManagedDiskCreationData(creationData *disk.CreationData) map[string]interface{} {
|
2017-03-03 21:12:00 +01:00
|
|
|
result := make(map[string]interface{})
|
2017-03-03 23:31:40 +01:00
|
|
|
result["create_option"] = string(creationData.CreateOption)
|
2017-03-03 21:12:00 +01:00
|
|
|
if creationData.SourceURI != nil {
|
2017-03-04 03:15:05 +01:00
|
|
|
result["source_uri"] = *creationData.SourceURI
|
2017-03-03 21:12:00 +01:00
|
|
|
}
|
|
|
|
|
2017-03-04 04:33:04 +01:00
|
|
|
return result
|
2017-03-03 23:31:40 +01:00
|
|
|
}
|