diff --git a/internal/services/apimanagement/api_management_api_operation_tag_resource.go b/internal/services/apimanagement/api_management_api_operation_tag_resource.go index 8fd10c87c18a..f02f568e27c5 100644 --- a/internal/services/apimanagement/api_management_api_operation_tag_resource.go +++ b/internal/services/apimanagement/api_management_api_operation_tag_resource.go @@ -13,17 +13,17 @@ import ( "github.com/hashicorp/go-azure-sdk/resource-manager/apimanagement/2022-08-01/tag" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/features" "github.com/hashicorp/terraform-provider-azurerm/internal/services/apimanagement/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" ) func resourceApiManagementApiOperationTag() *pluginsdk.Resource { - return &pluginsdk.Resource{ - Create: resourceApiManagementApiOperationTagCreateUpdate, + resource := &pluginsdk.Resource{ + Create: resourceApiManagementApiOperationTagCreate, Read: resourceApiManagementApiOperationTagRead, - Update: resourceApiManagementApiOperationTagCreateUpdate, + Update: resourceApiManagementApiOperationTagUpdate, Delete: resourceApiManagementApiOperationTagDelete, Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { @@ -52,17 +52,22 @@ func resourceApiManagementApiOperationTag() *pluginsdk.Resource { ForceNew: true, ValidateFunc: validate.ApiManagementChildName, }, - - "display_name": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, }, } + + if !features.FivePointOhBeta() { + resource.Schema["display_name"] = &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "This property has been deprecated and will be removed in v5.0 of the provider. Use display_name property of azurerm_api_management_tag resource.", + } + } + + return resource } -func resourceApiManagementApiOperationTagCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { +func resourceApiManagementApiOperationTagCreate(d *pluginsdk.ResourceData, meta interface{}) error { subscriptionId := meta.(*clients.Client).Account.SubscriptionId tagClient := meta.(*clients.Client).ApiManagement.TagClient client := meta.(*clients.Client).ApiManagement.ApiOperationTagClient @@ -77,29 +82,51 @@ func resourceApiManagementApiOperationTagCreateUpdate(d *pluginsdk.ResourceData, apiName := getApiName(apiOperationId.ApiId) id := apioperationtag.NewOperationTagID(subscriptionId, apiOperationId.ResourceGroupName, apiOperationId.ServiceName, apiName, apiOperationId.OperationId, d.Get("name").(string)) + tagId := tag.NewTagID(subscriptionId, apiOperationId.ResourceGroupName, apiOperationId.ServiceName, d.Get("name").(string)) + + // For 4.0 we continue to create the tag if display_name is set (backward compatibility) + displayName := d.Get("display_name").(string) + if !features.FivePointOhBeta() && len(displayName) > 0 { + if d.IsNewResource() { + existing, err := client.TagGetByOperation(ctx, id) + if err != nil { + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing Tag %q: %s", id, err) + } + } - if d.IsNewResource() { - existing, err := client.TagGetByOperation(ctx, id) - if err != nil { if !response.WasNotFound(existing.HttpResponse) { - return fmt.Errorf("checking for presence of existing Tag %q: %s", id, err) + return tf.ImportAsExistsError("azurerm_api_management_api_operation_tag", id.ID()) } } - if !response.WasNotFound(existing.HttpResponse) { - return tf.ImportAsExistsError("azurerm_api_management_api_operation_tag", id.ID()) + parameters := tag.TagCreateUpdateParameters{ + Properties: &tag.TagContractProperties{ + DisplayName: d.Get("display_name").(string), + }, } - } - parameters := tag.TagCreateUpdateParameters{ - Properties: &tag.TagContractProperties{ - DisplayName: d.Get("display_name").(string), - }, - } + if _, err := tagClient.CreateOrUpdate(ctx, tagId, parameters, tag.CreateOrUpdateOperationOptions{}); err != nil { + return fmt.Errorf("creating/updating %q: %+v", id, err) + } + } else { + tagAssignmentExist, err := client.TagGetByOperation(ctx, id) + if err != nil { + if !response.WasNotFound(tagAssignmentExist.HttpResponse) { + return fmt.Errorf("checking for presence of Tag Assignment %q: %s", id, err) + } + } - tagId := tag.NewTagID(subscriptionId, apiOperationId.ResourceGroupName, apiOperationId.ServiceName, d.Get("name").(string)) - if _, err := tagClient.CreateOrUpdate(ctx, tagId, parameters, tag.CreateOrUpdateOperationOptions{}); err != nil { - return fmt.Errorf("creating/updating %q: %+v", id, err) + if !response.WasNotFound(tagAssignmentExist.HttpResponse) { + return tf.ImportAsExistsError("azurerm_api_management_api_operation_tag", id.ID()) + } + + tagExists, err := tagClient.Get(ctx, tagId) + if err != nil { + if !response.WasNotFound(tagExists.HttpResponse) { + return fmt.Errorf("checking for presence of Tag %q: %s", id, err) + } + } } if _, err := client.TagAssignToOperation(ctx, id); err != nil { @@ -139,15 +166,25 @@ func resourceApiManagementApiOperationTagRead(d *pluginsdk.ResourceData, meta in d.Set("api_operation_id", apioperationtag.NewOperationID(subscriptionId, id.ResourceGroupName, id.ServiceName, id.ApiId, id.OperationId).ID()) d.Set("name", id.TagId) - if model := resp.Model; model != nil { - if props := model.Properties; props != nil { - d.Set("display_name", props.DisplayName) + if !features.FivePointOhBeta() { + if model := resp.Model; model != nil { + if props := model.Properties; props != nil { + d.Set("display_name", props.DisplayName) + } } } return nil } +func resourceApiManagementApiOperationTagUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + if features.FivePointOhBeta() { + return nil + } + + return resourceApiManagementApiOperationTagCreate(d, meta) +} + func resourceApiManagementApiOperationTagDelete(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).ApiManagement.ApiOperationTagClient ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) diff --git a/internal/services/apimanagement/api_management_api_operation_tag_resource_test.go b/internal/services/apimanagement/api_management_api_operation_tag_resource_test.go index 071b37166ff6..6aec2c5632cd 100644 --- a/internal/services/apimanagement/api_management_api_operation_tag_resource_test.go +++ b/internal/services/apimanagement/api_management_api_operation_tag_resource_test.go @@ -48,27 +48,57 @@ func TestAccApiManagementApiOperationTag_requiresImport(t *testing.T) { }) } -func TestAccApiManagementApiOperationTag_update(t *testing.T) { +func TestAccApiManagementApiOperationTag_basic_withDisplayNameBackwardCompatibility(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_api_management_api_operation_tag", "test") r := ApiManagementApiOperationTagResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.basic_withDisplayNameBackwardCompatibility(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, data.ImportStep(), + }) +} + +func TestAccApiManagementApiOperationTag_requiresImport_withDisplayNameBackwardCompatibility(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_api_operation_tag", "test") + r := ApiManagementApiOperationTagResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic_withDisplayNameBackwardCompatibility(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport_withDisplayNameBackwardCompatibility), + }) +} + +func TestAccApiManagementApiOperationTag_update_withDisplayNameBackwardCompatibility(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_api_operation_tag", "test") + r := ApiManagementApiOperationTagResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.update(data), + Config: r.basic_withDisplayNameBackwardCompatibility(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, data.ImportStep(), { - Config: r.basic(data), + Config: r.update_withDisplayNameBackwardCompatibility(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basic_withDisplayNameBackwardCompatibility(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -95,6 +125,34 @@ func (r ApiManagementApiOperationTagResource) basic(data acceptance.TestData) st return fmt.Sprintf(` %s +resource "azurerm_api_management_tag" "test" { + api_management_id = azurerm_api_management.test.id + name = "acctest-Tag-%d" + display_name = "Display-Tag" +} + +resource "azurerm_api_management_api_operation_tag" "test" { + api_operation_id = azurerm_api_management_api_operation.test.id + name = azurerm_api_management_tag.test.name +} +`, ApiManagementApiOperationResource{}.basic(data), data.RandomInteger) +} + +func (r ApiManagementApiOperationTagResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_api_management_api_operation_tag" "import" { + api_operation_id = azurerm_api_management_api_operation_tag.test.api_operation_id + name = azurerm_api_management_api_operation_tag.test.name +} +`, r.basic(data)) +} + +func (r ApiManagementApiOperationTagResource) basic_withDisplayNameBackwardCompatibility(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + resource "azurerm_api_management_api_operation_tag" "test" { api_operation_id = azurerm_api_management_api_operation.test.id name = "acctest-Op-Tag-%d" @@ -103,7 +161,7 @@ resource "azurerm_api_management_api_operation_tag" "test" { `, ApiManagementApiOperationResource{}.basic(data), data.RandomInteger) } -func (r ApiManagementApiOperationTagResource) requiresImport(data acceptance.TestData) string { +func (r ApiManagementApiOperationTagResource) requiresImport_withDisplayNameBackwardCompatibility(data acceptance.TestData) string { return fmt.Sprintf(` %s @@ -112,10 +170,10 @@ resource "azurerm_api_management_api_operation_tag" "import" { name = azurerm_api_management_api_operation_tag.test.name display_name = azurerm_api_management_api_operation_tag.test.display_name } -`, r.basic(data)) +`, r.basic_withDisplayNameBackwardCompatibility(data)) } -func (r ApiManagementApiOperationTagResource) update(data acceptance.TestData) string { +func (r ApiManagementApiOperationTagResource) update_withDisplayNameBackwardCompatibility(data acceptance.TestData) string { return fmt.Sprintf(` %s diff --git a/website/docs/r/api_management_api_operation_tag.html.markdown b/website/docs/r/api_management_api_operation_tag.html.markdown index 1871f0df9fd0..c43ff06a9348 100644 --- a/website/docs/r/api_management_api_operation_tag.html.markdown +++ b/website/docs/r/api_management_api_operation_tag.html.markdown @@ -3,26 +3,40 @@ subcategory: "API Management" layout: "azurerm" page_title: "Azure Resource Manager: azurerm_api_management_api_operation_tag" description: |- - Manages a API Management API Operation Tag. + Manages an API Management API Operation Tag. --- # azurerm_api_management_api_operation_tag -Manages a API Management API Operation Tag. +Manages the Assignment of an API Management Tag to an Operation. ## Example Usage ```hcl -data "azurerm_api_management_api" "example" { - name = "search-api" - api_management_name = "search-api-management" - resource_group_name = "search-service" - revision = "2" +provider "azurerm" { + features {} +} + +data "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +data "azurerm_api_management" "example" { + name = "example-apim" + resource_group_name = data.azurerm_resource_group.example.name +} + +resource "azurerm_api_management_api" "example" { + name = "example-api" + resource_group_name = data.azurerm_resource_group.example.name + api_management_name = data.azurerm_api_management.example.name + revision = "1" } resource "azurerm_api_management_api_operation" "example" { operation_id = "user-delete" - api_name = data.azurerm_api_management_api.example.name + api_name = azurerm_api_management_api.example.name api_management_name = data.azurerm_api_management_api.example.api_management_name resource_group_name = data.azurerm_api_management_api.example.resource_group_name display_name = "Delete User Operation" @@ -41,10 +55,14 @@ resource "azurerm_api_management_api_operation" "example" { } } +resource "azurerm_api_management_tag" "example" { + api_management_id = data.azurerm_api_management.example.id + name = "example-tag" +} + resource "azurerm_api_management_api_operation_tag" "example" { - name = "example-Tag" + name = azurerm_api_management_tag.example.name api_operation_id = azurerm_api_management_api_operation.example.id - display_name = "example-Tag" } ``` @@ -54,11 +72,7 @@ The following arguments are supported: * `api_operation_id` - (Required) The ID of the API Management API Operation. Changing this forces a new API Management API Operation Tag to be created. -* `name` - (Required) The name which should be used for this API Management API Operation Tag. Changing this forces a new API Management API Operation Tag to be created. The name must be unique in the API Management Service. - ---- - -* `display_name` - (Required) The display name of the API Management API Operation Tag. +* `name` - (Required) The name of the tag. It must be known in the API Management instance. Changing this forces a new API Management API Tag to be created. ## Attributes Reference @@ -72,7 +86,6 @@ The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/l * `create` - (Defaults to 30 minutes) Used when creating the API Management API Operation Tag. * `read` - (Defaults to 5 minutes) Used when retrieving the API Management API Operation Tag. -* `update` - (Defaults to 30 minutes) Used when updating the API Management API Operation Tag. * `delete` - (Defaults to 30 minutes) Used when deleting the API Management API Operation Tag. ## Import