terraform-google-modules / terraform-google-project-factory

Creates an opinionated Google Cloud project by using Shared VPC, IAM, and Google Cloud APIs
https://registry.terraform.io/modules/terraform-google-modules/project-factory/google
Apache License 2.0
827 stars 535 forks source link

Perma-diff with server-side error on Project Budgets #541

Closed Jberlinsky closed 3 years ago

Jberlinsky commented 3 years ago

This is not actionable in this repository -- I'm filing the issue so the project-factory team is aware of the upstream issue and that it affects project-factory.

See upstream issue: https://github.com/hashicorp/terraform-provider-google/issues/8241.

drandell commented 3 years ago

Hi @Jberlinsky, there was one issue actually with the current implementation of the budget module. And that was simply changing the services var to be an empty array and not null. Happy to make the PR for the small change :)

mbghdev commented 3 years ago

Dear Team, I'm having the same issue w/this. When I commit to a dev/nonprd/prd branch, I get googleapi: Error 400: Request contains an invalid argument. w/project budget

the currency changes automatically from USD to null, here a detail of the tf plan done by cloud build:

 ------------------------------------------------------------------------

 An execution plan has been generated and is shown below.
 Resource actions are indicated with the following symbols:
   ~ update in-place

 Terraform will perform the following actions:

   # module.base_shared_vpc_project.module.project.module.budget.google_billing_budget.budget[0] will be updated in-place
   ~ resource "google_billing_budget" "budget" {
         billing_account = "XXXXXX-XXXXXX-XXXXXX"
         display_name    = "Budget For prj-bu2-d-sample-base-xxxx"
         id              = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/a69b009d-e07c-4ed9-baf3-xxxxxxxxxxxx"
         name            = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/a69b009d-e07c-4ed9-baf3-xxxxxxxxxxxx"

       ~ amount {
             last_period_amount = false

           ~ specified_amount {
               - currency_code = "USD" -> null
                 nanos         = 0
                 units         = "1000"
             }
         }

       ~ budget_filter {
             credit_types           = []
             credit_types_treatment = "INCLUDE_ALL_CREDITS"
             labels                 = {}
           ~ projects               = [
               - "projects/xxxxxxxxxxxxxx",
               + "projects/prj-bu2-d-sample-base-xxxx",
             ]
             services               = []
             subaccounts            = []
         }

         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.5
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.75
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.9
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.95
         }
     }

   # module.floating_project.module.project.module.budget.google_billing_budget.budget[0] will be updated in-place
   ~ resource "google_billing_budget" "budget" {
         billing_account = "XXXXXX-XXXXXX-XXXXXX"
         display_name    = "Budget For prj-bu2-d-sample-floating-xxxx"
         id              = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/1e64bde0-0bd0-465c-9ae5-xxxxxxxxxxxxxx"
         name            = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/1e64bde0-0bd0-465c-9ae5-xxxxxxxxxxxxxx"

       ~ amount {
             last_period_amount = false

           ~ specified_amount {
               - currency_code = "USD" -> null
                 nanos         = 0
                 units         = "1000"
             }
         }

       ~ budget_filter {
             credit_types           = []
             credit_types_treatment = "INCLUDE_ALL_CREDITS"
             labels                 = {}
           ~ projects               = [
               - "projects/xxxxxxxxxx",
               + "projects/prj-bu2-d-sample-floating-xxxx",
             ]
             services               = []
             subaccounts            = []
         }

         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.5
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.75
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.9
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.95
         }
     }

   # module.peering_project.module.project.module.budget.google_billing_budget.budget[0] will be updated in-place
   ~ resource "google_billing_budget" "budget" {
         billing_account = "XXXXXX-XXXXXX-XXXXXX"
         display_name    = "Budget For prj-bu2-d-sample-peering-xxxx"
         id              = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/3fd9eada-ea32-4954-89af-xxxxxxxxxx"
         name            = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/3fd9eada-ea32-4954-89af-xxxxxxxxxx"

       ~ amount {
             last_period_amount = false

           ~ specified_amount {
               - currency_code = "USD" -> null
                 nanos         = 0
                 units         = "1000"
             }
         }

       ~ budget_filter {
             credit_types           = []
             credit_types_treatment = "INCLUDE_ALL_CREDITS"
             labels                 = {}
           ~ projects               = [
               - "projects/xxxxxxxxxxxxx",
               + "projects/prj-bu2-d-sample-peering-xxxx",
             ]
             services               = []
             subaccounts            = []
         }

         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.5
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.75
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.9
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.95
         }
     }

   # module.restricted_shared_vpc_project.module.project.module.budget.google_billing_budget.budget[0] will be updated in-place
   ~ resource "google_billing_budget" "budget" {
         billing_account = "XXXXXX-XXXXXX-XXXXXX"
         display_name    = "Budget For prj-bu2-d-sample-restrict-xxxx"
         id              = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/b84dbb7c-af3b-4a6d-83bd-xxxxxxxxxxxxx"
         name            = "billingAccounts/XXXXXX-XXXXXX-XXXXXX/budgets/b84dbb7c-af3b-4a6d-83bd-xxxxxxxxxxxxx"

       ~ amount {
             last_period_amount = false

           ~ specified_amount {
               - currency_code = "USD" -> null
                 nanos         = 0
                 units         = "1000"
             }
         }

       ~ budget_filter {
             credit_types           = []
             credit_types_treatment = "INCLUDE_ALL_CREDITS"
             labels                 = {}
           ~ projects               = [
               - "projects/xxxxxxxxxxxxx",
               + "projects/prj-bu2-d-sample-restrict-xxxx",
             ]
             services               = []
             subaccounts            = []
         }

         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.5
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.75
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.9
         }
         threshold_rules {
             spend_basis       = "CURRENT_SPEND"
             threshold_percent = 0.95
         }
     }

 Plan: 0 to add, 4 to change, 0 to destroy.

 ------------------------------------------------------------------------

Here's the tf apply result:

*************** TERRAFORM APPLY *******************
      At environment: business_unit_1/development 
***************************************************
module.floating_project.module.project.module.budget.google_billing_budget.budget[0]: Modifying... [id=billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/212c3f75-53ca-4158-8de3-xxxxxxxxxxxxxx]
module.restricted_shared_vpc_project.module.project.module.budget.google_billing_budget.budget[0]: Modifying... [id=billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/02a6b888-7d7e-4532-8ab8-xxxxxxxxxxxxxx]
module.base_shared_vpc_project.module.project.module.budget.google_billing_budget.budget[0]: Modifying... [id=billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/d05079fd-63a5-42f8-8738-xxxxxxxxxxxxxx]
module.peering_project.module.project.module.budget.google_billing_budget.budget[0]: Modifying... [id=billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/e7926b73-bb19-44d7-b22e-xxxxxxxxxxxxxx]

Error: Error updating Budget "billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/212c3f75-53ca-4158-8de3-xxxxxxxxxxxxxx": googleapi: Error 400: Request contains an invalid argument.

Error: Error updating Budget "billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/d05079fd-63a5-42f8-8738-xxxxxxxxxxxxxx": googleapi: Error 400: Request contains an invalid argument.

Error: Error updating Budget "billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/02a6b888-7d7e-4532-8ab8-xxxxxxxxxxxxxx": googleapi: Error 400: Request contains an invalid argument.

Error: Error updating Budget "billingAccounts/xxxxxx-xxxxxx-xxxxxx/budgets/e7926b73-bb19-44d7-b22e-xxxxxxxxxxxxxx": googleapi: Error 400: Request contains an invalid argument.

I'm pretty ignorant w/TF+GCP: is this an issue strictly related to the provider from Terraform? Is there anything I can do in the meantime? since we can't run locally terraform plan+apply and only be done via CloudBuild I don't see what could be done as a workaround

Thanks!

drandell commented 3 years ago

@mbghdev should be projects/[PROJECT_NUMBER] its no longer projects/[PROJECT_ID]. I would also add 'currency_code = USD' (if you want that). That issue was mentioned here -> https://github.com/hashicorp/terraform-provider-google/issues/8228 and the fix has been merged. Will have to wait for the next provider version for that fix.

kmasi42 commented 3 years ago

Still the same problem with the budget_filter recreation:

budget_filter {
            credit_types           = []
            credit_types_treatment = "INCLUDE_ALL_CREDITS"
            labels                 = {}
          ~ projects               = [
              - "projects/722309552xxx",
              + "projects/budget-project-nwjr-cdd4",

With the google terraform provider v.3.55.0

morgante commented 3 years ago

@kmasi42 That looks like an expected diff.

If you're still seeing a permadiff please update on the provider bug.

kmasi42 commented 3 years ago

@morgante As I understood: now API (or provider) return project number, but not project ID, so when you create a budget filter with a project_id google store it with project_number, so every time google-project-factory wants to recreate budget filter. I think that part of the google-project-factory needed to be re-factored to use a new approach - put in budget filter projects number.