Управление YDB с помощью Terraform

С помощью Terraform можно создавать, удалять и изменять следующие объекты внутри кластера YDB:

Важно

На данный момент YDB провайдер для Terraform находится на стадии разработки и его функциональность будет расширяться.

Для начала работы необходимо:

  1. Развернуть кластер YDB
  2. Создать базу данных (описано в п.1 для соответствующего типа развертывания кластера)
  3. Установить Terraform
  4. Установить и настроить Terraform provider for YDB

Настройка Terraform провайдера для работы с YDB

  1. Нужно скачать код провайдера

  2. Собрать провайдер, выполнив $ make local-build в корневой директории кода провайдера. Для этого вам необходимо дополнительно установить утилиту make и go
    Провайдер установится в папку плагинов Terraform - ~/.terraform.d/plugins/terraform.storage.ydb.tech/...

  3. Добавить провайдер в ~/.terraformrc, дописав в секцию provider_installation следующее содержание (если такой секции ещё не было, то создать):

    provider_installation {
      direct {
        exclude = ["terraform.storage.ydb.tech/*/*"]
      }
    
      filesystem_mirror {
        path    = "/PATH_TO_HOME/.terraform.d/plugins"
        include = ["terraform.storage.ydb.tech/*/*"]
      }
    }
    
  4. Далее настраиваем сам YDB провайдер для работы (например в файле provider.tf в рабочей директории):

    terraform {
      required_providers {
        ydb = {
          source = "terraform.storage.ydb.tech/provider/ydb"
        }
      }
      required_version = ">= 0.13"
    }
    
    provider "ydb" {
      token = "<TOKEN>"
      //OR for static credentials
      user = "<USER>"
      password = "<PASSWORD>"
    }
    

Где:

  • token - указывается токен доступа к БД, если используется аутентификация, например, с использованием стороннего IAM провайдера.
  • user - имя пользователя для доступа к базе данных в случае использования аутентификации по логину и паролю
  • password - пароль для доступа к базе данных в случае использования аутентификации по логину и паролю

Использование Terraform провайдера YDB

Для применения изменений в terraform ресурсах используются следующие команды:

  1. terraform init - инициализация модуля terraform (выполняется в директории ресурсов terraform).
  2. terraform validate - проверка синтаксиса конфигурационных файлов ресурсов terraform.
  3. terraform apply - непосредственное применение конфигурации ресурсов terraform.

Для удобства использования файлы terraform рекомендуется именовать следующим образом:

  1. provider.tf - содержит настройки самого terraform провайдера.
  2. main.tf - содержит набор ресурсов для создания.

Соединение с базой данных (БД)

Для всех ресурсов, описывающих объекты схемы данных, необходимо задать реквизиты БД, в которой они размещаются. Для этого укажите один из двух аргументов:

  • Строка соединения connection_string — выражение вида grpc(s)://HOST:PORT/?database=/database/path, где grpc(s)://HOST:PORT/ эндпоинт, а /database/path — путь БД.
    Например, grpcs://example.com:2135?database=/Root/testdb0.
  • database_endpoint - используется при работе с ресурсом топиков (аналог connection_string при работе с ресурсами таблиц).

Примечание

Если требуется, пользователь может передавать строку соединения с БД стандартными средствами Terraform - через variables.

Если вы используете создание ресурсов ydb_table_changefeed или ydb_topic и на сервере YDB не включена авторизация, то в конфиге БД config.yaml нужно указать:

...
pqconfig:
  require_credentials_in_new_protocol: false
  check_acl: false

Пример использования всех типов ресурсов YDB Terraform провайдера

Данный пример объединяет все типы ресурсов, которые доступны в YDB Terraform провайдере:

variable "db-connect" {
  type = string
  default = "grpc(s)://HOST:PORT/?database=/database/path" # нужно указать путь к базе данных
}

resource "ydb_table" "table" {
  path        = "1/2/3/tftest"
  connection_string = var.db-connect
  column {
    name = "a"
    type = "Utf8"
  }
  column {
    name = "b"
    type = "String"
  }
  column {
    name = "ttlBase"
    type = "Uint32"
  }
  ttl {
    column_name = "ttlBase"
    expire_interval = "P7D"
    unit = "milliseconds"
  }

  primary_key = ["b", "a"]

  partitioning_settings {
    auto_partitioning_min_partitions_count = 5
    auto_partitioning_max_partitions_count = 8
    auto_partitioning_partition_size_mb    = 256
    auto_partitioning_by_load              = true
  }
}

resource "ydb_table_index" "table_index" {
  table_path        = ydb_table.table.path
  connection_string = ydb_table.table.connection_string
  name              = "my_index"
  type              = "global_sync" # "global_async"
  columns           = ["a", "b"]

  depends_on = [ydb_table.table] # ссылка на ресурс создания таблицы
}

resource "ydb_table_changefeed" "table_changefeed" {
  table_id = ydb_table.table.id
  name     = "changefeed"
  mode     = "NEW_IMAGE"
  format   = "JSON"
  consumer {
    name = "test"
    supported_codecs = ["raw", "gzip"]
  }

  depends_on = [ydb_table.table] # ссылка на ресурс создания таблицы
}

resource "ydb_topic" "test" {
  database_endpoint = ydb_table.table.connection_string
  name              = "1/2/test"
  supported_codecs  = ["zstd"]

  consumer {
    name             = "test-consumer3"
    starting_message_timestamp_ms = 0
    supported_codecs = ["zstd","raw"]
  }

  consumer {
    name             = "test-consumer1"
    starting_message_timestamp_ms = 2000
    supported_codecs = ["zstd"]
  }

  consumer {
    name             = "test-consumer2"
    starting_message_timestamp_ms = 0
    supported_codecs = ["zstd"]
  }
}

Ниже будут подробно расписаны все ресурсы YDB Terraform провайдера

Строковая таблица

Примечание

Работа с колоночными таблицами через Terraform пока не доступна.

Для работы с таблицами используется ресурс ydb_table.

Пример:

  resource "ydb_table" "ydb_table" {
    path = "path/to/table" # путь относительно корня базы
    connection_string = "grpc(s)://HOST:PORT/?database=/database/path" #пример подключения к БД
    column {
      name = "a"
      type = "Utf8"
      not_null = true
    }
    column {
      name = "b"
      type = "Uint32"
      not_null = true
    }
    column {
      name = "c"
      type = String
      not_null = false
    }
    column {
      name = "f"
      type = "Utf8"
    }
    column {
      name = "e"
      type = "String"
    }
    column {
      name = "d"
      type = "Timestamp"
    }
    primary_key = ["b", "a"]
  }

Поддерживаются следующие аргументы:

  • path — (обязательный) путь таблицы, относительно корня базы (пример - /path/to/table).

  • connection_string — (обязательный) строка соединения.

  • column — (обязательный) свойства колонки (см. аргумент column).

  • family — (необязательный) группа колонок (см. аргумент family).

  • primary_key — (обязательный) первичный ключ таблицы, содержит упорядоченный список имён колонок первичного ключа.

  • ttl — (необязательный) TTL (см. аргумент ttl).

  • partitioning_settings — (необязательный) настройки партицирования (см. аргумент partitioning_settings).

  • key_bloom_filter — (необязательный) (bool) использовать фильтра Блума для первичного ключа, значение по умолчанию - false.

  • read_replicas_settings — (необязательный) настройки реплик для чтения.

column

Аргумент column описывает свойства колонки таблицы.

Важно

При помощи Terraform нельзя удалить колонку, можно только добавить. Чтобы удалить колонку, используйте средства YDB, затем удалите колонку из описания ресурса. При попытке "прокатки" изменений колонок таблицы (смена типа, имени), Terraform не попытается их удалить, а попытается сделать update-in-place, но изменения применены не будут.

Пример:

column {
  name     = "column_name"
  type     = "Utf8"
  family   = "some_family"
  not_null = true
}
  • name — (обязательный) имя колонки.
  • type — (обязательный) тип данных YQL колонки. Допускается использовать простые типы колонок. Как пример, контейнерные типы не могут быть использованы в качестве типов данных колонок таблиц.
  • family — (необязательный) имя группы колонок (см. аргумент family).
  • not_null — (необязательный) колонка не может содержать NULL. Значение по умолчанию: false.

family

Аргумент family описывает свойства группы колонок.

Пример:

family {
  name        = "my_family"
  data        = "ssd"
  compression = "lz4"
}

partitioning_settings

Аргумент partitioning_settings описывает настройки партицирования.

Пример:

partitioning_settings {
  auto_partitioning_min_partitions_count = 5
  auto_partitioning_max_partitions_count = 8
  auto_partitioning_partition_size_mb    = 256
  auto_partitioning_by_load              = true
}

Подробнее про параметры и их значения по умолчанию написано по ссылкам выше.

ttl

Аргумент ttl описывает настройки Time To Live.

Пример:

ttl {
  column_name     = "column_name"
  expire_interval = "PT1H" # 1 час
  unit            = "seconds" # для числовых типов колонок (non ISO 8601)
}
  • column_name — (обязательный) имя колонки для TTL.
  • expire_interval — (обязательный) интервал в формате ISO 8601 (например, P1D — интервал длиной в 1 сутки, то есть 24 часа).
  • unit — (необязательный) задается в случае, если колонка с ttl имеет числовой тип. Поддерживаемые значения:
    • seconds
    • milliseconds
    • microseconds
    • nanoseconds

Вторичный индекс таблицы

Для работы с индексом таблицы используется ресурс ydb_table_index.

Пример:

resource "ydb_table_index" "ydb_table_index" {
  table_path        = "path/to/table" # путь относительно корня базы
  connection_string = "grpc(s)://HOST:PORT/?database=/database/path" #пример подключения к БД
  name              = "my_index"
  type              = "global_sync" # "global_async"
  columns           = ["a", "b"]
  cover             = ["c"]
}

Поддерживаются следующие аргументы:

  • table_path — путь таблицы. Указывается, если не задан table_id.

  • connection_stringстрока соединения. Указывается, если не задан table_id.

  • table_id - terraform-идентификатор таблицы. Указывается, если не задан table_path или connection_string.

  • name — (обязательный) имя индекса.

  • type — (обязательный) тип индекса global_sync | global_async.

  • columns — (обязательный) упорядоченный список имён колонок, участвующий в индексе.

  • cover — (обязательный) список дополнительных колонок для покрывающего индекса.

Поток изменений таблицы

Для работы с потоком изменений таблицы используется ресурс ydb_table_changefeed.

Пример:

resource "ydb_table_changefeed" "ydb_table_changefeed" {
  table_id = ydb_table.ydb_table.id
  name     = "changefeed"
  mode     = "NEW_IMAGE"
  format   = "JSON"
}

Поддерживаются следующие аргументы:

  • table_path — путь таблицы. Указывается, если не задан table_id.

  • connection_stringстрока соединения. Указывается, если не задан table_id.

  • table_id — terraform-идентификатор таблицы. Указывается, если не задан table_path или connection_string.

  • name — (обязательный) имя потока изменений.

  • mode — (обязательный) режим работы потока изменений.

  • format — (обязательный) формат потока изменений.

  • virtual_timestamps — (необязательный) использование виртуальных таймстеймпов.

  • retention_period — (необязательный) время хранения данных в формате ISO 8601.

  • consumer — (необязательный) читатель потока изменений (см. аргумент #consumer).

consumer

Аргумент consumer описывает читателя потока изменений.

  • name — (обязательный) имя читателя.
  • supported_codecs — (необязательный) поддерживаемые кодек данных.
  • starting_message_timestamp_ms — (необязательный) временная метка в формате UNIX timestamp в миллисекундах, с которой читатель начнет читать данные.

Примеры использования

Создание таблицы в существующей БД

resource "ydb_table" "ydb_table" {
  # Путь до таблицы
  path = "path/to/table" # путь относительно корня базы

  connection_string = "grpc(s)://HOST:PORT/?database=/database/path" #пример подключения к БД

  column {
    name = "a"
    type = "Uint64"
    not_null = true
  }
  column {
    name     = "b"
    type     = "Uint32"
    not_null = true
  }
  column {
    name = "c"
    type = String
    not_null = false
  }
  column {
    name = "f"
    type = "Utf8"
  }
  column {
    name = "e"
    type = "String"
  }
  column {
    name = "d"
    type = "Timestamp"
  }
  # Первичный ключ
  primary_key = [
    "a", "b"
  ]
}

Создание таблицы, индекса и потока изменений

resource "ydb_table" "ydb_table" {
  # Путь до таблицы
  path = "path/to/table" # путь относительно корня базы
  
  # ConnectionString до базы данных.
  connection_string = "grpc(s)://HOST:PORT/?database=/database/path" #пример подключения к БД

  column {
    name = "a"
    type = "Uint64"
    not_null = true
  }
  column {
    name     = "b"
    type     = "Uint32"
    not_null = true
  }
  column {
    name = "c"
    type = "Utf8"
  }
  column {
    name = "f"
    type = "Utf8"
  }
  column {
    name = "e"
    type = "String"
  }
  column {
    name = "d"
    type = "Timestamp"
  }

  # Первичный ключ
  primary_key = [
    "a", "b"
  ]


  ttl {
    column_name     = "d"
    expire_interval = "PT5S"
  }

  partitioning_settings {
    auto_partitioning_by_load = false
    auto_partitioning_partition_size_mb    = 256
    auto_partitioning_min_partitions_count = 6
    auto_partitioning_max_partitions_count = 8
  }

  read_replicas_settings = "PER_AZ:1"

  key_bloom_filter = true # Default = false
}

resource "ydb_table_changefeed" "ydb_table_changefeed" {
  table_id = ydb_table.ydb_table.id
  name = "changefeed"
  mode = "NEW_IMAGE"
  format = "JSON"

  consumer {
    name = "test_consumer"
  }

  depends_on = [ydb_table.ydb_table] # ссылка на ресурс создания таблицы
}

resource "ydb_table_index" "ydb_table_index" {
  table_id = ydb_table.ydb_table.id
  name = "some_index"
  columns = ["c", "d"]
  cover = ["e"]
  type = "global_sync"

  depends_on = [ydb_table.ydb_table] # ссылка на ресурс создания таблицы
}

Управление конфигурацией топиков YDB через Terraform

Для работы с топиками используется ресурс ydb_topic

Примечание

Топик не может быть создан в корне БД, нужно указать хотя бы один каталог в имени топика. При попытке создать топик в корне БД - провайдер выдаст ошибку.

Описание ресурса ydb_topic

Пример:

resource "ydb_topic" "ydb_topic" {
  database_endpoint = "grpcs://example.com:2135/?database=/Root/testdb0" #пример подключения к БД
  name              = "test/test1"
  supported_codecs  = ["zstd"]

  consumer {
    name             = "test-consumer1"
    starting_message_timestamp_ms = 0
    supported_codecs = ["zstd","raw"]
  }

  consumer {
    name             = "test-consumer2"
    starting_message_timestamp_ms = 2000
    supported_codecs = ["zstd"]
  }

  consumer {
    name             = "test-consumer3"
    starting_message_timestamp_ms = 0
    supported_codecs = ["zstd"]
  }
}

Поддерживаются следующие аргументы:

  • name - (обязательный) имя топика.
  • database_endpoint - (обязательный) полный путь до базы данных, например: "grpcs://example.com:2135/?database=/Root/testdb0"; аналог connection_string для таблиц.
  • retention_period_ms - длительность хранения данных в миллисекундах, значение по умолчанию - 86400000 (сутки).
  • partitions_count - количество партиций, значение по умолчанию - 2.
  • supported_codecs - поддерживаемые кодеки сжатия данных, значение по умолчанию - "gzip", "raw", "zstd".
  • consumer - читатели для топика.

Описание потребителя данных consumer:

  • name - (обязательное) имя читателя.
  • supported_codecs - поддерживаемые кодировки сжатия данных, по умолчанию - "gzip", "raw", "zstd".
  • starting_message_timestamp_ms - временная метка в формате UNIX timestamp в миллисекундах, с которой читатель начнёт читать данные, по умаолчанию - 0, то есть с начала поставки.