Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_advisor_recommendations - Add filter_by_resource_ids and filter_by_recommendation_type_guids #26220

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-sdk/resource-manager/advisor/2023-01-01/getrecommendations"
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
Expand Down Expand Up @@ -44,6 +45,23 @@ func dataSourceAdvisorRecommendations() *pluginsdk.Resource {

"filter_by_resource_groups": commonschema.ResourceGroupNameSetOptional(),

"filter_by_resource_ids": {
Type: pluginsdk.TypeSet,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: azure.ValidateResourceID,
},
},

"filter_by_recommendation_type_guids": {
Type: pluginsdk.TypeSet,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},

"recommendations": {
Type: pluginsdk.TypeList,
Computed: true,
Expand All @@ -59,6 +77,11 @@ func dataSourceAdvisorRecommendations() *pluginsdk.Resource {
Computed: true,
},

"id": {
Type: pluginsdk.TypeString,
Computed: true,
},

"impact": {
Type: pluginsdk.TypeString,
Computed: true,
Expand Down Expand Up @@ -117,6 +140,12 @@ func dataSourceAdvisorRecommendationsRead(d *pluginsdk.ResourceData, meta interf
if resGroups := expandAzureRmAdvisorRecommendationsMapString("ResourceGroup", d.Get("filter_by_resource_groups").(*pluginsdk.Set).List()); resGroups != "" {
filterList = append(filterList, resGroups)
}
if resIDs := expandAzureRmAdvisorRecommendationsMapString("ResourceId", d.Get("filter_by_resource_ids").(*pluginsdk.Set).List()); resIDs != "" {
filterList = append(filterList, resIDs)
}
if recommendationTypeGuids := expandAzureRmAdvisorRecommendationsMapString("RecommendationTypeGuid", d.Get("filter_by_recommendation_type_guids").(*pluginsdk.Set).List()); recommendationTypeGuids != "" {
filterList = append(filterList, recommendationTypeGuids)
}

opts := getrecommendations.RecommendationsListOperationOptions{}
if len(filterList) > 0 {
Expand All @@ -132,7 +161,7 @@ func dataSourceAdvisorRecommendationsRead(d *pluginsdk.ResourceData, meta interf
return fmt.Errorf("setting `recommendations`: %+v", err)
}

d.SetId(fmt.Sprintf("avdisor/recommendations/%s", time.Now().UTC().String()))
d.SetId(fmt.Sprintf("advisor/recommendations/%s", time.Now().UTC().String()))

return nil
}
Expand Down Expand Up @@ -161,6 +190,7 @@ func flattenAzureRmAdvisorRecommendations(recommends []getrecommendations.Resour
result = append(result, map[string]interface{}{
"category": string(pointer.From(v.Category)),
"description": description,
"id": pointer.From(r.Id),
"impact": string(pointer.From(v.Impact)),
"recommendation_name": pointer.From(r.Name),
"recommendation_type_id": pointer.From(v.RecommendationTypeId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestAccAdvisorRecommendationsDataSource_basic(t *testing.T) {
check.That(data.ResourceName).Key("recommendations.#").Exists(),
check.That(data.ResourceName).Key("recommendations.0.category").Exists(),
check.That(data.ResourceName).Key("recommendations.0.description").Exists(),
check.That(data.ResourceName).Key("recommendations.0.id").Exists(),
check.That(data.ResourceName).Key("recommendations.0.impact").Exists(),
check.That(data.ResourceName).Key("recommendations.0.recommendation_name").Exists(),
check.That(data.ResourceName).Key("recommendations.0.recommendation_type_id").Exists(),
Expand Down Expand Up @@ -61,6 +62,19 @@ func TestAccAdvisorRecommendationsDataSource_categoriesFilter(t *testing.T) {
})
}

func TestAccAdvisorRecommendationsDataSource_resourceFilter(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_advisor_recommendations", "test")

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: AdvisorRecommendationsDataSourceTests{}.resourceFilterConfig(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("recommendations.#").Exists(),
),
},
})
}

func (AdvisorRecommendationsDataSourceTests) basicConfig() string {
return `provider "azurerm" {
features {}
Expand Down Expand Up @@ -93,8 +107,10 @@ resource "azurerm_storage_account" "test" {
}

data "azurerm_advisor_recommendations" "test" {
filter_by_category = ["Security"]
filter_by_resource_groups = [azurerm_resource_group.test.name]
filter_by_category = ["Security"]
filter_by_resource_groups = [azurerm_resource_group.test.name]
filter_by_resource_ids = [azurerm_storage_account.test.id]
filter_by_recommendation_type_guids = ["42dbf883-9e4b-4f84-9da4-232b87c4b5e9"]
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString)
}
Expand All @@ -109,3 +125,32 @@ data "azurerm_advisor_recommendations" "test" {
}
`
}

// Advisor generated recommendations needs long time to take effects, sometimes up to one day or more,
// Please refer to the issue https://github.com/Azure/azure-rest-api-specs/issues/9284
// So here we get an empty list of recommendations
func (AdvisorRecommendationsDataSourceTests) resourceFilterConfig(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-advisor-%d"
location = "%s"
}

resource "azurerm_storage_account" "test" {
name = "accteststr%s"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
enable_https_traffic_only = false
account_tier = "Standard"
account_replication_type = "LRS"
}

data "azurerm_advisor_recommendations" "test" {
filter_by_resource_ids = [azurerm_storage_account.test.id]
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString)
}
6 changes: 6 additions & 0 deletions website/docs/d/advisor_recommendations.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ The following arguments are supported:

* `filter_by_resource_groups` - (Optional) Specifies a list of resource groups about which the Advisor Recommendations will be listed.

* `filter_by_resource_ids` - (Optional) Specifies a list of resource about which the Advisor Recommendations will be listed.

* `filter_by_recommendation_type_guids` - (Optional) Specifies a list of recommendation types about which the Advisor Recommendations will be listed.

## Attributes Reference

In addition to the Arguments listed above - the following Attributes are exported:
Expand All @@ -51,6 +55,8 @@ A `recommendations` block exports the following:

* `description` - The description of the issue or the opportunity identified by the recommendation.

* `id` - The name of the Advisor Recommendation.

* `impact` - The business impact of the recommendation.

* `recommendation_name` - The name of the Advisor Recommendation.
Expand Down
Loading