Перейти к основному содержимому

Автоматизация PostgreSQL — Ansible и Terraform

Инженеру

Раздел 8.11, шаг 12 из 12. Закрепление — итоги, чек-лист.


Infrastructure as Code для БД

Ручная настройка «зайду по SSH и поправлю conf» не масштабируется и не аудируется. IaC даёт:

  • версионирование параметров;
  • повторяемость dev/stage/prod;
  • code review изменений max_connections так же, как кода приложения.

Общая теория — IaC, Terraform, Ansible.


Ansible — bare metal и VM

Типовая role структура:

roles/postgresql/
tasks/main.yml
templates/postgresql.conf.j2
templates/pg_hba.conf.j2
handlers/main.yml
defaults/main.yml

tasks/main.yml (фрагмент):

- name: Install PostgreSQL
ansible.builtin.package:
name: postgresql-16
state: present

- name: Deploy postgresql.conf
ansible.builtin.template:
src: postgresql.conf.j2
dest: "/etc/postgresql/16/main/postgresql.conf"
notify: Restart postgres

- name: Ensure PostgreSQL started
ansible.builtin.service:
name: postgresql
state: started
enabled: true

defaults/main.yml:

postgresql_shared_buffers: 2GB
postgresql_max_connections: 200
postgresql_work_mem: 16MB

Patroni + etcd часто разворачивают отдельными roles (community patroni, etcd). Idempotency — повторный play не ломает данные, если tasks guarded creates: / when:.


Terraform — managed PostgreSQL

Пример AWS RDS (упрощённо):

resource "aws_db_instance" "app" {
identifier = "app-postgres"
engine = "postgres"
engine_version = "16.3"
instance_class = "db.r6g.large"
allocated_storage = 100
max_allocated_storage = 500
storage_encrypted = true

db_name = "appdb"
username = "app"
password = var.db_password

multi_az = true
backup_retention_period = 14
backup_window = "03:00-04:00"

parameter_group_name = aws_db_parameter_group.app.name
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.db.name

deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "app-postgres-final"
}

resource "aws_db_parameter_group" "app" {
family = "postgres16"
parameter {
name = "log_min_duration_statement"
value = "500"
}
parameter {
name = "shared_preload_libraries"
value = "pg_stat_statements"
}
}

Output для приложения:

output "database_url" {
value = "postgres://${aws_db_instance.app.username}:${var.db_password}@${aws_db_instance.app.endpoint}/${aws_db_instance.app.db_name}"
sensitive = true
}

Аналоги — yandex_mdb_postgresql_cluster, google_sql_database_instance, azurerm_postgresql_flexible_server.


Terraform + Kubernetes operator

CloudNativePG cluster как CR через kubernetes_manifest или Helm provider:

resource "helm_release" "cnpg" {
name = "cloudnative-pg"
repository = "https://cloudnative-pg.github.io/charts"
chart = "cloudnative-pg"
namespace = "database"
}

GitOps (Argo CD) хранит manifest Cluster в Git; Terraform создаёт только cluster K8s / VPC / S3 bucket для Wal-G.


Секреты

Anti-patternPattern
password в terraform.tfvars в GitVault, AWS Secrets Manager, SOPS
plain Secret YAML в repoExternal Secrets Operator
один password навсегдаrotation job

Ansible Vault для group_vars/production.yml.


CI/CD для миграций схемы

IaC не заменяет Flyway/Liquibase/Alembic для DDL приложения:

  1. Terraform/Ansible — инстанс, users, extensions, GUC.
  2. Migration tool — schema версионирование в pipeline приложения.

Порядок deploy — migration до rollout app, совместимость backward (expand-contract).


Drift detection

  • terraform plan в CI — изменения в managed DB.
  • Ansible --check или tools вроде databag для сравнения live GUC с template.
  • pg_settings.source — что задано через file vs session.

Практика

  1. Ansible play — установка Postgres 16 на VM, deploy custom postgresql.conf.
  2. Terraform module — RDS или Yandex MDB в dev account, output endpoint.
  3. Pipeline — terraform plan on MR, apply on merge to main с approval.

Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").