postgresql - terraform destroy 无法删除 postgresql 数据库
问题描述
我的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 pod 已被销毁(实际上所有 pod 都已被销毁),并且没有其他任何东西可以访问该数据库。再次尝试运行 destroy 成功删除了数据库,这表明这里不需要括号中的建议。
我怀疑 pod 的挂起时间比Terraform预期的要长,并且它很快报告了 pod 的破坏。我当然有一些标志来防止吊舱关闭得太快。但是我还没有找到一种方法来延迟或重试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
}
解决方案
我会使用图表来查看执行计划的可视化表示。
terraform graph -type=plan-destroy
输出将采用 DOT 格式,您可以使用GraphViz生成图表并通过以下方式转换为图像dot
:
terraform graph -type=plan-destroy | dot -Tsvg > graph.svg
在知道这是问题后,我会向您的资源添加依赖项。
# 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]
}
推荐阅读
- swift - 我可以在 Swift 中使用 Spark AR 导出吗?“.arexport”
- c++ - 在枚举中设置位标志的最简单方法是什么?
- javascript - 在 HTML5 Canvas 中绘制一致的手绘虚线
- node.js - npm 不安装任何包无法读取 null 的属性“版本”
- c++ - 即使在指定 OpenCV_DIR 之后,CMake 也找不到 OpenCVConfig.cmake
- python - 带有 ListedColormap 的 Matplotlib imshow 在边界上显示错误的颜色
- angular - Angular - 为什么“[selected]”在一个案例中有效,但在另一个案例中无效?
- math - 如何在Godot中最长的路线或路径的2个角度之间进行LERP
- html - 如何使用 html 和 css 使我的应用程序底部菜单全宽?
- javascript - 我是 React Native 的新手,并试图弄清楚如何在我的应用程序中使用自定义字体,这是我得到的错误: