diff --git a/azurerm/provider.go b/azurerm/provider.go index 8da231adbe2b..3c3cf332565c 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -301,6 +301,8 @@ func Provider() terraform.ResourceProvider { "azurerm_image": resourceArmImage(), "azurerm_iot_dps": resourceArmIotDPS(), "azurerm_iot_dps_certificate": resourceArmIotDPSCertificate(), + "azurerm_iothub_dps": resourceArmIotHubDPS(), + "azurerm_iothub_dps_certificate": resourceArmIotHubDPSCertificate(), "azurerm_iothub_consumer_group": resourceArmIotHubConsumerGroup(), "azurerm_iothub": resourceArmIotHub(), "azurerm_iothub_endpoint_eventhub": resourceArmIotHubEndpointEventHub(), diff --git a/azurerm/resource_arm_iot_dps.go b/azurerm/resource_arm_iot_dps.go index 25740c2db5cb..eef5db2e6260 100644 --- a/azurerm/resource_arm_iot_dps.go +++ b/azurerm/resource_arm_iot_dps.go @@ -34,6 +34,12 @@ func resourceArmIotDPS() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + DeprecationMessage: `The 'azurerm_iot_dps' resource is deprecated in favour of the renamed version 'azurerm_iothub_dps'. + +Information on migrating to the renamed resource can be found here: https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html + +As such the existing 'azurerm_iot_dps' resource is deprecated and will be removed in the next major version of the AzureRM Provider (2.0). +`, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), diff --git a/azurerm/resource_arm_iot_dps_cerificate.go b/azurerm/resource_arm_iot_dps_certificate.go similarity index 93% rename from azurerm/resource_arm_iot_dps_cerificate.go rename to azurerm/resource_arm_iot_dps_certificate.go index 5a7444c1a5b3..a22ac872b5c9 100644 --- a/azurerm/resource_arm_iot_dps_cerificate.go +++ b/azurerm/resource_arm_iot_dps_certificate.go @@ -24,6 +24,12 @@ func resourceArmIotDPSCertificate() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + DeprecationMessage: `The 'azurerm_iot_dps_certificate' resource is deprecated in favour of the renamed version 'azurerm_iothub_dps_certificate'. + +Information on migrating to the renamed resource can be found here: https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html + +As such the existing 'azurerm_iot_dps_certificate' resource is deprecated and will be removed in the next major version of the AzureRM Provider (2.0). +`, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(30 * time.Minute), diff --git a/azurerm/resource_arm_iothub_dps.go b/azurerm/resource_arm_iothub_dps.go new file mode 100644 index 000000000000..411e4a5a08e6 --- /dev/null +++ b/azurerm/resource_arm_iothub_dps.go @@ -0,0 +1,402 @@ +package azurerm + +import ( + "context" + "fmt" + "log" + "regexp" + "strconv" + "time" + + "github.com/Azure/azure-sdk-for-go/services/preview/iothub/mgmt/2018-12-01-preview/devices" + "github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmIotHubDPS() *schema.Resource { + return &schema.Resource{ + Create: resourceArmIotHubDPSCreateUpdate, + Read: resourceArmIotHubDPSRead, + Update: resourceArmIotHubDPSCreateUpdate, + Delete: resourceArmIotHubDPSDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), // azure.SchemaResourceGroupNameDiffSuppress(), + + "location": azure.SchemaLocation(), + + "sku": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(devices.B1), + string(devices.B2), + string(devices.B3), + string(devices.F1), + string(devices.S1), + string(devices.S2), + string(devices.S3), + }, true), + }, + + "tier": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(devices.Basic), + string(devices.Free), + string(devices.Standard), + }, true), + }, + + "capacity": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + }, + }, + }, + + "linked_hub": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "connection_string": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + ForceNew: true, + // Azure returns the key as ****. We'll suppress that here. + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + secretKeyRegex := regexp.MustCompile("(SharedAccessKey)=[^;]+") + maskedNew := secretKeyRegex.ReplaceAllString(new, "$1=****") + return (new == d.Get(k).(string)) && (maskedNew == old) + }, + Sensitive: true, + }, + "location": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + StateFunc: azure.NormalizeLocation, + ForceNew: true, + }, + "apply_allocation_policy": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "allocation_weight": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validation.IntBetween(0, 1000), + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "allocation_policy": { + Type: schema.TypeString, + Computed: true, + }, + + "device_provisioning_host_name": { + Type: schema.TypeString, + Computed: true, + }, + + "id_scope": { + Type: schema.TypeString, + Computed: true, + }, + + "service_operations_host_name": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmIotHubDPSCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSResourceClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + defer cancel() + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name, resourceGroup) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_iothub_dps", *existing.ID) + } + } + + iotdps := iothub.ProvisioningServiceDescription{ + Location: utils.String(d.Get("location").(string)), + Name: utils.String(name), + Sku: expandIoTHubDPSSku(d), + Properties: &iothub.IotDpsPropertiesDescription{ + IotHubs: expandIoTHubDPSIoTHubs(d.Get("linked_hub").([]interface{})), + }, + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, name, iotdps) + if err != nil { + return fmt.Errorf("Error creating/updating IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for the completion of the creating/updating of IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + resp, err := client.Get(ctx, name, resourceGroup) + if err != nil { + return fmt.Errorf("Error retrieving IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmIotHubDPSRead(d, meta) +} + +func resourceArmIotHubDPSRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSResourceClient + ctx, cancel := timeouts.ForRead(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["provisioningServices"] + + resp, err := client.Get(ctx, name, resourceGroup) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + sku := flattenIoTHubDPSSku(resp.Sku) + if err := d.Set("sku", sku); err != nil { + return fmt.Errorf("Error setting `sku`: %+v", err) + } + + if props := resp.Properties; props != nil { + if err := d.Set("linked_hub", flattenIoTHubDPSLinkedHub(props.IotHubs)); err != nil { + return fmt.Errorf("Error setting `linked_hub`: %+v", err) + } + + d.Set("service_operations_host_name", props.ServiceOperationsHostName) + d.Set("device_provisioning_host_name", props.DeviceProvisioningHostName) + d.Set("id_scope", props.IDScope) + d.Set("allocation_policy", props.AllocationPolicy) + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmIotHubDPSDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSResourceClient + ctx, cancel := timeouts.ForDelete(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + name := id.Path["provisioningServices"] + + future, err := client.Delete(ctx, name, resourceGroup) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return waitForIotHubDPSToBeDeleted(ctx, client, resourceGroup, name, d) +} + +func waitForIotHubDPSToBeDeleted(ctx context.Context, client *iothub.IotDpsResourceClient, resourceGroup, name string, d *schema.ResourceData) error { + // we can't use the Waiter here since the API returns a 404 once it's deleted which is considered a polling status code.. + log.Printf("[DEBUG] Waiting for IoT Device Provisioning Service %q (Resource Group %q) to be deleted", name, resourceGroup) + stateConf := &resource.StateChangeConf{ + Pending: []string{"200"}, + Target: []string{"404"}, + Refresh: iothubdpsStateStatusCodeRefreshFunc(ctx, client, resourceGroup, name), + } + + if features.SupportsCustomTimeouts() { + stateConf.Timeout = d.Timeout(schema.TimeoutDelete) + } else { + stateConf.Timeout = 40 * time.Minute + } + + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for IoT Device Provisioning Service %q (Resource Group %q) to be deleted: %+v", name, resourceGroup, err) + } + + return nil +} + +func iothubdpsStateStatusCodeRefreshFunc(ctx context.Context, client *iothub.IotDpsResourceClient, resourceGroup, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + res, err := client.Get(ctx, name, resourceGroup) + + log.Printf("Retrieving IoT Device Provisioning Service %q (Resource Group %q) returned Status %d", resourceGroup, name, res.StatusCode) + + if err != nil { + if utils.ResponseWasNotFound(res.Response) { + return res, strconv.Itoa(res.StatusCode), nil + } + return nil, "", fmt.Errorf("Error polling for the status of the IoT Device Provisioning Service %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return res, strconv.Itoa(res.StatusCode), nil + } +} + +func expandIoTHubDPSSku(d *schema.ResourceData) *iothub.IotDpsSkuInfo { + skuList := d.Get("sku").([]interface{}) + skuMap := skuList[0].(map[string]interface{}) + capacity := int64(skuMap["capacity"].(int)) + + name := skuMap["name"].(string) + tier := skuMap["tier"].(string) + + return &iothub.IotDpsSkuInfo{ + Name: iothub.IotDpsSku(name), + Tier: utils.String(tier), + Capacity: utils.Int64(capacity), + } +} + +func expandIoTHubDPSIoTHubs(input []interface{}) *[]iothub.DefinitionDescription { + linkedHubs := make([]iothub.DefinitionDescription, 0) + + for _, attr := range input { + linkedHubConfig := attr.(map[string]interface{}) + linkedHub := iothub.DefinitionDescription{ + ConnectionString: utils.String(linkedHubConfig["connection_string"].(string)), + AllocationWeight: utils.Int32(int32(linkedHubConfig["allocation_weight"].(int))), + ApplyAllocationPolicy: utils.Bool(linkedHubConfig["apply_allocation_policy"].(bool)), + Location: utils.String(linkedHubConfig["location"].(string)), + } + + linkedHubs = append(linkedHubs, linkedHub) + } + + return &linkedHubs +} + +func flattenIoTHubDPSSku(input *iothub.IotDpsSkuInfo) []interface{} { + output := make(map[string]interface{}) + + output["name"] = string(input.Name) + output["tier"] = input.Tier + if capacity := input.Capacity; capacity != nil { + output["capacity"] = int(*capacity) + } + + return []interface{}{output} +} + +func flattenIoTHubDPSLinkedHub(input *[]iothub.DefinitionDescription) []interface{} { + linkedHubs := make([]interface{}, 0) + if input == nil { + return linkedHubs + } + + for _, attr := range *input { + linkedHub := make(map[string]interface{}) + + if attr.Name != nil { + linkedHub["hostname"] = *attr.Name + } + if attr.ApplyAllocationPolicy != nil { + linkedHub["apply_allocation_policy"] = *attr.ApplyAllocationPolicy + } + if attr.AllocationWeight != nil { + linkedHub["allocation_weight"] = *attr.AllocationWeight + } + if attr.ConnectionString != nil { + linkedHub["connection_string"] = *attr.ConnectionString + } + if attr.Location != nil { + linkedHub["location"] = *attr.Location + } + + linkedHubs = append(linkedHubs, linkedHub) + } + + return linkedHubs +} diff --git a/azurerm/resource_arm_iothub_dps_certificate.go b/azurerm/resource_arm_iothub_dps_certificate.go new file mode 100644 index 000000000000..fc3f72ebc298 --- /dev/null +++ b/azurerm/resource_arm_iothub_dps_certificate.go @@ -0,0 +1,166 @@ +package azurerm + +import ( + "fmt" + "time" + + "github.com/Azure/azure-sdk-for-go/services/provisioningservices/mgmt/2018-01-22/iothub" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmIotHubDPSCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceArmIotHubDPSCertificateCreateUpdate, + Read: resourceArmIotHubDPSCertificateRead, + Update: resourceArmIotHubDPSCertificateCreateUpdate, + Delete: resourceArmIotHubDPSCertificateDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "iot_dps_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.IoTHubName, + }, + + "certificate_content": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + Sensitive: true, + }, + }, + } +} + +func resourceArmIotHubDPSCertificateCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSCertificateClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + defer cancel() + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + iotDPSName := d.Get("iot_dps_name").(string) + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_iothub_dps_certificate", *existing.ID) + } + } + + certificate := iothub.CertificateBodyDescription{ + Certificate: utils.String(d.Get("certificate_content").(string)), + } + + if _, err := client.CreateOrUpdate(ctx, resourceGroup, iotDPSName, name, certificate, ""); err != nil { + return fmt.Errorf("Error creating/updating IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + if resp.ID == nil { + return fmt.Errorf("Cannot read IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmIotHubDPSCertificateRead(d, meta) +} + +func resourceArmIotHubDPSCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSCertificateClient + ctx, cancel := timeouts.ForRead(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + iotDPSName := id.Path["provisioningServices"] + name := id.Path["certificates"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("iot_dps_name", iotDPSName) + // We are unable to set `certificate_content` since it is not returned from the API + + return nil +} + +func resourceArmIotHubDPSCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).IoTHub.DPSCertificateClient + ctx, cancel := timeouts.ForDelete(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + iotDPSName := id.Path["provisioningServices"] + name := id.Path["certificates"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return fmt.Errorf("Error retrieving IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + + if resp.Etag == nil { + return fmt.Errorf("Error deleting IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q) because Etag is nil", name, iotDPSName, resourceGroup) + } + + // TODO address this delete call if https://github.com/Azure/azure-rest-api-specs/pull/6311 get's merged + if _, err := client.Delete(ctx, resourceGroup, *resp.Etag, iotDPSName, name, "", nil, nil, iothub.ServerAuthentication, nil, nil, nil, ""); err != nil { + return fmt.Errorf("Error deleting IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q): %+v", name, iotDPSName, resourceGroup, err) + } + return nil +} diff --git a/azurerm/resource_arm_iothub_dps_certificate_test.go b/azurerm/resource_arm_iothub_dps_certificate_test.go new file mode 100644 index 000000000000..2675e2fcb846 --- /dev/null +++ b/azurerm/resource_arm_iothub_dps_certificate_test.go @@ -0,0 +1,242 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMIotHubDPSCertificate_basic(t *testing.T) { + resourceName := "azurerm_iothub_dps_certificate.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPSCertificate_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + }, + }) +} + +func TestAccAzureRMIotHubDPSCertificate_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_iothub_dps_certificate.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPSCertificate_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSCertificateExists(resourceName), + ), + }, + { + Config: testAccAzureRMIotHubDPSCertificate_requiresImport(rInt, location), + ExpectError: testRequiresImportError("azurerm_iothubdps"), + }, + }, + }) +} + +func TestAccAzureRMIotHubDPSCertificate_update(t *testing.T) { + resourceName := "azurerm_iothub_dps_certificate.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDPSCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPSCertificate_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + { + Config: testAccAzureRMIotHubDPSCertificate_update(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSCertificateExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "certificate_content", + }, + }, + }, + }) +} + +func testCheckAzureRMIotHubDPSCertificateDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).IoTHub.DPSCertificateClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_iothub_dps_certificate" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + iotDPSName := rs.Primary.Attributes["iot_dps_name"] + + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("IoT Device Provisioning Service Certificate %s still exists in (device provisioning service %s / resource group %s)", name, iotDPSName, resourceGroup) + } + } + return nil +} + +func testCheckAzureRMIotHubDPSCertificateExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + iotDPSName := rs.Primary.Attributes["iot_dps_name"] + + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for IoT Device Provisioning Service Certificate: %s", name) + } + + client := testAccProvider.Meta().(*ArmClient).IoTHub.DPSCertificateClient + resp, err := client.Get(ctx, name, resourceGroup, iotDPSName, "") + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: IoT Device Provisioning Service Certificate %q (Device Provisioning Service %q / Resource Group %q) does not exist", name, iotDPSName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on iothubDPSCertificateClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMIotHubDPSCertificate_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} + +resource "azurerm_iothub_dps_certificate" "test" { + name = "acctestIoTDPSCertificate-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iothub_dps.test.name}" + + certificate_content = "${filebase64("testdata/batch_certificate.cer")}" +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMIotHubDPSCertificate_requiresImport(rInt int, location string) string { + template := testAccAzureRMIotHubDPS_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_iothub_dps_certificate" "test" { + name = "${azurerm_iothub_dps_certificate.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iothub_dps.test.name}" + + certificate_content = "${filebase64("testdata/batch_certificate.cer")}" +} +`, template) +} + +func testAccAzureRMIotHubDPSCertificate_update(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} + +resource "azurerm_iothub_dps_certificate" "test" { + name = "acctestIoTDPSCertificate-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + iot_dps_name = "${azurerm_iothub_dps.test.name}" + + certificate_content = "${filebase64("testdata/application_gateway_test.cer")}" +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_iothub_dps_test.go b/azurerm/resource_arm_iothub_dps_test.go new file mode 100644 index 000000000000..794514ae9982 --- /dev/null +++ b/azurerm/resource_arm_iothub_dps_test.go @@ -0,0 +1,317 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" +) + +func TestAccAzureRMIotHubDPS_basic(t *testing.T) { + resourceName := "azurerm_iothub_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPS_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "allocation_policy"), + resource.TestCheckResourceAttrSet(resourceName, "device_provisioning_host_name"), + resource.TestCheckResourceAttrSet(resourceName, "id_scope"), + resource.TestCheckResourceAttrSet(resourceName, "service_operations_host_name"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotHubDPS_requiresImport(t *testing.T) { + if !features.ShouldResourcesBeImported() { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_iothub_dps.test" + rInt := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPS_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + ), + }, + { + Config: testAccAzureRMIotHubDPS_requiresImport(rInt, location), + ExpectError: testRequiresImportError("azurerm_iothubdps"), + }, + }, + }) +} + +func TestAccAzureRMIotHubDPS_update(t *testing.T) { + resourceName := "azurerm_iothub_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPS_basic(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMIotHubDPS_update(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMIotHubDPS_linkedHubs(t *testing.T) { + resourceName := "azurerm_iothub_dps.test" + rInt := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMIotHubDPSDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMIotHubDPS_linkedHubs(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMIotHubDPS_linkedHubsUpdated(rInt, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMIotHubDPSExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMIotHubDPSDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).IoTHub.DPSResourceClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_iothubdps" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("IoT Device Provisioning Service %s still exists in resource group %s", name, resourceGroup) + } + } + return nil +} + +func testCheckAzureRMIotHubDPSExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + iotdpsName := 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 IoT Device Provisioning Service: %s", iotdpsName) + } + + client := testAccProvider.Meta().(*ArmClient).IoTHub.DPSResourceClient + resp, err := client.Get(ctx, iotdpsName, resourceGroup) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: IoT Device Provisioning Service %q (Resource Group %q) does not exist", iotdpsName, resourceGroup) + } + + return fmt.Errorf("Bad: Get on iothubDPSResourceClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMIotHubDPS_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotHubDPS_requiresImport(rInt int, location string) string { + template := testAccAzureRMIotHubDPS_basic(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_iothub_dps" "import" { + name = "${azurerm_iothub_dps.test.name}" + resource_group_name = "${azurerm_iothub_dps.test.name}" + location = "${azurerm_iothub_dps.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } +} +`, template) +} + +func testAccAzureRMIotHubDPS_update(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + tags = { + purpose = "testing" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotHubDPS_linkedHubs(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + linked_hub { + connection_string = "HostName=test.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=booo" + location = "${azurerm_resource_group.test.location}" + allocation_weight = 15 + apply_allocation_policy = true + } + + linked_hub { + connection_string = "HostName=test2.azure-devices.net;SharedAccessKeyName=iothubowner2;SharedAccessKey=key2" + location = "${azurerm_resource_group.test.location}" + } +} +`, rInt, location, rInt) +} + +func testAccAzureRMIotHubDPS_linkedHubsUpdated(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_iothub_dps" "test" { + name = "acctestIoTDPS-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + sku { + name = "S1" + tier = "Standard" + capacity = "1" + } + + linked_hub { + connection_string = "HostName=test.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=booo" + location = "${azurerm_resource_group.test.location}" + allocation_weight = 150 + } +} +`, rInt, location, rInt) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index a725c344ce83..b49c77f0780b 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1401,11 +1401,11 @@
  • - azurerm_iot_dps + azurerm_iothub_dps
  • - azurerm_iot_dps_certificate + azurerm_iothub_dps_certificate
  • diff --git a/website/docs/guides/2.0-upgrade-guide.html.markdown b/website/docs/guides/2.0-upgrade-guide.html.markdown index a90a51990537..b7c94bbf63b4 100644 --- a/website/docs/guides/2.0-upgrade-guide.html.markdown +++ b/website/docs/guides/2.0-upgrade-guide.html.markdown @@ -288,6 +288,14 @@ The deprecated `location` field will be removed, since this is no longer used. The deprecated `internal_public_ip_address_id` field in the `ip_configuration` block will be removed. This field has been replaced by the `public_ip_address_id` field in the `ip_configuration` block. +### Resource: `azurerm_iot_dps` + +This resource has been renamed to `azurerm_iothub_dps` which is available from v1.37 of the AzureRM Provider - instructions on [how to migrate are available in this guide](https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html). As such this resource will be removed. + +### Resource: `azurerm_iot_dps_certificate` + +This resource has been renamed to `azurerm_iothub_dps_certificate` which is available from v1.37 of the AzureRM Provider - instructions on [how to migrate are available in this guide](https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html). As such this resource will be removed. + ### Resource: `azurerm_kubernetes_cluster` The deprecated `dns_prefix` field in the `agent_pool_profile` block will be removed. This field has been removed by Azure and is no longer used. @@ -320,12 +328,14 @@ The deprecated `location` field will be removed, since this is no longer used. The `resource_id` field has been moved from the `linked_service_properties` block to the top-level. -The `linked_service_properties` block will be removed, since it's no longer required. +The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. ### Resource: `azurerm_log_analytics_workspace_linked_service` This resource has been renamed to `azurerm_log_analytics_linked_service` which is available from v1.22 of the AzureRM Provider - instructions on [how to migrate are available in this guide](https://terraform.io/docs/providers/azurerm/guides/migrating-between-renamed-resources.html). As such this resource will be removed. +The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. + ### Resource: `azurerm_mssql_elasticpool` The deprecated `elastic_pool_properties` block will be removed. The fields inside this block have been moved to the top-level. @@ -426,14 +436,6 @@ Splitting the Virtual Machine Scale Set resource in two allows us to both provid The existing `azurerm_virtual_machine_scale_set` Resource will continue to be available in it's current form, however it will eventually be deprecated and we recommend using the new resources going forward. -### Resource: `azurerm_log_analytics_linked_service` - -The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. - -### Resource: `azurerm_log_analytics_workspace_linked_service` - -The deprecated field `linked_service_properties` will be removed. This has been replaced by the `resource_id` resource. - --- We've spent the past few months laying the groundwork for these changes - and whilst we appreciate that your Terraform Configurations may require code changes to upgrade to 2.0 - we take Semantic Versioning seriously and so try our best to limit these changes to major versions. diff --git a/website/docs/guides/migrating-between-renamed-resources.html.markdown b/website/docs/guides/migrating-between-renamed-resources.html.markdown index 07ab8bce7907..abe822dee923 100644 --- a/website/docs/guides/migrating-between-renamed-resources.html.markdown +++ b/website/docs/guides/migrating-between-renamed-resources.html.markdown @@ -9,20 +9,17 @@ description: |- # Azure Provider: Migrating to a renamed resource -In v1.22 of the AzureRM Provider several resources have been deprecated in favour of a renamed version - this guide covers how to migrate from the old resource to the new one and is applicable for the following resources: +Please see the following versions below to see which resources have been deprecated in favor of the renamed version. This guide covers how to migrate from the old resource to the new one. -| Old Name | New Name | -| ---------------------------------------------- | ------------------------------------ | -| azurerm_log_analytics_workspace_linked_service | azurerm_log_analytics_linked_service | -| azurerm_autoscale_setting | azurerm_monitor_autoscale_setting | -| azurerm_metric_alertrule | azurerm_monitor_metric_alert | -| azurerm_connection_monitor | azurerm_network_connection_monitor | -| azurerm_ddos_protection_plan | azurerm_network_ddos_protection_plan | -| azurerm_packet_capture | azurerm_network_packet_capture | +Versions with renamed resources: +* [v1.21](#v1.21) +* [v1.37](#v1.37) + +## Migrate to a renamed resource As the Schema's for each resource are the same at this time - it's possible to migrate between the resources by updating your Terraform Configuration and updating the Statefile. -In this guide we'll assume we're migrating from the `azurerm_autoscale_setting` resource to the new `azurerm_monitor_autoscale_setting` resource, but this should be applicable for any of the resources listed above. +In this guide we'll assume we're migrating from the `azurerm_autoscale_setting` resource to the new `azurerm_monitor_autoscale_setting` resource, but this should be applicable for any of the resources listed below. Assuming we have the following Terraform Configuration: @@ -101,3 +98,25 @@ actions need to be performed. ``` At this point you've switched over to using the newly renamed resources and should be able to continue using Terraform as normal. + +## v1.22 + +In v1.22 of the AzureRM Provider several resources have been deprecated in favor of a renamed version: + +| Old Name | New Name | +| ---------------------------------------------- | ------------------------------------ | +| azurerm_log_analytics_workspace_linked_service | azurerm_log_analytics_linked_service | +| azurerm_autoscale_setting | azurerm_monitor_autoscale_setting | +| azurerm_metric_alertrule | azurerm_monitor_metric_alert | +| azurerm_connection_monitor | azurerm_network_connection_monitor | +| azurerm_ddos_protection_plan | azurerm_network_ddos_protection_plan | +| azurerm_packet_capture | azurerm_network_packet_capture | + +## v1.37 + +In v1.37 of the AzureRM Provider several resources have been deprecated in favor of a renamed version: + +| Old Name | New Name | +| ---------------------------------------------- | ------------------------------------ | +| azurerm_iot_dps | azurerm_iothub_dps | +| azurerm_iot_dps_certificate | azurerm_iothub_dps_certificate | \ No newline at end of file diff --git a/website/docs/r/iothub.html.markdown b/website/docs/r/iothub.html.markdown index c9fafbcb7e43..ff3609e49657 100644 --- a/website/docs/r/iothub.html.markdown +++ b/website/docs/r/iothub.html.markdown @@ -1,8 +1,8 @@ --- -subcategory: "Messaging" +subcategory: "IoT Hub" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_iothub" -sidebar_current: "docs-azurerm-resource-messaging-iothub-x" +sidebar_current: "docs-azurerm-iothub-x" description: |- Manages an IotHub --- diff --git a/website/docs/r/iothub_consumer_group.html.markdown b/website/docs/r/iothub_consumer_group.html.markdown index ce244bf790c9..a892b0da93be 100644 --- a/website/docs/r/iothub_consumer_group.html.markdown +++ b/website/docs/r/iothub_consumer_group.html.markdown @@ -1,8 +1,8 @@ --- -subcategory: "Messaging" +subcategory: "IoT Hub" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_iothub_consumer_group" -sidebar_current: "docs-azurerm-resource-messaging-iothub-consumer-group" +sidebar_current: "docs-azurerm-resource-iothub-consumer-group" description: |- Manages a Consumer Group within an IotHub --- diff --git a/website/docs/r/iot_dps.html.markdown b/website/docs/r/iothub_dps.html.markdown similarity index 75% rename from website/docs/r/iot_dps.html.markdown rename to website/docs/r/iothub_dps.html.markdown index 33d772618424..8f84c35c536b 100644 --- a/website/docs/r/iot_dps.html.markdown +++ b/website/docs/r/iothub_dps.html.markdown @@ -1,15 +1,15 @@ --- -subcategory: "Messaging" +subcategory: "IoT Hub" layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_iot_dps" -sidebar_current: "docs-azurerm-resource-messaging-iot-dps-x" +page_title: "Azure Resource Manager: azurerm_iothub_dps" +sidebar_current: "docs-azurerm-resource-iothub-dps-x" description: |- Manages an IoT Device Provisioning Service. --- -# azurerm_iot_dps +# azurerm_iothub_dps -Manages an IoT Device Provisioning Service. +Manages an IotHub Device Provisioning Service. ## Example Usage @@ -19,7 +19,7 @@ resource "azurerm_resource_group" "example" { location = "West US" } -resource "azurerm_iot_dps" "example" { +resource "azurerm_iothub_dps" "example" { name = "example" resource_group_name = "${azurerm_resource_group.example.name}" location = "${azurerm_resource_group.example.location}" @@ -78,10 +78,18 @@ The following attributes are exported: * `id` - The ID of the IoT Device Provisioning Service. +* `allocation_policy` - The allocation policy of the IoT Device Provisioning Service. + +* `device_provisioning_host_name` - The device endpoint of the IoT Device Provisioning Service. + +* `id_scope` - The unique identifier of the IoT Device Provisioning Service. + +* `service_operations_host_name` - The service endpoint of the IoT Device Provisioning Service. + ## Import IoT Device Provisioning Service can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_iot_dps.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example +terraform import azurerm_iothub_dps.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example ``` diff --git a/website/docs/r/iot_dps_certificate.html.markdown b/website/docs/r/iothub_dps_certificate.html.markdown similarity index 72% rename from website/docs/r/iot_dps_certificate.html.markdown rename to website/docs/r/iothub_dps_certificate.html.markdown index 320da19d2299..87948c1f4cc5 100644 --- a/website/docs/r/iot_dps_certificate.html.markdown +++ b/website/docs/r/iothub_dps_certificate.html.markdown @@ -1,15 +1,15 @@ --- -subcategory: "Messaging" +subcategory: "IoT Hub" layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_iot_dps_certificate" -sidebar_current: "docs-azurerm-resource-messaging-iot-dps_certificate" +page_title: "Azure Resource Manager: azurerm_iothub_dps_certificate" +sidebar_current: "docs-azurerm-resource-iothub-dps_certificate" description: |- Manages an IoT Device Provisioning Service Certificate. --- -# azurerm_iot_dps_certificate +# azurerm_iothub_dps_certificate -Manages an IoT Device Provisioning Service Certificate. +Manages an IotHub Device Provisioning Service Certificate. ## Example Usage @@ -19,7 +19,7 @@ resource "azurerm_resource_group" "example" { location = "West US" } -resource "azurerm_iot_dps" "example" { +resource "azurerm_iothub_dps" "example" { name = "example" resource_group_name = "${azurerm_resource_group.example.name}" location = "${azurerm_resource_group.example.location}" @@ -31,10 +31,10 @@ resource "azurerm_iot_dps" "example" { } } -resource "azurerm_iot_dps_certificate" "example" { +resource "azurerm_iothub_dps_certificate" "example" { name = "example" resource_group_name = "${azurerm_resource_group.example.name}" - iot_dps_name = "${azurerm_iot_dps.example.name}" + iot_dps_name = "${azurerm_iothub_dps.example.name}" certificate_content = "${filebase64("example.cer")}" } @@ -63,5 +63,5 @@ The following attributes are exported: IoT Device Provisioning Service Certificate can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_iot_dps_certificate.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example/certificates/example +terraform import azurerm_iothub_dps_certificate.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Devices/provisioningServices/example/certificates/example ``` diff --git a/website/docs/r/iothub_shared_access_policy.html.markdown b/website/docs/r/iothub_shared_access_policy.html.markdown index 5409ff548955..145c75508a6a 100644 --- a/website/docs/r/iothub_shared_access_policy.html.markdown +++ b/website/docs/r/iothub_shared_access_policy.html.markdown @@ -1,8 +1,8 @@ --- -subcategory: "Messaging" +subcategory: "IoT Hub" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_iothub_shared_access_policy" -sidebar_current: "docs-azurerm-resource-messaging-iothub-shared-access-policy-x" +sidebar_current: "docs-azurerm-resource-iothub-shared-access-policy-x" description: |- Manages an IotHub Shared Access Policy ---