193 KiB
Rozumiem, że chcesz przygotować kompletny materiał wdrożeniowy dotyczący integracji następujących narzędzi:
- NinjaOne (NinjaRMM)
- Ansible
- ServiceNow
- Splunk (monitoring)
- SQL Server
- Oracle
- MariaDB
- PostgreSQL
- MySQL
Zanim rozpocznę badanie, chciałbym doprecyzować kilka kwestii, aby lepiej zrozumieć Twoje potrzeby:
- Cel integracji: Czy chcesz zintegrować te narzędzia w ramach jednej platformy zarządzania IT (np. automatyzacja zadań, monitorowanie, zgłaszanie incydentów), czy chodzi o coś innego?
- Zakres materiału wdrożeniowego: Czy interesuje Cię dokumentacja techniczna krok po kroku (np. instalacja, konfiguracja, przykładowe playbooki Ansible, integracja API), czy raczej ogólny przegląd możliwości i architektury?
- Środowisko docelowe: Czy planujesz wdrożenie w środowisku produkcyjnym, testowym, chmurowym (np. Azure, AWS), czy lokalnym (on-premises)?
- Priorytety integracji: Czy któreś z tych narzędzi są kluczowe i powinny być traktowane jako centralne (np. ServiceNow jako główny system zgłoszeń, Ansible jako główny silnik automatyzacji)?
- Odbiorcy materiału: Czy materiał ma być przeznaczony dla zespołu DevOps, administratorów baz danych, działu wsparcia IT, czy może dla wszystkich?
Daj mi znać, jeśli chcesz, żebym od razu przeszedł do przygotowania materiału i użył własnego osądu — wystarczy, że napiszesz „kontynuuj” lub „użyj własnego osądu”.
Implementation Guide: Integrating NinjaOne, Ansible, ServiceNow, Splunk, and Databases (On‑Premises)
<style> :root { --accent: #464feb; --timeline-ln: linear-gradient(to bottom, transparent 0%, #b0beff 15%, #b0beff 85%, transparent 100%); --timeline-border: #ffffff; --bg-card: #f5f7fa; --bg-hover: #ebefff; --text-title: #424242; --text-accent: var(--accent); --text-sub: #424242; --radius: 12px; --border: #e0e0e0; --shadow: 0 2px 10px rgba(0, 0, 0, 0.06); --hover-shadow: 0 4px 14px rgba(39, 16, 16, 0.1); --font: "Segoe Sans", "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; --overflow-wrap: break-word; } @media (prefers-color-scheme: dark) { :root { --accent: #7385ff; --timeline-ln: linear-gradient(to bottom, transparent 0%, transparent 3%, #6264a7 30%, #6264a7 50%, transparent 97%, transparent 100%); --timeline-border: #424242; --bg-card: #1a1a1a; --bg-hover: #2a2a2a; --text-title: #ffffff; --text-sub: #ffffff; --shadow: 0 2px 10px rgba(0, 0, 0, 0.3); --hover-shadow: 0 4px 14px rgba(0, 0, 0, 0.5); --border: #3d3d3d; } } @media (prefers-contrast: more), (forced-colors: active) { :root { --accent: ActiveText; --timeline-ln: ActiveText; --timeline-border: Canvas; --bg-card: Canvas; --bg-hover: Canvas; --text-title: CanvasText; --text-sub: CanvasText; --shadow: 0 2px 10px Canvas; --hover-shadow: 0 4px 14px Canvas; --border: ButtonBorder; } } .insights-container { display: grid; grid-template-columns: repeat(2,minmax(240px,1fr)); padding: 0px 16px 0px 16px; gap: 16px; margin: 0 0; font-family: var(--font); } .insight-card:last-child:nth-child(odd){ grid-column: 1 / -1; } .insight-card { background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); box-shadow: var(--shadow); min-width: 220px; padding: 16px 20px 16px 20px; } .insight-card:hover { background-color: var(--bg-hover); } .insight-card h4 { margin: 0px 0px 8px 0px; font-size: 1.1rem; color: var(--text-accent); font-weight: 600; display: flex; align-items: center; gap: 8px; } .insight-card .icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; font-size: 1.1rem; color: var(--text-accent); } .insight-card p { font-size: 0.92rem; color: var(--text-sub); line-height: 1.5; margin: 0px; overflow-wrap: var(--overflow-wrap); } .insight-card p b, .insight-card p strong { font-weight: 600; } .metrics-container { display:grid; grid-template-columns:repeat(2,minmax(210px,1fr)); font-family: var(--font); padding: 0px 16px 0px 16px; gap: 16px; } .metric-card:last-child:nth-child(odd){ grid-column:1 / -1; } .metric-card { flex: 1 1 210px; padding: 16px; background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); text-align: center; display: flex; flex-direction: column; gap: 8px; } .metric-card:hover { background-color: var(--bg-hover); } .metric-card h4 { margin: 0px; font-size: 1rem; color: var(--text-title); font-weight: 600; } .metric-card .metric-card-value { margin: 0px; font-size: 1.4rem; font-weight: 600; color: var(--text-accent); } .metric-card p { font-size: 0.85rem; color: var(--text-sub); line-height: 1.45; margin: 0; overflow-wrap: var(--overflow-wrap); } .timeline-container { position: relative; margin: 0 0 0 0; padding: 0px 16px 0px 56px; list-style: none; font-family: var(--font); font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container::before { content: ""; position: absolute; top: 0; left: calc(-40px + 56px); width: 2px; height: 100%; background: var(--timeline-ln); } .timeline-container > li { position: relative; margin-bottom: 16px; padding: 16px 20px 16px 20px; border-radius: var(--radius); background: var(--bg-card); border: 1px solid var(--border); } .timeline-container > li:last-child { margin-bottom: 0px; } .timeline-container > li:hover { background-color: var(--bg-hover); } .timeline-container > li::before { content: ""; position: absolute; top: 18px; left: -40px; width: 14px; height: 14px; background: var(--accent); border: var(--timeline-border) 2px solid; border-radius: 50%; transform: translateX(-50%); box-shadow: 0px 0px 2px 0px #00000012, 0px 4px 8px 0px #00000014; } .timeline-container > li h4 { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); } .timeline-container > li h4 em { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); font-style: normal; } .timeline-container > li * { margin: 0; font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container > li * b, .timeline-container > li * strong { font-weight: 600; } @media (max-width:600px){ .metrics-container, .insights-container{ grid-template-columns:1fr; } } </style>🔗 Unified Monitoring & Alerting
NinjaOne RMM agents monitor all database servers and automatically trigger ServiceNow incidents on policy violations or alerts. Meanwhile, Splunk ingests database logs and performance metrics, with critical anomalies also generating ServiceNow events via integration. This ensures no issue goes unnoticed and all alerts are centrally tracked.
🤖 Automation Across All DB Systems
Ansible playbooks automate repetitive DBA tasks (backups, user provisioning, patching) consistently across heterogeneous databases (SQL Server, Oracle, MySQL/MariaDB, PostgreSQL). One playbook can target every engine with appropriate modules or scripts, saving time and eliminating human error.
🗂️ Centralized ITSM & CMDB
ServiceNow acts as the integration hub: it receives incidents from NinjaOne and Splunk, tracks changes, and maintains a unified CMDB. NinjaOne’s bi-directional integration keeps ServiceNow’s CMDB device records updated in real-time, and ServiceNow change requests can trigger or document Ansible automation runs, ensuring all actions are logged and compliant.
🔒 Security, Scalability & Best Practices
Use dedicated service accounts with least-privilege for each integration (e.g. a limited API user on ServiceNow, read-only DB accounts for Splunk). Secure credentials via Ansible Vault and NinjaOne’s built-in secrets management. Patch in phases (avoid updating all cluster nodes at once) and test automation playbooks in a staging environment. Document and version-control everything for maintainability.
1. High-Level Architecture Overview
The integrated solution combines remote monitoring/management, IT automation, IT service management, and observability in a unified workflow for on-premises databases (SQL Server, Oracle, MariaDB, PostgreSQL, MySQL). The diagram below illustrates how these components connect:
! Figure: Integration architecture linking monitoring (NinjaOne, Splunk), automation (Ansible), and ITSM (ServiceNow) with the on-premises database servers. Arrows indicate data flow or automation triggers between components.
-
NinjaOne (RMM) – Deploys lightweight agents on each database server (Windows or Linux). These agents report system health (CPU, memory, disk, etc.) and can enforce policies or run scripts. NinjaOne serves as a central endpoint management and patching platform, orchestrating tasks like OS updates and capturing alerts (e.g. high CPU, low disk space). It’s a cloud-based service (formerly NinjaRMM) that simplifies IT ops by providing remote access, automated patching, and asset inventory.
-
ServiceNow (ITSM) – Manages the incident, problem, and change management processes. It also houses the Configuration Management Database (CMDB) for assets. ServiceNow integrates with NinjaOne so that any alert condition from NinjaOne can automatically open an incident ticket with relevant device details. Likewise, NinjaOne’s device inventory synchronizes into ServiceNow’s CMDB, ensuring up-to-date configuration items. ServiceNow becomes the single source for tracking issues and changes, with technicians working in ServiceNow but able to pivot to NinjaOne for remote endpoint actions (e.g. one-click RDP/remote control from a ticket). [ninjaone.com], [store.servicenow.com] [store.servicenow.com] [ninjaone.com], [ninjaone.com]
-
Splunk (Monitoring & Observability) – Collects and indexes logs and performance metrics from all database servers and related infrastructure. Splunk Universal Forwarders installed on servers (or a centralized collector) send database error logs, audit logs, and OS logs to the Splunk indexer. In addition, Splunk’s DB integration (via Splunk DB Connect and database-specific add-ons) pulls in metrics and status information directly from the databases. For example, the Splunk Add-on for Microsoft SQL Server uses performance counters, Windows event logs, and database audit logs to gather comprehensive data, while the Splunk Add-on for Oracle Database monitors Oracle’s alert logs, trace files, and even queries performance tables via DB Connect. Dashboards in Splunk provide real-time views of database health (query delays, resource utilization, error rates). Splunk can also trigger alerts – e.g. if a database error rate spikes or a host’s disk usage is critical – and thanks to the Splunk Add-on for ServiceNow, those alerts can create or update incidents in ServiceNow automatically via the ServiceNow REST API. [help.splunk.com] [splunk.github.io] [splunk.com], [splunk.com] [help.splunk.com]
-
Ansible (Automation) – Ansible is used as the automation engine to perform routine tasks and changes uniformly across all databases:
- It runs playbooks from a central control node (on-premises Linux VM or Ansible AWX server) over SSH (for Linux servers) or WinRM (for Windows servers running SQL Server).
- The inventory is organized by groups (e.g.
[mysql_servers],[oracle_servers],[postgres_servers],[mssql_servers]) so tasks can target specific DB platforms. - Playbooks can leverage database-specific Ansible modules or roles: for example, the
community.mysqlcollection provides amysql_backupormysql_dbmodule to dump databases,community.postgresqloffers modules for PostgreSQL, and community roles exist for Oracle tasks (or raw SQL/OS commands can be used). Ansible ensures that a task (like “create a new read-only user” or “apply this configuration to all dev databases”) is executed on all relevant servers in one go, using the appropriate method for each DB platform. This reduces error-prone manual work and keeps configurations consistent. [blog.poespas.me]
All components are integrated securely. NinjaOne and Splunk feed data into ServiceNow (either via built-in integration or APIs), and ServiceNow in turn can trigger automation or serve as a single pane of glass. Below, we detail the step-by-step implementation for each part of this architecture.
2. Step-by-Step Installation and Configuration
This section provides step-by-step instructions for setting up each tool and integrating them. The assumption is an on-premises environment for databases and automation, with NinjaOne and ServiceNow as cloud services (requiring internet connectivity for agents and API calls), and Splunk/Ansible deployed on-prem.
2.1 NinjaOne – Deployment and Policy Configuration
Step 2.1.1: Obtain NinjaOne and Deploy Agents. If you don’t already have NinjaOne, start by obtaining an account or deploying the NinjaOne appliance (NinjaOne is primarily cloud-hosted SaaS; on-premises usage involves the same cloud console with agents on your servers). Log in to the NinjaOne web console and add your devices. For each database server, install the NinjaOne agent: this can be done by downloading the installer from the NinjaOne console (available for Windows and Linux) and running it on the server. The agent registers the node with the NinjaOne platform. Ensure each agent shows as “online” in NinjaOne.
Step 2.1.2: Organize Devices into Groups. In NinjaOne, create device groups or tags for easier management. For example, group servers by DB type or environment (e.g. a group for “Production DB Servers”, sub-groups for “SQL Server”, “Oracle”, etc.). This helps in applying policies uniformly (patch schedules, alert thresholds) per group.
Step 2.1.3: Configure Monitoring Alerts. Define monitoring policies in NinjaOne for key metrics:
- Set threshold alerts (conditions) for CPU, memory, disk space, and critical services (e.g. SQL Server service stopped). For instance, configure an alert if CPU > 90% for 5 minutes or if free disk space < 10%.
- NinjaOne allows scripting and custom monitors – for example, you might deploy a PowerShell script via NinjaOne to check SQL Server health and report into NinjaOne. Leverage these to catch database-specific conditions (like “SQL Agent job failed” events forwarded to Windows Event Log, which NinjaOne can monitor).
Step 2.1.4: Configure Automated Patching. Use NinjaOne’s patch management to schedule OS-level patches for the database servers. Best practice is to stagger patching to avoid downtime on all servers at once – e.g., schedule different maintenance windows for different server groups or cluster nodes. NinjaOne can automatically apply Windows Updates or Linux package updates during these windows, and you can include reboots if needed. Confirm patch policies are assigned to all servers (servers with no policy won’t get updates). For database software patches (like Oracle PSU or SQL Server cumulative updates), you might handle those via Ansible or manual processes – but document in NinjaOne when they’re done for inventory accuracy. [ninjaone.com]
Step 2.1.5: Integration with ServiceNow – API Credentials. To integrate NinjaOne with ServiceNow, first set up credentials on the ServiceNow side:
- In ServiceNow, go to System OAuth > Application Registry, and click “New” to register a new OAuth endpoint for external clients. Create a record (e.g. Name it “NinjaOne OAuth”) and note the Client ID and Client Secret that ServiceNow generates. Add the useraccount OAuth scope in the record (this scope is required for the NinjaOne integration). [aemcorp.com], [aemcorp.com] [aemcorp.com]
- Next, create an API user account in ServiceNow (e.g. a user “ninjaone_integration”). Give this user the ITIL role (for incident creation) and potentially the asset/CMDB roles if you’ll sync configuration items. This user + OAuth client will be used by NinjaOne to call ServiceNow’s API. [aemcorp.com]
Step 2.1.6: Enable Integration in NinjaOne. In the NinjaOne console, navigate to Integrations > ServiceNow. Provide the ServiceNow instance URL and the OAuth Client ID/Secret from the previous step, and the username/password of the integration user if needed (the exact fields depend on NinjaOne’s UI). NinjaOne will test the connection to ServiceNow’s API. Once enabled, you can configure:
- Incident Creation Rules: e.g. map certain NinjaOne alerts to auto-create incidents. NinjaOne’s integration allows you to specify which alert severity or type triggers a ServiceNow incident. For example, you might enable “Critical alerts open ServiceNow incident”. Each incident created will include details like the device name, alert description, and a direct link back to NinjaOne. [store.servicenow.com]
- CMDB Sync: Map NinjaOne device fields to ServiceNow CMDB fields. The NinjaOne ServiceNow integration plugin includes out-of-box mappings so that each NinjaOne “device” corresponds to a CI in ServiceNow (with attributes like hostname, IP, OS, last user login, etc.). Review these mappings (in ServiceNow, the NinjaOne integration application might show a configuration for CI synchronization) and adjust if necessary (for example, ensure custom attributes like location or environment are mapped correctly). [store.servicenow.com], [ninjaone.com]
Step 2.1.7: Test NinjaOne–ServiceNow integration. To ensure everything is working:
- Force an alert: e.g. artificially generate a high CPU load or use NinjaOne’s “send test alert” feature if available.
- Verify that an Incident appears in ServiceNow with the correct details (check the ServiceNow Incident list). It should show the NinjaOne device information and the alert description. [store.servicenow.com]
- In ServiceNow, try using any NinjaOne embedded functionality. If the integration is set up, ServiceNow tickets might display a “NinjaOne Remote Access” link or device details fetched from NinjaOne. Confirm you can remote into the device from the incident (if applicable) and that device configuration is visible. [ninjaone.com], [ninjaone.com]
2.2 Splunk – Installation and Database Monitoring Setup
Step 2.2.1: Install Splunk Enterprise. Choose a server (or set of servers, if in a distributed Splunk deployment) within your on-prem environment to host Splunk. Follow Splunk’s installation steps for your OS (download the Splunk Enterprise installer, run the installation). For a smaller setup, a single Splunk instance can serve as indexer and search head. Ensure the Splunk web UI is accessible internally and that you have admin credentials set up.
Step 2.2.2: Install Universal Forwarders on DB Servers. On each database server, install the Splunk Universal Forwarder (a lightweight agent) to send logs and metrics to Splunk:
- For Windows servers (e.g. SQL Server machines), install the forwarder and use the Splunk Add-on for Microsoft SQL Server on that forwarder. This add-on knows how to collect various data: it can pull Windows Performance Monitor counters (like Buffer Manager metrics, cache hit ratios), read the SQL Server error logs, and collect Windows Event Logs (for SQL Server events). It also uses Splunk’s DB Connect under the hood to query certain SQL DMVs if configured. After installing the add-on, configure inputs: e.g. enable the “SQL Server:ErrorLog” input to watch the SQL error log file, enable performance counter inputs for SQL statistics, etc. [help.splunk.com]
- For Linux servers (e.g. those running Oracle, MariaDB, PostgreSQL), install the forwarder and deploy the relevant add-ons:
- Splunk Add-on for Oracle Database on Oracle DB servers. This add-on will monitor Oracle’s alert log, trace files, listener log, etc., and can also use DB Connect to query Oracle’s performance tables for metrics. Configuration entails editing its inputs (specify paths to alert log, enable auditing logs ingestion, set up connection info for DB Connect if you want to pull session or performance data). [splunk.github.io]
- Splunk Add-on for Unix/Linux (for system metrics) can capture OS-level data on Linux servers. Use it to get Syslog, CPU, memory, disk stats from those machines, complementing the DB-specific data.
- For MySQL/MariaDB and PostgreSQL: There may not be official Splunk add-ons from Splunk Inc, but you can still monitor these databases effectively:
- Forward their logs: e.g. configure the forwarder to tail the MySQL error log and slow query log, or PostgreSQL’s log file. Splunk will index those logs so you can search for errors or bad queries.
- Use Splunk DB Connect to pull metrics: e.g. connect to MySQL and run
SHOW GLOBAL STATUSperiodically, or to PostgreSQL to run queries onpg_stat_activityand other stats views. Splunk DB Connect allows scheduling input queries that run at intervals and ingest results into Splunk. [Bi-Weekly...2026-01-28 | Loop], [Bi-Weekly...2026-01-28 | Loop] - Alternatively, use export tools: for example, you might schedule a cron job (or Ansible task) to output certain DB stats to a file that Splunk then ingests – but using DB Connect is more direct.
Step 2.2.3: Configure Indexes and Source Types. In Splunk, set up separate indexes for organization if desired (e.g. an index for “dba_logs” and one for “dba_metrics”). This isn’t strictly required but helps with access control and searching later. Ensure the forwarders are sending data to the correct index (update the outputs.conf/indexes.conf as needed). The add-ons usually come with predefined source types for the data they collect (e.g. mssql:errorlog for SQL error logs), which enable CIM (Common Information Model) field extractions. [help.splunk.com]
Step 2.2.4: Dashboards and Alerts in Splunk. Next, create some dashboards in Splunk to visualize the data:
- Performance Dashboards: For each database type, create panels showing key metrics. For example: a time chart of transactions per second on each SQL Server instance, a panel for Oracle session counts and wait events, charts for MySQL slow query count, etc. You can base these on data from the add-ons or custom queries. Splunk’s search processing language (SPL) can aggregate and transform the metrics. Example: use the data from the Oracle add-on (which collects Oracle wait event stats) to highlight the top wait events by time consumed. [splunk.com], [splunk.com]
- Health Check Dashboards: e.g. a dashboard listing all current error events or failed backups gleaned from logs (across all DB engines).
- Alerts: Define Splunk alerts for significant conditions. Some ideas:
- If Oracle alert log contains “ORA-00600” or other critical errors, trigger an alert.
- If MySQL replication delay exceeds X seconds (if such metric is collected or can be computed from logs), alert.
- If any database server has not reported data (could indicate an agent or DB outage).
- These alerts can be set to either email the DBA team or, better, use the Splunk → ServiceNow integration. The Splunk Add-on for ServiceNow enables Splunk to create incidents in ServiceNow using custom alert actions. For instance, you can configure an alert in Splunk such that when a search finds a critical condition, it calls the ServiceNow alert action to open an incident (populating fields like short description, assignment group, etc.). This way, even issues detected by Splunk outside of NinjaOne’s scope get tracked in ServiceNow. [help.splunk.com]
Step 2.2.5: Integrate Splunk with ServiceNow. As noted, use the Splunk-provided add-on:
- Install the Splunk Add-on for ServiceNow on your Splunk search head. [help.splunk.com]
- In Splunk, go to Configuration for the add-on and enter your ServiceNow instance URL and credentials (it will use ServiceNow’s REST API). Use basic auth or OAuth – ServiceNow may allow a dedicated technical user for API. As with NinjaOne, that ServiceNow user should have permissions for the data you plan to pull/push (for pulling data, roles like
itilandasset; for pushing incidents,itilis enough to create incidents). - Enable data inputs if you want Splunk to index ServiceNow data (for trend analysis). The add-on can pull incidents, changes, CMDB CIs, etc., into Splunk at intervals. This is useful if you want, for example, to correlate incident counts with performance metrics in Splunk dashboards. [help.splunk.com]
- Alert Action: The ServiceNow add-on also provides alert action scripts to create ServiceNow records. Set up an alert action (in Splunk’s Saved Searches UI) to create an incident when a certain condition is met. For example, when the “DB Disk Free % < 5” alert triggers in Splunk, add an action: Create ServiceNow Incident with a preset mapping (maybe the search results or host name go into the ticket fields). Test this by manually triggering a Splunk search that meets the condition and verifying an incident appears in ServiceNow.
Step 2.2.6: Validate End-to-End Monitoring. Now simulate a scenario to test the full pipeline:
- Intentionally stop a database service or generate a test error (for example, stop the SQL Server service on a non-production box, or fill a disk to trigger a low space condition).
- Check NinjaOne: it should catch the service down or low disk via its agent and likely fire an alert. That alert should create a ServiceNow incident (see ServiceNow for a new incident, possibly with NinjaOne’s incident template).
- Check Splunk: it should receive log events (service stopped error in Windows Event Log, or disk threshold crossed in system logs). Splunk might also trigger its own alert if configured, which would open another ServiceNow incident or update one.
- In ServiceNow, you might see two incidents (one from NinjaOne, one from Splunk). This is a good opportunity to refine your setup – perhaps you choose to rely on one primary source to create the incident and have the other provide data. A best practice is to integrate at the data level but avoid duplicate alert noise: for example, let NinjaOne create the incident for infrastructure alerts, and use Splunk’s data in that incident for additional diagnostics rather than opening a separate ticket. You can achieve this by having Splunk forward events to the existing incident (the Splunk add-on could update an incident if one already exists for the same host issue, using correlation rules).
2.3 Ansible – Automation Playbooks for DBA Tasks
Step 2.3.1: Install Ansible. Set up an Ansible control machine on-prem (this can be your admin workstation or a dedicated automation server). Install the latest Ansible (e.g., via pip install ansible or using your OS package manager). If you prefer a web interface and centralized execution, consider installing AWX (the open-source edition of Ansible Tower) so you can manage playbooks and jobs via UI – but this is optional.
Step 2.3.2: Configure Inventory. Create an inventory file (INI or YAML) listing all database servers and grouping them:
[sql_servers]
sqlprod1.example.com ansible_user=AdminUser ansible_connection=winrm
sqlprod2.example.com ansible_user=AdminUser ansible_connection=winrm
[oracle_servers]
ora-prod-01.example.com ansible_user=oracle
ora-prod-02.example.com ansible_user=oracle
[mysql_servers]
mysql01.example.com ansible_user=root
[postgres_servers]
pg01.example.com ansible_user=postgres
In the above, we define groups for each DB type. We specify ansible_connection=winrm for Windows machines (SQL Servers) and perhaps credentials (or better, set up Kerberos/NTLM or CredSSP for WinRM auth). For Linux, ensure SSH keys or passwords are configured. Verify connectivity with ansible -m ping all.
Step 2.3.3: Install Ansible Collections for DB modules. Ansible has community collections that provide modules for databases:
- Run
ansible-galaxy collection install community.mysql community.postgresql community.generalto get MySQL and PostgreSQL modules (and general Windows modules if needed). - The
community.mysqlcollection provides modules likemysql_user,mysql_db, andmysql_queryfor MySQL/MariaDB automation (creating users, backing up databases, running queries). [blog.poespas.me] - The
community.postgresqlcollection similarly providespostgresql_user,postgresql_db, etc., for PostgreSQL. - For Oracle, there's no official core module in Ansible distribution, but there are third-party roles (for example, the
oravirt.oraclerole provides modules for managing Oracle users, tablespaces, etc.). You can use those, or simply use Ansible to run SQL scripts via the Oracle SQL*Plus client. - For SQL Server, use the community.windows collection coupled with PowerShell/SQL scripts: e.g.,
win_shell: sqlcmd -Q "<T-SQL command>"to execute queries. There is amssql_scriptmodule in community.mssql (to run a SQL script against SQL Server) if you install that collection.
Step 2.3.4: Develop Playbooks for Common Tasks. Identify the daily or frequent tasks you want to streamline. For a DBA, typical tasks include: backups, user management, permission audits, configuration changes, health checks, and patch automation. Create playbooks or roles for each. Below are examples:
-
Database Backup Automation: Write a playbook that backs up every database:
- name: Daily Backup of All Databases hosts: all_dbs # an inventory group containing all DB servers, or use host pattern gather_facts: no vars: backup_dir: "/backup/{{ inventory_hostname }}" tasks: - name: Backup MySQL databases mysql_db: state: dump target: "{{ backup_dir }}/mysql_backup.sql" login_user: "{{ db_admin_user }}" # use appropriate creds login_password: "{{ db_admin_pass }}" when: "'mysql_servers' in group_names" - name: Backup PostgreSQL databases postgresql_db: state: dump target: "{{ backup_dir }}/pg_backup.sql" login_user: "{{ db_admin_user }}" login_password: "{{ db_admin_pass }}" when: "'postgres_servers' in group_names" - name: Backup Oracle database via expdp become: yes become_user: oracle shell: | expdp system/{{ db_admin_pass }} full=Y directory=DATA_PUMP_DIR dumpfile={{ inventory_hostname }}_expdp.dmp logfile={{ inventory_hostname }}_expdp.log when: "'oracle_servers' in group_names" - name: Backup SQL Server database win_shell: | BACKUP DATABASE [MyDB] TO DISK = 'C:\\Backup\\{{ inventory_hostname }}_MyDB.bak' WITH COPY_ONLY, INIT; when: "'sql_servers' in group_names"The playbook above (hypothetical) uses the appropriate module or command on each host based on its group. For MySQL/Postgres it calls Ansible modules to perform a dump (thereby leveraging native tools like
mysqldumporpg_dumpinternally), for Oracle it switches to the oracle OS user and runs anexpdpcommand (Data Pump export), and for SQL Server it uses a T-SQL backup command via the Windows shell. This could be run nightly via cron or scheduled in AWX. (Ensure credentials likedb_admin_passare stored securely, e.g. encrypted with Ansible Vault). -
User and Permissions Management: Create playbooks to ensure security baseline, e.g.:
- Remove default or unused accounts on all databases.
- Create necessary read-only accounts. For instance, use
mysql_userto create a user on all MySQL instances with appropriate grants, andpostgresql_useron Postgres, etc., while for Oracle/SQL you run SQL scripts. By using Ansible, you ensure every server gets the same script applied, which is logged centrally.
-
Patching/Configuration Changes: While NinjaOne handles OS patching, you can use Ansible for database software patching or config changes:
- Oracle patching: Ansible can copy the Oracle patch files and invoke the Opatch tool across DB servers (ensuring the database is stopped, patch applied, started). This can be complex, but automating it ensures every node is patched in sync. (Always test on a staging environment first).
- Parameter changes: e.g., update
mysql.cnforpostgresql.confacross dozens of instances with one playbook, then trigger service restarts if needed (Ansible’slineinfileto change config andservice: restartto apply).
The key is to leverage Ansible’s idempotency – write tasks such that if the desired state is already present, nothing changes. This allows you to run playbooks repeatedly (or schedule them) without adverse effects.
Step 2.3.5: Integrate Ansible with ServiceNow (optional). Though not strictly required, you can enhance change management by integrating Ansible runs with ServiceNow change requests:
- Change Tickets: Before running a disruptive automation (like patching or a schema change), open a Change in ServiceNow. This can be done manually by following ITIL process, or automated. Ansible can actually talk to ServiceNow’s API as well – for instance, using the
servicenow.itsm.change_requestmodule (provided by an Ansible ServiceNow collection) or the genericurimodule to call the ServiceNow REST API to create a record. Red Hat’s certified collection for ServiceNow ITSM provides modules to create/update tickets as part of playbook runs. This means your playbook could automatically log a change and even update it upon success/failure. - Job Triggers: Conversely, ServiceNow can trigger Ansible. If using AWX/Ansible Tower, you could integrate Tower with ServiceNow so that when a change record is approved, it invokes an Ansible Tower job template (e.g., “Apply patch on DB Servers” job runs when a change is executed). This requires some custom integration (ServiceNow Orchestration or a custom script in ServiceNow calling Tower’s API). It’s advanced, but ensures traceability: ServiceNow holds the record of what was run, and Ansible Tower handles the execution.
Step 2.3.6: Testing and Iteration. Test your playbooks in a safe environment:
- Run the backup playbook on non-production servers and verify backups are created properly.
- Run user management tasks and verify they had the intended effect (and did not lock out anything inadvertently).
- Ensure idempotency (run them twice and confirm the second run reports “OK” with no changes).
- Incorporate error handling and notifications: e.g., if any task fails on a server, have Ansible send an email or create a ServiceNow incident. This can be done by using Ansible callback plugins or handlers that notify on failure.
Step 2.3.7: Schedule Automation Jobs. Use a scheduler to run routine jobs:
- For example, schedule the backup playbook nightly via cron or use AWX’s scheduling feature.
- Use ServiceNow for on-demand: e.g., have a catalog item in ServiceNow that a DBA can trigger to run a specific playbook (via integration), though this needs some scripting, it can further streamline requests (like “restart a database instance” on demand goes through change control and automation automatically).
2.4 Integration Points Between All Components
Having set up each component, here is how they work together in daily operations:
<style> :root { --accent: #464feb; --timeline-ln: linear-gradient(to bottom, transparent 0%, #b0beff 15%, #b0beff 85%, transparent 100%); --timeline-border: #ffffff; --bg-card: #f5f7fa; --bg-hover: #ebefff; --text-title: #424242; --text-accent: var(--accent); --text-sub: #424242; --radius: 12px; --border: #e0e0e0; --shadow: 0 2px 10px rgba(0, 0, 0, 0.06); --hover-shadow: 0 4px 14px rgba(39, 16, 16, 0.1); --font: "Segoe Sans", "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; --overflow-wrap: break-word; } @media (prefers-color-scheme: dark) { :root { --accent: #7385ff; --timeline-ln: linear-gradient(to bottom, transparent 0%, transparent 3%, #6264a7 30%, #6264a7 50%, transparent 97%, transparent 100%); --timeline-border: #424242; --bg-card: #1a1a1a; --bg-hover: #2a2a2a; --text-title: #ffffff; --text-sub: #ffffff; --shadow: 0 2px 10px rgba(0, 0, 0, 0.3); --hover-shadow: 0 4px 14px rgba(0, 0, 0, 0.5); --border: #3d3d3d; } } @media (prefers-contrast: more), (forced-colors: active) { :root { --accent: ActiveText; --timeline-ln: ActiveText; --timeline-border: Canvas; --bg-card: Canvas; --bg-hover: Canvas; --text-title: CanvasText; --text-sub: CanvasText; --shadow: 0 2px 10px Canvas; --hover-shadow: 0 4px 14px Canvas; --border: ButtonBorder; } } .insights-container { display: grid; grid-template-columns: repeat(2,minmax(240px,1fr)); padding: 0px 16px 0px 16px; gap: 16px; margin: 0 0; font-family: var(--font); } .insight-card:last-child:nth-child(odd){ grid-column: 1 / -1; } .insight-card { background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); box-shadow: var(--shadow); min-width: 220px; padding: 16px 20px 16px 20px; } .insight-card:hover { background-color: var(--bg-hover); } .insight-card h4 { margin: 0px 0px 8px 0px; font-size: 1.1rem; color: var(--text-accent); font-weight: 600; display: flex; align-items: center; gap: 8px; } .insight-card .icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; font-size: 1.1rem; color: var(--text-accent); } .insight-card p { font-size: 0.92rem; color: var(--text-sub); line-height: 1.5; margin: 0px; overflow-wrap: var(--overflow-wrap); } .insight-card p b, .insight-card p strong { font-weight: 600; } .metrics-container { display:grid; grid-template-columns:repeat(2,minmax(210px,1fr)); font-family: var(--font); padding: 0px 16px 0px 16px; gap: 16px; } .metric-card:last-child:nth-child(odd){ grid-column:1 / -1; } .metric-card { flex: 1 1 210px; padding: 16px; background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); text-align: center; display: flex; flex-direction: column; gap: 8px; } .metric-card:hover { background-color: var(--bg-hover); } .metric-card h4 { margin: 0px; font-size: 1rem; color: var(--text-title); font-weight: 600; } .metric-card .metric-card-value { margin: 0px; font-size: 1.4rem; font-weight: 600; color: var(--text-accent); } .metric-card p { font-size: 0.85rem; color: var(--text-sub); line-height: 1.45; margin: 0; overflow-wrap: var(--overflow-wrap); } .timeline-container { position: relative; margin: 0 0 0 0; padding: 0px 16px 0px 56px; list-style: none; font-family: var(--font); font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container::before { content: ""; position: absolute; top: 0; left: calc(-40px + 56px); width: 2px; height: 100%; background: var(--timeline-ln); } .timeline-container > li { position: relative; margin-bottom: 16px; padding: 16px 20px 16px 20px; border-radius: var(--radius); background: var(--bg-card); border: 1px solid var(--border); } .timeline-container > li:last-child { margin-bottom: 0px; } .timeline-container > li:hover { background-color: var(--bg-hover); } .timeline-container > li::before { content: ""; position: absolute; top: 18px; left: -40px; width: 14px; height: 14px; background: var(--accent); border: var(--timeline-border) 2px solid; border-radius: 50%; transform: translateX(-50%); box-shadow: 0px 0px 2px 0px #00000012, 0px 4px 8px 0px #00000014; } .timeline-container > li h4 { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); } .timeline-container > li h4 em { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); font-style: normal; } .timeline-container > li * { margin: 0; font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container > li * b, .timeline-container > li * strong { font-weight: 600; } @media (max-width:600px){ .metrics-container, .insights-container{ grid-template-columns:1fr; } } </style>🔧 NinjaOne → ServiceNow
NinjaOne automatically creates ServiceNow incidents for critical alerts and syncs device inventory to the CMDB.
📊 Splunk → ServiceNow
Splunk alerts can create or update incidents via ServiceNow’s API. ServiceNow incident and change data is also pulled into Splunk for correlation.
🤝 ServiceNow ↔ NinjaOne
Technicians can launch NinjaOne remote actions directly from a ServiceNow ticket. Ticket updates can sync back to NinjaOne (e.g., closure or notes syncing).
🚀 Ansible ↔ ServiceNow
ServiceNow Change workflows can trigger Ansible jobs for deployment tasks, and Ansible playbooks can log results back into ServiceNow (e.g., post change completion comments).
🗄️ Splunk ← Databases
All databases feed logs and telemetry into Splunk (via forwarders and DB Connect), enabling cross-platform dashboards (e.g., comparing error rates between Oracle and MySQL instances).
Table: Key integration flows between tools and their purpose.
Additionally, the table below outlines how common database administration tasks are achieved across different database platforms using this toolchain:
| DB Task | SQL Server (Windows) | Oracle (Linux/Unix) | MySQL/MariaDB (Linux) | PostgreSQL (Linux) |
|---|---|---|---|---|
| Scheduled Backups | Use Ansible with PowerShell/SQL scripts or community modules to run BACKUP DATABASE commands. For example, an Ansible task can invoke sqlcmd via win_shell to back up each database to disk [Bi-Weekly...2026-01-28 | Loop], [Bi-Weekly...2026-01-28 | Loop]. NinjaOne can be used to schedule and monitor the backup script execution on Windows. |
Use Ansible to run Oracle’s RMAN or Data Pump. E.g., a playbook executes an expdp or RMAN backup command on all Oracle servers in parallel [Bi-Weekly...2026-01-28 | Loop], [Bi-Weekly...2026-01-28 | Loop]. Monitor backup logs through Splunk (the Oracle alert log will log backups). |
Use Ansible’s mysql_db module with state=dump to perform logical backups (mysqldump) of each database [blog.poespas.me]. Alternatively, use OS scripts triggered by Ansible for physical backups (e.g., LVM snapshot or Percona XtraBackup), and have NinjaOne ensure the backup software is installed on all relevant servers. |
Use Ansible’s postgresql_db module or pg_dump via shell to back up databases. A playbook can iterate over databases and run backups to files. Splunk can monitor the backup script output or cron logs for success/failure. |
| User Account Management | Use Ansible with the mssql collection or Powershell: e.g., a task running sqlcmd to create logins and users, or the dbatools PowerShell module via Ansible to manage SQL Server accounts. NinjaOne’s scripts feature could also run a predefined SQL script on all SQL instances to create or audit logins. |
Use Ansible to run SQL*Plus scripts. There are community roles that provide modules like oracle_user to create Oracle users, or you can use Ansible’s shell module to run a script that creates users and grants privileges. Tie this into ServiceNow requests (e.g. a ServiceNow catalog item for “Create DB User” triggers an Ansible playbook which then updates the ticket when done). |
Use Ansible’s mysql_user module to ensure MySQL/MariaDB users exist with correct privileges. This module is idempotent, so it will only create or update if needed. Store credentials in Ansible Vault for security. Regularly, you could run a playbook to remove any unauthorized users, using a desired-state approach. |
Use Ansible’s postgresql_user module for role management in PostgreSQL. This can create roles and set passwords and permissions. Combine with postgresql_privs module to manage GRANTs. Ansible’s inventory can define desired users per environment, and the playbook ensures the DB matches that state. |
| Patching DB Software | Use a combination of tools: NinjaOne can deploy Windows patches (including SQL Server cumulative updates if they come via Windows Update). For SQL Server upgrades or specific hotfixes, consider an Ansible playbook that copies the installer and runs it silently via win_package or win_shell. ServiceNow Change can document the patch, and the Splunk forwarder can track installation logs for any errors. |
Use Ansible to automate Oracle database patching. For example, a playbook can stop the database, apply Oracle PSU/OPatch, and start it, one server at a time (especially for RAC or Data Guard environments). Leverage Ansible’s orchestration to ensure patches apply in the correct order. Monitor patch logs in Splunk. (Given the complexity, test this thoroughly in a dev environment.) | Use Ansible or package managers to update MySQL/MariaDB versions (if using system packages). Ansible’s apt/yum modules can apply minor version updates in a controlled way (e.g., rolling restarts for HA setups). ServiceNow should record these changes. If using Percona or MariaDB with custom repos, Ansible can manage those repositories and updates as well. |
Use Ansible to upgrade PostgreSQL or apply minor updates. This might involve installing the new version and running pg_upgrade – tasks well-suited to automation so that each instance is handled uniformly. As with others, coordinate via change management and log outcomes to Splunk (Postgres logs or Ansible callback output). |
Table: Examples of how tasks are automated across SQL Server, Oracle, MySQL/MariaDB, and PostgreSQL using the integration tools.
3. Best Practices for Security, Scalability, and Maintainability
Implementing this integrated toolchain brings powerful capabilities, but it’s crucial to follow best practices to ensure the solution is secure, scalable, and maintainable over time:
-
Secure Integration Credentials: Use dedicated service accounts for each integration point with the principle of least privilege. For example, the ServiceNow API user used by NinjaOne should only have roles to create incidents and update CIs, nothing more. Similarly, the Splunk database accounts should have read-only access, only to the necessary tables or views (e.g., a user that can
SELECTperformance views but not modify anything). Store sensitive credentials securely: [Bi-Weekly...2026-01-28 | Loop], [Bi-Weekly...2026-01-28 | Loop]- In Ansible, use Ansible Vault to encrypt passwords (for database creds, API keys, etc.).
- In NinjaOne and ServiceNow, leverage their built-in credential storage or encryption for integration secrets (OAuth client secrets, etc.).
- Rotate API keys/passwords periodically and update the configurations.
-
Network and Access Security: Since NinjaOne and ServiceNow are cloud services, ensure your on-prem environment can reach them securely. NinjaOne agents initiate outbound connections to the NinjaOne cloud (so open egress on required ports, typically HTTPS/443). For ServiceNow API calls from NinjaOne or Splunk, make sure your firewall allows HTTPS traffic to your ServiceNow instance. If direct internet access from the Splunk server is restricted, consider using a proxy or a ServiceNow MID Server inside your network for the integration. Use TLS everywhere (which is default for these tools’ communications).
-
Audit and Logging: Leverage the fact that we have multiple logging points:
- All Ansible playbook runs should produce logs. If using AWX, these are stored in the job records. You can also configure Ansible to log to a file. Importantly, consider sending Ansible execution logs to Splunk as well (for example, Splunk can ingest AWX job logs or ansible callback logs). This provides a historical record of changes applied.
- ServiceNow acts as a log of incidents and changes. Ensure that significant automated changes are tied to a change record. Even if you automate the change creation, having that record in ServiceNow will help with auditing and knowledge capture (e.g., “Production Oracle DB patch applied via Ansible on 2026-05-01, Change CHG003456 closed – see attached Ansible output for details”).
- Use ServiceNow CMDB and NinjaOne together for asset tracking. New database servers should be added to NinjaOne (agent installed) and also registered in CMDB via the integration. Define processes to keep these in sync (the NinjaOne-ServiceNow integration will help, but ensure, for instance, decommissioned servers get marked retired in CMDB when their NinjaOne agent is removed).
-
Scalability Considerations:
- Splunk: As log volume increases (with more databases or more detailed logging), you may need to scale out your Splunk deployment (indexer clustering, etc.). Monitor Splunk’s own performance. Use indexing on specific fields (like host, source type) to speed up queries in large data sets. Archive or age out old data as appropriate to manage index sizes.
- Ansible: If you have a very large number of servers or perform very frequent automation, consider using AWX/Ansible Tower which supports scaling out via multiple execution nodes. Even without AWX, you can tune Ansible’s parallelism (e.g., running with
-f 50to run on 50 hosts at a time) to balance speed with load on the network/servers. - ServiceNow: Large volumes of automated incident creation can overwhelm ITSM processes. Use incident de-duplication strategies. For example, if Splunk and NinjaOne both create incidents, you might get two for the same issue – refine your alerting so that one system is primary and the other’s data is correlated. ServiceNow can use business rules to auto-close or merge certain tickets. Also, if you anticipate many CI updates (from NinjaOne sync), schedule them in off-hours or adjust the sync frequency to avoid performance hits on the CMDB.
-
Maintainability and Updates:
- Treat your automation content as code. Store Ansible playbooks (and any scripts for NinjaOne or Splunk) in a version control system (e.g., Git). This way changes are tracked, and you can roll back if a new automation causes issues.
- Regularly update the tools: apply updates to NinjaOne agents, upgrade Splunk and its add-ons to benefit from improvements (for instance, updated Splunk add-ons might support new DB versions). Keep Ansible and its collections updated as well – new versions often include bug fixes and new modules.
- Modularize and Document: Write clear documentation for your team about how the integration works. Document the architecture (you can use the high-level diagram as part of an internal wiki). Also document operational procedures: e.g., “If a ServiceNow incident comes from NinjaOne vs from Splunk, what’s the difference?” so operators know how to respond. Within Ansible roles and playbooks, include comments for any non-obvious logic. For maintainability, break playbooks into roles (as demonstrated in the Ansible roles example) to reuse code for similar tasks across DB types.
-
Testing and Change Management: Whenever possible, test changes in a lower environment:
- Maintain a subset of servers (or VMs) as a staging environment for this entire toolchain. Integrate them in a non-prod ServiceNow instance or use test projects. This sandbox lets you try new playbooks or updates (e.g., a Splunk add-on update or a NinjaOne policy change) before rolling out to production.
- Use ServiceNow Change Management for any major modifications to the automation. Even though automation makes changes fast, ensure that you follow approval processes for production-impacting changes. This might involve getting a change approved that triggers an Ansible playbook on all prod databases—thus everyone is aware and has a back-out plan if something goes wrong.
By adhering to these best practices, you will ensure the integrated system remains secure (no unintended access or data leakage), scalable (able to handle growth in infrastructure and data volume), and maintainable (easy to update and troubleshoot by the team) over the long term.
Finally, always seek feedback from your team’s DBAs and system engineers. They can pinpoint which automations are most beneficial and where adjustments might be needed. Over time you can extend this framework – for example, integrating additional tools (maybe a configuration management database or a BI tool for reporting) – but the foundation you’ve built with NinjaOne, Ansible, ServiceNow, and Splunk will greatly streamline daily DBA operations, improve reliability, and reduce manual toil. Good luck with your implementation!
Sources:
-
NinjaOne ServiceNow Integration Overview – NinjaOne Integrations documentation describing ServiceNow incident integration and benefits (service desk and CMDB sync). [ninjaone.com], [ninjaone.com]
-
ServiceNow App Store – NinjaOne Integration – Highlights of NinjaOne’s bidirectional integration with ServiceNow (auto incidents, device sync). [store.servicenow.com]
-
Splunk Add-on for ServiceNow – Splunk documentation on the ServiceNow add-on, enabling incident data collection and incident creation via API. [help.splunk.com]
-
Splunk Add-ons for Databases – Oracle and SQL Server – Official Splunk add-ons allowing ingestion of Oracle and SQL Server logs/metrics (using DB Connect and file monitoring for comprehensive DB monitoring). [splunk.github.io], [help.splunk.com]
-
Internal Team Meeting Notes – NinjaOne & Splunk Projects – Discussion of integrating ServiceNow API for automation and best practices like staggered patching schedules for reliability. [ninjaone.com]
Oczywiście! Oto przykładowy playbook Ansible do wykonania kopii zapasowej bazy danych. Poniżej znajdziesz prosty, ale funkcjonalny przykład dla MySQL, z możliwością łatwej adaptacji do innych silników baz danych (np. PostgreSQL, Oracle, SQL Server).
📦 Przykład: Playbook Ansible do backupu bazy danych MySQL
Struktura katalogu:
backup_mysql/
├── backup_mysql.yml
└── roles/
└── mysql_backup/
├── tasks/
│ └── main.yml
└── templates/
└── backup.sh.j2
🔧 Plik: backup_mysql.yml
---
- name: Backup MySQL databases
hosts: mysql_servers
become: yes
vars:
backup_dir: /var/backups/mysql
mysql_user: root
mysql_password: "{{ vault_mysql_root_password }}"
databases:
- mydb1
- mydb2
roles:
- mysql_backup
📄 Plik: roles/mysql_backup/tasks/main.yml
---
- name: Ensure backup directory exists
file:
path: "{{ backup_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Create backup script from template
template:
src: backup.sh.j2
dest: /usr/local/bin/mysql_backup.sh
mode: '0750'
- name: Run backup script
shell: /usr/local/bin/mysql_backup.sh
📄 Plik: roles/mysql_backup/templates/backup.sh.j2
#!/bin/bash
TIMESTAMP=$(date +%F_%H-%M-%S)
BACKUP_DIR="{{ backup_dir }}/$TIMESTAMP"
mkdir -p "$BACKUP_DIR"
{% for db in databases %}
mysqldump -u {{ mysql_user }} -p'{{ mysql_password }}' {{ db }} > "$BACKUP_DIR/{{ db }}.sql"
{% endfor %}
🔐 Uwaga: Hasło do MySQL powinno być przechowywane w bezpieczny sposób, np. za pomocą Ansible Vault:
ansible-vault create group_vars/all/vault.yml
Zawartość vault.yml:
vault_mysql_root_password: "TwojeSuperTajneHaslo"
I w pliku backup_mysql.yml dodaj:
vars_files:
- group_vars/all/vault.yml
🧪 Testowanie:
- Upewnij się, że masz grupę
mysql_serversw inwentarzu (inventory). - Uruchom playbook:
ansible-playbook backup_mysql.yml --ask-vault-pass
Automatyzacja backupów baz danych (MySQL, PostgreSQL, Oracle, SQL Server) za pomocą Ansible
<style> :root { --accent: #464feb; --timeline-ln: linear-gradient(to bottom, transparent 0%, #b0beff 15%, #b0beff 85%, transparent 100%); --timeline-border: #ffffff; --bg-card: #f5f7fa; --bg-hover: #ebefff; --text-title: #424242; --text-accent: var(--accent); --text-sub: #424242; --radius: 12px; --border: #e0e0e0; --shadow: 0 2px 10px rgba(0, 0, 0, 0.06); --hover-shadow: 0 4px 14px rgba(39, 16, 16, 0.1); --font: "Segoe Sans", "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; --overflow-wrap: break-word; } @media (prefers-color-scheme: dark) { :root { --accent: #7385ff; --timeline-ln: linear-gradient(to bottom, transparent 0%, transparent 3%, #6264a7 30%, #6264a7 50%, transparent 97%, transparent 100%); --timeline-border: #424242; --bg-card: #1a1a1a; --bg-hover: #2a2a2a; --text-title: #ffffff; --text-sub: #ffffff; --shadow: 0 2px 10px rgba(0, 0, 0, 0.3); --hover-shadow: 0 4px 14px rgba(0, 0, 0, 0.5); --border: #3d3d3d; } } @media (prefers-contrast: more), (forced-colors: active) { :root { --accent: ActiveText; --timeline-ln: ActiveText; --timeline-border: Canvas; --bg-card: Canvas; --bg-hover: Canvas; --text-title: CanvasText; --text-sub: CanvasText; --shadow: 0 2px 10px Canvas; --hover-shadow: 0 4px 14px Canvas; --border: ButtonBorder; } } .insights-container { display: grid; grid-template-columns: repeat(2,minmax(240px,1fr)); padding: 0px 16px 0px 16px; gap: 16px; margin: 0 0; font-family: var(--font); } .insight-card:last-child:nth-child(odd){ grid-column: 1 / -1; } .insight-card { background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); box-shadow: var(--shadow); min-width: 220px; padding: 16px 20px 16px 20px; } .insight-card:hover { background-color: var(--bg-hover); } .insight-card h4 { margin: 0px 0px 8px 0px; font-size: 1.1rem; color: var(--text-accent); font-weight: 600; display: flex; align-items: center; gap: 8px; } .insight-card .icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; font-size: 1.1rem; color: var(--text-accent); } .insight-card p { font-size: 0.92rem; color: var(--text-sub); line-height: 1.5; margin: 0px; overflow-wrap: var(--overflow-wrap); } .insight-card p b, .insight-card p strong { font-weight: 600; } .metrics-container { display:grid; grid-template-columns:repeat(2,minmax(210px,1fr)); font-family: var(--font); padding: 0px 16px 0px 16px; gap: 16px; } .metric-card:last-child:nth-child(odd){ grid-column:1 / -1; } .metric-card { flex: 1 1 210px; padding: 16px; background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); text-align: center; display: flex; flex-direction: column; gap: 8px; } .metric-card:hover { background-color: var(--bg-hover); } .metric-card h4 { margin: 0px; font-size: 1rem; color: var(--text-title); font-weight: 600; } .metric-card .metric-card-value { margin: 0px; font-size: 1.4rem; font-weight: 600; color: var(--text-accent); } .metric-card p { font-size: 0.85rem; color: var(--text-sub); line-height: 1.45; margin: 0; overflow-wrap: var(--overflow-wrap); } .timeline-container { position: relative; margin: 0 0 0 0; padding: 0px 16px 0px 56px; list-style: none; font-family: var(--font); font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container::before { content: ""; position: absolute; top: 0; left: calc(-40px + 56px); width: 2px; height: 100%; background: var(--timeline-ln); } .timeline-container > li { position: relative; margin-bottom: 16px; padding: 16px 20px 16px 20px; border-radius: var(--radius); background: var(--bg-card); border: 1px solid var(--border); } .timeline-container > li:last-child { margin-bottom: 0px; } .timeline-container > li:hover { background-color: var(--bg-hover); } .timeline-container > li::before { content: ""; position: absolute; top: 18px; left: -40px; width: 14px; height: 14px; background: var(--accent); border: var(--timeline-border) 2px solid; border-radius: 50%; transform: translateX(-50%); box-shadow: 0px 0px 2px 0px #00000012, 0px 4px 8px 0px #00000014; } .timeline-container > li h4 { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); } .timeline-container > li h4 em { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); font-style: normal; } .timeline-container > li * { margin: 0; font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container > li * b, .timeline-container > li * strong { font-weight: 600; } @media (max-width:600px){ .metrics-container, .insights-container{ grid-template-columns:1fr; } } </style>🛠 Dedykowane moduły i narzędzia
Wykorzystaj natywne moduły Ansible do backupów gdzie to możliwe: MySQL/MariaDB – moduł mysql_db z opcją dump (oparty na mysqldump); PostgreSQL – moduł postgresql_db (wykorzystuje pg_dump). Dla Oracle i SQL Server użyj natywnych narzędzi baz danych wywołując je w playbooku (np. skrypty RMAN/expdp dla Oracle, polecenie T-SQL BACKUP dla SQL) – brak wbudowanych modułów do bezpośredniego backupu tych silników.
🔐 Bezpieczne poświadczenia
Wrażliwe dane (hasła do baz, klucze) przechowuj w zaszyfrowanych zmiennych Ansible Vault zamiast wprost w playbooku. Zapobiega to przypadkowemu ujawnieniu haseł. W playbookach odwołuj się do zaszyfrowanych wartości (np. {{ vault_db_password }}) – Ansible odszyfruje je w locie podczas wykonywania.
📁 Nazwy, kompresja i rotacja
Nadawaj kopiom zapasowym unikalne nazwy zawierające datę/godzinę (np. miadb_backup_20260312.sql) dla łatwej identyfikacji. Stosuj kompresję backupów, aby oszczędzić miejsce i przyspieszyć operacje (np. dump przez gzip; SQL Server obsługuje kompresję natywnie). Zaimplementuj rotację – np. za pomocą zadań Ansible lub skryptu czyszczącego – usuwaj pliki starsze niż X dni, utrzymując tylko wymagany okres retencji danych (np. ostatnie 7-14 dni).
📅 Harmonogram i powiadomienia
Automatyzuj uruchamianie backupów: skonfiguruj zadania CRON na serwerze Ansible lub harmonogram w AWX/Tower, aby playbooki wykonywały się codziennie o ustalonej porze (np. 1:00 w nocy). Monitoruj wyniki – w razie błędu backupu wyślij powiadomienie (np. e-mail do administratorów lub automatyczne zgłoszenie awarii w ServiceNow). Regularnie testuj odtwarzanie z backupów, by mieć pewność, że procedury działają.
1. Przykładowe playbooki dla pełnych backupów różnych silników
Poniżej przedstawiono przykładowe playbooki Ansible (lub role) realizujące pełny backup dla każdej z wymienionych baz danych. Każdy playbook uwzględnia zalecane moduły bądź narzędzia, sposób podania poświadczeń (korzystając z Ansible Vault), oraz zapisywanie plików kopii zapasowych w ustalonym katalogu.
1.1 MySQL / MariaDB – backup przy pomocy mysqldump
Dla MySQL i MariaDB najprostszą metodą jest wykonanie backupu logicznego za pomocą narzędzia mysqldump. Ansible oferuje moduł community.mysql.mysql_db, który potrafi wygenerować zrzut bazy danych (wewnętrznie używa mysqldump). Można nim wykonać dump konkretnej bazy lub wszystkich baz naraz (parametr name: all). Alternatywnie, można wywołać bezpośrednio polecenie mysqldump poprzez moduł shell lub command. Poniżej przykład roli mysql_backup tworzącej pełne kopie wszystkich baz danych MySQL na danym hoście: [stackoverflow.com]
# roles/mysql_backup/tasks/main.yml
- name: Upewnij się, że katalog backupów istnieje
file:
path: "{{ mysql_backup_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Wykonaj dump wszystkich baz MySQL do jednego pliku
community.mysql.mysql_db:
state: dump
name: all
target: "{{ mysql_backup_dir }}/mysql_all_{{ ansible_date_time.date }}.sql"
login_user: "{{ mysql_user }}"
login_password: "{{ mysql_password }}"
register: mysql_backup_result
when: mysql_backup_strategy == 'single_file'
- name: Wykonaj dump każdej bazy MySQL do osobnego pliku
shell: mysqldump -u{{ mysql_user }} -p'{{ mysql_password }}' {{ item }} > "{{ mysql_backup_dir }}/{{ item }}_{{ ansible_date_time.date }}.sql"
with_items: "{{ mysql_databases_list }}"
when: mysql_backup_strategy == 'separate_files'
register: mysql_backup_result
Objaśnienia:
- Zmienna
mysql_backup_dirpowinna wskazywać lokalizację (na serwerze baz danych), gdzie zapiszemy pliki backupu. Dobrze, by był to osobny dysk lub katalog na backupy. - Rolę zaprojektowano elastycznie: jeśli zmienna
mysql_backup_strategyma wartość"single_file", używamy modułu mysql_db zname: alldo zrzucenia wszystkich baz do jednego pliku (np.mysql_all_2026-03-12.sql). Jeśli zaś strategia to"separate_files", najpierw należy uzyskać listę wszystkich baz danych i zapisać ją wmysql_databases_list(np. przy użyciu modułumysql_infolub poleceniaSHOW DATABASES). Następnie powyższy task w pętli wykonamysqldumpdla każdej bazy osobno, pomijając systemowe bazy (mysql,information_schemaitd.). Każda baza trafi do osobnego pliku o nazwienazwaBazy_data.sql– dzięki temu łatwiej zarządzać pojedynczymi dumpami lub przywracać pojedyncze bazy w razie potrzeby. [stackoverflow.com] - Zmienna
mysql_userpowinna być uprawnionym użytkownikiem (np.rootlub dedykowany użytkownik backupowy z uprawnieniamiSELECT/lock na wszystkich bazach).mysql_passwordjest jego hasłem – przechowuj je w Ansible Vault i odszyfruj do zmiennej podczas działania playbooka (jak pokazano wyżej). - W powyższych przykładach użyto
ansible_date_time.date(co zwróci datę w formacie YYYY-MM-DD) jako część nazwy pliku backupu. Można użyć innego formatu daty/godziny (np.{{ ansible_date_time.iso8601 }}dla pełnego znacznika czasu). Dzięki temu każda kopia ma unikalną nazwę z datą, co ułatwia rozróżnienie kolejnych backupów.
Moduły: community.mysql.mysql_db – do wykonywania dumpów MySQL/MariaDB. Wymaga zainstalowanej kolekcji community.mysql oraz dostępności programu mysqldump na serwerze bazy. Alternatywnie, modul community.mysql.mysql_info może pobrać listę baz. Jeśli potrzebna jest większa kontrola (np. filtrowanie określonych baz wg wzorca), można posłużyć się bezpośrednio modułem shell/command z mysqldump, jak pokazano wyżej, ewentualnie dynamicznie budować listę baz do dumpu (np. z pominięciem systemowych). [claudiokuenzler.com] [stackoverflow.com]
1.2 PostgreSQL – backup przy pomocy pg_dump
PostgreSQL również umożliwia backup logiczny (zrzut bazy do pliku .sql lub formatu skompresowanego) za pomocą narzędzia pg_dump. Ansible posiada moduł community.postgresql.postgresql_db, który potrafi wykonać operację dump – wewnętrznie korzysta z pg_dump i potrafi zapisać wskazaną bazę do pliku docelowego. Przykładowa rola postgres_backup: [ansiblepilot.com]
# roles/postgres_backup/tasks/main.yml
- name: Zainstaluj bibliotekę kliencką PostgreSQL (psycopg2)
package:
name: python3-psycopg2
state: present
- name: Upewnij się, że katalog backupów istnieje
file:
path: "{{ pg_backup_dir }}"
state: directory
owner: postgres
group: postgres
mode: '0700'
- name: Wykonaj dump bazy {{ pg_database }}
community.postgresql.postgresql_db:
state: dump
name: "{{ pg_database }}"
target: "{{ pg_backup_dir }}/{{ pg_database }}_{{ ansible_date_time.date }}.sql"
become: yes
become_user: postgres
register: pg_backup_result
Objaśnienia:
- Użyto tu parametru
state: dumpmodułu postgresql_db, co spowoduje wywołaniepg_dumpna wskazanej bazie (name: "{{ pg_database }}") i zapisanie wynikowego dumpa do plikutarget. Moduł ten wymaga zainstalowanej na zdalnym serwerze biblioteki psycopg2 (stąd pierwszy task instalujący pakiet Python). Domyślniepostgresql_dbutworzy nieskompresowany dump SQL; można go później spakować osobno (np. komendągzipw kolejnym tasku) lub od razu wskazać nazwę pliku z rozszerzeniem.gz(moduł wtedy automatycznie kompresuje wyjściepg_dump). [ansiblepilot.com] - Playbook wykonuje się z uprawnieniami użytkownika systemowego
postgres(poprzezbecome_user: postgres), aby mieć dostęp do bazy. Alternatywnie można podać parametry połączenia (użytkownik/hasło bazy) bezpośrednio w zadaniu, ale wykorzystanie konta systemowego postgres często bywa prostsze wewnątrz serwera baz danych PostgreSQL. - Należy zdefiniować zmienną
pg_database(nazwa bazy do backupu) – w przypadku wielu baz, można wywoływać rolę kilkukrotnie dla różnych baz lub iterować po liście baz. Jeżeli chcemy backupować wszystkie bazy w instancji, można użyć pętli, podobnie jak to pokazano dla MySQL (np. pętlę po wynikach poleceniapsql -lfiltrując bazy systemowe).
Moduły: community.postgresql.postgresql_db – obsługuje tworzenie (present), usuwanie (absent), dump i odtwarzanie (restore) baz PostgreSQL. W razie potrzeby można użyć też community.postgresql.postgresql_dump (analogiczny moduł tylko do dumpów) lub wykonać surowe polecenie pg_dump przez shell. Jednak użycie gotowego modułu upraszcza operację i dba o spójność (np. wykorzystuje opcję --no-password i zmienne środowiskowe do autoryzacji). [ansiblepilot.com]
1.3 Oracle – backup przy pomocy RMAN lub Data Pump
W przypadku Oracle sprawa jest nieco bardziej złożona, ponieważ Ansible nie ma oficjalnego modułu do wykonywania backupu Oracle (poza specyficznymi modułami do Oracle Cloud, które tutaj nie mają zastosowania). Standardem backupu fizycznego Oracle jest RMAN (Recovery Manager) – narzędzie Oracle do tworzenia pełnych i przyrostowych kopii fizycznych baz danych na poziomie bloków oraz zarządzania archiwizacją redo logów. Alternatywną metodą, w szczególności do celów migrowania danych lub tworzenia logicznych kopii wybranych tabel/schematów, jest Oracle Data Pump (expdp/impdp) – narzędzie do eksportu i importu danych (backup logiczny).
Rekomendowane podejście produkcyjne: W środowisku produkcyjnym Oracle zaleca się używanie RMAN do regularnych pełnych backupów, gdyż jest to rozwiązanie najszybsze, zintegrowane z mechanizmami bazy i wspierające zaawansowane scenariusze odzyskiwania (np. przywracanie point-in-time z wykorzystaniem archivelogów). Data Pump natomiast można używać dodatkowo do eksportów wybranych danych (np. pojedynczych schematów) lub migracji między wersjami Oracle, ale nie zastępuje to pełnych backupów RMAN w kontekście odtwarzania awaryjnego całej bazy. [vinchin.com]
Automatyzacja RMAN przez Ansible: Backupy RMAN zwykle są definiowane skryptami wykonywanymi na serwerze bazy. Ansible może pomóc w generowaniu i dystrybucji skryptów RMAN oraz towarzyszących im zadań harmonogramu (cron) na serwerach Oracle, zapewniając standaryzację i spójność konfiguracji we wszystkich środowiskach. Przykładowo, można przygotować szablon skryptu RMAN (jako plik .rman lub skrypt powłoki odpalający RMAN z odpowiednimi komendami) i użyć modułu template, aby wstawić tam parametry (lokalizacja backupów, nazwa SID, polityka retencji, itp.). Następnie modułem cron można utworzyć zadanie harmonogramu odpalające ten skrypt np. codziennie w nocy. [pythian.com]
Przykład: Poniżej znajduje się prosty przykład użycia Data Pump do wykonania pełnego eksportu wszystkich obiektów bazy (tzw. full export) za pomocą Ansible:
# roles/oracle_backup/tasks/main.yml (fragment)
- name: Ustaw zmienne środowiskowe Oracle (dla usera oracle)
become: yes
become_user: oracle
shell: . /home/oracle/.bash_profile && echo ORACLE_SID=$ORACLE_SID
register: oracle_env
- name: Wykonaj pełny export Data Pump
become: yes
become_user: oracle
shell: |
expdp \'/ as sysdba\' full=Y directory=DATA_PUMP_DIR dumpfile={{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.dmp logfile={{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.log
args:
creates: "{{ oracle_data_pump_dir }}/{{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.dmp"
register: oracle_backup_result
Objaśnienia:
- Powyższy task zakłada, że na serwerze baza działa pod SID
{{ oracle_sid }}i że user systemowyoraclema w swoim.bash_profileustawione zmienne środowiskoweORACLE_HOME,ORACLE_SIDitp. Dlatego w pierwszym kroku upewniamy się, że po przełączeniu na kontooraclemamy skonfigurowane środowisko (poleceniem.wczytujemy profil). - Używamy tutaj polecenia
expdp(Export Data Pump) z parametremfull=Y, co oznacza eksport całej bazy (wszystkich schematów) do pliku.dmpzapisanego w lokalizacji wskazanej przez Oracle Directory o nazwieDATA_PUMP_DIR. Nazwa pliku zawiera SID bazy oraz datę (np.ORCL_FULL_2026-03-12.dmp). - Opcja
createsprzy zadaniushellpowoduje, że Ansible pominie wykonanie zadania, jeśli plik dumpa już istnieje – to zabezpieczenie przed nadpisaniem istniejącej kopii (można też zamiast tego użyć unikalnej nazwy pliku per uruchomienie). - Uwaga: Taki pełny eksport Data Pump nie zastępuje kopii RMAN – traktuj go raczej jako uzupełniającą kopię logiczną. Do pełnego backupu fizycznego posłuż się RMAN. Można zautomatyzować RMAN w Ansible np. przygotowując plik skryptowy:
- Utwórz w roli szablon
backup.rman.j2zawierający komendy RMAN (BACKUP DATABASE PLUS ARCHIVELOG, itp.), z parametrami takimi jak ścieżka docelowa, ustawienia retencji, kanały itp., wypełnianymi przez zmienne. - Za pomocą modułu
templatewygeneruj skrypt RMAN na serwerze. - Uruchom skrypt RMAN poleceniem
shell: rman target / @/ścieżka/do/skryptu.rman. - Alternatywnie, możesz wykorzystać istniejące community role/plugins. Np. kolekcja oravirt.oracle zawiera moduły do zarządzania Oracle (choć gotowe moduły do backupu RMAN mogą wymagać dodatkowej konfiguracji).
- Utwórz w roli szablon
- Podobnie jak w poprzednich przypadkach, upewnij się, że pliki backupu są zapisywane na odpowiednim dysku (np. udział sieciowy lub dedykowany mount point o odpowiedniej pojemności), a hasła (np. do konta sys/system, jeśli używasz expdp z takimi poświadczeniami) są bezpiecznie przechowywane (Vault).
Moduły/narzędzia: Brak oficjalnych modułów do backupu Oracle – wykorzystujemy polecenia systemowe. W przykładzie powyżej użyto Data Pump (expdp). RMAN z kolei może być wywoływany w trybie nienadzorowanym (rman target / cmdfile=...) i generować kopie na dysk lub taśmę. W automatyzacji warto pamiętać o:
- Spójność danych: w przypadku klastrów (np. Oracle RAC) czy dużych baz, RMAN zadba o spójność. W przypadku Data Pump pełny eksport może być wykonywany online, ale nie jest to backup transakcyjny – nie zachowa np. niezatwierdzonych transakcji ani informacji koniecznych do odtworzenia do punktu w czasie.
- Czas trwania: Eksport Data Pump przyspiesza backup poprzez mechanizmy przetwarzania równoległego, ale wciąż przy dużych wolumenach danych może trwać długo i generować bardzo duże pliki .dmp. RMAN jest generalnie szybszy przy dużych bazach, zwłaszcza dzięki możliwości backupu przyrostowego i kopiowania bitowego danych zamiast przez SQL. [vinchin.com]
1.4 Microsoft SQL Server – backup poleceniem BACKUP DATABASE
W przypadku Microsoft SQL Servera również nie istnieje prosty dedykowany moduł do wykonania backupu (moduł mssql_db obsługuje tworzenie i usuwanie baz oraz import, ale nie posiada opcji dump). Dlatego należy posłużyć się natywnymi mechanizmami SQL Server. Standardowo pełny backup bazy SQL Server wykonuje się poleceniem T-SQL BACKUP DATABASE ... TO DISK = 'plik.bak'. Możemy je wywołać z Ansible na dwa sposoby: [ansible.fontein.de]
-
Na serwerach Windows: użyć modułu
win_shelllubwin_command, aby uruchomić narzędzie wiersza poleceńsqlcmdbądź PowerShell. Przykład zadania Ansible na Windows może wyglądać tak:- name: Pełny backup bazy MSSQL ansible.windows.win_shell: | Backup-SqlDatabase -ServerInstance "{{ mssql_instance_name }}" -Database "{{ mssql_database }}" \ -BackupFile "{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak" \ -CompressionOption On args: executable: PowershellPowyższe zadanie wykorzystuje polecenie PowerShell (
Backup-SqlDatabasez modułu SqlServer) do wykonania pełnego backupu wskazanej bazy. Parametr-CompressionOption Onwłącza kompresję backupu (o ile edycja SQL Server na to pozwala – w nowoczesnych wersjach SQL Server kompresja backupów jest dostępna w edycjach Standard i Enterprise). Zamiast PowerShell można użyćsqlcmd: [learn.microsoft.com], [learn.microsoft.com]- name: Pełny backup bazy MSSQL (alternatywnie przez sqlcmd) ansible.windows.win_shell: | sqlcmd -Q "BACKUP DATABASE [{{ mssql_database }}] TO DISK = N'{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak' WITH INIT, COMPRESSION"Ten wariant wykonuje analogiczne polecenie T-SQL poprzez narzędzie linii komend
sqlcmd. PrzełącznikWITH COMPRESSIONwłącza kompresję backupu, aINITnadpisuje istniejący plik kopii (jeśli chcemy zachować wiele pokoleń backupów, można pominąćINITlub dodawać timestamp do nazwy pliku). -
Na serwerach Linux (SQL Server na Linux): składnia T-SQL jest identyczna, ale wywołujemy
sqlcmd(lubbcp/sqlpackagew zależności od potrzeb) za pomocą modułushell. Np.:- name: Pełny backup bazy MSSQL (Linux) shell: /opt/mssql-tools/bin/sqlcmd -S {{ mssql_hostname }} -U {{ mssql_user }} -P '{{ mssql_password }}' -Q "BACKUP DATABASE [{{ mssql_database }}] TO DISK = N'{{ mssql_backup_dir }}/{{ mssql_database }}_{{ ansible_date_time.date }}.bak' WITH INIT, COMPRESSION"(Oczywiście należy wcześniej zainstalować klienta sqlcmd na serwerze control machine lub zainstalować go na zdalnym hoście i odpowiednio dostosować polecenie).
Moduły/role: Warto wspomnieć, że istnieją kolekcje społecznościowe ułatwiające zarządzanie SQL Serverem:
- community.general.mssql_script – umożliwia wykonanie skryptu SQL na bazie MSSQL (np. możemy nim wykonać zapytanie BACKUP DATABASE zamiast korzystać z
win_shell). - lowlydba.sqlserver.backup – specjalizowany moduł (w kolekcji
lowlydba.sqlserver) służący do wykonywania backupu bazy SQL Server, oparty o moduł dbatools w PowerShell. Wymaga on jednak zainstalowania na serwerze docelowym biblioteki dbatools (PowerShell) i może być wykorzystany, jeśli decydujemy się na to dodatkowe zależne środowisko. Przykładowe użycie: [docs.ansible.com]Ten moduł obsługuje różne typy backupu (Full, Differential, Log) i pod spodem korzysta z dbatools (popularnego modułu PS dla SQL Server).- name: Backup bazy za pomocą modułu lowlydba.sqlserver.backup lowlydba.sqlserver.backup: database: "{{ mssql_database }}" path: "{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak" type: Full compression: true
Bezpieczeństwo: Niezależnie od metody, pamiętaj o przekazaniu poświadczeń dostępu do bazy:
- Dla
sqlcmdmożna użyć autentykacji Windows (Trusted Connection) jeśli Ansible uruchamia zdalnie komendę na Windows z kontekstu autoryzowanego użytkownika domenowego. W przeciwnym razie podaj użytkownika/hasło (-U/-Pjak wyżej) – hasło oczywiście z Vault. - Dla modułów Ansible (np.
mssql_scriptczylowlydba.sqlserver.backup) parametrylogin_user,login_passwordprzekaż z bezpiecznie przechowywanych zmiennych.
Uwaga dot. wydajności: Backupy SQL Server są na ogół szybkie, zwłaszcza przy włączonej kompresji, która zmniejsza ilość danych do zapisania na dysk. Należy jednak monitorować obciążenie CPU podczas kompresji – może być znaczące, szczególnie przy dużych bazach, więc w razie potrzeby planuj backupy w oknach mniejszego obciążenia serwera. Warto też rozważyć backup różnicowy (Differential) między pełnymi kopiami – SQL Server wspiera tworzenie backupów przyrostowych, co pozwala np. robić jedną pełną kopię tygodniowo i codziennie mniejsze backupy różnicowe. Dla zapewnienia Point-In-Time Recovery w SQL Server należy regularnie backupować również log transakcyjny (BACKUP LOG) – także to można zautomatyzować Ansiblem (np. oddzielny playbook odpalany co godzinę). Pełna strategia mogłaby wyglądać: pełny backup .bak co niedzielę, backupy różnicowe .bak codziennie, backup logów co godzinę; odtworzenie bazy do konkretnego punktu czasu wymaga wtedy ostatniego pełnego + ostatniego różnicowego + logów do żądanego momentu. [learn.microsoft.com]
2. Zarządzanie poświadczeniami za pomocą Ansible Vault
Praktycznie wszystkie playbooki backupowe muszą korzystać z poświadczeń dostępowych do baz danych (czy to hasła użytkownika SQL, czy hasła systemowego, np. sys dla Oracle, bądź hasła do kont systemowych). Nigdy nie należy wpisywać takich haseł wprost w playbooku ani przechowywać ich w repozytorium w formie jawnej. Zamiast tego zastosuj Ansible Vault – mechanizm pozwalający zaszyfrować w plikach YAML istotne dane.
Jak to zrobić?
- Utwórz plik z zaszyfrowanymi zmiennymi, np.
group_vars/all/vault.yml, zawierający klucze:Następnie zaszyfruj go poleceniemvault_mysql_password: "TwojeTajneHasloMySQL" vault_pg_password: "TwojeTajneHasloPG" vault_mssql_password: "TwojeTajneHasloMSSQL"ansible-vault encrypt group_vars/all/vault.yml(podaj hasło Vault, które będzie wymagane przy uruchamianiu playbooka). - W playbookach głównych dołącz ten plik przez
vars_files, np.:vars_files: - group_vars/all/vault.yml - W zadaniach Ansible odwołuj się do tych ukrytych haseł poprzez zmienne (np.
login_password: "{{ vault_mysql_password }}"). W ten sposób nigdy nie pojawią się one w logach czy w systemie kontroli wersji w postaci otwartego tekstu. [stackoverflow.com]
Jeśli używasz AWX/Ansible Tower, tam również jest możliwość zarządzania poświadczeniami (Credentials) – można przechowywać hasła, klucze itp. w bezpieczny sposób i w playbooku po prostu odwoływać się do nich poprzez tzw. lookup plugin (np. {{ lookup('env', 'VAR_NAME') }} dla haseł w zmiennych środowiskowych ustawionych przez mechanizm Credentials, lub bezpośrednio {{ some_credential_var }} jeśli AWX je wstrzyknie). Istotne jest, by ograniczyć dostęp do takich wrażliwych danych tylko dla osób/zespołów, które ich potrzebują.
3. Najlepsze praktyki: nazewnictwo plików, rotacja i przechowywanie
Nazewnictwo plików backupu: Wprowadzaj w nazwach plików elementy takie jak data i ewentualnie nazwa bazy. Dzięki temu łatwo od razu zidentyfikować zawartość i czas utworzenia kopii. Przykładowo, zamiast ogólnej nazwy backup.sql lepiej użyć crmdb_full_2026-03-12.sql lub nawet dodać czas crmdb_full_2026-03-12_0100.sql (dla backupu z 1:00 w nocy). Powyższe przykłady playbooków właśnie to ilustrują. W efekcie otrzymamy np. pliki:
mysql_all_2026-03-12.sql(dump wszystkich baz MySQL z 12 marca 2026)pgdb_full_2026-03-12.sql(dump bazy PostgreSQL „pgdb” z 12 marca 2026)ORCL_FULL_2026-03-12.dmp(pełny export Oracle z 12 marca 2026)SalesDB_2026-03-12.bak(pełny backup SQL Server bazy SalesDB z 12 marca 2026)
Takie nazwy z datą ułatwiają automatyczne skrypty czyszczące (np. usuwanie plików starszych niż N dni). Można ewentualnie zastosować podkatalogi datowane (np. .../2026-03-12/backup_pliki).
Kompresja: Surowe pliki zrzutów baz danych mogą zajmować dużo miejsca, często znacznie więcej niż sama baza (zwłaszcza gdy zawierają indeksy czy nieużywane miejsce). Dlatego wskazane jest kompresowanie backupów:
- W przypadku mysqldump czy pg_dump można od razu przekierować wyjście przez
gzip, np. w zadaniu shell:mysqldump ... \| gzip > /backup/moja_baza.sql.gz. Alternatywnie, po wykonaniu dumpu do.sqlmożna użyć modułu Ansiblearchivelubshell: gzip. - PostgreSQL: Gdy używamy modułu
postgresql_db, ustawienie rozszerzenia pliku na.gzspowoduje, że backup będzie spakowany (moduł automatycznie dołączy kompresję do komendy pg_dump). Można też wykonać dump w formacie własnym (custom format) i spakować go później. [ansiblepilot.com] - SQL Server: W nowszych wersjach (SQL 2008+), jak wspomniano, opcja
WITH COMPRESSIONw T-SQL znacząco zmniejsza rozmiar backupu i zwykle przyspiesza proces dzięki redukcji operacji dyskowych. Trzeba jednak pamiętać o dodatkowym obciążeniu CPU podczas kompresji. [learn.microsoft.com] - Oracle RMAN: RMAN wspiera kompresję backupów (PARAMETER
as compressed backupset) oraz deduplikację segmentów nieużywanych. Data Pump również ma parametryCOMPRESSION. - W razie potrzeby zastosuj kompresję na poziomie systemu plików (np. BTRFS/ZFS) lub zewnętrzne narzędzia (np.
pigzdo szybszej kompresji wielowątkowej gzip).
Rotacja i retencja: Ważne jest, by usuwać/przenosić starsze kopie zapasowe, aby nie zapełniły magazynu:
- Prosty sposób to użycie modułu Ansible
findz opcjąageoraz modułufile(state=absent) do usunięcia plików starszych niż określony okres. Przykład:Powyższe usunie wszystkie pliki- name: Wyszukaj stare pliki backupów (starsze niż 14 dni) find: paths: "{{ backup_base_dir }}" patterns: "*.sql" age: 14d recurse: yes register: old_backups - name: Usuń stare pliki backupów file: path: "{{ item.path }}" state: absent loop: "{{ old_backups.files }}".sqlstarsze niż 14 dni w podanym katalogu bazowym backupów (należy dostosować ścieżkę i rozszerzenie plików; dla .bak czy .dmp analogicznie). - Inną opcją jest przenoszenie starszych backupów na taśmę lub zewnętrzny serwer archiwizacji po określonym czasie – to jednak wykracza poza zakres tego omówienia. W kontekście on-premises często wykorzystuje się do tego centralne serwery backupu lub rozwiązania typu Veeam, CommVault itp. Jeśli jednak chcemy pozostać w świecie Ansible, można np. użyć modułu
synchronizedo zrsynchronizowania lokalnych backupów na zewnętrzny serwer/NAS, a następnie usunięcia lokalnych plików.
Lokalizacja backupów: Upewnij się, że kopi zapasowych nie trzymamy na tej samej macierzy/serwerze, co oryginalne bazy, bo w razie awarii sprzętu/dysku stracimy i bazę, i backup. Idealnie backupy powinny trafiać na inne maszyny lub zewnętrzne nośniki:
- W przypadku MySQL/PostgreSQL na Linux – możemy bezpośrednio w dumpie podać ścieżkę do montowanego udziału sieciowego (NFS/SMB) lub po wykonaniu lokalnie – przesłać plik na serwer backupów (moduł
copylubsynchronize). - W przypadku Windows/SQL Server – zwykle backupy wykonuje się od razu na udziały sieciowe (można użyć UNC w ścieżce, np.
\\\\nas\\backup\\db1.bakw poleceniu BACKUP DATABASE). Jeśli to niemożliwe, rozważyć skrypt Ansible wysyłający plik .bak na serwer zdalny (choć przy dużych plikach lepiej, by to SQL Server bezpośrednio zapisał na docelowym zasobie). - Pamiętaj o prawach dostępu – konto, pod którym działa serwer bazodanowy, musi mieć prawo zapisu do lokalizacji backupu (np. odpowiednie uprawnienia NTFS/SMB dla konta usługowego SQL Server, lub prawo zapisu dla użytkownika
postgresczyoraclew docelowym folderze).
4. Integracja raportowania statusu backupu
Poza samym wykonywaniem kopii zapasowych, istotne jest monitorowanie ich wyników. W skryptach powyżej używaliśmy konstrukcji register: backup_result przy zadaniach wykonujących właściwy backup (dump/eksport). Dzięki temu w zmiennej (np. mysql_backup_result, pg_backup_result itp.) mamy wynik działania modułu czy polecenia. Kluczowe jest pole rc (return code) oraz ewentualnie stderr/stdout.
Powiadomienia e-mail: W razie używania wewnętrznej infrastruktury pocztowej, można skorzystać z modułu Ansible mail na hoście sterującym, by wysłać wiadomość z informacją o sukcesie lub porażce backupu:
- name: Wyślij powiadomienie o wyniku backupu
delegate_to: localhost
mail:
host: mail.firma.pl
port: 587
username: monitor@firma.pl
password: "{{ vault_mail_password }}"
to: dba_team@firma.pl
subject: "Backup bazy {{ inventory_hostname }} - {{ backup_name }}: {{ backup_result.rc == 0 \
and 'SUKCES' or 'BŁĄD' }}"
body: >
Backup bazy {{ backup_name }} na serwerze {{ inventory_hostname }}
z dnia {{ ansible_date_time.date }} o godzinie {{ ansible_date_time.time }}
zakończył się statusem: {{ backup_result.rc == 0 and 'POWODZENIEM' or 'BŁĘDEM' }}.
{% if backup_result.rc != 0 %}
Szczegóły błędu:
{{ backup_result.stderr }}
{% endif %}
subtype: html
Powyższy task (delegowany do localhost, czyli maszyny sterującej Ansible) wyśle e-mail na adres zespołu DBA z informacją czy backup się powiódł. Treść i listę odbiorców dostosuj do swoich potrzeb. Musisz też zapewnić dostęp do serwera SMTP (parametry jak host, login, hasło).
Integracja z ServiceNow lub innym systemem ITSM: Jeśli w Twojej firmie używa się narzędzia typu ServiceNow, Jira itp. do śledzenia incydentów, możesz rozważyć automatyczne tworzenie zgłoszeń w razie niepowodzenia backupu. Przykładowo, istnieje kolekcja Ansible servicenow.itsm, która udostępnia moduł servicenow.itsm.incident do tworzenia incydentów przez API. Taki moduł można wywołać warunkowo, np.:
- name: Utwórz incydent w ServiceNow w razie błędu backupu
servicenow.itsm.incident:
data:
short_description: "Błąd backupu bazy {{ backup_name }} na serwerze {{ inventory_hostname }}"
description: "Backup z {{ ansible_date_time.iso8601 }} zakończył się niepowodzeniem: {{ backup_result.stderr }}."
severity: 2
when: backup_result.rc != 0
delegate_to: localhost
Taki krok utworzy zgłoszenie o określonym tytule i opisie, jeśli wynik backupu (backup_result.rc) wskazuje błąd. Alternatywnie, prostszym podejściem jest wysłanie e-maila lub komunikatu na czat (Slack/Teams) w razie błędu. Ważne jest, by awaria procesu backupu nie pozostała niezauważona – DB Administratorzy powinni od razu otrzymać alert, by mogli podjąć działania (np. ponowić backup ręcznie lub rozwiązać problem ze środowiskiem). W przytoczonym wcześniej artykule poświęconym skryptom RMAN autor zaleca dodanie modułów powiadomień mailowych o sukcesie/porażce do skryptu backupu. [pythian.com]
5. Harmonogramowanie automatycznego wykonywania backupów
Skrypty Ansible można zintegrować z harmonogramem zadań, aby backupy były wykonywane periodycznie bez interwencji. Mamy dwie główne ścieżki:
- CRON (po stronie serwera Ansible): Najprostszym rozwiązaniem jest uruchamianie polecenia
ansible-playbookz odpowiednim playbookiem według harmonogramu CRON na serwerze, z którego odpalamy Ansible. Np. edytując crontab użytkownika (poleceniemcrontab -e), dodaj linię:
0 1 * * * /usr/bin/ansible-playbook /home/ansible/playbooks/backup.yml --ask-vault-pass
co spowoduje uruchamianie pełnego playbooka backupów codziennie o 1:00 w nocy. (Opcja--ask-vault-passspowoduje, że crontab musi mieć dostęp do hasła Vault – zamiast tego można użyć np.--vault-password-filewskazując plik z hasłem Vault lub skonfigurować w AWX). [learnitguide.net] - Harmonogram w AWX/Ansible Tower: Jeśli używasz AWX (open-source) lub Ansible Tower, te narzędzia mają wbudowany mechanizm Schedules do cyklicznego uruchamiania zadań. Wystarczy utworzyć Job Template dla playbooka backupowego, przetestować go ręcznie, a następnie na zakładce Harmonogramy (Schedules) tego szablonu dodać nowy harmonogram. AWX pozwala na precyzyjne planowanie z użyciem standardu RRULE (znanego z kalendarzy) – można ustawić np. codzienny start o określonej godzinie, wykluczyć weekendy itp.. Po zaplanowaniu, AWX będzie dbał o uruchamianie backupu punktualnie o zadanych porach, pełniąc rolę centralnego harmonogramu (zastępując de facto serwer CRON). [oneuptime.com]
Które rozwiązanie wybrać? Jeśli masz już wdrożony AWX/Tower, wygodnie jest korzystać z jego harmonogramów – masz wtedy centralny podgląd, logi z każdej realizacji, powiadomienia o ewentualnych błędach itp. W mniejszych środowiskach, gdzie Ansible uruchamiasz ręcznie lub ze skryptów, CRON może być wystarczający. Pamiętaj jednak, że w przypadku CRON musisz zadbać o bezpieczne przechowywanie poświadczeń (np. hasła Vault) – nie powinny one stać w crontabie wprost. Często rozwiązuje się to przez użycie dedykowanego pliku z hasłem Vault (dostępnego tylko dla odpowiedniego użytkownika) lub skryptu powłoki, który wywołuje Ansible (ten skrypt może mieć zaszyte hasło lub odwoływać się do zmiennej środowiskowej).
6. Tabela porównawcza strategii i narzędzi backupu wg silnika
Na koniec, podsumujmy i porównajmy najważniejsze cechy i zalecenia dla poszczególnych silników baz danych:
| Silnik bazy | Podejście do backupu | Zalety | Ograniczenia / uwagi |
|---|---|---|---|
| MySQL / MariaDB | Backup logiczny: Narzędzie mysqldump (moduł Ansible mysql_db). Możliwy zrzut wszystkich baz jednym poleceniem [stackoverflow.com] lub pojedynczo w pętli. Backup fizyczny: Narzędzia typu Percona XtraBackup / MariaDB Backup – pozwalają na „gorący” backup bez blokowania bazy, kopiując bezpośrednio pliki danych [dbcalm.com]. |
– Mysqldump: prostota, uniwersalność (standardowy format SQL, przenośność między wersjami/technologiami) [dbcalm.com], [dbcalm.com]. – XtraBackup: szybkie kopie dużych baz (zwłaszcza > 100GB) – operują na poziomie plików, wspierają backup przyrostowy, brak przestojów w pracy bazy (hot backup) [dbcalm.com], [dbcalm.com]. |
– Dump logiczny: wolny przy wielkich bazach (konieczność przetworzenia każdej rekordów, generacji wielu INSERTów) [dbcalm.com], obciąża serwer i może wymagać blokad (np. dla MyISAM). Przy odtwarzaniu duży dump zajmuje dużo czasu (odtworzenie wszystkich rekordów) [dbcalm.com]. – Backup fizyczny: wymaga dodatkowych narzędzi i spójności wersji (backup fizyczny odtwarzać należy na identycznej lub bardzo zbliżonej wersji silnika) [dbcalm.com]. Trudniejszy do wykorzystania przy migracji (plików nie przeniesiemy na inną architekturę). |
| PostgreSQL | Backup logiczny: Narzędzie pg_dump (moduł postgresql_db z state: dump) – umożliwia zrzut pojedynczej bazy do pliku SQL lub w formacie binarnym (custom/pgdump) [ansiblepilot.com]. Backup fizyczny: Narzędzia wbudowane jak pg_basebackup do tworzenia pełnej kopii katalogu danych (współpracuje z mechanizmem WAL, daje możliwość Point-in-Time Recovery). |
– pg_dump: działa online (bez wyłączania bazy), zapewnia spójny zrzut dzięki mechanizmowi MVCC, pozwala wybierać konkretne bazy/tabele, wynikowy plik jest przenośny między wersjami PostgreSQL [codegenes.net]. Przy formacie custom lub directory wspiera kompresję i odtwarzanie wybiórcze tabel (przez pg_restore) [codegenes.net], [codegenes.net]. – pg_basebackup: prosty sposób na pełny backup całego klastera, łącznie z konfiguracją; szybki przy dużych wolumenach (kopiuje pliki zamiast rekordów) i umożliwia odtworzenie do punktu w czasie (przy archiwizacji WAL) [codegenes.net]. |
– Dump logiczny: dla bardzo dużych baz danych jest względnie wolny i zasobożerny (odczyt i serializacja wszystkich danych) [codegenes.net]. Brak natywnego wsparcia dla backupu różnicowego/przyrostowego – każde uruchomienie pg_dump to pełny zrzut. – Backup fizyczny pg_basebackup: odtwarzanie przywraca cały klaster (nie poszczególne bazy) – nie da się łatwo odzyskać pojedynczej bazy bez odtwarzania całości. Wymaga uprawnień REPLICATION i włączonego archiwizowania WAL. Nie zastępuje to potrzeby okresowego pg_dump (np. na osobnym serwerze) w celu posiadania kopii logicznej (na wypadek awarii logicznej bazy, błędu aplikacji usuwającego dane etc.). |
| Oracle | Backup fizyczny: RMAN – główne narzędzie Oracle do backupu na poziomie bloków (pełne i przyrostowe backupy, kopie archiwów redo, restore danych) [vinchin.com]. Backup logiczny: Oracle Data Pump ( expdp/impdp) – eksportuje obiekty bazy do plików binarnych .dmp (możliwy eksport całej bazy, wybranych schematów lub tabel) [vinchin.com]. |
– RMAN: oficjalne, w pełni zintegrowane z Oracle rozwiązanie backupowe. Zapewnia spójność backupu bez przerywania pracy bazy, wspiera duże środowiska (np. Oracle RAC) [vinchin.com], pozwala na automatyzację i harmonogramowanie w samej bazie (katalog RMAN lub poprzez zewnętrzne narzędzia), obsługuje kompresję i szyfrowanie backupów [vinchin.com], umożliwia bardzo szybki restore całej bazy lub poszczególnych tablespace/plików danych. – Data Pump: bardzo przydatny do szybkiego eksportu wybranych elementów (np. pojedynczego schematu, tabeli) – działa z równoległym przetwarzaniem, co przyspiesza eksport dużych wolumenów danych [vinchin.com]. Pliki .dmp są przenośne między różnymi wersjami Oracle, co ułatwia migracje i aktualizacje bazy. |
– RMAN: wymaga strategii zarządzania przestrzenią na backup (backupy mogą być składowane na dysku lub taśmach – trzeba dbać o rotację w RMAN katalogu). Konfiguracja i skrypty RMAN wymagają wiedzy specjalistycznej DBA. Brak natywnego modułu Ansible – konieczność utrzymania skryptów. – Data Pump: nie zachowuje wszystkich elementów bazy (np. ustawień konfiguracyjnych instance, praw systemowych spoza zakresu schematów itp.), więc pełen restore bazy tylko z Data Pump nie odtworzy dokładnie stanu bazy, a jedynie dane aplikacyjne. Ponadto, Data Pump nie umożliwia point-in-time recovery – służy raczej do migracji lub logical backup niż do odtworzenia po awarii. |
| MS SQL Server | Backup fizyczny (na poziomie silnika): Polecenie BACKUP DATABASE do pliku .bak – może być wywołane ręcznie lub automatycznie (SQL Server Agent, Maintenance Plans) albo zewnętrznie przez Ansible. W Ansible korzystaj z win_shell/shell lub modułów PowerShell do uruchomienia backupu. Backup logiczny: (rzadko stosowany) – eksport skryptów CREATE/INSERT (np. z użyciem narzędzia sqlpackage do tworzenia paczek BACPAC) – wykorzystywany głównie przy migracji do Azure, nie do typowego backupu. |
– Natywny backup .bak: bardzo wydajny, szczególnie z kompresją (znaczne zredukowanie rozmiaru i czasu backupu dzięki mniejszemu I/O) [learn.microsoft.com]. Pozwala na backup przyrostowy (differential) i backup dziennika transakcyjnego, co daje pełną elastyczność odtwarzania do wybranego punktu w czasie. Powszechne narzędzie, wspierane przez wiele aplikacji do backupu danych. – Skrypty T-SQL: umożliwiają wyciąganie definicji obiektów i danych do przenośnych formatów (np. BACPAC zawiera schemat + dane, nadaje się do migracji między instancjami czy na Azure SQL). |
– Backup .bak: w środowisku klastrowym (Always On Availability Groups) backupy powinny być wykonywane na preferowanym replice wtórnej, aby odciążyć główną (Ansible może to uwzględnić, np. poprzez dynamiczny wybór hosta do backupu). Duże pliki .bak wymagają zabezpieczenia odpowiedniej przestrzeni oraz przepustowości sieci przy przenoszeniu na zewnętrzny storage. – Eksport logiczny: nie nadaje się do regularnych pełnych backupów – brak wsparcia dla odtwarzania stanów transakcyjnych, a generowane skrypty mogą nie odtworzyć użytkowników, rolek, ustawień serwera itp. |
Legenda: backup logiczny – eksport w postaci pliku z instrukcjami SQL (INSERT, DDL); backup fizyczny – kopia fizycznych plików bazy danych (bez pośrednictwa SQL). W praktyce codziennej administracji bazami podstawą są backupy fizyczne (bądź ich logiczne odpowiedniki w przypadku MySQL/PG), natomiast eksporty logiczne pełnią rolę uzupełniającą (np. migracje, dodatkowe bezpieczeństwo dla wybranych danych). Wybór narzędzi i strategii powinien uwzględniać zarówno wymagania biznesowe (RPO/RTO, regulacje dot. przechowywania danych), jak i uwarunkowania techniczne (wielkość baz, dostępna przestrzeń, okna serwisowe).
Wdrożenie powyższych playbooków i zaleceń pozwoli zautomatyzować proces tworzenia backupów we wspólnym harmonogramie, odciąży codzienną pracę DBA i zminimalizuje ryzyko błędu ludzkiego. Pamiętaj, aby regularnie testować odtwarzanie danych z tworzonych kopii – nawet najlepszy backup jest bezwartościowy, jeśli nie da się go poprawnie przywrócić. Dzięki integracji z mechanizmami powiadomień będziesz na bieżąco informowany o ewentualnych problemach, co umożliwi szybkie podjęcie działań naprawczych i zapewni bezpieczeństwo kluczowych danych we wszystkich Twoich bazach. Powodzenia w automatyzacji backupów!
Źródła: Dokumentacje i artykuły branżowe, m.in. [Stack Overflow – przykład użycia mysql_db do dumpu wszystkich baz], [Ansible Pilot – backup PostgreSQL z użyciem postgresql_db], [Blog Claudiokuenzler – skrypt z mysqldump i datowaniem plików], [Pythian Blog – automatyzacja RMAN z Ansible], [Vinchin – porównanie RMAN vs Data Pump], [Porównanie backupów logicznych i fizycznych MySQL], [Codegenes – porównanie pg_dump vs pg_basebackup], [Microsoft Docs – korzyści z kompresji backupów SQL]. [stackoverflow.com] [ansiblepilot.com] [claudiokuenzler.com] [pythian.com], [pythian.com] [vinchin.com], [vinchin.com] [dbcalm.com], [dbcalm.com] [codegenes.net], [codegenes.net] [learn.microsoft.com]
Automatyzacja backupów baz danych (MySQL, PostgreSQL, Oracle, SQL Server) za pomocą Ansible
<style> :root { --accent: #464feb; --timeline-ln: linear-gradient(to bottom, transparent 0%, #b0beff 15%, #b0beff 85%, transparent 100%); --timeline-border: #ffffff; --bg-card: #f5f7fa; --bg-hover: #ebefff; --text-title: #424242; --text-accent: var(--accent); --text-sub: #424242; --radius: 12px; --border: #e0e0e0; --shadow: 0 2px 10px rgba(0, 0, 0, 0.06); --hover-shadow: 0 4px 14px rgba(39, 16, 16, 0.1); --font: "Segoe Sans", "Segoe UI", "Segoe UI Web (West European)", -apple-system, "system-ui", Roboto, "Helvetica Neue", sans-serif; --overflow-wrap: break-word; } @media (prefers-color-scheme: dark) { :root { --accent: #7385ff; --timeline-ln: linear-gradient(to bottom, transparent 0%, transparent 3%, #6264a7 30%, #6264a7 50%, transparent 97%, transparent 100%); --timeline-border: #424242; --bg-card: #1a1a1a; --bg-hover: #2a2a2a; --text-title: #ffffff; --text-sub: #ffffff; --shadow: 0 2px 10px rgba(0, 0, 0, 0.3); --hover-shadow: 0 4px 14px rgba(0, 0, 0, 0.5); --border: #3d3d3d; } } @media (prefers-contrast: more), (forced-colors: active) { :root { --accent: ActiveText; --timeline-ln: ActiveText; --timeline-border: Canvas; --bg-card: Canvas; --bg-hover: Canvas; --text-title: CanvasText; --text-sub: CanvasText; --shadow: 0 2px 10px Canvas; --hover-shadow: 0 4px 14px Canvas; --border: ButtonBorder; } } .insights-container { display: grid; grid-template-columns: repeat(2,minmax(240px,1fr)); padding: 0px 16px 0px 16px; gap: 16px; margin: 0 0; font-family: var(--font); } .insight-card:last-child:nth-child(odd){ grid-column: 1 / -1; } .insight-card { background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); box-shadow: var(--shadow); min-width: 220px; padding: 16px 20px 16px 20px; } .insight-card:hover { background-color: var(--bg-hover); } .insight-card h4 { margin: 0px 0px 8px 0px; font-size: 1.1rem; color: var(--text-accent); font-weight: 600; display: flex; align-items: center; gap: 8px; } .insight-card .icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; font-size: 1.1rem; color: var(--text-accent); } .insight-card p { font-size: 0.92rem; color: var(--text-sub); line-height: 1.5; margin: 0px; overflow-wrap: var(--overflow-wrap); } .insight-card p b, .insight-card p strong { font-weight: 600; } .metrics-container { display:grid; grid-template-columns:repeat(2,minmax(210px,1fr)); font-family: var(--font); padding: 0px 16px 0px 16px; gap: 16px; } .metric-card:last-child:nth-child(odd){ grid-column:1 / -1; } .metric-card { flex: 1 1 210px; padding: 16px; background-color: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); text-align: center; display: flex; flex-direction: column; gap: 8px; } .metric-card:hover { background-color: var(--bg-hover); } .metric-card h4 { margin: 0px; font-size: 1rem; color: var(--text-title); font-weight: 600; } .metric-card .metric-card-value { margin: 0px; font-size: 1.4rem; font-weight: 600; color: var(--text-accent); } .metric-card p { font-size: 0.85rem; color: var(--text-sub); line-height: 1.45; margin: 0; overflow-wrap: var(--overflow-wrap); } .timeline-container { position: relative; margin: 0 0 0 0; padding: 0px 16px 0px 56px; list-style: none; font-family: var(--font); font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container::before { content: ""; position: absolute; top: 0; left: calc(-40px + 56px); width: 2px; height: 100%; background: var(--timeline-ln); } .timeline-container > li { position: relative; margin-bottom: 16px; padding: 16px 20px 16px 20px; border-radius: var(--radius); background: var(--bg-card); border: 1px solid var(--border); } .timeline-container > li:last-child { margin-bottom: 0px; } .timeline-container > li:hover { background-color: var(--bg-hover); } .timeline-container > li::before { content: ""; position: absolute; top: 18px; left: -40px; width: 14px; height: 14px; background: var(--accent); border: var(--timeline-border) 2px solid; border-radius: 50%; transform: translateX(-50%); box-shadow: 0px 0px 2px 0px #00000012, 0px 4px 8px 0px #00000014; } .timeline-container > li h4 { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); } .timeline-container > li h4 em { margin: 0 0 5px; font-size: 1rem; font-weight: 600; color: var(--accent); font-style: normal; } .timeline-container > li * { margin: 0; font-size: 0.9rem; color: var(--text-sub); line-height: 1.4; } .timeline-container > li * b, .timeline-container > li * strong { font-weight: 600; } @media (max-width:600px){ .metrics-container, .insights-container{ grid-template-columns:1fr; } } </style>🛠 Dedykowane moduły i narzędzia
Wykorzystaj natywne moduły Ansible do backupów gdzie to możliwe: MySQL/MariaDB – moduł mysql_db z opcją dump (oparty na mysqldump); PostgreSQL – moduł postgresql_db (wykorzystuje pg_dump). Dla Oracle i SQL Server użyj natywnych narzędzi baz danych wywołując je w playbooku (np. skrypty RMAN/expdp dla Oracle, polecenie T-SQL BACKUP dla SQL) – brak wbudowanych modułów do bezpośredniego backupu tych silników.
🔐 Bezpieczne poświadczenia
Wrażliwe dane (hasła do baz, klucze) przechowuj w zaszyfrowanych zmiennych Ansible Vault zamiast wprost w playbooku. Zapobiega to przypadkowemu ujawnieniu haseł. W playbookach odwołuj się do zaszyfrowanych wartości (np. {{ vault_db_password }}) – Ansible odszyfruje je w locie podczas wykonywania.
📁 Nazwy, kompresja i rotacja
Nadawaj kopiom zapasowym unikalne nazwy zawierające datę/godzinę (np. miadb_backup_20260312.sql) dla łatwej identyfikacji. Stosuj kompresję backupów, aby oszczędzić miejsce i przyspieszyć operacje (np. dump przez gzip; SQL Server obsługuje kompresję natywnie). Zaimplementuj rotację – np. za pomocą zadań Ansible lub skryptu czyszczącego – usuwaj pliki starsze niż X dni, utrzymując tylko wymagany okres retencji danych (np. ostatnie 7-14 dni).
📅 Harmonogram i powiadomienia
Automatyzuj uruchamianie backupów: skonfiguruj zadania CRON na serwerze Ansible lub harmonogram w AWX/Tower, aby playbooki wykonywały się codziennie o ustalonej porze (np. 1:00 w nocy). Monitoruj wyniki – w razie błędu backupu wyślij powiadomienie (np. e-mail do administratorów lub automatyczne zgłoszenie awarii w ServiceNow). Regularnie testuj odtwarzanie z backupów, by mieć pewność, że procedury działają.
1. Przykładowe playbooki dla pełnych backupów różnych silników
Poniżej przedstawiono przykładowe playbooki Ansible (lub role) realizujące pełny backup dla każdej z wymienionych baz danych. Każdy playbook uwzględnia zalecane moduły bądź narzędzia, sposób podania poświadczeń (korzystając z Ansible Vault), oraz zapisywanie plików kopii zapasowych w ustalonym katalogu.
1.1 MySQL / MariaDB – backup przy pomocy mysqldump
Dla MySQL i MariaDB najprostszą metodą jest wykonanie backupu logicznego za pomocą narzędzia mysqldump. Ansible oferuje moduł community.mysql.mysql_db, który potrafi wygenerować zrzut bazy danych (wewnętrznie używa mysqldump). Można nim wykonać dump konkretnej bazy lub wszystkich baz naraz (parametr name: all). Alternatywnie, można wywołać bezpośrednio polecenie mysqldump poprzez moduł shell lub command. Poniżej przykład roli mysql_backup tworzącej pełne kopie wszystkich baz danych MySQL na danym hoście: [stackoverflow.com]
# roles/mysql_backup/tasks/main.yml
- name: Upewnij się, że katalog backupów istnieje
file:
path: "{{ mysql_backup_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Wykonaj dump wszystkich baz MySQL do jednego pliku
community.mysql.mysql_db:
state: dump
name: all
target: "{{ mysql_backup_dir }}/mysql_all_{{ ansible_date_time.date }}.sql"
login_user: "{{ mysql_user }}"
login_password: "{{ mysql_password }}"
register: mysql_backup_result
when: mysql_backup_strategy == 'single_file'
- name: Wykonaj dump każdej bazy MySQL do osobnego pliku
shell: mysqldump -u{{ mysql_user }} -p'{{ mysql_password }}' {{ item }} > "{{ mysql_backup_dir }}/{{ item }}_{{ ansible_date_time.date }}.sql"
with_items: "{{ mysql_databases_list }}"
when: mysql_backup_strategy == 'separate_files'
register: mysql_backup_result
Objaśnienia:
- Zmienna
mysql_backup_dirpowinna wskazywać lokalizację (na serwerze baz danych), gdzie zapiszemy pliki backupu. Dobrze, by był to osobny dysk lub katalog na backupy. - Rolę zaprojektowano elastycznie: jeśli zmienna
mysql_backup_strategyma wartość"single_file", używamy modułu mysql_db zname: alldo zrzucenia wszystkich baz do jednego pliku (np.mysql_all_2026-03-12.sql). Jeśli zaś strategia to"separate_files", najpierw należy uzyskać listę wszystkich baz danych i zapisać ją wmysql_databases_list(np. przy użyciu modułumysql_infolub poleceniaSHOW DATABASES). Następnie powyższy task w pętli wykonamysqldumpdla każdej bazy osobno, pomijając systemowe bazy (mysql,information_schemaitd.). Każda baza trafi do osobnego pliku o nazwienazwaBazy_data.sql– dzięki temu łatwiej zarządzać pojedynczymi dumpami lub przywracać pojedyncze bazy w razie potrzeby. [stackoverflow.com] - Zmienna
mysql_userpowinna być uprawnionym użytkownikiem (np.rootlub dedykowany użytkownik backupowy z uprawnieniamiSELECT/lock na wszystkich bazach).mysql_passwordjest jego hasłem – przechowuj je w Ansible Vault i odszyfruj do zmiennej podczas działania playbooka (jak pokazano wyżej). - W powyższych przykładach użyto
ansible_date_time.date(co zwróci datę w formacie YYYY-MM-DD) jako część nazwy pliku backupu. Można użyć innego formatu daty/godziny (np.{{ ansible_date_time.iso8601 }}dla pełnego znacznika czasu). Dzięki temu każda kopia ma unikalną nazwę z datą, co ułatwia rozróżnienie kolejnych backupów.
Moduły: community.mysql.mysql_db – do wykonywania dumpów MySQL/MariaDB. Wymaga zainstalowanej kolekcji community.mysql oraz dostępności programu mysqldump na serwerze bazy. Alternatywnie, modul community.mysql.mysql_info może pobrać listę baz. Jeśli potrzebna jest większa kontrola (np. filtrowanie określonych baz wg wzorca), można posłużyć się bezpośrednio modułem shell/command z mysqldump, jak pokazano wyżej, ewentualnie dynamicznie budować listę baz do dumpu (np. z pominięciem systemowych). [claudiokuenzler.com] [stackoverflow.com]
1.2 PostgreSQL – backup przy pomocy pg_dump
PostgreSQL również umożliwia backup logiczny (zrzut bazy do pliku .sql lub formatu skompresowanego) za pomocą narzędzia pg_dump. Ansible posiada moduł community.postgresql.postgresql_db, który potrafi wykonać operację dump – wewnętrznie korzysta z pg_dump i potrafi zapisać wskazaną bazę do pliku docelowego. Przykładowa rola postgres_backup: [ansiblepilot.com]
# roles/postgres_backup/tasks/main.yml
- name: Zainstaluj bibliotekę kliencką PostgreSQL (psycopg2)
package:
name: python3-psycopg2
state: present
- name: Upewnij się, że katalog backupów istnieje
file:
path: "{{ pg_backup_dir }}"
state: directory
owner: postgres
group: postgres
mode: '0700'
- name: Wykonaj dump bazy {{ pg_database }}
community.postgresql.postgresql_db:
state: dump
name: "{{ pg_database }}"
target: "{{ pg_backup_dir }}/{{ pg_database }}_{{ ansible_date_time.date }}.sql"
become: yes
become_user: postgres
register: pg_backup_result
Objaśnienia:
- Użyto tu parametru
state: dumpmodułu postgresql_db, co spowoduje wywołaniepg_dumpna wskazanej bazie (name: "{{ pg_database }}") i zapisanie wynikowego dumpa do plikutarget. Moduł ten wymaga zainstalowanej na zdalnym serwerze biblioteki psycopg2 (stąd pierwszy task instalujący pakiet Python). Domyślniepostgresql_dbutworzy nieskompresowany dump SQL; można go później spakować osobno (np. komendągzipw kolejnym tasku) lub od razu wskazać nazwę pliku z rozszerzeniem.gz(moduł wtedy automatycznie kompresuje wyjściepg_dump). [ansiblepilot.com] - Playbook wykonuje się z uprawnieniami użytkownika systemowego
postgres(poprzezbecome_user: postgres), aby mieć dostęp do bazy. Alternatywnie można podać parametry połączenia (użytkownik/hasło bazy) bezpośrednio w zadaniu, ale wykorzystanie konta systemowego postgres często bywa prostsze wewnątrz serwera baz danych PostgreSQL. - Należy zdefiniować zmienną
pg_database(nazwa bazy do backupu) – w przypadku wielu baz, można wywoływać rolę kilkukrotnie dla różnych baz lub iterować po liście baz. Jeżeli chcemy backupować wszystkie bazy w instancji, można użyć pętli, podobnie jak to pokazano dla MySQL (np. pętlę po wynikach poleceniapsql -lfiltrując bazy systemowe).
Moduły: community.postgresql.postgresql_db – obsługuje tworzenie (present), usuwanie (absent), dump i odtwarzanie (restore) baz PostgreSQL. W razie potrzeby można użyć też community.postgresql.postgresql_dump (analogiczny moduł tylko do dumpów) lub wykonać surowe polecenie pg_dump przez shell. Jednak użycie gotowego modułu upraszcza operację i dba o spójność (np. wykorzystuje opcję --no-password i zmienne środowiskowe do autoryzacji). [ansiblepilot.com]
1.3 Oracle – backup przy pomocy RMAN lub Data Pump
W przypadku Oracle sprawa jest nieco bardziej złożona, ponieważ Ansible nie ma oficjalnego modułu do wykonywania backupu Oracle (poza specyficznymi modułami do Oracle Cloud, które tutaj nie mają zastosowania). Standardem backupu fizycznego Oracle jest RMAN (Recovery Manager) – narzędzie Oracle do tworzenia pełnych i przyrostowych kopii fizycznych baz danych na poziomie bloków oraz zarządzania archiwizacją redo logów. Alternatywną metodą, w szczególności do celów migrowania danych lub tworzenia logicznych kopii wybranych tabel/schematów, jest Oracle Data Pump (expdp/impdp) – narzędzie do eksportu i importu danych (backup logiczny).
Rekomendowane podejście produkcyjne: W środowisku produkcyjnym Oracle zaleca się używanie RMAN do regularnych pełnych backupów, gdyż jest to rozwiązanie najszybsze, zintegrowane z mechanizmami bazy i wspierające zaawansowane scenariusze odzyskiwania (np. przywracanie point-in-time z wykorzystaniem archivelogów). Data Pump natomiast można używać dodatkowo do eksportów wybranych danych (np. pojedynczych schematów) lub migracji między wersjami Oracle, ale nie zastępuje to pełnych backupów RMAN w kontekście odtwarzania awaryjnego całej bazy. [vinchin.com]
Automatyzacja RMAN przez Ansible: Backupy RMAN zwykle są definiowane skryptami wykonywanymi na serwerze bazy. Ansible może pomóc w generowaniu i dystrybucji skryptów RMAN oraz towarzyszących im zadań harmonogramu (cron) na serwerach Oracle, zapewniając standaryzację i spójność konfiguracji we wszystkich środowiskach. Przykładowo, można przygotować szablon skryptu RMAN (jako plik .rman lub skrypt powłoki odpalający RMAN z odpowiednimi komendami) i użyć modułu template, aby wstawić tam parametry (lokalizacja backupów, nazwa SID, polityka retencji, itp.). Następnie modułem cron można utworzyć zadanie harmonogramu odpalające ten skrypt np. codziennie w nocy. [pythian.com]
Przykład: Poniżej znajduje się prosty przykład użycia Data Pump do wykonania pełnego eksportu wszystkich obiektów bazy (tzw. full export) za pomocą Ansible:
# roles/oracle_backup/tasks/main.yml (fragment)
- name: Ustaw zmienne środowiskowe Oracle (dla usera oracle)
become: yes
become_user: oracle
shell: . /home/oracle/.bash_profile && echo ORACLE_SID=$ORACLE_SID
register: oracle_env
- name: Wykonaj pełny export Data Pump
become: yes
become_user: oracle
shell: |
expdp \'/ as sysdba\' full=Y directory=DATA_PUMP_DIR dumpfile={{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.dmp logfile={{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.log
args:
creates: "{{ oracle_data_pump_dir }}/{{ oracle_sid }}_FULL_{{ ansible_date_time.date }}.dmp"
register: oracle_backup_result
Objaśnienia:
- Powyższy task zakłada, że na serwerze baza działa pod SID
{{ oracle_sid }}i że user systemowyoraclema w swoim.bash_profileustawione zmienne środowiskoweORACLE_HOME,ORACLE_SIDitp. Dlatego w pierwszym kroku upewniamy się, że po przełączeniu na kontooraclemamy skonfigurowane środowisko (poleceniem.wczytujemy profil). - Używamy tutaj polecenia
expdp(Export Data Pump) z parametremfull=Y, co oznacza eksport całej bazy (wszystkich schematów) do pliku.dmpzapisanego w lokalizacji wskazanej przez Oracle Directory o nazwieDATA_PUMP_DIR. Nazwa pliku zawiera SID bazy oraz datę (np.ORCL_FULL_2026-03-12.dmp). - Opcja
createsprzy zadaniushellpowoduje, że Ansible pominie wykonanie zadania, jeśli plik dumpa już istnieje – to zabezpieczenie przed nadpisaniem istniejącej kopii (można też zamiast tego użyć unikalnej nazwy pliku per uruchomienie). - Uwaga: Taki pełny eksport Data Pump nie zastępuje kopii RMAN – traktuj go raczej jako uzupełniającą kopię logiczną. Do pełnego backupu fizycznego posłuż się RMAN. Można zautomatyzować RMAN w Ansible np. przygotowując plik skryptowy:
- Utwórz w roli szablon
backup.rman.j2zawierający komendy RMAN (BACKUP DATABASE PLUS ARCHIVELOG, itp.), z parametrami takimi jak ścieżka docelowa, ustawienia retencji, kanały itp., wypełnianymi przez zmienne. - Za pomocą modułu
templatewygeneruj skrypt RMAN na serwerze. - Uruchom skrypt RMAN poleceniem
shell: rman target / @/ścieżka/do/skryptu.rman. - Alternatywnie, możesz wykorzystać istniejące community role/plugins. Np. kolekcja oravirt.oracle zawiera moduły do zarządzania Oracle (choć gotowe moduły do backupu RMAN mogą wymagać dodatkowej konfiguracji).
- Utwórz w roli szablon
- Podobnie jak w poprzednich przypadkach, upewnij się, że pliki backupu są zapisywane na odpowiednim dysku (np. udział sieciowy lub dedykowany mount point o odpowiedniej pojemności), a hasła (np. do konta sys/system, jeśli używasz expdp z takimi poświadczeniami) są bezpiecznie przechowywane (Vault).
Moduły/narzędzia: Brak oficjalnych modułów do backupu Oracle – wykorzystujemy polecenia systemowe. W przykładzie powyżej użyto Data Pump (expdp). RMAN z kolei może być wywoływany w trybie nienadzorowanym (rman target / cmdfile=...) i generować kopie na dysk lub taśmę. W automatyzacji warto pamiętać o:
- Spójność danych: w przypadku klastrów (np. Oracle RAC) czy dużych baz, RMAN zadba o spójność. W przypadku Data Pump pełny eksport może być wykonywany online, ale nie jest to backup transakcyjny – nie zachowa np. niezatwierdzonych transakcji ani informacji koniecznych do odtworzenia do punktu w czasie.
- Czas trwania: Eksport Data Pump przyspiesza backup poprzez mechanizmy przetwarzania równoległego, ale wciąż przy dużych wolumenach danych może trwać długo i generować bardzo duże pliki .dmp. RMAN jest generalnie szybszy przy dużych bazach, zwłaszcza dzięki możliwości backupu przyrostowego i kopiowania bitowego danych zamiast przez SQL. [vinchin.com]
1.4 Microsoft SQL Server – backup poleceniem BACKUP DATABASE
W przypadku Microsoft SQL Servera również nie istnieje prosty dedykowany moduł do wykonania backupu (moduł mssql_db obsługuje tworzenie i usuwanie baz oraz import, ale nie posiada opcji dump). Dlatego należy posłużyć się natywnymi mechanizmami SQL Server. Standardowo pełny backup bazy SQL Server wykonuje się poleceniem T-SQL BACKUP DATABASE ... TO DISK = 'plik.bak'. Możemy je wywołać z Ansible na dwa sposoby: [ansible.fontein.de]
-
Na serwerach Windows: użyć modułu
win_shelllubwin_command, aby uruchomić narzędzie wiersza poleceńsqlcmdbądź PowerShell. Przykład zadania Ansible na Windows może wyglądać tak:- name: Pełny backup bazy MSSQL ansible.windows.win_shell: | Backup-SqlDatabase -ServerInstance "{{ mssql_instance_name }}" -Database "{{ mssql_database }}" \ -BackupFile "{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak" \ -CompressionOption On args: executable: PowershellPowyższe zadanie wykorzystuje polecenie PowerShell (
Backup-SqlDatabasez modułu SqlServer) do wykonania pełnego backupu wskazanej bazy. Parametr-CompressionOption Onwłącza kompresję backupu (o ile edycja SQL Server na to pozwala – w nowoczesnych wersjach SQL Server kompresja backupów jest dostępna w edycjach Standard i Enterprise). Zamiast PowerShell można użyćsqlcmd: [learn.microsoft.com], [learn.microsoft.com]- name: Pełny backup bazy MSSQL (alternatywnie przez sqlcmd) ansible.windows.win_shell: | sqlcmd -Q "BACKUP DATABASE [{{ mssql_database }}] TO DISK = N'{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak' WITH INIT, COMPRESSION"Ten wariant wykonuje analogiczne polecenie T-SQL poprzez narzędzie linii komend
sqlcmd. PrzełącznikWITH COMPRESSIONwłącza kompresję backupu, aINITnadpisuje istniejący plik kopii (jeśli chcemy zachować wiele pokoleń backupów, można pominąćINITlub dodawać timestamp do nazwy pliku). -
Na serwerach Linux (SQL Server na Linux): składnia T-SQL jest identyczna, ale wywołujemy
sqlcmd(lubbcp/sqlpackagew zależności od potrzeb) za pomocą modułushell. Np.:- name: Pełny backup bazy MSSQL (Linux) shell: /opt/mssql-tools/bin/sqlcmd -S {{ mssql_hostname }} -U {{ mssql_user }} -P '{{ mssql_password }}' -Q "BACKUP DATABASE [{{ mssql_database }}] TO DISK = N'{{ mssql_backup_dir }}/{{ mssql_database }}_{{ ansible_date_time.date }}.bak' WITH INIT, COMPRESSION"(Oczywiście należy wcześniej zainstalować klienta sqlcmd na serwerze control machine lub zainstalować go na zdalnym hoście i odpowiednio dostosować polecenie).
Moduły/role: Warto wspomnieć, że istnieją kolekcje społecznościowe ułatwiające zarządzanie SQL Serverem:
- community.general.mssql_script – umożliwia wykonanie skryptu SQL na bazie MSSQL (np. możemy nim wykonać zapytanie BACKUP DATABASE zamiast korzystać z
win_shell). - lowlydba.sqlserver.backup – specjalizowany moduł (w kolekcji
lowlydba.sqlserver) służący do wykonywania backupu bazy SQL Server, oparty o moduł dbatools w PowerShell. Wymaga on jednak zainstalowania na serwerze docelowym biblioteki dbatools (PowerShell) i może być wykorzystany, jeśli decydujemy się na to dodatkowe zależne środowisko. Przykładowe użycie: [docs.ansible.com]Ten moduł obsługuje różne typy backupu (Full, Differential, Log) i pod spodem korzysta z dbatools (popularnego modułu PS dla SQL Server).- name: Backup bazy za pomocą modułu lowlydba.sqlserver.backup lowlydba.sqlserver.backup: database: "{{ mssql_database }}" path: "{{ mssql_backup_dir }}\\{{ mssql_database }}_{{ ansible_date_time.date }}.bak" type: Full compression: true
Bezpieczeństwo: Niezależnie od metody, pamiętaj o przekazaniu poświadczeń dostępu do bazy:
- Dla
sqlcmdmożna użyć autentykacji Windows (Trusted Connection) jeśli Ansible uruchamia zdalnie komendę na Windows z kontekstu autoryzowanego użytkownika domenowego. W przeciwnym razie podaj użytkownika/hasło (-U/-Pjak wyżej) – hasło oczywiście z Vault. - Dla modułów Ansible (np.
mssql_scriptczylowlydba.sqlserver.backup) parametrylogin_user,login_passwordprzekaż z bezpiecznie przechowywanych zmiennych.
Uwaga dot. wydajności: Backupy SQL Server są na ogół szybkie, zwłaszcza przy włączonej kompresji, która zmniejsza ilość danych do zapisania na dysk. Należy jednak monitorować obciążenie CPU podczas kompresji – może być znaczące, szczególnie przy dużych bazach, więc w razie potrzeby planuj backupy w oknach mniejszego obciążenia serwera. Warto też rozważyć backup różnicowy (Differential) między pełnymi kopiami – SQL Server wspiera tworzenie backupów przyrostowych, co pozwala np. robić jedną pełną kopię tygodniowo i codziennie mniejsze backupy różnicowe. Dla zapewnienia Point-In-Time Recovery w SQL Server należy regularnie backupować również log transakcyjny (BACKUP LOG) – także to można zautomatyzować Ansiblem (np. oddzielny playbook odpalany co godzinę). Pełna strategia mogłaby wyglądać: pełny backup .bak co niedzielę, backupy różnicowe .bak codziennie, backup logów co godzinę; odtworzenie bazy do konkretnego punktu czasu wymaga wtedy ostatniego pełnego + ostatniego różnicowego + logów do żądanego momentu. [learn.microsoft.com]
2. Zarządzanie poświadczeniami za pomocą Ansible Vault
Praktycznie wszystkie playbooki backupowe muszą korzystać z poświadczeń dostępowych do baz danych (czy to hasła użytkownika SQL, czy hasła systemowego, np. sys dla Oracle, bądź hasła do kont systemowych). Nigdy nie należy wpisywać takich haseł wprost w playbooku ani przechowywać ich w repozytorium w formie jawnej. Zamiast tego zastosuj Ansible Vault – mechanizm pozwalający zaszyfrować w plikach YAML istotne dane.
Jak to zrobić?
- Utwórz plik z zaszyfrowanymi zmiennymi, np.
group_vars/all/vault.yml, zawierający klucze:Następnie zaszyfruj go poleceniemvault_mysql_password: "TwojeTajneHasloMySQL" vault_pg_password: "TwojeTajneHasloPG" vault_mssql_password: "TwojeTajneHasloMSSQL"ansible-vault encrypt group_vars/all/vault.yml(podaj hasło Vault, które będzie wymagane przy uruchamianiu playbooka). - W playbookach głównych dołącz ten plik przez
vars_files, np.:vars_files: - group_vars/all/vault.yml - W zadaniach Ansible odwołuj się do tych ukrytych haseł poprzez zmienne (np.
login_password: "{{ vault_mysql_password }}"). W ten sposób nigdy nie pojawią się one w logach czy w systemie kontroli wersji w postaci otwartego tekstu. [stackoverflow.com]
Jeśli używasz AWX/Ansible Tower, tam również jest możliwość zarządzania poświadczeniami (Credentials) – można przechowywać hasła, klucze itp. w bezpieczny sposób i w playbooku po prostu odwoływać się do nich poprzez tzw. lookup plugin (np. {{ lookup('env', 'VAR_NAME') }} dla haseł w zmiennych środowiskowych ustawionych przez mechanizm Credentials, lub bezpośrednio {{ some_credential_var }} jeśli AWX je wstrzyknie). Istotne jest, by ograniczyć dostęp do takich wrażliwych danych tylko dla osób/zespołów, które ich potrzebują.
3. Najlepsze praktyki: nazewnictwo plików, rotacja i przechowywanie
Nazewnictwo plików backupu: Wprowadzaj w nazwach plików elementy takie jak data i ewentualnie nazwa bazy. Dzięki temu łatwo od razu zidentyfikować zawartość i czas utworzenia kopii. Przykładowo, zamiast ogólnej nazwy backup.sql lepiej użyć crmdb_full_2026-03-12.sql lub nawet dodać czas crmdb_full_2026-03-12_0100.sql (dla backupu z 1:00 w nocy). Powyższe przykłady playbooków właśnie to ilustrują. W efekcie otrzymamy np. pliki:
mysql_all_2026-03-12.sql(dump wszystkich baz MySQL z 12 marca 2026)pgdb_full_2026-03-12.sql(dump bazy PostgreSQL „pgdb” z 12 marca 2026)ORCL_FULL_2026-03-12.dmp(pełny export Oracle z 12 marca 2026)SalesDB_2026-03-12.bak(pełny backup SQL Server bazy SalesDB z 12 marca 2026)
Takie nazwy z datą ułatwiają automatyczne skrypty czyszczące (np. usuwanie plików starszych niż N dni). Można ewentualnie zastosować podkatalogi datowane (np. .../2026-03-12/backup_pliki).
Kompresja: Surowe pliki zrzutów baz danych mogą zajmować dużo miejsca, często znacznie więcej niż sama baza (zwłaszcza gdy zawierają indeksy czy nieużywane miejsce). Dlatego wskazane jest kompresowanie backupów:
- W przypadku mysqldump czy pg_dump można od razu przekierować wyjście przez
gzip, np. w zadaniu shell:mysqldump ... \| gzip > /backup/moja_baza.sql.gz. Alternatywnie, po wykonaniu dumpu do.sqlmożna użyć modułu Ansiblearchivelubshell: gzip. - PostgreSQL: Gdy używamy modułu
postgresql_db, ustawienie rozszerzenia pliku na.gzspowoduje, że backup będzie spakowany (moduł automatycznie dołączy kompresję do komendy pg_dump). Można też wykonać dump w formacie własnym (custom format) i spakować go później. [ansiblepilot.com] - SQL Server: W nowszych wersjach (SQL 2008+), jak wspomniano, opcja
WITH COMPRESSIONw T-SQL znacząco zmniejsza rozmiar backupu i zwykle przyspiesza proces dzięki redukcji operacji dyskowych. Trzeba jednak pamiętać o dodatkowym obciążeniu CPU podczas kompresji. [learn.microsoft.com] - Oracle RMAN: RMAN wspiera kompresję backupów (PARAMETER
as compressed backupset) oraz deduplikację segmentów nieużywanych. Data Pump również ma parametryCOMPRESSION. - W razie potrzeby zastosuj kompresję na poziomie systemu plików (np. BTRFS/ZFS) lub zewnętrzne narzędzia (np.
pigzdo szybszej kompresji wielowątkowej gzip).
Rotacja i retencja: Ważne jest, by usuwać/przenosić starsze kopie zapasowe, aby nie zapełniły magazynu:
- Prosty sposób to użycie modułu Ansible
findz opcjąageoraz modułufile(state=absent) do usunięcia plików starszych niż określony okres. Przykład:Powyższe usunie wszystkie pliki- name: Wyszukaj stare pliki backupów (starsze niż 14 dni) find: paths: "{{ backup_base_dir }}" patterns: "*.sql" age: 14d recurse: yes register: old_backups - name: Usuń stare pliki backupów file: path: "{{ item.path }}" state: absent loop: "{{ old_backups.files }}".sqlstarsze niż 14 dni w podanym katalogu bazowym backupów (należy dostosować ścieżkę i rozszerzenie plików; dla .bak czy .dmp analogicznie). - Inną opcją jest przenoszenie starszych backupów na taśmę lub zewnętrzny serwer archiwizacji po określonym czasie – to jednak wykracza poza zakres tego omówienia. W kontekście on-premises często wykorzystuje się do tego centralne serwery backupu lub rozwiązania typu Veeam, CommVault itp. Jeśli jednak chcemy pozostać w świecie Ansible, można np. użyć modułu
synchronizedo zrsynchronizowania lokalnych backupów na zewnętrzny serwer/NAS, a następnie usunięcia lokalnych plików.
Lokalizacja backupów: Upewnij się, że kopi zapasowych nie trzymamy na tej samej macierzy/serwerze, co oryginalne bazy, bo w razie awarii sprzętu/dysku stracimy i bazę, i backup. Idealnie backupy powinny trafiać na inne maszyny lub zewnętrzne nośniki:
- W przypadku MySQL/PostgreSQL na Linux – możemy bezpośrednio w dumpie podać ścieżkę do montowanego udziału sieciowego (NFS/SMB) lub po wykonaniu lokalnie – przesłać plik na serwer backupów (moduł
copylubsynchronize). - W przypadku Windows/SQL Server – zwykle backupy wykonuje się od razu na udziały sieciowe (można użyć UNC w ścieżce, np.
\\\\nas\\backup\\db1.bakw poleceniu BACKUP DATABASE). Jeśli to niemożliwe, rozważyć skrypt Ansible wysyłający plik .bak na serwer zdalny (choć przy dużych plikach lepiej, by to SQL Server bezpośrednio zapisał na docelowym zasobie). - Pamiętaj o prawach dostępu – konto, pod którym działa serwer bazodanowy, musi mieć prawo zapisu do lokalizacji backupu (np. odpowiednie uprawnienia NTFS/SMB dla konta usługowego SQL Server, lub prawo zapisu dla użytkownika
postgresczyoraclew docelowym folderze).
4. Integracja raportowania statusu backupu
Poza samym wykonywaniem kopii zapasowych, istotne jest monitorowanie ich wyników. W skryptach powyżej używaliśmy konstrukcji register: backup_result przy zadaniach wykonujących właściwy backup (dump/eksport). Dzięki temu w zmiennej (np. mysql_backup_result, pg_backup_result itp.) mamy wynik działania modułu czy polecenia. Kluczowe jest pole rc (return code) oraz ewentualnie stderr/stdout.
Powiadomienia e-mail: W razie używania wewnętrznej infrastruktury pocztowej, można skorzystać z modułu Ansible mail na hoście sterującym, by wysłać wiadomość z informacją o sukcesie lub porażce backupu:
- name: Wyślij powiadomienie o wyniku backupu
delegate_to: localhost
mail:
host: mail.firma.pl
port: 587
username: monitor@firma.pl
password: "{{ vault_mail_password }}"
to: dba_team@firma.pl
subject: "Backup bazy {{ inventory_hostname }} - {{ backup_name }}: {{ backup_result.rc == 0 \
and 'SUKCES' or 'BŁĄD' }}"
body: >
Backup bazy {{ backup_name }} na serwerze {{ inventory_hostname }}
z dnia {{ ansible_date_time.date }} o godzinie {{ ansible_date_time.time }}
zakończył się statusem: {{ backup_result.rc == 0 and 'POWODZENIEM' or 'BŁĘDEM' }}.
{% if backup_result.rc != 0 %}
Szczegóły błędu:
{{ backup_result.stderr }}
{% endif %}
subtype: html
Powyższy task (delegowany do localhost, czyli maszyny sterującej Ansible) wyśle e-mail na adres zespołu DBA z informacją czy backup się powiódł. Treść i listę odbiorców dostosuj do swoich potrzeb. Musisz też zapewnić dostęp do serwera SMTP (parametry jak host, login, hasło).
Integracja z ServiceNow lub innym systemem ITSM: Jeśli w Twojej firmie używa się narzędzia typu ServiceNow, Jira itp. do śledzenia incydentów, możesz rozważyć automatyczne tworzenie zgłoszeń w razie niepowodzenia backupu. Przykładowo, istnieje kolekcja Ansible servicenow.itsm, która udostępnia moduł servicenow.itsm.incident do tworzenia incydentów przez API. Taki moduł można wywołać warunkowo, np.:
- name: Utwórz incydent w ServiceNow w razie błędu backupu
servicenow.itsm.incident:
data:
short_description: "Błąd backupu bazy {{ backup_name }} na serwerze {{ inventory_hostname }}"
description: "Backup z {{ ansible_date_time.iso8601 }} zakończył się niepowodzeniem: {{ backup_result.stderr }}."
severity: 2
when: backup_result.rc != 0
delegate_to: localhost
Taki krok utworzy zgłoszenie o określonym tytule i opisie, jeśli wynik backupu (backup_result.rc) wskazuje błąd. Alternatywnie, prostszym podejściem jest wysłanie e-maila lub komunikatu na czat (Slack/Teams) w razie błędu. Ważne jest, by awaria procesu backupu nie pozostała niezauważona – DB Administratorzy powinni od razu otrzymać alert, by mogli podjąć działania (np. ponowić backup ręcznie lub rozwiązać problem ze środowiskiem). W przytoczonym wcześniej artykule poświęconym skryptom RMAN autor zaleca dodanie modułów powiadomień mailowych o sukcesie/porażce do skryptu backupu. [pythian.com]
5. Harmonogramowanie automatycznego wykonywania backupów
Skrypty Ansible można zintegrować z harmonogramem zadań, aby backupy były wykonywane periodycznie bez interwencji. Mamy dwie główne ścieżki:
- CRON (po stronie serwera Ansible): Najprostszym rozwiązaniem jest uruchamianie polecenia
ansible-playbookz odpowiednim playbookiem według harmonogramu CRON na serwerze, z którego odpalamy Ansible. Np. edytując crontab użytkownika (poleceniemcrontab -e), dodaj linię:
0 1 * * * /usr/bin/ansible-playbook /home/ansible/playbooks/backup.yml --ask-vault-pass
co spowoduje uruchamianie pełnego playbooka backupów codziennie o 1:00 w nocy. (Opcja--ask-vault-passspowoduje, że crontab musi mieć dostęp do hasła Vault – zamiast tego można użyć np.--vault-password-filewskazując plik z hasłem Vault lub skonfigurować w AWX). [learnitguide.net] - Harmonogram w AWX/Ansible Tower: Jeśli używasz AWX (open-source) lub Ansible Tower, te narzędzia mają wbudowany mechanizm Schedules do cyklicznego uruchamiania zadań. Wystarczy utworzyć Job Template dla playbooka backupowego, przetestować go ręcznie, a następnie na zakładce Harmonogramy (Schedules) tego szablonu dodać nowy harmonogram. AWX pozwala na precyzyjne planowanie z użyciem standardu RRULE (znanego z kalendarzy) – można ustawić np. codzienny start o określonej godzinie, wykluczyć weekendy itp.. Po zaplanowaniu, AWX będzie dbał o uruchamianie backupu punktualnie o zadanych porach, pełniąc rolę centralnego harmonogramu (zastępując de facto serwer CRON). [oneuptime.com]
Które rozwiązanie wybrać? Jeśli masz już wdrożony AWX/Tower, wygodnie jest korzystać z jego harmonogramów – masz wtedy centralny podgląd, logi z każdej realizacji, powiadomienia o ewentualnych błędach itp. W mniejszych środowiskach, gdzie Ansible uruchamiasz ręcznie lub ze skryptów, CRON może być wystarczający. Pamiętaj jednak, że w przypadku CRON musisz zadbać o bezpieczne przechowywanie poświadczeń (np. hasła Vault) – nie powinny one stać w crontabie wprost. Często rozwiązuje się to przez użycie dedykowanego pliku z hasłem Vault (dostępnego tylko dla odpowiedniego użytkownika) lub skryptu powłoki, który wywołuje Ansible (ten skrypt może mieć zaszyte hasło lub odwoływać się do zmiennej środowiskowej).
6. Tabela porównawcza strategii i narzędzi backupu wg silnika
Na koniec, podsumujmy i porównajmy najważniejsze cechy i zalecenia dla poszczególnych silników baz danych:
| Silnik bazy | Podejście do backupu | Zalety | Ograniczenia / uwagi |
|---|---|---|---|
| MySQL / MariaDB | Backup logiczny: Narzędzie mysqldump (moduł Ansible mysql_db). Możliwy zrzut wszystkich baz jednym poleceniem [stackoverflow.com] lub pojedynczo w pętli. Backup fizyczny: Narzędzia typu Percona XtraBackup / MariaDB Backup – pozwalają na „gorący” backup bez blokowania bazy, kopiując bezpośrednio pliki danych [dbcalm.com]. |
– Mysqldump: prostota, uniwersalność (standardowy format SQL, przenośność między wersjami/technologiami) [dbcalm.com], [dbcalm.com]. – XtraBackup: szybkie kopie dużych baz (zwłaszcza > 100GB) – operują na poziomie plików, wspierają backup przyrostowy, brak przestojów w pracy bazy (hot backup) [dbcalm.com], [dbcalm.com]. |
– Dump logiczny: wolny przy wielkich bazach (konieczność przetworzenia każdej rekordów, generacji wielu INSERTów) [dbcalm.com], obciąża serwer i może wymagać blokad (np. dla MyISAM). Przy odtwarzaniu duży dump zajmuje dużo czasu (odtworzenie wszystkich rekordów) [dbcalm.com]. – Backup fizyczny: wymaga dodatkowych narzędzi i spójności wersji (backup fizyczny odtwarzać należy na identycznej lub bardzo zbliżonej wersji silnika) [dbcalm.com]. Trudniejszy do wykorzystania przy migracji (plików nie przeniesiemy na inną architekturę). |
| PostgreSQL | Backup logiczny: Narzędzie pg_dump (moduł postgresql_db z state: dump) – umożliwia zrzut pojedynczej bazy do pliku SQL lub w formacie binarnym (custom/pgdump) [ansiblepilot.com]. Backup fizyczny: Narzędzia wbudowane jak pg_basebackup do tworzenia pełnej kopii katalogu danych (współpracuje z mechanizmem WAL, daje możliwość Point-in-Time Recovery). |
– pg_dump: działa online (bez wyłączania bazy), zapewnia spójny zrzut dzięki mechanizmowi MVCC, pozwala wybierać konkretne bazy/tabele, wynikowy plik jest przenośny między wersjami PostgreSQL [codegenes.net]. Przy formacie custom lub directory wspiera kompresję i odtwarzanie wybiórcze tabel (przez pg_restore) [codegenes.net], [codegenes.net]. – pg_basebackup: prosty sposób na pełny backup całego klastera, łącznie z konfiguracją; szybki przy dużych wolumenach (kopiuje pliki zamiast rekordów) i umożliwia odtworzenie do punktu w czasie (przy archiwizacji WAL) [codegenes.net]. |
– Dump logiczny: dla bardzo dużych baz danych jest względnie wolny i zasobożerny (odczyt i serializacja wszystkich danych) [codegenes.net]. Brak natywnego wsparcia dla backupu różnicowego/przyrostowego – każde uruchomienie pg_dump to pełny zrzut. – Backup fizyczny pg_basebackup: odtwarzanie przywraca cały klaster (nie poszczególne bazy) – nie da się łatwo odzyskać pojedynczej bazy bez odtwarzania całości. Wymaga uprawnień REPLICATION i włączonego archiwizowania WAL. Nie zastępuje to potrzeby okresowego pg_dump (np. na osobnym serwerze) w celu posiadania kopii logicznej (na wypadek awarii logicznej bazy, błędu aplikacji usuwającego dane etc.). |
| Oracle | Backup fizyczny: RMAN – główne narzędzie Oracle do backupu na poziomie bloków (pełne i przyrostowe backupy, kopie archiwów redo, restore danych) [vinchin.com]. Backup logiczny: Oracle Data Pump ( expdp/impdp) – eksportuje obiekty bazy do plików binarnych .dmp (możliwy eksport całej bazy, wybranych schematów lub tabel) [vinchin.com]. |
– RMAN: oficjalne, w pełni zintegrowane z Oracle rozwiązanie backupowe. Zapewnia spójność backupu bez przerywania pracy bazy, wspiera duże środowiska (np. Oracle RAC) [vinchin.com], pozwala na automatyzację i harmonogramowanie w samej bazie (katalog RMAN lub poprzez zewnętrzne narzędzia), obsługuje kompresję i szyfrowanie backupów [vinchin.com], umożliwia bardzo szybki restore całej bazy lub poszczególnych tablespace/plików danych. – Data Pump: bardzo przydatny do szybkiego eksportu wybranych elementów (np. pojedynczego schematu, tabeli) – działa z równoległym przetwarzaniem, co przyspiesza eksport dużych wolumenów danych [vinchin.com]. Pliki .dmp są przenośne między różnymi wersjami Oracle, co ułatwia migracje i aktualizacje bazy. |
– RMAN: wymaga strategii zarządzania przestrzenią na backup (backupy mogą być składowane na dysku lub taśmach – trzeba dbać o rotację w RMAN katalogu). Konfiguracja i skrypty RMAN wymagają wiedzy specjalistycznej DBA. Brak natywnego modułu Ansible – konieczność utrzymania skryptów. – Data Pump: nie zachowuje wszystkich elementów bazy (np. ustawień konfiguracyjnych instance, praw systemowych spoza zakresu schematów itp.), więc pełen restore bazy tylko z Data Pump nie odtworzy dokładnie stanu bazy, a jedynie dane aplikacyjne. Ponadto, Data Pump nie umożliwia point-in-time recovery – służy raczej do migracji lub logical backup niż do odtworzenia po awarii. |
| MS SQL Server | Backup fizyczny (na poziomie silnika): Polecenie BACKUP DATABASE do pliku .bak – może być wywołane ręcznie lub automatycznie (SQL Server Agent, Maintenance Plans) albo zewnętrznie przez Ansible. W Ansible korzystaj z win_shell/shell lub modułów PowerShell do uruchomienia backupu. Backup logiczny: (rzadko stosowany) – eksport skryptów CREATE/INSERT (np. z użyciem narzędzia sqlpackage do tworzenia paczek BACPAC) – wykorzystywany głównie przy migracji do Azure, nie do typowego backupu. |
– Natywny backup .bak: bardzo wydajny, szczególnie z kompresją (znaczne zredukowanie rozmiaru i czasu backupu dzięki mniejszemu I/O) [learn.microsoft.com]. Pozwala na backup przyrostowy (differential) i backup dziennika transakcyjnego, co daje pełną elastyczność odtwarzania do wybranego punktu w czasie. Powszechne narzędzie, wspierane przez wiele aplikacji do backupu danych. – Skrypty T-SQL: umożliwiają wyciąganie definicji obiektów i danych do przenośnych formatów (np. BACPAC zawiera schemat + dane, nadaje się do migracji między instancjami czy na Azure SQL). |
– Backup .bak: w środowisku klastrowym (Always On Availability Groups) backupy powinny być wykonywane na preferowanym replice wtórnej, aby odciążyć główną (Ansible może to uwzględnić, np. poprzez dynamiczny wybór hosta do backupu). Duże pliki .bak wymagają zabezpieczenia odpowiedniej przestrzeni oraz przepustowości sieci przy przenoszeniu na zewnętrzny storage. – Eksport logiczny: nie nadaje się do regularnych pełnych backupów – brak wsparcia dla odtwarzania stanów transakcyjnych, a generowane skrypty mogą nie odtworzyć użytkowników, rolek, ustawień serwera itp. |
Legenda: backup logiczny – eksport w postaci pliku z instrukcjami SQL (INSERT, DDL); backup fizyczny – kopia fizycznych plików bazy danych (bez pośrednictwa SQL). W praktyce codziennej administracji bazami podstawą są backupy fizyczne (bądź ich logiczne odpowiedniki w przypadku MySQL/PG), natomiast eksporty logiczne pełnią rolę uzupełniającą (np. migracje, dodatkowe bezpieczeństwo dla wybranych danych). Wybór narzędzi i strategii powinien uwzględniać zarówno wymagania biznesowe (RPO/RTO, regulacje dot. przechowywania danych), jak i uwarunkowania techniczne (wielkość baz, dostępna przestrzeń, okna serwisowe).
Wdrożenie powyższych playbooków i zaleceń pozwoli zautomatyzować proces tworzenia backupów we wspólnym harmonogramie, odciąży codzienną pracę DBA i zminimalizuje ryzyko błędu ludzkiego. Pamiętaj, aby regularnie testować odtwarzanie danych z tworzonych kopii – nawet najlepszy backup jest bezwartościowy, jeśli nie da się go poprawnie przywrócić. Dzięki integracji z mechanizmami powiadomień będziesz na bieżąco informowany o ewentualnych problemach, co umożliwi szybkie podjęcie działań naprawczych i zapewni bezpieczeństwo kluczowych danych we wszystkich Twoich bazach. Powodzenia w automatyzacji backupów!
Źródła: Dokumentacje i artykuły branżowe, m.in. [Stack Overflow – przykład użycia mysql_db do dumpu wszystkich baz], [Ansible Pilot – backup PostgreSQL z użyciem postgresql_db], [Blog Claudiokuenzler – skrypt z mysqldump i datowaniem plików], [Pythian Blog – automatyzacja RMAN z Ansible], [Vinchin – porównanie RMAN vs Data Pump], [Porównanie backupów logicznych i fizycznych MySQL], [Codegenes – porównanie pg_dump vs pg_basebackup], [Microsoft Docs – korzyści z kompresji backupów SQL]. [stackoverflow.com] [ansiblepilot.com] [claudiokuenzler.com] [pythian.com], [pythian.com] [vinchin.com], [vinchin.com] [dbcalm.com], [dbcalm.com] [codegenes.net], [codegenes.net] [learn.microsoft.com]