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

New data source: azurerm_consumption_budget_resource_group #12538

Merged
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package consumption

import (
"fmt"
"time"

"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/consumption/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/consumption/validate"
resourceParse "github.com/hashicorp/terraform-provider-azurerm/internal/services/resource/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func resourceArmConsumptionBudgetResourceGroupDataSource() *pluginsdk.Resource {
return &pluginsdk.Resource{
Read: resourceArmConsumptionBudgetResourceGroupDataSourceRead,
Timeouts: &pluginsdk.ResourceTimeout{
Read: pluginsdk.DefaultTimeout(5 * time.Minute),
},
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validate.ConsumptionBudgetName(),
},

"resource_group_id": {
Type: pluginsdk.TypeString,
Required: true,
},

"amount": {
Type: pluginsdk.TypeFloat,
Computed: true,
},

"filter": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"dimension": {
Type: pluginsdk.TypeSet,
Optional: true,
Computed: true,
Set: pluginsdk.HashResource(SchemaConsumptionBudgetFilterDimensionElement()),
Elem: SchemaConsumptionBudgetFilterDimensionElement(),
gro1m marked this conversation as resolved.
Show resolved Hide resolved
},
"tag": {
Type: pluginsdk.TypeSet,
Optional: true,
Set: pluginsdk.HashResource(SchemaConsumptionBudgetFilterTagElement()),
Elem: SchemaConsumptionBudgetFilterTagElement(),
gro1m marked this conversation as resolved.
Show resolved Hide resolved
},
"not": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"dimension": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
Elem: SchemaConsumptionBudgetFilterDimensionElement(),
gro1m marked this conversation as resolved.
Show resolved Hide resolved
},
"tag": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
Elem: SchemaConsumptionBudgetFilterTagElement(),
gro1m marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
},
},
},
},

"notification": {
Type: pluginsdk.TypeSet,
Computed: true,
Set: pluginsdk.HashResource(SchemaConsumptionBudgetNotificationElement()),
Elem: SchemaConsumptionBudgetNotificationElement(),
gro1m marked this conversation as resolved.
Show resolved Hide resolved
},

"time_grain": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},

"time_period": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"start_date": {
Type: pluginsdk.TypeString,
Required: true,
},
"end_date": {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
},
},
},
},
},
}
}

func resourceArmConsumptionBudgetResourceGroupDataSourceRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Consumption.BudgetsClient
subscriptionID := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

resourceGroupId, err := resourceParse.ResourceGroupID(d.Get("resource_group_id").(string))
if err != nil {
return err
}

id := parse.NewConsumptionBudgetResourceGroupID(subscriptionID, resourceGroupId.ResourceGroup, d.Get("name").(string))
d.SetId(id.ID())

resp, err := client.Get(ctx, resourceGroupId.ID(), id.BudgetName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("making read request on %s: %+v", id, err)
}

d.Set("name", resp.Name)
if resp.Amount != nil {
amount, _ := resp.Amount.Float64()
d.Set("amount", amount)
}
d.Set("time_grain", string(resp.TimeGrain))
d.Set("time_period", FlattenConsumptionBudgetTimePeriod(resp.TimePeriod))
d.Set("notification", pluginsdk.NewSet(pluginsdk.HashResource(SchemaConsumptionBudgetNotificationElement()), FlattenConsumptionBudgetNotifications(resp.Notifications)))
d.Set("filter", FlattenConsumptionBudgetFilter(resp.Filter))

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package consumption_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type ConsumptionBudgetResourceGroupDataSource struct{}

func TestAccDataSourceBudget_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_consumption_budget_resource_group", "test")
r := ConsumptionBudgetResourceGroupDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("name").Exists(),
// TODO fill in remaining checks
),
},
})
}

func (d ConsumptionBudgetResourceGroupDataSource) basic(data acceptance.TestData) string {
config := ConsumptionBudgetResourceGroupResource{}.basic(data)
return fmt.Sprintf(`
%s

data "azurerm_consumption_budget_resource_group" "test" {
name = azurerm_consumption_budget_resource_group.test.name
resource_group_id = azurerm_consumption_budget_resource_group.test.resource_group_id
}
`, config)
}
9 changes: 6 additions & 3 deletions internal/services/consumption/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const (
// as the core logic for the Consumption Budget resources is generic and has been
// extracted out of the specific Consumption Budget resources. These constants are
// used when the generic Consumption Budget functions require a resource name.
consumptionBudgetResourceGroupName = "azurerm_consumption_budget_resource_group"
consumptionBudgetSubscriptionName = "azurerm_consumption_budget_subscription"
consumptionBudgetResourceGroupName = "azurerm_consumption_budget_resource_group"
consumptionBudgetSubscriptionName = "azurerm_consumption_budget_subscription"
consumptionBudgetResourceGroupDataSourceName = "azurerm_consumption_budget_resource_group"
)

type Registration struct{}
Expand All @@ -29,7 +30,9 @@ func (r Registration) WebsiteCategories() []string {

// SupportedDataSources returns the supported Data Sources supported by this Service
func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource {
return map[string]*pluginsdk.Resource{}
return map[string]*pluginsdk.Resource{
consumptionBudgetResourceGroupDataSourceName: resourceArmConsumptionBudgetResourceGroupDataSource(),
}
}

// SupportedResources returns the supported Resources supported by this Service
Expand Down
120 changes: 120 additions & 0 deletions website/docs/d/consumption_budget_resource_group.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
subcategory: "Consumption"
layout: "azurerm"
page_title: "Azure Resource Manager: Data Source: azurerm_consumption_budget_resource_group"
description: |-
Gets information about an existing Consumption Budget in a specific resource group.
---

# Data Source: azurerm_consumption_budget_resource_group

Use this data source to access information about an existing Consumption Budget in a specific resource group.

## Example Usage

```hcl
data "azurerm_consumption_budget_resource_group" "example" {
name = "existing"
subscription_id = "/subscriptions/00000000-0000-0000-0000-000000000000/"
}

output "id" {
value = data.azurerm_consumption_budget_resource_group.example.id
}
```

## Arguments Reference

The following arguments are supported:

* `name` - (Required) The name of this Consumption Budget. Changing this forces a new Consumption Budget to be created.

* `subscription_id` - (Required) The ID of the subscription.

---

* `resource_group_id` - (Optional) The ID of the resource group.

## Attributes Reference

In addition to the Arguments listed above - the following Attributes are exported:

* `id` - The ID of the Consumption Budget.

* `amount` - The total amount of cost to track with the budget.

* `filter` - A `filter` block as defined below.

* `notification` - A `notification` block as defined below.

* `time_grain` - The time covered by a budget. Tracking of the amount will be reset based on the time grain. Must be one of `Monthly`, `Quarterly`, `Annually`, `BillingMonth`, `BillingQuarter`, or `BillingYear`. Defaults to `Monthly`.

* `time_period` - A `time_period` block as defined below.

---

A `dimension` block exports the following:

* `name` - The name of the column to use for the filter. The allowed values are

* `operator` - The operator to use for comparison. The allowed values are `In`.

* `values` - A `values` block as defined below.

---

A `filter` block exports the following:

* `dimension` - A `dimension` block as defined above.

* `not` - A `not` block as defined below.

* `tag` - A `tag` block as defined below.

---

A `not` block exports the following:

* `dimension` - A `dimension` block as defined above.

* `tag` - A `tag` block as defined below.

---

A `notification` block exports the following:

* `contact_emails` - A `contact_emails` block as defined above.

* `contact_groups` - A `contact_groups` block as defined above.

* `contact_roles` - A `contact_roles` block as defined above.

* `enabled` - Should the notification enabled?

* `operator` - The comparison operator for the notification. Must be one of `EqualTo`, `GreaterThan`, or `GreaterThanOrEqualTo`.

* `threshold` - Threshold value associated with a notification. Notification is sent when the cost exceeded the threshold. It is always percent and has to be between 0 and 1000.

---

A `tag` block exports the following:

* `name` - The name of the tag to use for the filter.

* `operator` - The operator to use for comparison. The allowed values are `In`.

* `values` - A `values` block as defined below.

---

A `time_period` block exports the following:

* `end_date` - The end date for the budget. If not set this will be 10 years after the start date.

* `start_date` - The start date for the budget. The start date must be first of the month and should be less than the end date. Budget start date must be on or after June 1, 2017. Future start date should not be more than twelve months. Past start date should be selected within the timegrain period. Changing this forces a new Subscription Consumption Budget to be created.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:

* `read` - (Defaults to 5 minutes) Used when retrieving the Consumption Budget.