-
Notifications
You must be signed in to change notification settings - Fork 81
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
RAD Lab Module to create GCP Projects with Billing budgets #58
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Initial Commit for Billing Budget Module
- Loading branch information
commit a1a2cdc1a13818a5922b8ef946d701d1874e6383
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# RAD Lab Billing Budget Module | ||
|
||
This module creates a simple GCP project, enables APIs, adds users to the project and also creates a Billing Budget for the Project. | ||
|
||
## GCP Products/Services | ||
|
||
* GCP Project | ||
* APIs & Services | ||
* Billing Budget | ||
|
||
## Reference Architecture Diagram | ||
|
||
Below Architechture Diagram is the base representation of what will be created as a part of [RAD Lab Launcher](../../radlab-launcher/radlab.py). | ||
|
||
![](../../docs/images/V7_Billing_Budget.png) | ||
|
||
## API Prerequisites | ||
|
||
In the RAD Lab Management Project make sure that _Cloud Billing Budget API (`billingbudgets.googleapis.com`)_ is enabled. | ||
|
||
## IAM Permissions Prerequisites | ||
|
||
Create a Terraform Service Account in RAD Lab Management Project to execute / deploy the RAD Lab module. Ensure that the Service Account has the following IAM permissions, **when creating the project** (`create_project` = true): | ||
|
||
- Parent: `roles/resourcemanager.projectCreator` | ||
- Parent: `roles/billing.user` | ||
- Parent: `roles/billing.costsManager` | ||
|
||
The User, Group, or Service Account who will be deploying the module should have access to impersonate and grant it the roles, `roles/iam.serviceAccountTokenCreator` on the **Terraform Service Account’s IAM Policy**. | ||
|
||
Note: This is not a Project IAM Binding; this is a **Service Account** IAM Binding. | ||
|
||
NOTE: Additional [permissions](../../radlab-launcher/README.md#iam-permissions-prerequisites) are required when deploying the RAD Lab modules via [RAD Lab Launcher](../../radlab-launcher) | ||
|
||
|
||
<!-- BEGIN TFDOC --> | ||
## Variables | ||
|
||
| name | description | type | required | default | | ||
|---|---|:---: |:---:|:---:| | ||
| billing_account_id | Billing Account associated to the GCP Resources | <code title="">string</code> | ✓ | | | ||
| *apis* | The list of GCP apis to enable. | <code title="set(string)">set(string)</code> | | <code title="">["compute.googleapis.com","bigquery.googleapis.com","bigquerystorage.googleapis.com"]</code> | | ||
| *billing_budget_alert_spend_basis* | The type of basis used to determine if spend has passed the threshold | <code title="">string</code> | | <code title="">CURRENT_SPEND</code> | | ||
| *billing_budget_alert_spent_percents* | A list of percentages of the budget to alert on when threshold is exceeded | <code title="list(number)">list(number)</code> | | <code title="">[0.5,0.7,1]</code> | | ||
| *billing_budget_amount* | The amount to use as the budget in USD | <code title="">number</code> | | <code title="">1000</code> | | ||
| *billing_budget_credit_types_treatment* | Specifies how credits should be treated when determining spend for threshold calculations | <code title="">string</code> | | <code title="">INCLUDE_ALL_CREDITS</code> | | ||
| *billing_budget_labels* | A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget. | <code title="map(string)">map(string)</code> | | <code title="{} validation { condition = length(var.billing_budget_labels) <= 1 error_message = "Only 0 or 1 labels may be supplied for the budget filter." }">...</code> | | ||
| *billing_budget_services* | A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/ | <code title="list(string)">list(string)</code> | | <code title="">null</code> | | ||
| *create_project* | Set to true if the module has to create a project. If you want to deploy in an existing project, set this variable to false. | <code title="">bool</code> | | <code title="">true</code> | | ||
| *enable_services* | Enable the necessary APIs on the project. When using an existing project, this can be set to false. | <code title="">bool</code> | | <code title="">true</code> | | ||
| *folder_id* | Folder ID where the project should be created. It can be skipped if already setting organization_id. Leave blank if the project should be created directly underneath the Organization node. | <code title="">string</code> | | <code title=""></code> | | ||
| *organization_id* | Organization ID where GCP Resources need to get spin up. It can be skipped if already setting folder_id | <code title="">string</code> | | <code title=""></code> | | ||
| *project_name* | Project name or ID, if it's an existing project. | <code title="">string</code> | | <code title="">radlab-billing-budget</code> | | ||
| *random_id* | Adds a suffix of 4 random characters to the `project_id` | <code title="">string</code> | | <code title="">null</code> | | ||
| *sa* | Terraform Service Account which will be creating the GCP resources | <code title="">string</code> | | <code title=""></code> | | ||
| *trusted_users* | The list of trusted users who will be assigned Editor role on the project | <code title="set(string)">set(string)</code> | | <code title="">[]</code> | | ||
|
||
## Outputs | ||
|
||
| name | description | sensitive | | ||
|---|---|:---:| | ||
| billing_budget_budgetId | Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}` | | | ||
| deployment_id | RADLab Module Deployment ID | | | ||
| project-radlab-billing-budget-id | GCP Project ID | | | ||
<!-- END TFDOC --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/** | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
|
||
provider "google" { | ||
alias = "impersonated" | ||
scopes = [ | ||
"https://www.googleapis.com/auth/cloud-platform", | ||
"https://www.googleapis.com/auth/userinfo.email" | ||
] | ||
} | ||
|
||
data "google_service_account_access_token" "default" { | ||
provider = google.impersonated | ||
scopes = ["userinfo-email", "cloud-platform"] | ||
target_service_account = var.sa | ||
lifetime = "1800s" | ||
} | ||
|
||
provider "google" { | ||
access_token = data.google_service_account_access_token.default.access_token | ||
} | ||
|
||
provider "google-beta" { | ||
access_token = data.google_service_account_access_token.default.access_token | ||
} | ||
|
||
|
||
locals { | ||
random_id = var.random_id != null ? var.random_id : random_id.default.hex | ||
project = (var.create_project | ||
? try(module.project_radlab_billing_budget.0, null) | ||
: try(data.google_project.existing_project.0, null) | ||
) | ||
|
||
project_services = var.enable_services ? var.apis : [] | ||
} | ||
|
||
resource "random_id" "default" { | ||
byte_length = 2 | ||
} | ||
|
||
############### | ||
# GCP PROJECT # | ||
############### | ||
|
||
data "google_project" "existing_project" { | ||
count = var.create_project ? 0 : 1 | ||
project_id = var.project_name | ||
} | ||
|
||
module "project_radlab_billing_budget" { | ||
count = var.create_project ? 1 : 0 | ||
source = "terraform-google-modules/project-factory/google" | ||
version = "~> 11.0" | ||
|
||
name = format("%s-%s", var.project_name, local.random_id) | ||
random_project_id = false | ||
folder_id = var.folder_id | ||
billing_account = var.billing_account_id | ||
org_id = var.organization_id | ||
|
||
activate_apis = [] | ||
} | ||
|
||
|
||
resource "google_project_service" "enabled_services" { | ||
for_each = toset(local.project_services) | ||
project = local.project.project_id | ||
service = each.value | ||
disable_dependent_services = true | ||
disable_on_destroy = true | ||
} | ||
|
||
resource "time_sleep" "wait_120_seconds" { | ||
count = var.enable_services ? 1 : 0 | ||
create_duration = "120s" | ||
|
||
depends_on = [ | ||
google_project_service.enabled_services | ||
] | ||
} | ||
|
||
module "billing_budget" { | ||
source = "terraform-google-modules/project-factory/google//modules/budget" | ||
display_name = format("RADLab Billing Budget - %s", local.project.project_id) | ||
billing_account = var.billing_account_id | ||
projects = ["${local.project.project_id}"] | ||
amount = var.billing_budget_amount | ||
alert_spend_basis = var.billing_budget_alert_spend_basis | ||
alert_spent_percents = var.billing_budget_alert_spent_percents | ||
credit_types_treatment = var.billing_budget_credit_types_treatment | ||
labels = var.billing_budget_labels | ||
services = var.billing_budget_services | ||
|
||
depends_on = [ | ||
time_sleep.wait_120_seconds | ||
] | ||
|
||
} | ||
|
||
resource "google_project_iam_member" "user_role_assignment" { | ||
for_each = var.trusted_users | ||
project = local.project.project_id | ||
member = each.value | ||
role = "roles/editor" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
output "deployment_id" { | ||
description = "RADLab Module Deployment ID" | ||
value = local.random_id | ||
} | ||
|
||
output "project-radlab-billing-budget-id" { | ||
description = "GCP Project ID" | ||
value = local.project.project_id | ||
} | ||
|
||
output "billing_budget_budgetId" { | ||
description = "Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`" | ||
value = module.billing_budget.name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
variable "apis" { | ||
description = "The list of GCP apis to enable." | ||
type = set(string) | ||
default = ["compute.googleapis.com","bigquery.googleapis.com","bigquerystorage.googleapis.com"] | ||
} | ||
|
||
variable "billing_account_id" { | ||
description = "Billing Account associated to the GCP Resources" | ||
type = string | ||
} | ||
|
||
variable "billing_budget_alert_spend_basis" { | ||
description = "The type of basis used to determine if spend has passed the threshold" | ||
type = string | ||
default = "CURRENT_SPEND" | ||
} | ||
|
||
variable "billing_budget_alert_spent_percents" { | ||
description = "A list of percentages of the budget to alert on when threshold is exceeded" | ||
type = list(number) | ||
default = [0.5,0.7,1] | ||
} | ||
|
||
variable "billing_budget_amount" { | ||
description = "The amount to use as the budget in USD" | ||
type = number | ||
default = 1000 | ||
} | ||
|
||
variable "billing_budget_credit_types_treatment" { | ||
description = "Specifies how credits should be treated when determining spend for threshold calculations" | ||
type = string | ||
default = "INCLUDE_ALL_CREDITS" | ||
} | ||
|
||
variable "billing_budget_labels" { | ||
description = "A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget." | ||
type = map(string) | ||
default = {} | ||
validation { | ||
condition = length(var.billing_budget_labels) <= 1 | ||
error_message = "Only 0 or 1 labels may be supplied for the budget filter." | ||
} | ||
} | ||
|
||
variable "billing_budget_services" { | ||
description = "A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/" | ||
type = list(string) | ||
default = null | ||
} | ||
|
||
variable "create_project" { | ||
description = "Set to true if the module has to create a project. If you want to deploy in an existing project, set this variable to false." | ||
type = bool | ||
default = true | ||
} | ||
|
||
variable "enable_services" { | ||
description = "Enable the necessary APIs on the project. When using an existing project, this can be set to false." | ||
type = bool | ||
default = true | ||
} | ||
|
||
variable "folder_id" { | ||
description = "Folder ID where the project should be created. It can be skipped if already setting organization_id. Leave blank if the project should be created directly underneath the Organization node. " | ||
type = string | ||
default = "" | ||
} | ||
|
||
variable "organization_id" { | ||
description = "Organization ID where GCP Resources need to get spin up. It can be skipped if already setting folder_id" | ||
type = string | ||
default = "" | ||
} | ||
|
||
variable "project_name" { | ||
description = "Project name or ID, if it's an existing project." | ||
type = string | ||
default = "radlab-billing-budget" | ||
} | ||
|
||
variable "random_id" { | ||
description = "Adds a suffix of 4 random characters to the `project_id`" | ||
type = string | ||
default = null | ||
} | ||
|
||
variable "sa" { | ||
description = "Terraform Service Account which will be creating the GCP resources" | ||
type = string | ||
default = "" | ||
} | ||
|
||
variable "trusted_users" { | ||
description = "The list of trusted users who will be assigned Editor role on the project" | ||
type = set(string) | ||
default = [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
terraform { | ||
required_version = "~> 1.0" | ||
|
||
required_providers { | ||
google = ">= 3.87.0" | ||
google-beta = ">= 3.87.0" | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename this to something more meaningful?
resource_creator_identity
or something?