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 Resource: azure_consumption_budget_* #9201

Merged
merged 50 commits into from
May 13, 2021
Merged

New Resource: azure_consumption_budget_* #9201

merged 50 commits into from
May 13, 2021

Conversation

marc-sensenich
Copy link
Contributor

@marc-sensenich marc-sensenich commented Nov 6, 2020

Adds resources

  • azurerm_consumption_budget_subscription
  • azurerm_consumption_budget_resource_group

Test status as of 60f9fd3

--- PASS: TestAccConsumptionBudgetSubscription_basic (82.18s)
--- PASS: TestAccConsumptionBudgetSubscription_basicUpdate (136.08s)
--- PASS: TestAccConsumptionBudgetSubscription_complete (132.56s)
--- PASS: TestAccConsumptionBudgetSubscription_completeUpdate (190.34s)
--- PASS: TestAccConsumptionBudgetSubscription_requiresImport (90.68s)

--- PASS: TestAccConsumptionBudgetResourceGroup_basic (128.89s)
--- PASS: TestAccConsumptionBudgetResourceGroup_complete (128.99s)
--- PASS: TestAccConsumptionBudgetResourceGroup_completeUpdate (190.29s)
--- PASS: TestAccConsumptionBudgetResourceGroup_requiresImport (131.36s)
--- PASS: TestAccConsumptionBudgetResourceGroup_basicUpdate (170.65s)

Closes #2677

@@ -1248,6 +1248,15 @@
</ul>
</li>

<li>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to generate these sections via make? I did this one manually and it appeared on make website

@@ -0,0 +1,178 @@
---
subcategory: "Consumption"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a Consumption subcategory based on API spec, it could also go under the existing Cost Management subcategory as well based on the goal of budgets

@marc-sensenich marc-sensenich marked this pull request as ready for review December 2, 2020 04:35
@sebastianreloaded
Copy link

Will this be merged at some point?

@marc-sensenich
Copy link
Contributor Author

@sebastianreloaded this PR should be updated to the new service layout and testing structure based on the changes that have happened since this PR was originally opened as it is greenfield. I'll try to take a look at updating this PR early next week with those changes and work with the maintainers to get this PR merged in

Copy link
Member

@mbfrahry mbfrahry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @marc-sensenich! Thanks for your patience here! I've given it a cursory look and things look generally good! It's just a bit behind (through no fault of your own) so I haven't been able to extensively test it yet. Do you mind addressing what I've called out and bringing it back up to date.

Once that's done, I can give it another review to confirm everything is in place. If everything looks good, we can get it merged quickly.


func FlattenConsumptionBudgetNotifications(input map[string]*consumption.Notification) []interface{} {
if input == nil {
return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes we get weird diffing when returning nil in flatten methods so we'd rather return an empty []interface{}{}

for _, v := range input {
notificationBlock := make(map[string]interface{})

notificationBlock["enabled"] = *v.Enabled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure this isn't nil before pointing to it

notifications := make(map[string]*consumption.Notification)

for _, v := range input {
notificationRaw := v.(map[string]interface{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll want to make sure that v isn't nil before casting to map[string]interface{}

amount := decimal.NewFromFloat(d.Get("amount").(float64))
timePeriod, err := ExpandConsumptionBudgetTimePeriod(d.Get("time_period").([]interface{}))
if err != nil {
return fmt.Errorf("error in expanding`time_period`: %+v", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Errorf("error in expanding`time_period`: %+v", err)
return fmt.Errorf("error expanding`time_period`: %+v", err)

return err
}

if read.ID == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than setting the ID through this check. We've been generating the ID and then setting that. That lets us avoid issues where ID is nil.

ValidateFunc: validation.FloatAtLeast(1.0),
},

"category": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if there is plan to expand values that are accepted here? If not, we can leave it out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have insight into if this will be expanded, I added it for completeness just in case. If preferred, I'll remove it from the code path

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go ahead and remove it since only one value can be specified. We can add it back in later if more categories get added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 25e2561

}

func ExpandConsumptionBudgetComparisonExpression(input interface{}) *consumption.BudgetComparisonExpression {
v := input.(map[string]interface{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll want to confirm that v isn't nil before casting.

}

// DiffSuppressFuncs
func DiffSuppressFuncConsumptionBudgetTimePeriodEndDate(k, old, new string, d *schema.ResourceData) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be mistaken but I thought having Computed: true on end_date would catch this. Is that not the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to double check this as I can't recall now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were right, I can't recall exactly why I felt this was needed at the time or if it was a user error. Refactored out in 7da9f12

)

const (
consumptionBudgetResourceGroupName = "azurerm_consumption_budget_resource_group"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels weird to use this format but I can see the value after thinking it through. Do you mind leaving a comment about why we're using this format in case we come back and forget why it's done this way

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbfrahry when you say "format" do you mean the actual resource name of azurerm_consumption_budget_$RESOURCE_TYPE? I usually have a tendency to be a bit verbose with naming, so if azurerm_budget_$RESOURCE_TYPE makes more sense it is cleaner and I can also refactor ConsumptionBudget to Budget in the code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the added confusion. Normally we don't call out resource names into their own variables but there is a use case here because of how you're passing the names along in various methods throughout this package. I just want us to call out that in a comment so we don't forget why we're doing this differently than every other package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification added in 2a6d556

website/azurerm.erb Outdated Show resolved Hide resolved
Copy link
Member

@mbfrahry mbfrahry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things are looking good! I just have concerns about the way we're doing ResourceIDs. Please let me know if what I'm suggesting makes sense!


d.Set("name", resp.Name)
d.Set("category", resp.Category)
amount, _ := resp.Amount.Float64()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this could panic if the value is nil for whatever reason. Let's check that it isn't nil just to be sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nil checked in 926f618

Update: resourceArmConsumptionBudgetResourceGroupCreateUpdate,
Delete: resourceArmConsumptionBudgetDelete,
Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
_, err := parse.ConsumptionBudgetID(id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have concerns with this generic ConsumptionBudgetID. Someone could pass any consumption budget id as if it was a Consumption Budget ResourceGroup and Terraform would manage it. I saw that in the id tests, you were testing various consumption budget ids from different resources. I'd like to see that expanded out so we have ConsumptionBudgetResourceGroupID so we have 100% certainty that the resource is in fact a Consumption Budget Resource Group. Do you think that's possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good call out and for details I pass in the the various consumption budget IDs to test the ID across the 8 various scopes that a budget could be applied to. I do believe it's possible to expand these out into per consumption budget scope ID structs with a generator. My thought process is to make a generator for Consumption Budget ID structs that will generate the code for each ID and it could leverage existing validators to verify that that scope provided is in the format expected for that ID type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That ID path you laid out sounds great! Have you seen how we generate IDs in other services? Do you think a format like this could be used for Consumption Budget? Hopefully it won't be anymore issue then that for generating the ids.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbfrahry I was able to use the available resource ID generator for this as the new features that have been added since my initial opening of this PR now support resource IDs such as the ones for Consumption Budgets. Thanks for pointing them out!

azurerm/utils/common_marshal.go Outdated Show resolved Hide resolved
azurerm/utils/common_marshal.go Outdated Show resolved Hide resolved
These were used with the AzureRM Consumption Budget 2019-01-01 API and are no longer required
…date is computed

Remove DiffSuppressFuncConsumptionBudgetTimePeriodEndDate as the
end_date is computed due to the Azure RM API setting this to be 10
years in the future from start_date if not specified in the config.
This is due to these being passed into generic Consumption Budget functions containing the core logic for Consumption Budget resources
marc-sensenich and others added 4 commits May 12, 2021 21:38
Now that the resource ID generator supports IDs with nested resources, leverage this for generating Consumption Budget resource IDs over a custom implementation
Copy link
Member

@mbfrahry mbfrahry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I went ahead and changed the way we grab the scope for the delete methods because we really shouldn't do d.Get inside of delete methods because it may have been removed from the statefile and the config file so we won't know what that value is. I went ahead and got the scope from the id (exactly the way you did it in the Read methods).

Other than that we're good to go! Thank you for getting this done!

@mbfrahry mbfrahry changed the title Add azure_consumption_budget_* New Resource: azure_consumption_budget_* May 13, 2021
@mbfrahry mbfrahry merged commit f4b5edd into hashicorp:master May 13, 2021
mbfrahry added a commit that referenced this pull request May 13, 2021
@mbfrahry mbfrahry added this to the v2.59.0 milestone May 13, 2021
@ghost
Copy link

ghost commented May 14, 2021

This has been released in version 2.59.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.59.0"
}
# ... other configuration ...

@marc-sensenich marc-sensenich deleted the gh-2677 branch May 14, 2021 17:12
@marc-sensenich
Copy link
Contributor Author

@mbfrahry thanks for the details, cleanup, and review!

@ghost ghost removed the waiting-response label May 14, 2021
@jebaraa
Copy link

jebaraa commented May 19, 2021

Hilp

favoretti pushed a commit to gro1m/terraform-provider-azurerm that referenced this pull request May 26, 2021
favoretti pushed a commit to gro1m/terraform-provider-azurerm that referenced this pull request May 26, 2021
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New Resource: Consumption Budgets
5 participants