From 8f9d12436588cc3e8ede1bb0e4cda1e09e2fe10f Mon Sep 17 00:00:00 2001 From: Xu Zhang Date: Thu, 7 Nov 2024 11:30:56 +0800 Subject: [PATCH 1/2] add support for MLW vnet outbound rule service tag --- ...work_outbound_rule_service_tag_resource.go | 344 ++++++++++++++++++ ...outbound_rule_service_tag_resource_test.go | 252 +++++++++++++ .../services/machinelearning/registration.go | 1 + ...rk_outbound_rule_service_tag.html.markdown | 112 ++++++ 4 files changed, 709 insertions(+) create mode 100644 internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource.go create mode 100644 internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource_test.go create mode 100644 website/docs/r/machine_learning_workspace_network_outbound_rule_service_tag.html.markdown 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..9616192dd0a9 --- /dev/null +++ b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource.go @@ -0,0 +1,344 @@ +// 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 { + var model machineLearningWorkspaceServiceTagOutboundRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.MachineLearning.ManagedNetwork + subscriptionId := metadata.Client.Account.SubscriptionId + + 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 { + var model machineLearningWorkspaceServiceTagOutboundRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.MachineLearning.ManagedNetwork + id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id()) + 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 := managednetwork.ServiceTagOutboundRule{ + Type: managednetwork.RuleTypeServiceTag, + Category: pointer.To(managednetwork.RuleCategoryUserDefined), + Destination: &managednetwork.ServiceTagDestination{}, + } + + 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) + } + + model := resp.Model + if model == nil { + return fmt.Errorf("retrieving %s: model was nil", id) + } + + state := machineLearningWorkspaceServiceTagOutboundRuleModel{ + Name: id.OutboundRuleName, + } + + if props := model.Properties; props != nil { + if prop, ok := props.(managednetwork.ServiceTagOutboundRule); ok && prop.Destination != nil { + if prop.Destination.ServiceTag != nil { + state.ServiceTag = *prop.Destination.ServiceTag + } + + if prop.Destination.Protocol != nil { + state.Protocol = *prop.Destination.Protocol + } + + if prop.Destination.PortRanges != nil { + state.PortRanges = *prop.Destination.PortRanges + } + } + } + state.WorkspaceId = managednetwork.NewWorkspaceID(id.SubscriptionId, id.ResourceGroupName, id.WorkspaceName).ID() + 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 + } + + future, err := client.SettingsRuleDelete(ctx, *id) + if err != nil { + return fmt.Errorf("deleting Machine Learning Workspace Service Tag Network Outbound Rule %q (Resource Group %q, Workspace %q): %+v", id.OutboundRuleName, id.ResourceGroupName, id.WorkspaceName, err) + } + + if err = future.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("waiting for deletion of Machine Learning Workspace Service Tag Network Outbound Rule %q (Resource Group %q, Workspace %q): %+v", id.OutboundRuleName, id.ResourceGroupName, id.WorkspaceName, 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..6774c3aba454 --- /dev/null +++ b/internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_service_tag_resource_test.go @@ -0,0 +1,252 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package machinelearning_test + +import ( + "context" + "fmt" + "testing" + + "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/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" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +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) { + maangedNetworkClient := client.MachineLearning.ManagedNetwork + id, err := managednetwork.ParseOutboundRuleID(state.ID) + if err != nil { + return nil, err + } + + resp, err := maangedNetworkClient.SettingsRuleGet(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving Machine Learning Workspace Outbound Rule Service Tag %q: %+v", state.ID, err) + } + + return utils.Bool(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" + name = "rg-sfi-%[1]d" + location = "%[2]s" + lifecycle { + ignore_changes = [ + tags, + ] + } +} + +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 + } + resource_group { + prevent_deletion_if_contains_resources = 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 + } + resource_group { + prevent_deletion_if_contains_resources = 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 ffcb53b87cf5..cd70891fd814 100644 --- a/internal/services/machinelearning/registration.go +++ b/internal/services/machinelearning/registration.go @@ -58,5 +58,6 @@ func (r Registration) Resources() []sdk.Resource { MachineLearningDataStoreDataLakeGen2{}, MachineLearningDataStoreFileShare{}, WorkspaceNetworkOutboundRuleFqdn{}, + 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..1efeeb99e9ee --- /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 Service Tag Network Outbound Rule . +--- +# azurerm_machine_learning_workspace_network_outbound_rule_service_tag + +Manages an Azure Machine Learning Workspace Service Tag Network Outbound Rule. + + +## 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 FQDN Network Outbound Rule. 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. Provide a single port, such as 80; a port range, such as 1024-655535; or a comma-separated list of single ports and/or port ranges, such as 80,1024-655535. Provide an asterisk(*) 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. + +### 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 Service Tag Network Outbound Rule. +* `update` - (Defaults to 30 minutes) Used when updating the Machine Learning Workspace Service Tag Network Outbound Rule. +* `read` - (Defaults to 5 minutes) Used when retrieving the Machine Learning Workspace Service Tag Network Outbound Rule. +* `delete` - (Defaults to 30 minutes) Used when deleting the Machine Learning Workspace Service Tag Network Outbound Rule. + +## Import + +Machine Learning Workspace FQDN Network Outbound Rule 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 +``` From 48ba2efa54014ba6a68e46c55630e0cdaa8064d4 Mon Sep 17 00:00:00 2001 From: Xu Zhang Date: Thu, 7 Nov 2024 14:08:39 +0800 Subject: [PATCH 2/2] fix lint --- ...ace_network_outbound_rule_service_tag_resource_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) 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 index 6774c3aba454..96691b4bb29c 100644 --- 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 @@ -100,14 +100,8 @@ func (r WorkspaceNetworkOutboundRuleServiceTagResource) template(data acceptance data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - //name = "acctestRG-ml-%[1]d" - name = "rg-sfi-%[1]d" + name = "acctestRG-ml-%[1]d" location = "%[2]s" - lifecycle { - ignore_changes = [ - tags, - ] - } } resource "azurerm_application_insights" "test" {