terraform destroy无法删除postgresql数据库

时间:2019-08-06 09:30:44

标签: postgresql terraform

我的 Terraform 脚本愉快地创建了具有三个数据库的 Postgresql 实例以及具有三个部署的 Kubernetes 集群。效果很好。当我运行销毁时,它几乎可以工作,但是当使用此方法删除一个数据库实例时,它会失败

Error: Error reading Database: googleapi: Error 400: Invalid request: Failed to delete database "xyz". Detail: pq: database "xyz" is being accessed by other users. (Please use psql client to delete database that is not owned by "cloudsqlsuperuser")
., invalid

Terraform 已报告使用该数据库的k8容器已被破坏(实际上所有容器已被破坏),并且没有其他人可以访问该数据库。第二次尝试运行destroy可以成功删除数据库,这表明这里不需要括号中的建议。

我怀疑吊舱的挂起时间超过了 Terraform 的预期,并且它报告了吊舱的毁灭很快。我当然在那里有一些标志,以防止豆荚关闭得太快。但是我还没有找到一种方法来延迟或重试 Terraform对数据库销毁的处理。

有办法吗?

这是创建我的数据库的 Terraform ,当然也会破坏它们。

resource "random_id" "db_name_suffix" {
  byte_length = 4
}

data "http" "myip" {
  url = "http://ipv4.icanhazip.com"
}

data "null_data_source" "my_ip_allowed" {
  inputs = {
    name  = "tf"
    value = chomp(data.http.myip.body)
  }
}

resource "google_sql_database_instance" "master" {
  name             = "${var.environment}-sql-${random_id.db_name_suffix.hex}"
  database_version = "POSTGRES_11"
  region           = var.region

  settings {
    tier             = "db-custom-1-3840"
    disk_autoresize  = "true"
    disk_size        = "10"
    disk_type        = "PD_SSD"
    replication_type = "SYNCHRONOUS"
    pricing_plan     = "PER_USE"
    ip_configuration {
      ipv4_enabled    = "true"
      private_network = "projects/${var.project}/global/networks/default"
      require_ssl     = "false"
      authorized_networks {
        name = "creatorIP"
        value = chomp(data.http.myip.body)
      }
    }
  }

  # Generate the DDL scripts that will be used when the databases are created.
  # and change the postgres password  
  provisioner "local-exec" {
    command = "chmod +x ddlsetup.sh && ./ddlsetup.sh ${google_sql_database_instance.master.name} ${var.dbpassword}"
  }
}

resource "google_sql_database" "xyz" {
  name      = "xyz"
  instance  = google_sql_database_instance.master.name
  charset   = "UTF8"
  collation = "en_US.UTF8"
  provisioner "local-exec" {
    command = "psql -h ${google_sql_database_instance.master.public_ip_address} -p 5432 -U postgres -d xyz -f \"/tmp/xyz-postgres.sql\""
    environment = {
      PGPASSWORD = var.dbpassword
    }
  }
}

resource "google_sql_database" "abc" {
  name      = "abc"
  instance  = google_sql_database_instance.master.name
  charset   = "UTF8"
  collation = "en_US.UTF8"

  provisioner "local-exec" {
    command = "psql -h ${google_sql_database_instance.master.public_ip_address} -p 5432 -U postgres -d abc -f \"/tmp/abc-postgres.sql\""
    environment = {
      PGPASSWORD = var.dbpassword
    }
  }
}

resource "google_sql_database" "jkl" {
  name      = "jkl"
  instance  = google_sql_database_instance.master.name
  charset   = "UTF8"
  collation = "en_US.UTF8"
}

output "database_public_ip_address" {
  value = google_sql_database_instance.master.public_ip_address
}

1 个答案:

答案 0 :(得分:0)

我将使用graph来查看执行计划的视觉表示。

terraform graph -type=plan-destroy

输出将为DOT格式,您可以使用dot使用GraphViz来生成图表并转换为图像:

terraform graph -type=plan-destroy | dot -Tsvg > graph.svg

知道这是问题之后,我将向您的资源中添加一个dependencies

# New resource for the S3 bucket our application will use.
resource "aws_s3_bucket" "example" {
  # NOTE: S3 bucket names must be unique across _all_ AWS accounts, so
  # this name must be changed before applying this example to avoid naming
  # conflicts.
  bucket = "terraform-getting-started-guide"
  acl    = "private"
}

# Change the aws_instance we declared earlier to now include "depends_on"
resource "aws_instance" "example" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"

  # Tells Terraform that this EC2 instance must be created only after the
  # S3 bucket has been created.
  depends_on = [aws_s3_bucket.example]
}