diff --git a/azurerm/provider.go b/azurerm/provider.go index 09afedad9d2e..2a8286d428e2 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -379,6 +379,7 @@ func Provider() terraform.ResourceProvider { "azurerm_stream_analytics_output_mssql": resourceArmStreamAnalyticsOutputSql(), "azurerm_stream_analytics_output_eventhub": resourceArmStreamAnalyticsOutputEventHub(), "azurerm_stream_analytics_output_servicebus_queue": resourceArmStreamAnalyticsOutputServiceBusQueue(), + "azurerm_stream_analytics_output_servicebus_topic": resourceArmStreamAnalyticsOutputServiceBusTopic(), "azurerm_stream_analytics_stream_input_blob": resourceArmStreamAnalyticsStreamInputBlob(), "azurerm_stream_analytics_stream_input_eventhub": resourceArmStreamAnalyticsStreamInputEventHub(), "azurerm_stream_analytics_stream_input_iothub": resourceArmStreamAnalyticsStreamInputIoTHub(), diff --git a/azurerm/resource_arm_stream_analytics_output_servicebus_topic.go b/azurerm/resource_arm_stream_analytics_output_servicebus_topic.go new file mode 100644 index 000000000000..c9b22edcf85e --- /dev/null +++ b/azurerm/resource_arm_stream_analytics_output_servicebus_topic.go @@ -0,0 +1,209 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/streamanalytics/mgmt/2016-03-01/streamanalytics" + "github.com/hashicorp/terraform/helper/schema" + "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/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmStreamAnalyticsOutputServiceBusTopic() *schema.Resource { + return &schema.Resource{ + Create: resourceArmStreamAnalyticsOutputServiceBusTopicCreateUpdate, + Read: resourceArmStreamAnalyticsOutputServiceBusTopicRead, + Update: resourceArmStreamAnalyticsOutputServiceBusTopicCreateUpdate, + Delete: resourceArmStreamAnalyticsOutputServiceBusTopicDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "stream_analytics_job_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "topic_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "servicebus_namespace": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "shared_access_policy_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "shared_access_policy_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "serialization": azure.SchemaStreamAnalyticsOutputSerialization(), + }, + } +} + +func resourceArmStreamAnalyticsOutputServiceBusTopicCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.OutputsClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Azure Stream Analytics Output ServiceBus Topic creation.") + name := d.Get("name").(string) + jobName := d.Get("stream_analytics_job_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Stream Analytics Output ServiceBus Topic %q (Job %q / Resource Group %q): %s", name, jobName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_stream_analytics_output_servicebus_topic", *existing.ID) + } + } + + topicName := d.Get("topic_name").(string) + serviceBusNamespace := d.Get("servicebus_namespace").(string) + sharedAccessPolicyKey := d.Get("shared_access_policy_key").(string) + sharedAccessPolicyName := d.Get("shared_access_policy_name").(string) + + serializationRaw := d.Get("serialization").([]interface{}) + serialization, err := azure.ExpandStreamAnalyticsOutputSerialization(serializationRaw) + if err != nil { + return fmt.Errorf("Error expanding `serialization`: %+v", err) + } + + props := streamanalytics.Output{ + Name: utils.String(name), + OutputProperties: &streamanalytics.OutputProperties{ + Datasource: &streamanalytics.ServiceBusTopicOutputDataSource{ + Type: streamanalytics.TypeMicrosoftServiceBusTopic, + ServiceBusTopicOutputDataSourceProperties: &streamanalytics.ServiceBusTopicOutputDataSourceProperties{ + TopicName: utils.String(topicName), + ServiceBusNamespace: utils.String(serviceBusNamespace), + SharedAccessPolicyKey: utils.String(sharedAccessPolicyKey), + SharedAccessPolicyName: utils.String(sharedAccessPolicyName), + }, + }, + Serialization: serialization, + }, + } + + if d.IsNewResource() { + if _, err := client.CreateOrReplace(ctx, props, resourceGroup, jobName, name, "", ""); err != nil { + return fmt.Errorf("Error Creating Stream Analytics Output ServiceBus Topic %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return fmt.Errorf("Error retrieving Stream Analytics Output ServiceBus Topic %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + if read.ID == nil { + return fmt.Errorf("Cannot read ID of Stream Analytics Output ServiceBus Topic %q (Job %q / Resource Group %q)", name, jobName, resourceGroup) + } + + d.SetId(*read.ID) + } else { + if _, err := client.Update(ctx, props, resourceGroup, jobName, name, ""); err != nil { + return fmt.Errorf("Error Updating Stream Analytics Output ServiceBus Topic %q (Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + } + + return resourceArmStreamAnalyticsOutputServiceBusTopicRead(d, meta) +} + +func resourceArmStreamAnalyticsOutputServiceBusTopicRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.OutputsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + jobName := id.Path["streamingjobs"] + name := id.Path["outputs"] + + resp, err := client.Get(ctx, resourceGroup, jobName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Output ServiceBus Topic %q was not found in Stream Analytics Job %q / Resource Group %q - removing from state!", name, jobName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving Stream Output EventHub %q (Stream Analytics Job %q / Resource Group %q): %+v", name, jobName, resourceGroup, err) + } + + d.Set("name", name) + d.Set("resource_group_name", resourceGroup) + d.Set("stream_analytics_job_name", jobName) + + if props := resp.OutputProperties; props != nil { + v, ok := props.Datasource.AsServiceBusTopicOutputDataSource() + if !ok { + return fmt.Errorf("Error converting Output Data Source to a ServiceBus Topic Output: %+v", err) + } + + d.Set("topic_name", v.TopicName) + d.Set("servicebus_namespace", v.ServiceBusNamespace) + d.Set("shared_access_policy_name", v.SharedAccessPolicyName) + + if err := d.Set("serialization", azure.FlattenStreamAnalyticsOutputSerialization(props.Serialization)); err != nil { + return fmt.Errorf("Error setting `serialization`: %+v", err) + } + } + + return nil +} + +func resourceArmStreamAnalyticsOutputServiceBusTopicDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).streamanalytics.OutputsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + jobName := id.Path["streamingjobs"] + name := id.Path["outputs"] + + if resp, err := client.Delete(ctx, resourceGroup, jobName, name); err != nil { + if !response.WasNotFound(resp.Response) { + return fmt.Errorf("Error deleting Output ServiceBus Topic %q (Stream Analytics Job %q / Resource Group %q) %+v", name, jobName, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_stream_analytics_output_servicebus_topic_test.go b/azurerm/resource_arm_stream_analytics_output_servicebus_topic_test.go new file mode 100644 index 000000000000..2c1fe06642ce --- /dev/null +++ b/azurerm/resource_arm_stream_analytics_output_servicebus_topic_test.go @@ -0,0 +1,376 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccAzureRMStreamAnalyticsOutputServiceBusTopic_avro(t *testing.T) { + resourceName := "azurerm_stream_analytics_output_servicebus_topic.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_avro(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "shared_access_policy_key", + }, + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsOutputServiceBusTopic_csv(t *testing.T) { + resourceName := "azurerm_stream_analytics_output_servicebus_topic.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_csv(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "shared_access_policy_key", + }, + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(t *testing.T) { + resourceName := "azurerm_stream_analytics_output_servicebus_topic.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "shared_access_policy_key", + }, + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsOutputServiceBusTopic_update(t *testing.T) { + resourceName := "azurerm_stream_analytics_output_servicebus_topic.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_updated(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "shared_access_policy_key", + }, + }, + }, + }) +} + +func TestAccAzureRMStreamAnalyticsOutputServiceBusTopic_requiresImport(t *testing.T) { + if !requireResourcesToBeImported { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_stream_analytics_output_servicebus_topic.test" + ri := tf.AccRandTimeInt() + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName), + ), + }, + { + Config: testAccAzureRMStreamAnalyticsOutputServiceBusTopic_requiresImport(ri, location), + ExpectError: testRequiresImportError("azurerm_stream_analytics_output_servicebus_topic"), + }, + }, + }) +} + +func testCheckAzureRMStreamAnalyticsOutputServiceBusTopicExists(resourceName 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[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + jobName := rs.Primary.Attributes["stream_analytics_job_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).streamanalytics.OutputsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return fmt.Errorf("Bad: Get on streamAnalyticsOutputsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Stream Output %q (Stream Analytics Job %q / Resource Group %q) does not exist", name, jobName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMStreamAnalyticsOutputServiceBusTopicDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).streamanalytics.OutputsClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_stream_analytics_output_servicebus_topic" { + continue + } + + name := rs.Primary.Attributes["name"] + jobName := rs.Primary.Attributes["stream_analytics_job_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := conn.Get(ctx, resourceGroup, jobName, name) + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Stream Analytics Output ServiceBus Topic still exists:\n%#v", resp.OutputProperties) + } + } + + return nil +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_avro(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsOutputServiceBusTopic_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_stream_analytics_output_servicebus_topic" "test" { + name = "acctestinput-%d" + stream_analytics_job_name = "${azurerm_stream_analytics_job.test.name}" + resource_group_name = "${azurerm_stream_analytics_job.test.resource_group_name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + servicebus_namespace = "${azurerm_servicebus_namespace.test.name}" + shared_access_policy_key = "${azurerm_servicebus_namespace.test.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Avro" + } +} +`, template, rInt) +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_csv(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsOutputServiceBusTopic_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_stream_analytics_output_servicebus_topic" "test" { + name = "acctestinput-%d" + stream_analytics_job_name = "${azurerm_stream_analytics_job.test.name}" + resource_group_name = "${azurerm_stream_analytics_job.test.resource_group_name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + servicebus_namespace = "${azurerm_servicebus_namespace.test.name}" + shared_access_policy_key = "${azurerm_servicebus_namespace.test.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Csv" + encoding = "UTF8" + field_delimiter = "," + } +} +`, template, rInt) +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsOutputServiceBusTopic_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_stream_analytics_output_servicebus_topic" "test" { + name = "acctestinput-%d" + stream_analytics_job_name = "${azurerm_stream_analytics_job.test.name}" + resource_group_name = "${azurerm_stream_analytics_job.test.resource_group_name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + servicebus_namespace = "${azurerm_servicebus_namespace.test.name}" + shared_access_policy_key = "${azurerm_servicebus_namespace.test.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Json" + encoding = "UTF8" + format = "LineSeparated" + } +} +`, template, rInt) +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_updated(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsOutputServiceBusTopic_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_servicebus_namespace" "updated" { + name = "acctest2-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_servicebus_topic" "updated" { + name = "acctest2-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_servicebus_namespace.updated.name}" + enable_partitioning = true +} + +resource "azurerm_stream_analytics_output_servicebus_topic" "test" { + name = "acctestinput-%d" + stream_analytics_job_name = "${azurerm_stream_analytics_job.test.name}" + resource_group_name = "${azurerm_stream_analytics_job.test.resource_group_name}" + topic_name = "${azurerm_servicebus_topic.updated.name}" + servicebus_namespace = "${azurerm_servicebus_namespace.updated.name}" + shared_access_policy_key = "${azurerm_servicebus_namespace.updated.default_primary_key}" + shared_access_policy_name = "RootManageSharedAccessKey" + + serialization { + type = "Avro" + } +} +`, template, rInt, rInt, rInt) +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_requiresImport(rInt int, location string) string { + template := testAccAzureRMStreamAnalyticsOutputServiceBusTopic_json(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_stream_analytics_output_servicebus_topic" "import" { + name = "${azurerm_stream_analytics_output_servicebus_topic.test.name}" + stream_analytics_job_name = "${azurerm_stream_analytics_output_servicebus_topic.test.stream_analytics_job_name}" + resource_group_name = "${azurerm_stream_analytics_output_servicebus_topic.test.resource_group_name}" + topic_name = "${azurerm_stream_analytics_output_servicebus_topic.test.topic_name}" + servicebus_namespace = "${azurerm_stream_analytics_output_servicebus_topic.test.servicebus_namespace}" + shared_access_policy_key = "${azurerm_stream_analytics_output_servicebus_topic.test.shared_access_policy_key}" + shared_access_policy_name = "${azurerm_stream_analytics_output_servicebus_topic.test.shared_access_policy_name}" + serialization = "${azurerm_stream_analytics_output_servicebus_topic.test.serialization}" +} +`, template) +} + +func testAccAzureRMStreamAnalyticsOutputServiceBusTopic_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_servicebus_namespace" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_servicebus_topic" "test" { + name = "acctest-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + enable_partitioning = true +} + +resource "azurerm_stream_analytics_job" "test" { + name = "acctestjob-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + compatibility_level = "1.0" + data_locale = "en-GB" + events_late_arrival_max_delay_in_seconds = 60 + events_out_of_order_max_delay_in_seconds = 50 + events_out_of_order_policy = "Adjust" + output_error_policy = "Drop" + streaming_units = 3 + + transformation_query = < **NOTE:** This is required when `type` is set to `Csv` or `Json`. + +* `field_delimiter` - (Optional) The delimiter that will be used to separate comma-separated value (CSV) records. Possible values are ` ` (space), `,` (comma), ` ` (tab), `|` (pipe) and `;`. + +-> **NOTE:** This is required when `type` is set to `Csv`. + +* `format` - (Optional) Specifies the format of the JSON the output will be written in. Possible values are `Array` and `LineSeparated`. + +-> **NOTE:** This is Required and can only be specified when `type` is set to `Json`. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `id` - The ID of the Stream Analytics Output ServiceBus Topic. + +## Import + +Stream Analytics Output ServiceBus Topic's can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_stream_analytics_output_servicebus_topic.test /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/outputs/output1 +```