I am very new to GCP with terraform and I want to deploy all my modules using centralized tools.
Is there any way to remove the step of enabling google API's every time so that deployment is not interrupted?
I am very new to GCP with terraform and I want to deploy all my modules using centralized tools.
Is there any way to remove the step of enabling google API's every time so that deployment is not interrupted?
There is a Terraform resource definition called "google_project_service" that allows one to enable a service (API). This is documented at google_project_service.
An example of usage appears to be:
resource "google_project_service" "project" {
project = "your-project-id"
service = "iam.googleapis.com"
}
instead of using count
as suggested by @pradeep you may also loop over the services in question:
variable "gcp_service_list" {
description ="The list of apis necessary for the project"
type = list(string)
default = [
"cloudresourcemanager.googleapis.com",
"serviceusage.googleapis.com"
]
}
resource "google_project_service" "gcp_services" {
for_each = toset(var.gcp_service_list)
project = "your-project-id"
service = each.key
}
Error when reading or editing Project Service nvoi-playground/cloudresourcemanager.googleapis.com: Request
List Project Services xxx` returned error: Batch request and retried single request ...` is this expected ? –
Bigname Yes , you can use google_project_service
resource to enable one API at a time. You can use count
or other loop methods to enable multiple APIs. You would need project editor/owner role to do this.
# Enable services in newly created GCP Project.
resource "google_project_service" "gcp_services" {
count = length(var.gcp_service_list)
project = google_project.demo_project.project_id
service = var.gcp_service_list[count.index]
disable_dependent_services = true
}
You can find the complete example here.
For those reading this in 2022, enabling serviceusage
and cloudresourcesmanager
automatically from Terraform doesn't work as enabling those APIs through the API has a dependency on them being already enabled...
The solution is to do it through the gcloud command line:
# Use `gcloud` to enable:
# - serviceusage.googleapis.com
# - cloudresourcemanager.googleapis.com
resource "null_resource" "enable_service_usage_api" {
provisioner "local-exec" {
command = "gcloud services enable serviceusage.googleapis.com cloudresourcemanager.googleapis.com --project ${var.project_id}"
}
depends_on = [google_project.project]
}
# Wait for the new configuration to propagate
# (might be redundant)
resource "time_sleep" "wait_project_init" {
create_duration = "60s"
depends_on = [null_resource.enable_service_usage_api]
}
More details on https://medium.com/rockedscience/how-to-fully-automate-the-deployment-of-google-cloud-platform-projects-with-terraform-16c33f1fb31f
2022 - Sharing my personal experience of enabling services using code
Usually a cost is associated with enabling services and Billing account have to be linked to the services at time. Example, you want to create a static public ip or setup a Cloud CDN.
Enabling services using code is possible as suggested in https://cloud.google.com/service-usage/docs/enable-disable#gcloud and https://mcmap.net/q/395701/-can-i-automatically-enable-apis-when-using-gcp-cloud-with-terraform (Using Terraform null resource running gcloud command) but the additional challenge is, enabling a service does not happen in second or minute.
Adding wait/sleep or dependency flow helped me for a while but, in the long run it complicated my code.
Cross dependency issues. Using Terraform code when I enabled services for Compute, then other developer were able to create resources. After sometime, when I no longer need and tried to terraform destroy
I got several dependency issue.
TL;DR Enabling services is usually one-time task just like creating a billing account. As per my experience, I recommend not to automate such important things.
Below is added on April 2023
Distribute your TF Code. As suggested in by @FreshMike & @Juarez_Rudsatz, distribute your TF code into multiple folders.
You can do this by product wise(Compute/Networking/IAM/ServiceAccounts/..) or module wise(Permissions/Admin/Module-A/Product-A/Product-B/..) or others depending on what suits your requirement.
In my team project, we used a separate folder call test/setup
and used this module https://registry.terraform.io/modules/terraform-google-modules/project-factory/google/latest/submodules/project_services to enable multiple APIs in one go.
All the answers are excellent; however, I'd like to add a new scenario not yet covered.
I tried all the answers, e.g.,
resource "google_project_service" "x" {
project = ...
service = "compute.googleapis.com"
}
but the Compute Engine default service account
ends up in the disabled
state:
After a lot of investigation, I found the culprit to be the way I created the project. I used the following open source module to create the project:
module "my_project" {
source = "terraform-google-modules/project-factory/google"
...
}
The open source module's underlying source code contains this snippet:
resource "google_project_default_service_accounts" "default_service_accounts" {
count = upper(var.default_service_account) == "KEEP" ? 0 : 1
action = upper(var.default_service_account)
...
where the var's default value is this:
variable "default_service_account" {
description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."
default = "disable"
The combined result is equivalent to the sample code at google_project_default_service_accounts:
resource "google_project_default_service_accounts" "my_project" {
project = "my-project-id"
action = "DISABLE"
...
}
Therefore, the solution is:
module "my_project" {
source = "terraform-google-modules/project-factory/google"
default_service_account = "KEEP" # <<<<====== solution
...
}
Caveat: The security best practice is to disable the default SAs and create your own custom SAs, I suppose. So, my solution above is to solve a mystery, not to be considered the security best practice.
© 2022 - 2024 — McMap. All rights reserved.