terraform-provider-google: Error: Provider produced inconsistent result after apply at GCP project + SA creation
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request.
- Please do not leave +1 or me too comments, they generate extra noise for issue followers and do not help prioritize the request.
- If you are interested in working on this issue or have submitted a pull request, please leave a comment.
- If an issue is assigned to the
modular-magicianuser, 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
Terraform version: 0.12.24 terraform-provider-google-beta_v3.21.0_x5 “terraform-provider-google-beta_v3.21.0_x5” “terraform-provider-google_v3.21.0_x5” “terraform-provider-null_v2.1.2_x4” “terraform-provider-random_v2.2.1_x4” “terraform-provider-template_v2.1.2_x4”
Affected Resource(s)
The error is around service account but don’t know which resource exactly. The code creates 2 SA and may fail for one or other SA. Or not fail at all
- google_service_account
Terraform Configuration Files
# Création du SA ressources à utiliser par les ressources runner
resource "google_service_account" "project_runner" {
account_id = "sa-${var.project_name}-infra"
display_name = "sa-${var.project_name}-infra"
project = google_project.main.project_id
}
# Création du SA application
resource "google_service_account" "appli_sa" {
account_id = "sa-${var.project_name}-appli"
display_name = "sa-${var.project_name}-appli"
project = google_project.main.project_id
}
# Récupération des informations sur le subnet auquel sera rattaché le projet
data "google_compute_subnetwork" "subnet" {
count = var.connection_to_host_project == "true" ? 1 : 0
name = "${var.subnet_prefix_name}${var.host_project_instance}${var.subnet_suffix_name}${var.subnet_index}"
project = var.host_project_id
depends_on = [google_project_service.main]
}
# Donne le droit au SA ressources du projet de connecter des ressources au subnet du host project. Par exemple un GCE
resource "google_compute_subnetwork_iam_member" "default_sa" {
count = var.connection_to_host_project == "true" ? 1 : 0
subnetwork = data.google_compute_subnetwork.subnet[0].name
role = "roles/compute.networkUser"
member = "serviceAccount:${google_service_account.project_runner.email}"
project = var.host_project_id
}
# Récupération des informations sur d'éventuels subnets supplémentaires auquel le SA devra avoir le droit networkuser
data "google_compute_subnetwork" "get_supplemental_subnets" {
count = (var.connection_to_host_project == "true" ? 1 : 0) * var.sa_folder_supplemental_subnets
name = "${var.subnet_prefix_name}${var.host_project_instance}-${var.sia}-${element(split("-", var.project_name), 0)}${element(split("-", var.project_name), 1)}${var.subnet_suffix_name}${count.index + 1}"
project = var.host_project_id
depends_on = [google_project_service.main]
}
# Donne le droit au SA ressources du projet de connecter des ressources à d'éventuels autres subnets du host project dans le même VPC. Par exemple un GCE
resource "google_compute_subnetwork_iam_member" "supplemental_subnets" {
count = (var.connection_to_host_project == "true" ? 1 : 0) * var.sa_folder_supplemental_subnets
subnetwork = element(
data.google_compute_subnetwork.get_supplemental_subnets.*.name,
count.index,
)
role = "roles/compute.networkUser"
member = "serviceAccount:${google_service_account.project_runner.email}"
project = var.host_project_id
}
# Donne le droit au compte google_api_agent du projet de connecter des ressources au subnet du host project. Ce compte sert pour les services managés de google
resource "google_compute_subnetwork_iam_member" "google_api_agent" {
count = var.connection_to_host_project == "true" ? 1 : 0
subnetwork = data.google_compute_subnetwork.subnet[0].name
role = "roles/compute.networkUser"
member = "serviceAccount:${google_project.main.number}@cloudservices.gserviceaccount.com"
project = var.host_project_id
}
# Donne le droit au SA ressources du projet de lire les VPC du host project : necessaire pour CloudSQL private et Load Balancer
resource "google_project_iam_member" "network-get" {
count = var.connection_to_host_project == "true" ? 1 : 0
project = var.host_project_id
role = "organizations/${var.org_id}/roles/svc.project.rights.on.hostprj" # Contains compute-network-get-for-hostprojects
member = "serviceAccount:${google_service_account.project_runner.email}"
}
# Attribue les droits au SA de création des ressources sur le service projet
resource "google_project_iam_member" "editor" {
count = length(var.sa_folder_iam_roles)
project = google_project.main.project_id
role = var.sa_folder_iam_roles[count.index]
member = "serviceAccount:${google_service_account.project_runner.email}"
}
# Cre les SA décrits dans la variable sas_map du .tfvars. S'ils apparaissent plusieurs fois car ils ont plusieurs roles, les doublons sont ignores a cette etape
resource "google_service_account" "sas" {
count = length(var.sas_nickname_list)
project = google_project.main.project_id
account_id = "sa-${var.project_name}-${var.sas_nickname_list[count.index]}"
display_name = "sa-${var.project_name}-${var.sas_nickname_list[count.index]}"
}
# Attribue les droits aux SA décrits dans la variable sas_map du .tfvars
resource "google_project_iam_member" "sas" {
count = length(var.sas_map)
project = google_project.main.project_id
role = var.sas_map[count.index]["role"]
member = "serviceAccount:sa-${var.project_name}-${var.sas_map[count.index]["sa_nickname"]}@${google_project.main.project_id}.iam.gserviceaccount.com"
depends_on = [google_service_account.sas]
}
# Autorise si besoin les "customer-managed encryption keys" pour le service pubsub (cf. https://cloud.google.com/pubsub/docs/cmek)
resource "google_project_iam_member" "pubsub_cmek" {
count = var.pubsub_crypt_enable ? 1 : 0
project = google_project.main.project_id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:service-${google_project.main.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}
### Add IAM roles to a gcp managed service account
resource "google_project_iam_member" "extra_cloud_functions_permissions" {
count = length(var.extra_cloud_functions_service_account_permissions)
project = google_project.main.project_id
role = var.extra_cloud_functions_service_account_permissions[count.index]
member = "serviceAccount:service-${google_project.main.number}@gcf-admin-robot.iam.gserviceaccount.com"
# Add a dependency on the project APIs to make sure the Cloud Functions API is enabled and the Service Account is created before it is granted extra permissions.
depends_on = [google_project_service.main]
Debug Output
https://gist.github.com/mldmld68/c08c9db8383736e1df31a49cdbe10ab3
Panic Output
Expected Behavior
Terraform apply finish without error
Actual Behavior
I can get an error on 2 SA, but not everytime the same I terraform plan+apply/terraform destroy/terraform plan+apply
Error: Provider produced inconsistent result after apply When applying changes to google_service_account.appli_sa, provider “registry.terraform.io/-/google” produced an unexpected new value for was present, but now absent. This is a bug in the provider, which should be reported in the provider’s own issue tracker. If one restart terraform apply, on get Error: Error creating service account: googleapi: Error 409: Service account sa-xxxxx-appli already exists within project projects/xxxxxxx., alreadyExists on service_account.tf line 9, in resource “google_service_account” “appli_sa”:
Error: Provider produced inconsistent result after apply When applying changes to google_service_account.project_runner, provider “registry.terraform.io/-/google” produced an unexpected new value for was present, but now absent. This is a bug in the provider, which should be reported in the provider’s own issue tracker. ERROR: Job failed: exit code 1
Steps to Reproduce
terraform apply
terraform apply
Important Factoids
This job create a GCP projet, give roles to user groups and SAs. If one destroy the faultly SA and restart the job, the terrform plan plays successfully
References
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 11
- Comments: 16 (5 by maintainers)
Hi @unclebene The fix just missed the timing for the v3.22.0 release, so it won’t officially show until v3.23.0. If needed, you could always build from the commits generated by the pull request: TPG TPGB
Hi, Tried to apply this workaround without success. Got issue on both service accounts. Tried to add a depends_on section on the null ressource with project creation. It shows the delay do not fix the issue because it do not prevent other ressources of being created like Service Accounts.
But I noticed the sa creation begin while the project resource is still activating api.
So added depends_on section with depends_on = [google_project_service.main] in service account creation and the issue do not appear anymore. I tried only twice, but before I got the issue everytime.
I met the same issue with Terraform 0.11.14/0.12.24 and Google Provider 2.20.1.
I wrote a minimal code to reproduce this behavior, which repeats create a new service account -> get it -> delete it using raw IAM API client. https://gist.github.com/dtan4/a2081e75ff8e4737c872e80fd9e6f9e6
However, actually it’s still hard to reproduce… when I started running this script, I sometimes encountered the following error which looks the same as this issue. However, after running several times, I couldn’t see the error again…
I encountered this issue yesterday. On first Apply I saw that the resources that depended on the service account failed. A subsequent terraform plan showed that the service account needed to be created, running apply again gave the error service account alreadyExists.
terraform version: 0.11.14 provider version: 2.20
when investigating I found:
I resolved by:
Looks related to: https://github.com/terraform-providers/terraform-provider-google/issues/6362