Automação de bancos com Ansible
Sintoma
Objetivo: tornar repetíveis e idempotentes (rodar o mesmo playbook de novo não quebra o sistema) as tarefas de instalação, configuração, usuários e backup de bancos com Ansible.
1. Defina o inventário e os grupos
Agrupe os servidores no inventário por papel no banco; coloque servidores primários, réplicas e de backup em grupos separados. Use um inventário estático INI/YAML ou um inventário dinâmico para a nuvem (aws_ec2, gcp_compute). Coloque as variáveis de grupo em group_vars/ e as específicas de host em host_vars/.
PostgreSQL
[pg_primary]
db1.example.local
[pg_replica]
db2.example.local
[postgres:children]
pg_primary
pg_replica2. Instale a collection certa (community.postgresql / community.mysql / community.mongodb)
O Ansible core agora distribui os módulos de banco em collections separadas; instale a collection do seu engine via requirements.yml. Use community.postgresql (postgresql_db, postgresql_user, postgresql_privs) para PostgreSQL, community.mysql (mysql_db, mysql_user) para MySQL/MariaDB e community.mongodb para MongoDB. O cliente Python correspondente (psycopg2, PyMySQL, pymongo) precisa estar instalado no host de destino.
PostgreSQL
# requirements.yml
collections:
- name: community.postgresql
# install:
ansible-galaxy collection install -r requirements.ymlMySQL
collections:
- name: community.mysqlMongoDB
collections:
- name: community.mongodb3. Criptografe os segredos com Ansible Vault
Não deixe senhas de banco, segredos de replicação e credenciais de superusuário em texto puro; mantenha-os em um arquivo de variáveis criptografado com ansible-vault. Descriptografe em tempo de execução com --ask-vault-pass ou --vault-password-file. Assim os segredos podem ficar com segurança no Git e o playbook continua idempotente.
PostgreSQL
ansible-vault create group_vars/postgres/vault.yml
# contents:
vault_pg_admin_password: "S3cret!"
# run:
ansible-playbook site.yml --ask-vault-pass4. Monte a estrutura de roles (roles/postgres, roles/mysql)
Crie uma role por engine e divida a lógica nas subpastas tasks/, defaults/, templates/ e handlers/. Essa estrutura melhora a reutilização: defaults/main.yml para valores padrão, templates/ para templates de configuração jinja2, handlers/ para a lógica 'reiniciar só se algo mudou'. Você pode criar o esqueleto da role com ansible-galaxy init roles/postgres.
PostgreSQL
ansible-galaxy init roles/postgres
# roles/postgres/
# defaults/main.yml
# tasks/main.yml
# templates/postgresql.conf.j2
# handlers/main.yml5. Escreva as tarefas de instalação e configuração de forma idempotente
Instale o pacote, inicialize o diretório de dados e gere postgresql.conf/my.cnf a partir de um template; reinicie o serviço via handler quando a configuração mudar. Os módulos são idempotentes: um pacote já instalado não é reinstalado, e o handler não é disparado se o arquivo não mudou. Gere o template de configuração com o módulo template e ligue-o ao handler com 'notify'.
PostgreSQL
- name: postgresql.conf template
ansible.builtin.template:
src: postgresql.conf.j2
dest: /etc/postgresql/16/main/postgresql.conf
notify: restart postgresql
# handlers/main.yml
- name: restart postgresql
ansible.builtin.service:
name: postgresql
state: restartedMySQL
- name: my.cnf template
ansible.builtin.template:
src: my.cnf.j2
dest: /etc/mysql/my.cnf
notify: restart mysql6. Defina as tarefas de banco e de usuários
Crie o banco, os usuários e os privilégios com módulos; pegue a senha de uma variável do Vault. Os módulos community.postgresql são idempotentes: se o usuário/banco existir, não o recriam, aplicam só a diferença. Conceda privilégios à parte com postgresql_privs; no MySQL usa-se o campo priv do mysql_user.
PostgreSQL
- name: application database
community.postgresql.postgresql_db:
name: appdb
state: present
- name: application user
community.postgresql.postgresql_user:
name: app_user
password: "{{ vault_app_password }}"
db: appdb
state: presentMySQL
- name: application user
community.mysql.mysql_user:
name: app_user
password: "{{ vault_app_password }}"
priv: 'appdb.*:ALL'
state: present7. Adicione a tarefa de backup e o agendamento
Implante o script de backup a partir de um template e agende-o com ansible.builtin.cron; assim o job de backup também é gerenciado como código. Transforme em variáveis o diretório de destino do backup, o período de retenção e o agendamento. O módulo cron é idempotente e identifica a entrada pelo 'name', então rodar de novo não a duplica.
PostgreSQL
- name: nightly backup (cron)
ansible.builtin.cron:
name: "pg dump nightly"
minute: "0"
hour: "2"
job: "pg_dump -Fc appdb > /backup/appdb_$(date +\\%F).dump"