Closed12

はじめての HA Cloud SQL (by Terraform Module)

sogaohsogaoh

エラーの数々

sogaohsogaoh

gcloud config set account ACCOUNT をちゃんとし忘れてて

Error: Error, failed to create instance because the network doesn't have at least 1 private services connection. Please see https://cloud.google.com/sql/docs/mysql/private-ip#network_requirements for how to create this connection.
│
│   with module.pgsql_db.google_sql_database_instance.default,
│   on .terraform/modules/pgsql_db/modules/postgresql/main.tf line 44, in resource "google_sql_database_instance" "default":
│   44: resource "google_sql_database_instance" "default" {

ところでどうして mysql なんでしょう?
postgres のほうを見ましたけど。
https://cloud.google.com/sql/docs/postgres/private-ip#network_requirements

sogaohsogaoh

https://cloud.google.com/sql/pricing?hl=ja#instance-pricing
にあった HA db-g1-small を指定したら「 そんなのないよ そいつはおかしいよ」と。。。

Error: Error, failed to create instance production-${PROJECT}-pgsql-db: googleapi: Error 400: Invalid request: Tier (HA db-g1-small)., invalid
│
│   with module.pgsql_db.google_sql_database_instance.default,
│   on .terraform/modules/pgsql_db/modules/postgresql/main.tf line 44, in resource "google_sql_database_instance" "default":
│   44: resource "google_sql_database_instance" "default" {

https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1beta4/tiers/list
から API でリストして db-n1-standard-1 でいってみようと思いました。

https://cloud.google.com/sql/docs/postgres/instance-settings?hl=ja
から料金計算ツールなるものを見つけたりもしました。(そこにかいてある tier はたぶん指定できない・・・)

https://cloud.google.com/products/calculator?hl=ja

sogaohsogaoh

Only custom machine instance type and shared-core instance type allowed for PostgreSQL database.
なるほど...

Error: Error, failed to create instance production-${PROJECT}-pgsql-db: googleapi: Error 400: Invalid request: Only custom machine instance type and shared-core instance type allowed for PostgreSQL database., invalid
│
│   with module.pgsql_db.google_sql_database_instance.default,
│   on .terraform/modules/pgsql_db/modules/postgresql/main.tf line 44, in resource "google_sql_database_instance" "default":
│   44: resource "google_sql_database_instance" "default" {
sogaohsogaoh

ひとまず構築に成功したので調整していく

sogaohsogaoh

https://cloud.google.com/sql/docs/postgres/create-instance?hl=ja#machine-types
に従って db-custom-2-5120 を指定したところ作成成功。

sqldb.tf
# refs https://github.com/terraform-google-modules/terraform-google-sql-db
# refs https://github.com/terraform-google-modules/terraform-google-sql-db/tree/master/modules/private_service_access
# refs https://github.com/terraform-google-modules/terraform-google-sql-db/tree/master/modules/postgresql

module "private_service_access" {
  source  = "GoogleCloudPlatform/sql-db/google//modules/private_service_access"

  prefix_length = 20

  project_id = var.gcp_project_id
  vpc_network = var.vpc_network_name   # module.vpc.network_name
}

module "pgsql_db" {
  source  = "GoogleCloudPlatform/sql-db/google//modules/postgresql"
  #version = "8.0.0"

  project_id = var.gcp_project_id
  region     = var.region
  zone       = var.zone_a

  name = "production-${var.project}-pgsql-db"

  tier = "db-custom-2-5120"   # "db-n1-standard-1"  //productionのtier

  database_version = "POSTGRES_14"
  db_name       = var.db_name
  user_name     = var.db_user_name
  user_password = var.db_user_password

  backup_configuration = {
    enabled = true        //productionはtrue
    start_time = "17:00"   //UTC. JSTでは 2:00 //productionはset
    location = var.region
    point_in_time_recovery_enabled = true   //productionはtrue
    transaction_log_retention_days = 3
    retained_backups = 5                    //productionはset
    retention_unit   = "COUNT"
  }

  disk_autoresize = true
  disk_size = 16
  disk_type = "PD_SSD"

  #module_depends_on = [module.private_service_access]
  ip_configuration = {
    authorized_networks = [
#      {
#        name  = ""
#        value = ""
#      }
    ]
    ipv4_enabled = true
    private_network = var.vpc_network_self_link  # module.vpc.network_self_link
    require_ssl = false
    allocated_ip_range = null
  }

  insights_config = {
      query_string_length = 1024
      record_application_tags = true
      record_client_address = true
  }

  user_labels = {
    proj = var.project
    env  = var.environment
  }
}
sogaohsogaoh

ひと通り Cloud Run まで構築して疎通確認してから堅牢化(private ip)と冗長化することにした。

で、Redis を構築したが、どうやら単一系っぽい。。これも後で冗長化を・・・

redis.tf


# refs https://github.com/terraform-google-modules/terraform-google-memorystore

module "memorystore_redis" {
  source  = "terraform-google-modules/memorystore/google"
  #version = "4.1.0"

  project = var.gcp_project_id
  region  = var.region
  location_id = var.zone_a
  authorized_network = var.vpc_network_name   # module.vpc.network_name

  name    = "production-${var.project}-redis-cache"

  connect_mode = "PRIVATE_SERVICE_ACCESS"
  transit_encryption_mode = "DISABLED"  # "SERVER_AUTHENTICATION"

  tier = "STANDARD_HA"
  alternative_location_id = var.zone_c

  redis_version = "REDIS_6_X"
  #redis_configs = {
  #}

  memory_size_gb = 4

  labels = {
    proj = var.project
    env  = var.environment
  }
}

tier = "STANDARD_HA" にして
alternative_location_id = var.zone_c とするだけじゃあダメなのね・・・

あとで↓も読む・・・
https://cloud.google.com/memorystore/docs/redis/read-replicas

sogaohsogaoh

https://github.com/terraform-google-modules/terraform-google-memorystore
どうやら Module↑ では Redis の READ_REPLICAS_ENABLED にはできないようなので
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/redis_instance#example-usage---redis-instance-mrr
に従って再構築してみようとしたら・・・エラッた

google_redis_instance.memorystore_redis: Creating...
╷
│ Error: Cannot determine region: set in this resource, or set provider-level 'region' or 'zone'.

指定してるんだが・・・

sogaohsogaoh

時間空いたけど、Cloud Memorystore for Redis の冗長化も Cloud SQL の冗長化・堅牢化もできたのでまとめていきます

sogaohsogaoh
Error: Cannot determine region: set in this resource, or set provider-level 'region' or 'zone'.

のエラーは、provider google-beta を goole にして解消

最終的な redis.tf は以下のような内容

redis.tf (冗長化対応版)

# refs https://github.com/terraform-google-modules/terraform-google-memorystore/blob/master/main.tf

module "enable_apis" {
  source  = "terraform-google-modules/project-factory/google//modules/project_services"
  version = "~> 11.0"

  project_id                  = var.project
  enable_apis                 = true
  disable_services_on_destroy = false

  activate_apis = [
    "redis.googleapis.com",
  ]
}


# refs https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/redis_instance

resource google_redis_instance "memorystore_redis" {
  depends_on = [module.enable_apis]

  name = "production-${var.project}-redis-cache"

  tier = "STANDARD_HA"
  memory_size_gb = 5

  location_id = "asia-northeast1-a"
  alternative_location_id = "asia-northeast1-c"

  authorized_network = var.vpc_network_name   # module.vpc.network_name

  redis_version = "REDIS_6_X"
  #redis_configs = {
  #}
  display_name = ""
  reserved_ip_range = null  #var.reserved_ip_range
  replica_count = 1
  read_replicas_mode = "READ_REPLICAS_ENABLED"

  transit_encryption_mode = "DISABLED"  # "SERVER_AUTHENTICATION"
  connect_mode = "PRIVATE_SERVICE_ACCESS"

  maintenance_policy {
    weekly_maintenance_window {
      day = "SATURDAY"
      start_time {  //17:30 UTC : 2:30 JST
        hours = 17
        minutes = 30
        seconds = 0
        nanos = 0
      }
    }
  }

  labels = {
    proj = var.project
    env  = var.environment
  }
}

ポイントとして明記しておきたいのは以下

module では現時点では冗長化 Redis 構築やりきれないようだが、近いうちにやれるようになる気はする

sogaohsogaoh

Cloud SQL の冗長化・堅牢化版 tf

sqldb.tf (example)

# refs https://github.com/terraform-google-modules/terraform-google-sql-db
# refs https://github.com/terraform-google-modules/terraform-google-sql-db/tree/master/modules/private_service_access
# refs https://github.com/terraform-google-modules/terraform-google-sql-db/tree/master/modules/postgresql

module "private_service_access" {
  source  = "GoogleCloudPlatform/sql-db/google//modules/private_service_access"

  prefix_length = 20

  project_id = var.gcp_project_id
  vpc_network = var.vpc_network_name   # module.vpc.network_name
}

module "pgsql_db" {
  source  = "GoogleCloudPlatform/sql-db/google//modules/postgresql"
  #version = "8.0.0"

  project_id = var.gcp_project_id
  region     = var.region
  zone       = var.zone_a

  name = "production-${var.project}-pgsql-db"

  tier = "db-custom-2-5120"   # "db-n1-standard-1"  //productionのtier

  database_version = "POSTGRES_14"
  db_name       = var.db_name
  user_name     = var.db_user_name
  user_password = var.db_user_password

  backup_configuration = {
    enabled = true        //productionはtrue
    start_time = "18:00"   //UTC. JSTでは 3:00 //productionはset
    location = var.region
    point_in_time_recovery_enabled = true   //productionはtrue
    transaction_log_retention_days = 3
    retained_backups = 5                    //productionはset
    retention_unit   = "COUNT"
  }

  disk_autoresize = true
  disk_size = 16
  disk_type = "PD_SSD"

  #module_depends_on = [module.private_service_access]
  ip_configuration = {
    authorized_networks = [
#      {
#        name  = ""
#        value = ""
#      }
    ]
    ipv4_enabled = false    //productionはprivateのみ
    private_network = var.vpc_network_self_link  # module.vpc.network_self_link
    require_ssl = false
    allocated_ip_range = null
  }

  database_flags = [
  ]
  encryption_key_name = null

  maintenance_window_day = 6      //"SATURDAY"
  maintenance_window_hour = 17    //"17:00" UTC. -> JST 2:00

  insights_config = {
      query_string_length = 1024
      record_application_tags = true
      record_client_address = true
  }

  user_labels = {
    proj = var.project
    env  = var.environment
  }

  ################################################################
  # HA
  ################################################################
  availability_type = "REGIONAL"

  read_replica_name_suffix = ""
  read_replicas = [
    {
      name = ""
      tier = "db-custom-2-5120"   # "db-n1-standard-1"  //productionのtier
      zone = var.zone_c
      disk_autoresize = true
      disk_size = 16
      disk_type = "PD_SSD"
      ip_configuration = {
        authorized_networks = [
        #      {
        #        name  = ""
        #        value = ""
        #      }
        ]
        ipv4_enabled = false    //productionはprivateのみ
        private_network = var.vpc_network_self_link  # module.vpc.network_self_link
        require_ssl = false
        allocated_ip_range = null
      }
      database_flags = [
      ]
      encryption_key_name = null
      user_labels = {
        proj = var.project
        env  = var.environment
      }
    }
  ]
}

堅牢化のポイントは、ip_configuration の ipv4_enabled = false にする、っぽいです。
冗長化のポイントは、availability_type = "REGIONAL" にして read_replica の設定を write インスタンスと同様にかく、なのかなと思いました。

このスクラップは2022/05/01にクローズされました