From fac989ed5f7989934e1e0dbab7f1ab4f25486df7 Mon Sep 17 00:00:00 2001 From: stack72 Date: Thu, 7 Jan 2016 01:27:24 +0000 Subject: [PATCH] Azure RM Availability Sets. Adds Schema, CRUD, Acceptance Tests and Documentation --- builtin/providers/azurerm/provider.go | 3 +- .../azurerm/resource_arm_availability_set.go | 140 ++++++++++++++++++ .../resource_arm_availability_set_test.go | 136 +++++++++++++++++ .../azurerm/r/availability_set.html.markdown | 48 ++++++ website/source/layouts/azurerm.erb | 4 + 5 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/azurerm/resource_arm_availability_set.go create mode 100644 builtin/providers/azurerm/resource_arm_availability_set_test.go create mode 100644 website/source/docs/providers/azurerm/r/availability_set.html.markdown diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index c64d15148..612109fc3 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -42,6 +42,7 @@ func Provider() terraform.ResourceProvider { "azurerm_resource_group": resourceArmResourceGroup(), "azurerm_virtual_network": resourceArmVirtualNetwork(), "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), + "azurerm_availability_set": resourceArmAvailabilitySet(), }, ConfigureFunc: providerConfigure, @@ -87,7 +88,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { func registerAzureResourceProvidersWithSubscription(config *Config, client *ArmClient) error { providerClient := client.providers - providers := []string{"Microsoft.Network"} + providers := []string{"Microsoft.Network", "Microsoft.Compute"} for _, v := range providers { res, err := providerClient.Register(v) diff --git a/builtin/providers/azurerm/resource_arm_availability_set.go b/builtin/providers/azurerm/resource_arm_availability_set.go new file mode 100644 index 000000000..3209d7008 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_availability_set.go @@ -0,0 +1,140 @@ +package azurerm + +import ( + "fmt" + "log" + "net/http" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmAvailabilitySet() *schema.Resource { + return &schema.Resource{ + Create: resourceArmAvailabilitySetCreate, + Read: resourceArmAvailabilitySetRead, + Update: resourceArmAvailabilitySetCreate, + Delete: resourceArmAvailabilitySetDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: azureRMNormalizeLocation, + }, + + "platform_update_domain_count": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: 5, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(int) + if value > 20 { + errors = append(errors, fmt.Errorf( + "Maximum value for `platform_update_domain_count` is 20")) + } + return + }, + }, + + "platform_fault_domain_count": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + Default: 3, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(int) + if value > 3 { + errors = append(errors, fmt.Errorf( + "Maximum value for `platform_fault_domain_count` is 3", k)) + } + return + }, + }, + + "resource_group_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceArmAvailabilitySetCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + availSetClient := client.availSetClient + + log.Printf("[INFO] preparing arguments for Azure ARM Availability Set creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + updateDomainCount := d.Get("platform_update_domain_count").(int) + faultDomainCount := d.Get("platform_fault_domain_count").(int) + + availSet := compute.AvailabilitySet{ + Name: &name, + Location: &location, + Properties: &compute.AvailabilitySetProperties{ + PlatformFaultDomainCount: &faultDomainCount, + PlatformUpdateDomainCount: &updateDomainCount, + }, + } + + resp, err := availSetClient.CreateOrUpdate(resGroup, name, availSet) + if err != nil { + return err + } + + d.SetId(*resp.ID) + + return resourceArmAvailabilitySetRead(d, meta) +} + +func resourceArmAvailabilitySetRead(d *schema.ResourceData, meta interface{}) error { + availSetClient := meta.(*ArmClient).availSetClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["availabilitySets"] + + resp, err := availSetClient.Get(resGroup, name) + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure Availability Set %s: %s", name, err) + } + + availSet := *resp.Properties + d.Set("platform_update_domain_count", availSet.PlatformUpdateDomainCount) + d.Set("platform_fault_domain_count", availSet.PlatformFaultDomainCount) + + return nil +} + +func resourceArmAvailabilitySetDelete(d *schema.ResourceData, meta interface{}) error { + availSetClient := meta.(*ArmClient).availSetClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["availabilitySets"] + + _, err = availSetClient.Delete(resGroup, name) + + return err +} diff --git a/builtin/providers/azurerm/resource_arm_availability_set_test.go b/builtin/providers/azurerm/resource_arm_availability_set_test.go new file mode 100644 index 000000000..867b7484e --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_availability_set_test.go @@ -0,0 +1,136 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMAvailabilitySet_basic(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAvailabilitySetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureRMVAvailabilitySet_basic, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAvailabilitySetExists("azurerm_availability_set.test"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "name", "acceptanceTestAvailabilitySet1"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "platform_update_domain_count", "5"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "platform_fault_domain_count", "3"), + ), + }, + }, + }) +} + +func TestAccAzureRMAvailabilitySet_withDomainCounts(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMAvailabilitySetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureRMVAvailabilitySet_withDomainCounts, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMAvailabilitySetExists("azurerm_availability_set.test"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "name", "acceptanceTestAvailabilitySet1"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "platform_update_domain_count", "10"), + resource.TestCheckResourceAttr( + "azurerm_availability_set.test", "platform_fault_domain_count", "1"), + ), + }, + }, + }) +} + +func testCheckAzureRMAvailabilitySetExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + availSetName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for availability set: %s", availSetName) + } + + conn := testAccProvider.Meta().(*ArmClient).availSetClient + + resp, err := conn.Get(resourceGroup, availSetName) + if err != nil { + return fmt.Errorf("Bad: Get on availSetClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Availability Set %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMAvailabilitySetDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).vnetClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_availability_set" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Availability Set still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMVAvailabilitySet_basic = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} +resource "azurerm_availability_set" "test" { + name = "acceptanceTestAvailabilitySet1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} +` + +var testAccAzureRMVAvailabilitySet_withDomainCounts = ` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} +resource "azurerm_availability_set" "test" { + name = "acceptanceTestAvailabilitySet1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + platform_update_domain_count = 10 + platform_fault_domain_count = 1 +} +` diff --git a/website/source/docs/providers/azurerm/r/availability_set.html.markdown b/website/source/docs/providers/azurerm/r/availability_set.html.markdown new file mode 100644 index 000000000..651c39b2e --- /dev/null +++ b/website/source/docs/providers/azurerm/r/availability_set.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_availability_set" +sidebar_current: "docs-azurerm-resource-availability-set" +description: |- + Create an availability set for virtual machines. +--- + +# azurerm\_availability\_set + +Create an availability set for virtual machines. + +## Example Usage + +``` +resource "azurerm_resource_group" "test" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_availability_set" "test" { + name = "acceptanceTestAvailabilitySet1" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the availability set. Changing this forces a + new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to + create the availability set. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `platform_update_domain_count` - (Optional) Specifies the number of update domains that are used. Defaults to 5. + +* `platform_fault_domain_count` - (Optional) Specifies the number of fault domains that are used. Defaults to 3. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The virtual AvailabilitySet ID. \ No newline at end of file diff --git a/website/source/layouts/azurerm.erb b/website/source/layouts/azurerm.erb index fe00f7939..cbac83abf 100644 --- a/website/source/layouts/azurerm.erb +++ b/website/source/layouts/azurerm.erb @@ -25,6 +25,10 @@ azurerm_local_network_gateway + > + azurerm_availability_set + +