I have an odd issue that I have not yet been able to figure out. I am creating an application to create projects on demand by using a template for my provider targeting the project I am creating.
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.30.0"
}
}
}
provider "google" {
impersonate_service_account = "project-factory-21696@company-cicd.iam.gserviceaccount.com"
alias = "uswest1"
billing_project = "<project>"
project = "<project>"
region = "us-west1"
}
<project> gets replaced when the new directory is created. So it looks like this:
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.30.0"
}
}
}
provider "google" {
impersonate_service_account = "project-factory-21696@company-cicd.iam.gserviceaccount.com"
alias = "uswest1"
billing_project = "donotuse-1749079741-hoh"
project = "donotuse-1749079741-hoh"
region = "us-west1"
}
The service account has the following permissions as the org level:
API Keys Admin
My account has the following IAM permissions applied to the service account being used for project creation.
Service Account Token Creator, Service Usage Consumer
I run two modules as follows in the projects main.tf:
module "init_project" {
source = "../../modules/init_project"
providers = {
google.uswest1 = google.uswest1
}
project_id = var.project_name
org_id = var.org_id
billing_account = var.billing_account
}
module "populate_project" {
source = "../../modules/populate_project"
providers = {
google.uswest1 = google.uswest1
}
project_name = var.project_name
infra_project = var.infra_project
region = var.region
depends_on = [module.init_project]
}
The init_module runs correctly and creates the project as it is a simple wrapper to project-factory resource. I specify the following provider there as:
terraform {
required_providers {
google = {
source = "hashicorp/google"
configuration_aliases = [
google.uswest1
]
}
}
}
And my populate project modules looks like this:
terraform {
required_providers {
google = {
source = "hashicorp/google"
configuration_aliases = [
google.uswest1
]
}
}
}
module "auth" {
source = "../auth"
project_id = var.project_name
providers = {
google.uswest1 = google.uswest1
}
}
...other modules...
And finally the auth module has the following files:
resource "google_apikeys_key" "server_api_key" {
name = "server_api_key"
display_name = "Server API Key"
project = var.project_id
provider = google.uswest1
restrictions {
api_targets {
service = "geocoding-backend.googleapis.com"
}
api_targets {
service = "timezone-backend.googleapis.com"
}
}
}
resource "google_apikeys_key" "web_api_key" {
name = "web_api_key"
display_name = "Web API Key"
project = var.project_id
provider = google.uswest1
restrictions {
api_targets {
service = "geocoding-backend.googleapis.com"
}
api_targets {
service = "calendar-json.googleapis.com"
}
api_targets {
service = "maps-embed-backend.googleapis.com"
}
api_targets {
service = "maps-backend.googleapis.com"
}
api_targets {
service = "static-maps-backend.googleapis.com"
}
api_targets {
service = "places-backend.googleapis.com"
}
# For server keys, use:
server_key_restrictions {
allowed_ips = [
...
]
}
}
}
The first module completes with no issue and I can see the correct apis enabled in the target project, mainly
"apikeys.googleapis.com",
However when it gets to running the second module to populate the project it is using the wrong project. It is trying to create the api keys in the project where the service account resides and not the project under creation.
│ Error: Error creating Key: failed to create a diff: failed to retrieve Key resource: googleapi: Error 403: API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
│ Details:
│ [
│ {
│ "@type": "type.googleapis.com/google.rpc.ErrorInfo",
│ "domain": "googleapis.com",
│ "metadata": {
│ "activationUrl": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139",
│ "consumer": "projects/456219313139",
│ "containerInfo": "456219313139",
│ "service": "apikeys.googleapis.com",
│ "serviceTitle": "API Keys API"
│ },
│ "reason": "SERVICE_DISABLED"
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
│ "locale": "en-US",
│ "message": "API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.Help",
│ "links": [
│ {
│ "description": "Google developers console API activation",
│ "url": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139"
│ }
│ ]
│ }
│ ]
│
│ with module.populate_project.module.auth.google_apikeys_key.server_api_key,
│ on ../../modules/auth/api-keys.tf line 1, in resource "google_apikeys_key" "server_api_key":
│ 1: resource "google_apikeys_key" "server_api_key" {
│
╵
While the error is technically correct it is trying to create the api key in the wrong project. The api is enabled in the project that is being created. I am just not sure why it is switching the project. Looking to see what is happening here.
Solved! Go to Solution.
Okay if anyone reads this I found the solution. The solution was to add
user_project_override = true
to the provider definition. Then it finds the correct project.
hi @ricardoa81
The issue is that google_apikeys_key is ignoring project = var.project_id and using the project from the provider block instead (the service account’s project). Try this
Create a separate provider with the correct target project:
provider "google" {
alias = "target_project"
project = var.project_id
...
}
Then set:
provider = google.target_project
Some Google APIs require the project to be set in the provider itself, not just in the resource.
Thank you for the reply @a_aleinikov I will give this a shot and post back here!
Okay I tried to update to using the google-beta provider but it is still giving the same result:
╷
│ Error: Error creating Key: failed to create a diff: failed to retrieve Key resource: googleapi: Error 403: API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
│ Details:
│ [
│ {
│ "@type": "type.googleapis.com/google.rpc.ErrorInfo",
│ "domain": "googleapis.com",
│ "metadata": {
│ "activationUrl": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139",
│ "consumer": "projects/456219313139",
│ "containerInfo": "456219313139",
│ "service": "apikeys.googleapis.com",
│ "serviceTitle": "API Keys API"
│ },
│ "reason": "SERVICE_DISABLED"
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
│ "locale": "en-US",
│ "message": "API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.Help",
│ "links": [
│ {
│ "description": "Google developers console API activation",
│ "url": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139"
│ }
│ ]
│ }
│ ]
│
│ with module.populate_project.module.auth.google_apikeys_key.server_api_key,
│ on ../../modules/auth/api-keys.tf line 1, in resource "google_apikeys_key" "server_api_key":
│ 1: resource "google_apikeys_key" "server_api_key" {
│
╵
╷
│ Error: Error creating Key: failed to create a diff: failed to retrieve Key resource: googleapi: Error 403: API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
│ Details:
│ [
│ {
│ "@type": "type.googleapis.com/google.rpc.ErrorInfo",
│ "domain": "googleapis.com",
│ "metadata": {
│ "activationUrl": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139",
│ "consumer": "projects/456219313139",
│ "containerInfo": "456219313139",
│ "service": "apikeys.googleapis.com",
│ "serviceTitle": "API Keys API"
│ },
│ "reason": "SERVICE_DISABLED"
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
│ "locale": "en-US",
│ "message": "API Keys API has not been used in project 456219313139 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
│ },
│ {
│ "@type": "type.googleapis.com/google.rpc.Help",
│ "links": [
│ {
│ "description": "Google developers console API activation",
│ "url": "https://console.developers.google.com/apis/api/apikeys.googleapis.com/overview?project=456219313139"
│ }
│ ]
│ }
│ ]
│
│ with module.populate_project.module.auth.google_apikeys_key.web_api_key,
│ on ../../modules/auth/api-keys.tf line 18, in resource "google_apikeys_key" "web_api_key":
│ 18: resource "google_apikeys_key" "web_api_key" {
│
╵
+ echo 'ERROR: terraform apply failed for donotuse-1749163103-o7d. Exiting...'
ERROR: terraform apply failed for donotuse-1749163103-o7d. Exiting...
+ exit 1
For some reason it is still trying to default to the project that owns the service account.
I was also able to verify via the plan output that the correct project id is being collected but not honored when creation happens:
Terraform will perform the following actions:
# module.populate_project.module.auth.google_apikeys_key.server_api_key will be created
+ resource "google_apikeys_key" "server_api_key" {
+ display_name = "Server API Key"
+ id = (known after apply)
+ key_string = (sensitive value)
+ name = "server_api_key"
+ project = "donotuse-1749163103-o7d"
+ uid = (known after apply)
+ restrictions {
+ api_targets {
+ service = "geocoding-backend.googleapis.com"
}
+ api_targets {
+ service = "timezone-backend.googleapis.com"
}
}
}
# module.populate_project.module.auth.google_apikeys_key.web_api_key will be created
+ resource "google_apikeys_key" "web_api_key" {
+ display_name = "Web API Key"
+ id = (known after apply)
+ key_string = (sensitive value)
+ name = "web_api_key"
+ project = "donotuse-1749163103-o7d"
+ uid = (known after apply)
+ restrictions {
+ api_targets {
+ service = "geocoding-backend.googleapis.com"
}
+ api_targets {
+ service = "calendar-json.googleapis.com"
}
+ api_targets {
+ service = "maps-embed-backend.googleapis.com"
}
+ api_targets {
+ service = "maps-backend.googleapis.com"
}
+ api_targets {
+ service = "static-maps-backend.googleapis.com"
}
+ api_targets {
+ service = "places-backend.googleapis.com"
}
+ server_key_restrictions {
+ allowed_ips = [
+ "domain1",
+ "domain2",
+ "domain3",
]
}
}
}
Also my provider was already aliased and being passed in but here is the update to google-beta:
terraform {
required_providers {
google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.38.0"
}
}
}
provider "google-beta" {
impersonate_service_account = "project-factory-21696@company-cicd.iam.gserviceaccount.com"
alias = "uswest1"
billing_project = "donotuse-1749163103-o7d"
project = "donotuse-1749163103-o7d"
region = "us-west1"
}
module/auth/providers.tf
terraform {
required_providers {
google-beta = {
source = "hashicorp/google-beta"
configuration_aliases = [
google-beta.uswest1
]
}
}
}
/module/auth/main.tf
resource "google_apikeys_key" "server_api_key" {
name = "server_api_key"
display_name = "Server API Key"
project = var.project_id
provider = google-beta.uswest1
restrictions {
api_targets {
service = "geocoding-backend.googleapis.com"
}
api_targets {
service = "timezone-backend.googleapis.com"
}
}
}
resource "google_apikeys_key" "web_api_key" {
name = "web_api_key"
display_name = "Web API Key"
project = var.project_id
provider = google-beta.uswest1
restrictions {
api_targets {
service = "geocoding-backend.googleapis.com"
}
api_targets {
service = "calendar-json.googleapis.com"
}
api_targets {
service = "maps-embed-backend.googleapis.com"
}
api_targets {
service = "maps-backend.googleapis.com"
}
api_targets {
service = "static-maps-backend.googleapis.com"
}
api_targets {
service = "places-backend.googleapis.com"
}
# For server keys, use:
server_key_restrictions {
allowed_ips = [
"domain1",
"domain2",
"domain3"
]
}
}
}
I am not sure why the project is not being honored here.
Okay if anyone reads this I found the solution. The solution was to add
user_project_override = true
to the provider definition. Then it finds the correct project.