diff --git a/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_fqdn_resource_test.go b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_fqdn_resource_test.go index c825ff955cc0..d6645c38f2b8 100644 --- a/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_fqdn_resource_test.go +++ b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_fqdn_resource_test.go @@ -76,13 +76,12 @@ func TestAccMachineLearningWorkspaceNetworkOutboundRuleFqdn_requiresImport(t *te } func (r WorkspaceNetworkOutboundRuleFqdnResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - maangedNetworkClient := client.MachineLearning.ManagedNetwork id, err := managednetwork.ParseOutboundRuleID(state.ID) if err != nil { return nil, err } - resp, err := maangedNetworkClient.SettingsRuleGet(ctx, *id) + resp, err := client.MachineLearning.ManagedNetwork.SettingsRuleGet(ctx, *id) if err != nil { if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil diff --git a/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource.go b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource.go new file mode 100644 index 000000000000..794d8ed3fac6 --- /dev/null +++ b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource.go @@ -0,0 +1,322 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package machinelearning + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/machinelearningservices/2024-04-01/managednetwork" + "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" +) + +var _ sdk.ResourceWithUpdate = WorkspaceNetworkOutboundRuleServiceTag{} + +type MachineLearningWorkspaceServiceTagOutboundRuleModel struct { + Name string `tfschema:"name"` + WorkspaceId string `tfschema:"workspace_id"` + ServiceTag string `tfschema:"service_tag"` + Protocol string `tfschema:"protocol"` + PortRanges string `tfschema:"port_ranges"` +} + +type WorkspaceNetworkOutboundRuleServiceTag struct{} + +var _ sdk.Resource = WorkspaceNetworkOutboundRuleServiceTag{} + +func (r WorkspaceNetworkOutboundRuleServiceTag) ResourceType() string { + return "azurerm_machine_learning_workspace_network_outbound_rule_service_tag" +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) ModelObject() interface{} { + return &MachineLearningWorkspaceServiceTagOutboundRuleModel{} +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return managednetwork.ValidateOutboundRuleID +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Arguments() map[string]*pluginsdk.Schema { + arguments := map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "workspace_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: managednetwork.ValidateWorkspaceID, + }, + + "service_tag": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "AppConfiguration", + "AppService", + "AzureActiveDirectory", + "AzureAdvancedThreatProtection", + "AzureArcInfrastructure", + "AzureAttestation", + "AzureBackup", + "AzureBotService", + "AzureContainerRegistry", + "AzureCosmosDB", + "AzureDataLake", + "AzureDevSpaces", + "AzureInformationProtection", + "AzureIoTHub", + "AzureKeyVault", + "AzureManagedGrafana", + "AzureMonitor", + "AzureOpenDatasets", + "AzurePlatformDNS", + "AzurePlatformIMDS", + "AzurePlatformLKM", + "AzureResourceManager", + "AzureSignalR", + "AzureSiteRecovery", + "AzureSpringCloud", + "AzureStack", + "AzureUpdateDelivery", + "DataFactoryManagement", + "EventHub", + "GuestAndHybridManagement", + "M365ManagementActivityApi", + "M365ManagementActivityApi", + "MicrosoftAzureFluidRelay", + "MicrosoftCloudAppSecurity", + "MicrosoftContainerRegistry", + "PowerPlatformInfra", + "ServiceBus", + "Sql", + "Storage", + "WindowsAdminCenter", + "AppServiceManagement", + "AutonomousDevelopmentPlatform", + "AzureActiveDirectoryDomainServices", + "AzureCloud", + "AzureConnectors", + "AzureContainerAppsService", + "AzureDatabricks", + "AzureDeviceUpdate", + "AzureEventGrid", + "AzureFrontDoor.Frontend", + "AzureFrontDoor.Backend", + "AzureFrontDoor.FirstParty", + "AzureHealthcareAPIs", + "AzureLoadBalancer", + "AzureMachineLearning", + "AzureSphere", + "AzureWebPubSub", + "BatchNodeManagement", + "ChaosStudio", + "CognitiveServicesFrontend", + "CognitiveServicesManagement", + "DataFactory", + "Dynamics365ForMarketingEmail", + "Dynamics365BusinessCentral", + "EOPExternalPublishedIPs", + "Internet", + "LogicApps", + "Marketplace", + "MicrosoftDefenderForEndpoint", + "PowerBI", + "PowerQueryOnline", + "ServiceFabric", + "SqlManagement", + "StorageSyncService", + "WindowsVirtualDesktop", + "VirtualNetwork", + }, false), + }, + + "protocol": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"*", "TCP", "UDP", "ICMP"}, false), + }, + + "port_ranges": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } + return arguments +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.MachineLearning.ManagedNetwork + subscriptionId := metadata.Client.Account.SubscriptionId + + var model MachineLearningWorkspaceServiceTagOutboundRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + workspaceId, err := managednetwork.ParseWorkspaceID(model.WorkspaceId) + if err != nil { + return err + } + id := managednetwork.NewOutboundRuleID(subscriptionId, workspaceId.ResourceGroupName, workspaceId.WorkspaceName, model.Name) + existing, err := client.SettingsRuleGet(ctx, id) + if err != nil { + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) + } + } + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_machine_learning_workspace_network_outbound_rule_service_tag", id.ID()) + } + + outboundRule := managednetwork.OutboundRuleBasicResource{ + Name: pointer.To(model.Name), + Type: pointer.To(string(managednetwork.RuleTypeServiceTag)), + Properties: managednetwork.ServiceTagOutboundRule{ + Category: pointer.To(managednetwork.RuleCategoryUserDefined), + Destination: &managednetwork.ServiceTagDestination{ + PortRanges: &model.PortRanges, + Protocol: &model.Protocol, + ServiceTag: &model.ServiceTag, + }, + }, + } + + if err = client.SettingsRuleCreateOrUpdateThenPoll(ctx, id, outboundRule); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.MachineLearning.ManagedNetwork + id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id()) + + var model MachineLearningWorkspaceServiceTagOutboundRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + if err != nil { + return err + } + + existing, err := client.SettingsRuleGet(ctx, *id) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + if existing.Model == nil { + return fmt.Errorf("retrieving %s: `model` was nil", id) + } + + if existing.Model.Properties == nil { + return fmt.Errorf("retrieving %s: `properties` was nil", id) + } + + payload := existing.Model + serviceTagOutboundRule := payload.Properties.(managednetwork.ServiceTagOutboundRule) + if metadata.ResourceData.HasChange("service_tag") { + serviceTagOutboundRule.Destination.ServiceTag = pointer.To(model.ServiceTag) + } + + if metadata.ResourceData.HasChange("protocol") { + serviceTagOutboundRule.Destination.Protocol = pointer.To(model.Protocol) + } + + if metadata.ResourceData.HasChange("port_ranges") { + serviceTagOutboundRule.Destination.PortRanges = pointer.To(model.PortRanges) + } + + payload.Properties = serviceTagOutboundRule + if err := client.SettingsRuleCreateOrUpdateThenPoll(ctx, *id, *payload); err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + return nil + }, + } +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.MachineLearning.ManagedNetwork + + id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.SettingsRuleGet(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return metadata.MarkAsGone(id) + } + + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + state := MachineLearningWorkspaceServiceTagOutboundRuleModel{ + Name: id.OutboundRuleName, + WorkspaceId: managednetwork.NewWorkspaceID(id.SubscriptionId, id.ResourceGroupName, id.WorkspaceName).ID(), + } + + if model := resp.Model; model != nil { + if props := model.Properties; props != nil { + if prop, ok := props.(managednetwork.ServiceTagOutboundRule); ok && prop.Destination != nil { + state.ServiceTag = pointer.From(prop.Destination.ServiceTag) + state.Protocol = pointer.From(prop.Destination.Protocol) + state.PortRanges = pointer.From(prop.Destination.PortRanges) + } + } + } + return metadata.Encode(&state) + }, + } +} + +func (r WorkspaceNetworkOutboundRuleServiceTag) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.MachineLearning.ManagedNetwork + + id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + if err := client.SettingsRuleDeleteThenPoll(ctx, *id); err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + return nil + }, + } +} diff --git a/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource_test.go b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource_test.go new file mode 100644 index 000000000000..41bd5bc28d9b --- /dev/null +++ b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource_test.go @@ -0,0 +1,234 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package machinelearning_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/machinelearningservices/2024-04-01/managednetwork" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +type WorkspaceNetworkOutboundRuleServiceTagResource struct{} + +func TestAccMachineLearningWorkspaceNetworkOutboundRuleServiceTag_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_machine_learning_workspace_network_outbound_rule_service_tag", "test") + r := WorkspaceNetworkOutboundRuleServiceTagResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccMachineLearningWorkspaceNetworkOutboundRuleServiceTag_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_machine_learning_workspace_network_outbound_rule_service_tag", "test") + r := WorkspaceNetworkOutboundRuleServiceTagResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("service_tag").HasValue("AppService"), + check.That(data.ResourceName).Key("protocol").HasValue("UDP"), + check.That(data.ResourceName).Key("port_ranges").HasValue("445"), + ), + }, + data.ImportStep(), + }) +} + +func TestAccMachineLearningWorkspaceNetworkOutboundRuleServiceTag_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_machine_learning_workspace_network_outbound_rule_service_tag", "test") + r := WorkspaceNetworkOutboundRuleServiceTagResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("service_tag").Exists(), + check.That(data.ResourceName).Key("protocol").Exists(), + check.That(data.ResourceName).Key("port_ranges").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func (r WorkspaceNetworkOutboundRuleServiceTagResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := managednetwork.ParseOutboundRuleID(state.ID) + if err != nil { + return nil, err + } + + resp, err := client.MachineLearning.ManagedNetwork.SettingsRuleGet(ctx, *id) + if err != nil { + return nil, fmt.Errorf("retrieving %s: %+v", state.ID, err) + } + return pointer.To(resp.Model.Properties != nil), nil +} + +func (r WorkspaceNetworkOutboundRuleServiceTagResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-ml-%[1]d" + location = "%[2]s" +} + +resource "azurerm_application_insights" "test" { + name = "acctestai-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_type = "web" +} + +resource "azurerm_key_vault" "test" { + name = "acctestvault%[3]s" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + tenant_id = data.azurerm_client_config.current.tenant_id + + sku_name = "standard" + + purge_protection_enabled = true +} + +resource "azurerm_key_vault_access_policy" "test" { + key_vault_id = azurerm_key_vault.test.id + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + key_permissions = [ + "Create", + "Get", + "Delete", + "Purge", + "GetRotationPolicy", + ] +} + +resource "azurerm_storage_account" "test" { + name = "acctestsa%[4]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + account_tier = "Standard" + account_replication_type = "LRS" +} +`, data.RandomInteger, data.Locations.Primary, data.RandomString, data.RandomIntOfLength(10)) +} + +func (r WorkspaceNetworkOutboundRuleServiceTagResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + purge_soft_deleted_keys_on_destroy = false + } + } +} + +%[1]s + +resource "azurerm_machine_learning_workspace" "test" { + name = "acctest-MLW-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_insights_id = azurerm_application_insights.test.id + key_vault_id = azurerm_key_vault.test.id + storage_account_id = azurerm_storage_account.test.id + managed_network { + isolation_mode = "AllowOnlyApprovedOutbound" + } + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_machine_learning_workspace_network_outbound_rule_service_tag" "test" { + name = "acctest-MLW-outboundrule-%[3]s" + workspace_id = azurerm_machine_learning_workspace.test.id + service_tag = "AppConfiguration" + protocol = "TCP" + port_ranges = "443" +} +`, template, data.RandomInteger, data.RandomString) +} + +func (r WorkspaceNetworkOutboundRuleServiceTagResource) update(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + purge_soft_deleted_keys_on_destroy = false + } + } +} + +%[1]s + +resource "azurerm_machine_learning_workspace" "test" { + name = "acctest-MLW-%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + application_insights_id = azurerm_application_insights.test.id + key_vault_id = azurerm_key_vault.test.id + storage_account_id = azurerm_storage_account.test.id + managed_network { + isolation_mode = "AllowOnlyApprovedOutbound" + } + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_machine_learning_workspace_network_outbound_rule_service_tag" "test" { + name = "acctest-MLW-outboundrule-%[3]s" + workspace_id = azurerm_machine_learning_workspace.test.id + service_tag = "AppService" + protocol = "UDP" + port_ranges = "445" +} +`, template, data.RandomInteger, data.RandomString) +} + +func (r WorkspaceNetworkOutboundRuleServiceTagResource) requiresImport(data acceptance.TestData) string { + template := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_machine_learning_workspace_network_outbound_rule_service_tag" "import" { + name = azurerm_machine_learning_workspace_network_outbound_rule_service_tag.test.name + workspace_id = azurerm_machine_learning_workspace_network_outbound_rule_service_tag.test.workspace_id + service_tag = azurerm_machine_learning_workspace_network_outbound_rule_service_tag.test.service_tag + protocol = azurerm_machine_learning_workspace_network_outbound_rule_service_tag.test.protocol + port_ranges = azurerm_machine_learning_workspace_network_outbound_rule_service_tag.test.port_ranges +} +`, template) +} diff --git a/internal/services/machinelearning/registration.go b/internal/services/machinelearning/registration.go index ad956f6b8165..7ff88f95bf0d 100644 --- a/internal/services/machinelearning/registration.go +++ b/internal/services/machinelearning/registration.go @@ -61,5 +61,6 @@ func (r Registration) Resources() []sdk.Resource { MachineLearningDataStoreFileShare{}, WorkspaceNetworkOutboundRuleFqdn{}, WorkspaceNetworkOutboundRulePrivateEndpoint{}, + WorkspaceNetworkOutboundRuleServiceTag{}, } } diff --git a/website/docs/r/machine_learning_workspace_network_outbound_rule_service_tag.html.markdown b/website/docs/r/machine_learning_workspace_network_outbound_rule_service_tag.html.markdown new file mode 100644 index 000000000000..5cb7b8fd8c06 --- /dev/null +++ b/website/docs/r/machine_learning_workspace_network_outbound_rule_service_tag.html.markdown @@ -0,0 +1,112 @@ +--- +subcategory: "Machine Learning" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_machine_learning_workspace_network_outbound_rule_service_tag" +description: |- + Manages an Azure Machine Learning Workspace Network Outbound Rule Service Tag. +--- +# azurerm_machine_learning_workspace_network_outbound_rule_service_tag + +Manages an Azure Machine Learning Workspace Network Outbound Rule Service Tag. + + +## Example Usage + +```hcl +provider "azurerm" { + features {} +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_application_insights" "example" { + name = "workspace-example-ai" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + application_type = "web" +} + +resource "azurerm_key_vault" "example" { + name = "workspaceexamplekeyvault" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "premium" +} + +resource "azurerm_storage_account" "example" { + name = "workspacestorageaccount" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + account_tier = "Standard" + account_replication_type = "GRS" +} + +resource "azurerm_machine_learning_workspace" "example" { + name = "example-workspace" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + application_insights_id = azurerm_application_insights.example.id + key_vault_id = azurerm_key_vault.example.id + storage_account_id = azurerm_storage_account.example.id + + managed_network { + isolation_mode = "AllowOnlyApprovedOutbound" + } + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_machine_learning_workspace_network_outbound_rule_service_tag" "example" { + name = "example-outboundrule" + workspace_id = azurerm_machine_learning_workspace.example.id + service_tag = "AppService" + protocol = "TCP" + port_ranges = "443" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Machine Learning Workspace Network Outbound Rule Service Tag. Changing this forces a new resource to be created. + +* `workspace_id` - (Required) Specifies the ID of the Machine Learning Workspace. Changing this forces a new resource to be created. + +* `service_tag` - (Required) Specifies the fully qualified domain name to allow for outbound traffic. Possible values are `AppConfiguration`,`AppService`,`AzureActiveDirectory`,`AzureAdvancedThreatProtection`,`AzureArcInfrastructure`,`AzureAttestation`,`AzureBackup`,`AzureBotService`,`AzureContainerRegistry`,`AzureCosmosDB`,`AzureDataLake`,`AzureDevSpaces`,`AzureInformationProtection`,`AzureIoTHub`,`AzureKeyVault`,`AzureManagedGrafana`,`AzureMonitor`,`AzureOpenDatasets`,`AzurePlatformDNS`,`AzurePlatformIMDS`,`AzurePlatformLKM`,`AzureResourceManager`,`AzureSignalR`,`AzureSiteRecovery`,`AzureSpringCloud`,`AzureStack`,`AzureUpdateDelivery`,`DataFactoryManagement`,`EventHub`,`GuestAndHybridManagement`,`M365ManagementActivityApi`,`M365ManagementActivityApi`,`MicrosoftAzureFluidRelay`,`MicrosoftCloudAppSecurity`,`MicrosoftContainerRegistry`,`PowerPlatformInfra`,`ServiceBus`,`Sql`,`Storage`,`WindowsAdminCenter`,`AppServiceManagement`,`AutonomousDevelopmentPlatform`,`AzureActiveDirectoryDomainServices`,`AzureCloud`,`AzureConnectors`,`AzureContainerAppsService`,`AzureDatabricks`,`AzureDeviceUpdate`,`AzureEventGrid`,`AzureFrontDoor.Frontend`,`AzureFrontDoor.Backend`,`AzureFrontDoor.FirstParty`,`AzureHealthcareAPIs`,`AzureLoadBalancer`,`AzureMachineLearning`,`AzureSphere`,`AzureWebPubSub`,`BatchNodeManagement`,`ChaosStudio`,`CognitiveServicesFrontend`,`CognitiveServicesManagement`,`DataFactory`,`Dynamics365ForMarketingEmail`,`Dynamics365BusinessCentral`,`EOPExternalPublishedIPs`,`Internet`,`LogicApps`,`Marketplace`,`MicrosoftDefenderForEndpoint`,`PowerBI`,`PowerQueryOnline`,`ServiceFabric`,`SqlManagement`,`StorageSyncService`,`WindowsVirtualDesktop` and `VirtualNetwork`. + +* `protocol` - (Required) Specifies the network protocol. Possible values are `*`, `TCP`, `UDP` and `ICMP` + +* `port_ranges` - (Required) Specifies which ports traffic will be allowed by this rule. You can specify a single port (e.g. ` 80`) , a port range (e.g. `1024-655535`) or a comma-separated list of single ports and/or port ranges(e.g. `80,1024-655535`). `*` can be used to allow traffic on any port. + + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Machine Learning Workspace Network Outbound Rule Service Tag . + +### Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Machine Learning Workspace Network Outbound Rule Service Tag. +* `update` - (Defaults to 30 minutes) Used when updating the Machine Learning Workspace Network Outbound Rule Service Tag. +* `read` - (Defaults to 5 minutes) Used when retrieving the Machine Learning Workspace Network Outbound Rule Service Tag. +* `delete` - (Defaults to 30 minutes) Used when deleting the Machine Learning Workspace Network Outbound Rule Service Tag. + +## Import + +Machine Learning Workspace Network Outbound Rule Service Tag can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_machine_learning_workspace_network_outbound_rule_service_tag.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.MachineLearningServices/workspaces/workspace1/outboundRules/rule1 +```