diff --git a/azurerm/internal/services/compute/data_source_dedicated_host.go b/azurerm/internal/services/compute/data_source_dedicated_host.go index acd1ed2199588..f1a14ca3c59c2 100644 --- a/azurerm/internal/services/compute/data_source_dedicated_host.go +++ b/azurerm/internal/services/compute/data_source_dedicated_host.go @@ -28,16 +28,16 @@ func dataSourceArmDedicatedHost() *schema.Resource { ValidateFunc: validateDedicatedHostName(), }, - "location": azure.SchemaLocationForDataSource(), - - "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), - - "host_group_name": { + "dedicated_host_group_name": { Type: schema.TypeString, Required: true, ValidateFunc: validateDedicatedHostGroupName(), }, + "resource_group_name": azure.SchemaResourceGroupNameForDataSource(), + + "location": azure.SchemaLocationForDataSource(), + "tags": tags.SchemaDataSource(), }, } @@ -66,7 +66,7 @@ func dataSourceArmDedicatedHostRead(d *schema.ResourceData, meta interface{}) er if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) } - d.Set("host_group_name", hostGroupName) + d.Set("dedicated_host_group_name", hostGroupName) return tags.FlattenAndSet(d, resp.Tags) } diff --git a/azurerm/internal/services/compute/parse/dedicated_host_group.go b/azurerm/internal/services/compute/parse/dedicated_host_group.go new file mode 100644 index 0000000000000..d4b847cfc39bd --- /dev/null +++ b/azurerm/internal/services/compute/parse/dedicated_host_group.go @@ -0,0 +1,33 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type DedicatedHostGroupId struct { + ResourceGroup string + Name string +} + +func DedicatedHostGroupID(input string) (*DedicatedHostGroupId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse Dedicated Host Group ID %q: %+v", input, err) + } + + server := DedicatedHostGroupId{ + ResourceGroup: id.ResourceGroup, + } + + if server.Name, err = id.PopSegment("hostGroups"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &server, nil +} diff --git a/azurerm/internal/services/compute/parse/dedicated_host_group_test.go b/azurerm/internal/services/compute/parse/dedicated_host_group_test.go new file mode 100644 index 0000000000000..d02416904e8d8 --- /dev/null +++ b/azurerm/internal/services/compute/parse/dedicated_host_group_test.go @@ -0,0 +1,75 @@ +package parse + +import ( + "testing" +) + +func TestDedicatedHostGroupID(t *testing.T) { + testData := []struct { + Name string + Input string + Error bool + Expect *DedicatedHostGroupId + }{ + { + Name: "Empty", + Input: "", + Error: true, + }, + { + Name: "No Resource Groups Segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Error: true, + }, + { + Name: "No Resource Groups Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/", + Error: true, + }, + { + Name: "Resource Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/", + Error: true, + }, + { + Name: "Missing Host Group Value", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Compute/hostGroups/", + Error: true, + }, + { + Name: "Host Group ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Compute/hostGroups/group1", + Error: false, + Expect: &DedicatedHostGroupId{ + ResourceGroup: "resGroup1", + Name: "group1", + }, + }, + { + Name: "Wrong Casing", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Compute/HostGroups/group1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := DedicatedHostGroupID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expect.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expect.Name, actual.Name) + } + + if actual.ResourceGroup != v.Expect.ResourceGroup { + t.Fatalf("Expected %q but got %q for Resource Group", v.Expect.ResourceGroup, actual.ResourceGroup) + } + } +} diff --git a/azurerm/internal/services/compute/resource_arm_dedicated_host.go b/azurerm/internal/services/compute/resource_arm_dedicated_host.go index 5b2da6b16a29a..fa90cfa658846 100644 --- a/azurerm/internal/services/compute/resource_arm_dedicated_host.go +++ b/azurerm/internal/services/compute/resource_arm_dedicated_host.go @@ -7,6 +7,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/validate" "github.com/hashicorp/go-azure-helpers/response" @@ -56,11 +57,11 @@ func resourceArmDedicatedHost() *schema.Resource { "resource_group_name": azure.SchemaResourceGroupName(), - "host_group_name": { + "dedicated_host_group_id": { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateDedicatedHostGroupName(), + ValidateFunc: validate.DedicatedHostGroupID, }, "sku_name": { @@ -108,8 +109,13 @@ func resourceArmDedicatedHostCreate(d *schema.ResourceData, meta interface{}) er defer cancel() name := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - hostGroupName := d.Get("host_group_name").(string) + dedicatedHostGroupId, err := parse.DedicatedHostGroupID(d.Get("dedicated_host_group_id").(string)) + if err != nil { + return err + } + + resourceGroupName := dedicatedHostGroupId.ResourceGroup + hostGroupName := dedicatedHostGroupId.Name if features.ShouldResourcesBeImported() && d.IsNewResource() { existing, err := client.Get(ctx, resourceGroupName, hostGroupName, name, "") @@ -128,15 +134,13 @@ func resourceArmDedicatedHostCreate(d *schema.ResourceData, meta interface{}) er DedicatedHostProperties: &compute.DedicatedHostProperties{ AutoReplaceOnFailure: utils.Bool(d.Get("auto_replace_on_failure").(bool)), LicenseType: compute.DedicatedHostLicenseTypes(d.Get("license_type").(string)), + PlatformFaultDomain: utils.Int32(int32(d.Get("platform_fault_domain").(int))), }, Sku: &compute.Sku{ Name: utils.String(d.Get("sku_name").(string)), }, Tags: tags.Expand(d.Get("tags").(map[string]interface{})), } - if platformFaultDomain, ok := d.GetOk("platform_fault_domain"); ok { - parameters.DedicatedHostProperties.PlatformFaultDomain = utils.Int32(int32(platformFaultDomain.(int))) - } future, err := client.CreateOrUpdate(ctx, resourceGroupName, hostGroupName, name, parameters) if err != nil { @@ -151,7 +155,7 @@ func resourceArmDedicatedHostCreate(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Error retrieving Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", name, hostGroupName, resourceGroupName, err) } if resp.ID == nil { - return fmt.Errorf("Cannot read Dedicated Host %q (Host Group Name %q / Resource Group %q) ID", name, hostGroupName, resourceGroupName) + return fmt.Errorf("Cannot read ID for Dedicated Host %q (Host Group Name %q / Resource Group %q)", name, hostGroupName, resourceGroupName) } d.SetId(*resp.ID) @@ -159,7 +163,8 @@ func resourceArmDedicatedHostCreate(d *schema.ResourceData, meta interface{}) er } func resourceArmDedicatedHostRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Compute.DedicatedHostsClient + groupsClient := meta.(*clients.Client).Compute.DedicatedHostGroupsClient + hostsClient := meta.(*clients.Client).Compute.DedicatedHostsClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() @@ -168,27 +173,44 @@ func resourceArmDedicatedHostRead(d *schema.ResourceData, meta interface{}) erro return err } - resp, err := client.Get(ctx, id.ResourceGroup, id.HostGroup, id.Name, "") + group, err := groupsClient.Get(ctx, id.ResourceGroup, id.HostGroup) + if err != nil { + if utils.ResponseWasNotFound(group.Response) { + log.Printf("[INFO] Parent Dedicated Host Group %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Dedicated Host Group %q (Resource Group %q): %+v", id.HostGroup, id.ResourceGroup, err) + } + + resp, err := hostsClient.Get(ctx, id.ResourceGroup, id.HostGroup, id.Name, "") if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[INFO] Dedicated Host %q does not exist - removing from state", d.Id()) d.SetId("") return nil } - return fmt.Errorf("Error reading Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", id.Name, id.HostGroup, id.ResourceGroup, err) + + return fmt.Errorf("Error retrieving Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", id.Name, id.HostGroup, id.ResourceGroup, err) } d.Set("name", resp.Name) - d.Set("resource_group_name", id.ResourceGroup) + d.Set("dedicated_host_group_id", group.ID) + if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) } - d.Set("host_group_name", id.HostGroup) d.Set("sku_name", resp.Sku.Name) if props := resp.DedicatedHostProperties; props != nil { - d.Set("platform_fault_domain", props.PlatformFaultDomain) d.Set("auto_replace_on_failure", props.AutoReplaceOnFailure) d.Set("license_type", props.LicenseType) + + platformFaultDomain := 0 + if props.PlatformFaultDomain != nil { + platformFaultDomain = int(*props.PlatformFaultDomain) + } + d.Set("platform_fault_domain", platformFaultDomain) } return tags.FlattenAndSet(d, resp.Tags) @@ -199,9 +221,10 @@ func resourceArmDedicatedHostUpdate(d *schema.ResourceData, meta interface{}) er ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - name := d.Get("name").(string) - resourceGroupName := d.Get("resource_group_name").(string) - hostGroupName := d.Get("host_group_name").(string) + id, err := parse.DedicatedHostID(d.Id()) + if err != nil { + return err + } parameters := compute.DedicatedHostUpdate{ DedicatedHostProperties: &compute.DedicatedHostProperties{ @@ -211,12 +234,12 @@ func resourceArmDedicatedHostUpdate(d *schema.ResourceData, meta interface{}) er Tags: tags.Expand(d.Get("tags").(map[string]interface{})), } - future, err := client.Update(ctx, resourceGroupName, hostGroupName, name, parameters) + future, err := client.Update(ctx, id.ResourceGroup, id.HostGroup, id.Name, parameters) if err != nil { - return fmt.Errorf("Error updating Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", name, hostGroupName, resourceGroupName, err) + return fmt.Errorf("Error updating Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", id.Name, id.HostGroup, id.ResourceGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for update of Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", name, hostGroupName, resourceGroupName, err) + return fmt.Errorf("Error waiting for update of Dedicated Host %q (Host Group Name %q / Resource Group %q): %+v", id.Name, id.HostGroup, id.ResourceGroup, err) } return resourceArmDedicatedHostRead(d, meta) @@ -273,7 +296,7 @@ func dedicatedHostDeletedRefreshFunc(ctx context.Context, client *compute.Dedica if utils.ResponseWasNotFound(res.Response) { return "NotFound", "NotFound", nil } - return nil, "", fmt.Errorf("Error issuing read request in dedicatedHostDeletedRefreshFunc: %+v", err) + return nil, "", fmt.Errorf("Error polling to check if the Host Group has been deleted: %+v", err) } return res, "Exists", nil diff --git a/azurerm/internal/services/compute/tests/data_source_dedicated_host_test.go b/azurerm/internal/services/compute/tests/data_source_dedicated_host_test.go index 483469e28867c..cc72f50759fc9 100644 --- a/azurerm/internal/services/compute/tests/data_source_dedicated_host_test.go +++ b/azurerm/internal/services/compute/tests/data_source_dedicated_host_test.go @@ -19,7 +19,8 @@ func TestAccDataSourceAzureRMDedicatedHost_basic(t *testing.T) { { Config: testAccDataSourceDedicatedHost_basic(data), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "location"), + resource.TestCheckResourceAttrSet(data.ResourceName, "tags.%"), ), }, }, @@ -32,9 +33,9 @@ func testAccDataSourceDedicatedHost_basic(data acceptance.TestData) string { %s data "azurerm_dedicated_host" "test" { - name = azurerm_dedicated_host.test.name - resource_group_name = azurerm_dedicated_host.test.resource_group_name - host_group_name = azurerm_dedicated_host.test.host_group_name + name = azurerm_dedicated_host.test.name + dedicated_host_group_name = azurerm_dedicated_host_group.test.name + resource_group_name = azurerm_dedicated_host.test.resource_group_name } `, config) } diff --git a/azurerm/internal/services/compute/tests/resource_arm_dedicated_host_test.go b/azurerm/internal/services/compute/tests/resource_arm_dedicated_host_test.go index 046b730cb4fb9..b3ab2b1549606 100644 --- a/azurerm/internal/services/compute/tests/resource_arm_dedicated_host_test.go +++ b/azurerm/internal/services/compute/tests/resource_arm_dedicated_host_test.go @@ -6,7 +6,6 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" @@ -30,10 +29,82 @@ func TestAccAzureRMDedicatedHost_basic(t *testing.T) { Config: testAccAzureRMDedicatedHost_basic(data), Check: resource.ComposeTestCheckFunc( testCheckAzureRMDedicatedHostExists(data.ResourceName), - resource.TestCheckResourceAttr(data.ResourceName, "license_type", string(compute.DedicatedHostLicenseTypesNone)), - resource.TestCheckResourceAttr(data.ResourceName, "auto_replace_on_failure", "true"), - resource.TestCheckResourceAttr(data.ResourceName, "platform_fault_domain", "1"), - resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "DSv3-Type1"), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMDedicatedHost_autoReplaceOnFailure(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dedicated_host", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMDedicatedHostDestroy, + Steps: []resource.TestStep{ + { + // Enabled + Config: testAccAzureRMDedicatedHost_autoReplaceOnFailure(data, true), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + // Disabled + Config: testAccAzureRMDedicatedHost_autoReplaceOnFailure(data, false), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + // Enabled + Config: testAccAzureRMDedicatedHost_autoReplaceOnFailure(data, true), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccAzureRMDedicatedHost_licenseType(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dedicated_host", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMDedicatedHostDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDedicatedHost_licenceType(data, "None"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMDedicatedHost_licenceType(data, "Windows_Server_Hybrid"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMDedicatedHost_licenceType(data, "Windows_Server_Perpetual"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), + ), + }, + data.ImportStep(), + { + Config: testAccAzureRMDedicatedHost_licenceType(data, "None"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDedicatedHostExists(data.ResourceName), ), }, data.ImportStep(), @@ -53,10 +124,6 @@ func TestAccAzureRMDedicatedHost_complete(t *testing.T) { Config: testAccAzureRMDedicatedHost_complete(data), Check: resource.ComposeTestCheckFunc( testCheckAzureRMDedicatedHostExists(data.ResourceName), - resource.TestCheckResourceAttr(data.ResourceName, "platform_fault_domain", "1"), - resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "DSv3-Type1"), - resource.TestCheckResourceAttr(data.ResourceName, "license_type", string(compute.DedicatedHostLicenseTypesWindowsServerHybrid)), - resource.TestCheckResourceAttr(data.ResourceName, "auto_replace_on_failure", "false"), ), }, data.ImportStep(), @@ -76,8 +143,6 @@ func TestAccAzureRMDedicatedHost_update(t *testing.T) { Config: testAccAzureRMDedicatedHost_basic(data), Check: resource.ComposeTestCheckFunc( testCheckAzureRMDedicatedHostExists(data.ResourceName), - resource.TestCheckResourceAttr(data.ResourceName, "license_type", string(compute.DedicatedHostLicenseTypesNone)), - resource.TestCheckResourceAttr(data.ResourceName, "auto_replace_on_failure", "true"), ), }, data.ImportStep(), @@ -85,8 +150,6 @@ func TestAccAzureRMDedicatedHost_update(t *testing.T) { Config: testAccAzureRMDedicatedHost_complete(data), Check: resource.ComposeTestCheckFunc( testCheckAzureRMDedicatedHostExists(data.ResourceName), - resource.TestCheckResourceAttr(data.ResourceName, "license_type", string(compute.DedicatedHostLicenseTypesWindowsServerHybrid)), - resource.TestCheckResourceAttr(data.ResourceName, "auto_replace_on_failure", "false"), ), }, data.ImportStep(), @@ -171,69 +234,95 @@ func testCheckAzureRMDedicatedHostDestroy(s *terraform.State) error { } func testAccAzureRMDedicatedHost_basic(data acceptance.TestData) string { + template := testAccAzureRMDedicatedHost_template(data) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-compute-%d" - location = "%s" -} +%s -resource "azurerm_dedicated_host_group" "test" { - name = "acctest-DHG-%s" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - platform_fault_domain_count = 2 +resource "azurerm_dedicated_host" "test" { + name = "acctest-DH-%d" + location = azurerm_resource_group.test.location + dedicated_host_group_id = azurerm_dedicated_host_group.test.id + sku_name = "DSv3-Type1" + platform_fault_domain = 1 +} +`, template, data.RandomInteger) } +func testAccAzureRMDedicatedHost_autoReplaceOnFailure(data acceptance.TestData, replace bool) string { + template := testAccAzureRMDedicatedHost_template(data) + return fmt.Sprintf(` +%s resource "azurerm_dedicated_host" "test" { - name = "acctest-DH-%s" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - host_group_name = azurerm_dedicated_host_group.test.name - sku_name = "DSv3-Type1" - platform_fault_domain = 1 + name = "acctest-DH-%d" + location = azurerm_resource_group.test.location + dedicated_host_group_id = azurerm_dedicated_host_group.test.id + sku_name = "DSv3-Type1" + platform_fault_domain = 1 + auto_replace_on_failure = %t } -`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString) +`, template, data.RandomInteger, replace) } -func testAccAzureRMDedicatedHost_complete(data acceptance.TestData) string { +func testAccAzureRMDedicatedHost_licenceType(data acceptance.TestData, licenseType string) string { + template := testAccAzureRMDedicatedHost_template(data) return fmt.Sprintf(` -resource "azurerm_resource_group" "test" { - name = "acctestRG-compute-%d" - location = "%s" -} +%s -resource "azurerm_dedicated_host_group" "test" { - name = "acctest-DHG-%s" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - platform_fault_domain_count = 2 +resource "azurerm_dedicated_host" "test" { + name = "acctest-DH-%d" + location = azurerm_resource_group.test.location + dedicated_host_group_id = azurerm_dedicated_host_group.test.id + sku_name = "DSv3-Type1" + platform_fault_domain = 1 + license_type = %q +} +`, template, data.RandomInteger, licenseType) } +func testAccAzureRMDedicatedHost_complete(data acceptance.TestData) string { + template := testAccAzureRMDedicatedHost_template(data) + return fmt.Sprintf(` +%s resource "azurerm_dedicated_host" "test" { - name = "acctest-DH-%s" + name = "acctest-DH-%d" location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - host_group_name = azurerm_dedicated_host_group.test.name + dedicated_host_group_id = azurerm_dedicated_host_group.test.id sku_name = "DSv3-Type1" platform_fault_domain = 1 license_type = "Windows_Server_Hybrid" auto_replace_on_failure = false } -`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomString) +`, template, data.RandomInteger) } func testAccAzureRMDedicatedHost_requiresImport(data acceptance.TestData) string { + template := testAccAzureRMDedicatedHost_basic(data) return fmt.Sprintf(` %s resource "azurerm_dedicated_host" "import" { - name = azurerm_dedicated_host.test.name - resource_group_name = azurerm_dedicated_host.test.resource_group_name - location = azurerm_dedicated_host.test.location - host_group_name = azurerm_dedicated_host.test.host_group_name - sku_name = azurerm_dedicated_host.test.sku_name - platform_fault_domain = azurerm_dedicated_host.test.platform_fault_domain -} -`, testAccAzureRMDedicatedHost_basic(data)) + name = azurerm_dedicated_host.test.name + location = azurerm_dedicated_host.test.location + dedicated_host_group_id = azurerm_dedicated_host.test.dedicated_host_group_id + sku_name = azurerm_dedicated_host.test.sku_name + platform_fault_domain = azurerm_dedicated_host.test.platform_fault_domain +} +`, template) +} + +func testAccAzureRMDedicatedHost_template(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-compute-%d" + location = "%s" +} + +resource "azurerm_dedicated_host_group" "test" { + name = "acctest-DHG-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + platform_fault_domain_count = 2 +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } diff --git a/azurerm/internal/services/compute/validate/dedicated_host.go b/azurerm/internal/services/compute/validate/dedicated_host.go new file mode 100644 index 0000000000000..148e77a6dffac --- /dev/null +++ b/azurerm/internal/services/compute/validate/dedicated_host.go @@ -0,0 +1,22 @@ +package validate + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" +) + +func DedicatedHostID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := parse.DedicatedHostID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) + return + } + + return warnings, errors +} diff --git a/azurerm/internal/services/compute/validate/dedicated_host_group.go b/azurerm/internal/services/compute/validate/dedicated_host_group.go new file mode 100644 index 0000000000000..b5964eb82c037 --- /dev/null +++ b/azurerm/internal/services/compute/validate/dedicated_host_group.go @@ -0,0 +1,22 @@ +package validate + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" +) + +func DedicatedHostGroupID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := parse.DedicatedHostGroupID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) + return + } + + return warnings, errors +} diff --git a/website/docs/d/dedicated_host.html.markdown b/website/docs/d/dedicated_host.html.markdown index 43e6e46953adb..0ca46f0fe4a35 100644 --- a/website/docs/d/dedicated_host.html.markdown +++ b/website/docs/d/dedicated_host.html.markdown @@ -14,13 +14,13 @@ Use this data source to access information about an existing Dedicated Host. ```hcl data "azurerm_dedicated_host" "example" { - name = "example-dh" - resource_group_name = "example-rg" - host_group_name = "example-dhg" + name = "example-host" + dedicated_host_group_name = "example-host-group" + resource_group_name = "example-resources" } output "dedicated_host_id" { - value = "${data.azurerm_dedicated_host.example.id}" + value = data.azurerm_dedicated_host.example.id } ``` @@ -30,9 +30,9 @@ The following arguments are supported: * `name` - (Required) Specifies the name of the Dedicated Host. -* `resource_group_name` - (Required) Specifies the name of the resource group the Dedicated Host is located in. +* `dedicated_host_group_name` - (Required) Specifies the name of the Dedicated Host Group the Dedicated Host is located in. -* `host_group_name` - (Required) Specifies the name of the Dedicated Host Group the Dedicated Host is located in. +* `resource_group_name` - (Required) Specifies the name of the resource group the Dedicated Host is located in. ## Attributes Reference diff --git a/website/docs/r/dedicated_host.html.markdown b/website/docs/r/dedicated_host.html.markdown index 0a88550bc27b3..eddc788e39b49 100644 --- a/website/docs/r/dedicated_host.html.markdown +++ b/website/docs/r/dedicated_host.html.markdown @@ -3,36 +3,34 @@ subcategory: "Compute" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_dedicated_host" description: |- - Manage an Dedicated Host. + Manage a Dedicated Host within a Dedicated Host Group. --- # azurerm_dedicated_host -Manage an Dedicated Host. +Manage a Dedicated Host within a Dedicated Host Group. ## Example Usage ```hcl resource "azurerm_resource_group" "example" { - name = "example-rg" - location = "West US" + name = "example-resourcs" + location = "West Europe" } resource "azurerm_dedicated_host_group" "example" { - name = "example-dhg" + name = "example-host-group" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location platform_fault_domain_count = 2 } - resource "azurerm_dedicated_host" "example" { - name = "example-dh" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - host_group_name = azurerm_dedicated_host_group.example.name - sku_name = "DSv3-Type1" - platform_fault_domain = 1 + name = "example-host" + location = azurerm_resource_group.example.location + dedicated_host_group_id = azurerm_dedicated_host_group.example.id + sku_name = "DSv3-Type1" + platform_fault_domain = 1 } ``` @@ -40,21 +38,21 @@ resource "azurerm_dedicated_host" "example" { The following arguments are supported: -* `name` - (Required) Specify the name of the Dedicated Host. Changing this forces a new resource to be created. +* `name` - (Required) Specifies the name of this Dedicated Host. Changing this forces a new resource to be created. -* `resource_group_name` - (Required) The name of the resource group in which to create the Dedicated Host. Changing this forces a new resource to be created. +* `dedicated_host_group_id` - (Required) Specifies the ID of the Dedicated Host Group where the Dedicated Host should exist. Changing this forces a new resource to be created. * `location` - (Required) Specify the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `host_group_name` - (Required) Specify the name of the Dedicated Host Group in which to create the Dedicated Host. Changing this forces a new resource to be created. - * `sku_name` - (Required) Specify the sku name of the Dedicated Host. Possible values are `DSv3-Type1`, `ESv3-Type1`, `FSv2-Type2`. Changing this forces a new resource to be created. * `platform_fault_domain` - (Required) Specify the fault domain of the Dedicated Host Group in which to create the Dedicated Host. Changing this forces a new resource to be created. -* `auto_replace_on_failure` - (Optional) Specifies whether the Dedicated Host should be replaced automatically in case of a failure. The value is defaulted to `true` when not provided. +--- + +* `auto_replace_on_failure` - (Optional) Should the Dedicated Host automatically be replaced in case of a Hardware Failure? Defaults to `true`. -* `license_type` - (Optional) Specifies the software license type that will be applied to the VMs deployed on the Dedicated Host. Possible values are: `None`, `Windows_Server_Hybrid`, `Windows_Server_Perpetual`. The value is defaulted to `None` when not provided. +* `license_type` - (Optional) Specifies the software license type that will be applied to the VMs deployed on the Dedicated Host. Possible values are `None`, `Windows_Server_Hybrid` and `Windows_Server_Perpetual`. Defaults to `None`. * `tags` - (Optional) A mapping of tags to assign to the resource. @@ -66,7 +64,7 @@ The following attributes are exported: ## Import -Dedicated Host can be imported using the `resource id`, e.g. +Dedicated Hosts can be imported using the `resource id`, e.g. ```shell $ terraform import azurerm_dedicated_host.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/hostGroups/group1/hosts/host1