terraform-provider-postgresql icon indicating copy to clipboard operation
terraform-provider-postgresql copied to clipboard

Error when issuing certain grants and privileges to a user if they apply to multiple databases

Open me0wbear opened this issue 3 years ago • 1 comments

Hello. An example of when, when it is reproduced:

locals {
  databases = ["postgres", "second_db"]
  app_username = "app"
  admin_username = "admin"
  read_only_username = "read_only"
  schema_and_role_name = "public"
}

provider "postgresql" {
  host             = aws_rds_cluster.some-cluster.endpoint
  username         = aws_rds_cluster.some-cluster.username
  port             = aws_rds_cluster.some-cluster.port
  password         = aws_rds_cluster.some-cluster.password
  expected_version = aws_rds_cluster.some-cluster.engine_version

  superuser = false
}

resource "postgresql_database" "databases" {
  count            = length(local.databases)
  name             = element(local.databases, count.index)
  owner            = aws_rds_cluster.some-cluster.username
  connection_limit = -1

  depends_on = [aws_rds_cluster_instance.instances]
}

resource "postgresql_role" "admin_user" {
  name               = local.admin_username
  login              = true
  password           = random_password.password[1].result
  encrypted_password = true
  create_database    = false
  roles              = [aws_rds_cluster.some-cluster.username]

  depends_on = [
    postgresql_database.databases,
    postgresql_grant.revoke_public
  ]
}

resource "postgresql_role" "read_only_user" {
  name               = local.read_only_username
  login              = true
  password           = random_password.password[2].result
  encrypted_password = true
  create_database    = false

  depends_on = [
    postgresql_role.admin_user
  ]
}

resource "postgresql_role" "app_user" {
  name               = local.app_username
  login              = true
  password           = random_password.password[3].result
  encrypted_password = true
  create_database    = false

  depends_on = [
    postgresql_role.admin_user
  ]
}

resource "postgresql_default_privileges" "read_only_user_default_privileges_table" {
  count       = length(local.databases)
  database    = element(local.databases, count.index)
  role        = postgresql_role.read_only_user.name
  owner       = postgresql_role.admin_user.name
  schema      = local.schema_and_role_name
  object_type = "table"
  privileges  = ["SELECT"]

  depends_on = [
    postgresql_role.read_only_user
  ]
}

resource "postgresql_grant" "read_only_user_grant_table" {
  count       = length(local.databases)
  database    = element(local.databases, count.index)
  role        = postgresql_role.read_only_user.name
  schema      = local.schema_and_role_name
  object_type = "table"
  privileges  = ["SELECT"]

  depends_on = [
    postgresql_role.read_only_user
  ]
}

resource "postgresql_default_privileges" "app_user_default_privileges_table" {
  count       = length(local.databases)
  database    = element(local.databases, count.index)
  role        = postgresql_role.app_user.name
  owner       = postgresql_role.admin_user.name
  schema      = local.schema_and_role_name
  object_type = "table"
  privileges  = ["SELECT", "INSERT", "UPDATE", "DELETE"]

  depends_on = [
    postgresql_role.app_user
  ]
}

resource "postgresql_grant" "app_user_grant_table" {
  count       = length(local.databases)
  database    = element(local.databases, count.index)
  role        = postgresql_role.app_user.name
  schema      = local.schema_and_role_name
  object_type = "table"
  privileges  = ["SELECT", "INSERT", "UPDATE", "DELETE"]

  depends_on = [
    postgresql_role.app_user
  ]
}

resource "postgresql_grant" "revoke_public" {
  count       = length(local.databases)
  database    = element(local.databases, count.index)
  role        = local.schema_and_role_name
  schema      = local.schema_and_role_name
  object_type = "schema"
  privileges  = []
}

Error:

 Error: Error revoking role cluster_user from admin: pq: tuple concurrently deleted
│ 
│   with postgresql_grant.app_user_default_privileges_table[0],
│   on ../xxxx/xxxx.tf line XXX, in resource "postgresql_default_privileges" "app_user_default_privileges_table":
│  XXX: resource "postgresql_default_privileges" "app_user_default_privileges_table" {
│ 
╵

This error appears only when "terraform apply", and if you do a restart (repeat command "terraform apply"), then it can be applied without this problems.

me0wbear avatar May 24 '22 19:05 me0wbear

Having the same issue.

busla avatar Mar 07 '24 13:03 busla