使用Terraform为Google Cloud SQL PostgreSQL数据库创建架构

时间:2019-10-14 21:51:38

标签: postgresql terraform google-cloud-sql terraform-provider-gcp

我是Terraform的新手,我想为在Google云端SQL上的PostgreSQL 9.6实例上创建的postgres数据库创建架构。

要创建PostgreSQL实例,请在main.tf上添加它:

resource "google_sql_database_instance" "my-database" {
  name = "my-${var.deployment_name}"
  database_version = "POSTGRES_9_6"
  region = "${var.deployment_region}"

  settings {
      tier = "db-f1-micro"
      ip_configuration {
          ipv4_enabled = true
      }
  }
}

我正在尝试创建一个PostgreSQL对象,如下所示:

provider "postgresql" {
  host            = "${google_sql_database_instance.my-database.ip_address}"
  username        = "postgres"
}

最后创建模式:

resource "postgresql_schema" "my_schema" {
  name  = "my_schema"
  owner = "postgres"
}

但是,此配置不起作用,我们运行terraform plan

Inappropriate value for attribute "host": string required.

如果我删除了Postgres对象:

Error: Error initializing PostgreSQL client: error detecting capabilities: error PostgreSQL version: dial tcp :5432: connect: connection refused

此外,我想为用户postgres添加一个密码,该密码是在创建PostgreSQL实例时默认创建的。

已编辑: 使用的版本

Terraform v0.12.10
+ provider.google v2.17.0
+ provider.postgresql v1.2.0

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

您在上面设置的Terraform存在一些问题。

  1. 您的实例未定义任何授权网络。您应该将实例资源更改为以下形式:(注意:我仅将0.0.0.0/0用于测试目的)
    resource "google_sql_database_instance" "my-database" {
      name = "my-${var.deployment_name}"
      database_version = "POSTGRES_9_6"
      region = "${var.deployment_region}"

      settings {
          tier = "db-f1-micro"
          ip_configuration {
            ipv4_enabled = true
            authorized_networks {
              name = "all"
              value = "0.0.0.0/0"
            }
          }
      }
      depends_on = [
        "google_project_services.vpc"
      ]
    }
  1. here所述,您需要使用强密码创建用户
resource "google_sql_user" "user" {
  name     = "test_user"
  instance = "${google_sql_database_instance.my-database.name}"
  password = "VeryStrongPassword"

  depends_on = [
    "google_sql_database_instance.my-database"
  ]
}
  1. 您应该使用实例的“ public_ip_address”或“ ip_address.0.ip_address”属性来访问IP地址。另外,您应该更新您的提供程序和架构资源,以反映上面创建的用户。
provider "postgresql" {
  host            = "${google_sql_database_instance.my-database.public_ip_address}"
  username        = "${google_sql_user.user.name}"
  password        = "${google_sql_user.user.password}"
}

resource "postgresql_schema" "my_schema" {
  name  = "my_schema"
  owner = "test_user"
}
  1. 您的postgres提供程序取决于能否设置提供程序取决于google_sql_database_instance资源:

所有提供程序都在计划/应用程序开始时初始化,因此,如果一个提供程序的配置无效(在这种情况下为空主机),则Terraform将失败。 无法定义提供商与提供商之间的依赖关系 另一个提供程序中的资源。 但是,可以使用target parameter

来解决 terraform apply -target=google_sql_user.user

这将创建数据库用户(及其所有依赖项-在本例中为数据库实例),并在完成后跟随它:

terraform apply

然后应该成功,因为已经创建了实例,并且postgres提供程序可以使用ip_address。

最终提示:对于生产实例,建议不要使用没有SSL的公共IP地址来连接Cloud SQL实例。

答案 1 :(得分:0)

这是我的解决方案,通过这种方式,我只需要运行:terraform apply

// POSTGRESQL INSTANCE
resource "google_sql_database_instance" "my-database" {
  database_version = "POSTGRES_9_6"
  region = var.deployment_region

  settings {
      tier = var.db_machine_type
      ip_configuration {
          ipv4_enabled = true
          authorized_networks {
              name = "my_ip"
              value = var.db_allowed_networks.my_network_ip
          }
      }
  }
}

// DATABASE USER
resource "google_sql_user" "user" {
  name     = var.db_credentials.db_user
  instance = google_sql_database_instance.my-database.name
  password = var.db_credentials.db_password
  depends_on = [
    "google_sql_database_instance.my-database"
  ]

  provisioner "local-exec" {
    command = "psql postgresql://${google_sql_user.user.name}:${google_sql_user.user.password}@${google_sql_database_instance.my-database.public_ip_address}/postgres -c \"CREATE SCHEMA myschema;\""
  }
}