Open cschroer opened 3 years ago
This also appears to be returning project numbers instead of ids, see https://github.com/terraform-google-modules/terraform-google-project-factory/issues/544#issuecomment-777968811. Let's fix that at the same time.
~ budget_filter {
credit_types = []
credit_types_treatment = "INCLUDE_ALL_CREDITS"
labels = {}
~ projects = [
- "projects/1234567809",
+ "projects/prj-test-ffc8123454",
]
services = []
subaccounts = []
}
This looks like it changed recently on the API-side. I have filed an issue against the upstream team and am waiting on a resolution. It is difficult to go from project number -> project id within the provider, and I would like to avoid attempting to handle this in a DiffSuppressFunc if possible.
Hey, is there any update on this?
I can confirm that we have the same problem described in the issue
This looks like it changed recently on the API-side. I have filed an issue against the upstream team and am waiting on a resolution. It is difficult to go from project number -> project id within the provider, and I would like to avoid attempting to handle this in a DiffSuppressFunc if possible.
We are using a set of project numbers as described in the documentation but responses from the API don't seem to be idempotent as Terraform wants to change order at every re-apply.
Is this still an upstream error? For me it mostly looks like the terraform provider assumes a certain order for those project IDs and threshold_rules blocks and this order doesn't match the APIs responses.
I have come across the same issue, it looks like the projects are first sorted by the parent id/number (folder or org) and then by the project number. I have used the code below and so far the diffs are gone.
data "google_projects" "regional" {
filter = "labels.region:${lower(var.region)}"
}
data "google_project" "regional" {
count = length(data.google_projects.regional.projects[*].project_id)
project_id = data.google_projects.regional.projects[count.index].project_id
}
locals {
projects_map = {for project in data.google_projects.regional.projects[*]: "${project.parent.id}|${project.number}" => project.number}
sorted_project_numbers = [for key in sort(keys(local.projects_map)) : local.projects_map[key]]
}
I have come across the same issue, it looks like the projects are first sorted by the parent id/number (folder or org) and then by the project number. I have used the code below and so far the diffs are gone.
data "google_projects" "regional" { filter = "labels.region:${lower(var.region)}" } data "google_project" "regional" { count = length(data.google_projects.regional.projects[*].project_id) project_id = data.google_projects.regional.projects[count.index].project_id } locals { projects_map = {for project in data.google_projects.regional.projects[*]: "${project.parent.id}|${project.number}" => project.number} sorted_project_numbers = [for key in sort(keys(local.projects_map)) : local.projects_map[key]] }
I had no idea google_projects (plural) data source existed. My two cents for this and sorry for the complex locals:
data "google_projects" "company_projects" {
for_each = toset(var.company_projects)
filter = "id:${each.value}"
}
locals {
# This is a list of maps
projects_map_list = flatten([
for instance in data.google_projects.company_projects : [
for project in instance.projects : {
project_parent = project.parent.id
project_number = project.number
}
]
])
# This is a map
projects_map = { for e in local.projects_map_list : "${e.project_parent}/${e.project_number}" => e.project_number }
# This is the final list
sorted_projects = [ for key in sort(keys(local.projects_map)) : local.projects_map[key] ]
}
The variable company_projects is a list of strings with the project IDs. Then I used sorted_projects like this:
budget_filter {
projects = [ for p in local.sorted_projects : "projects/${p}"]
}
And this didn't work for me after all :(
That's odd, I have tested the workaround and no diffs show. We label all projects per region so that list of projects is kept up to date automatically. Below is the full example of what we use.
data "google_projects" "regional" {
filter = "labels.region:${lower(var.region)}"
}
data "google_project" "regional" {
count = length(data.google_projects.regional.projects[*].project_id)
project_id = data.google_projects.regional.projects[count.index].project_id
}
locals {
projects_map = {for project in data.google_projects.regional.projects[*]: "${project.parent.id}|${project.number}" => project.number}
sorted_project_numbers = [for key in sort(keys(local.projects_map)) : local.projects_map[key]]
}
resource "google_billing_budget" "regional" {
billing_account = var.billing_account
display_name = var.region
count = length(data.google_projects.regional.projects[*].project_id)>0?1:0
budget_filter {
projects = formatlist("projects/%s", local.sorted_project_numbers)
}
amount {
last_period_amount = true
}
threshold_rules {
threshold_percent = 1.01
}
threshold_rules {
threshold_percent = 1.05
spend_basis = "FORECASTED_SPEND"
}
}
N.B. Using google provider 3.60, as later has a DNS resource bug. Using Terraform v0.12.31 in case it makes any difference.
Seems like it is fixed in 3.77.0?
I'm having the same issue on 4.1.0 (with TF 0.13.0)
My TF:
threshold_rules {
threshold_percent = 0.5
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.5
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "FORECASTED_SPEND"
}
Actual:
TF-Apply:
TF State File:
"threshold_rules": [
{
"spend_basis": "CURRENT_SPEND",
"threshold_percent": 0.5
},
{
"spend_basis": "CURRENT_SPEND",
"threshold_percent": 0.75
},
{
"spend_basis": "CURRENT_SPEND",
"threshold_percent": 0.9
},
{
"spend_basis": "CURRENT_SPEND",
"threshold_percent": 1
},
{
"spend_basis": "FORECASTED_SPEND",
"threshold_percent": 0.5
},
{
"spend_basis": "FORECASTED_SPEND",
"threshold_percent": 0.75
},
{
"spend_basis": "FORECASTED_SPEND",
"threshold_percent": 0.9
},
{
"spend_basis": "FORECASTED_SPEND",
"threshold_percent": 1
}
],
The Billing API is grouping each rule into the _spendbasis category (even though the console doesn't display it like that).
API Result:
"thresholdRules": [
{
"thresholdPercent": 0.5,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 0.75,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 0.9,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 1,
"spendBasis": "CURRENT_SPEND"
},
{
"thresholdPercent": 0.5,
"spendBasis": "FORECASTED_SPEND"
},
{
"thresholdPercent": 0.75,
"spendBasis": "FORECASTED_SPEND"
},
{
"thresholdPercent": 0.9,
"spendBasis": "FORECASTED_SPEND"
},
{
"thresholdPercent": 1,
"spendBasis": "FORECASTED_SPEND"
}
Even if I change my Terraform to group the rules into their spendBasis category it still returns a change:
New TF:
threshold_rules {
threshold_percent = 0.5
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.5
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "FORECASTED_SPEND"
}
New TF Result:
Still experiencing the above issue as of today - any updates or is still pending upstream changes?
I tell a lie...ordering the threshold rules by spend_basis, no longer shows up as drift.
e.g group all CURRENT_SPEND together, followed by FORECASTED_SPEND.
threshold_rules {
threshold_percent = 0.5
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "CURRENT_SPEND"
}
threshold_rules {
threshold_percent = 0.5
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.75
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 0.9
spend_basis = "FORECASTED_SPEND"
}
threshold_rules {
threshold_percent = 1
spend_basis = "FORECASTED_SPEND"
}
@iamgeef thanks for the tip, this worked. Just one addition, it matters whether we specified the threshold percent as a string or a number :) If I add a threshold rule with a percent specified as a string, it gets sorted by the API after the numerically-specified values (inside the spend_basis group).
Community Note
modular-magician
user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned tohashibot
, a community member has claimed the issue already.Terraform Version
Affected Resource(s)
Terraform Configuration Files
Expected Behavior
After apply terraform should detect no change is needed.
Actual Behavior
Terraform does an in-place update every run:
Seams like using variables and dynamic blocks like we do in our module results in an in-place update. The order inside budget_filter projects isn't ignored, so it get's updated every time. Also the threshold_rules may have a different order in state and API return. This should be ignored, too
Steps to Reproduce
terraform apply
References
0000