Skip to content

Commit

Permalink
azurerm_advisor_recommendations: Add new filters
Browse files Browse the repository at this point in the history
  • Loading branch information
tombuildsstuff authored and jkroepke committed Jun 4, 2024
1 parent 19fc823 commit 7807dab
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ENHANCEMENTS:

* dependencies: updating to `v0.20240603.1145333` of `github.com/hashicorp/go-azure-sdk` [GH-26197]
* `advisor`: update API version to `2023-01-01` [GH-26205]
* `keyvault`: handling the Resources API returning Key Vaults that have been deleted when populating the cache [GH-26199]
* `machinelearning`: update API version to `2024-04-01` [GH-26168]
* `azurerm_container_app_job`: support new properties `key_vault_secret_id` and `identity` in `secret` block [GH-25969]
* `azurerm_notification_hub_authorization_rule` - add support for `primary_connection_string` and `secondary_connection_string` properties [GH-26188]
Expand Down
32 changes: 31 additions & 1 deletion internal/services/advisor/advisor_recommendations_data_source.go
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,20 @@ 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(),
check.That(data.ResourceName).Key("recommendations.0.category").HasValue("Cost"),
),
},
})
}

func (AdvisorRecommendationsDataSourceTests) basicConfig() string {
return `provider "azurerm" {
features {}
Expand Down Expand Up @@ -93,8 +108,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 +126,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

0 comments on commit 7807dab

Please sign in to comment.