You can connect an ETL pipeline to an on-premise MySQL database by choosing a secure network path (IP whitelist, SSH tunnel, or reverse SSH tunnel), creating a dedicated MySQL user with write permissions, and configuring your ETL tool's destination connection settings. This guide is written for data engineers and analysts who need to load processed data INTO an on-prem MySQL instance, not just extract from one. After reading, you will be able to configure a working ETL-to-on-prem-MySQL destination connection, verify that data lands correctly, and put credential rotation in place.
The key insight: on-premise MySQL as an ETL destination is a different problem from on-premise MySQL as a source. Extraction typically requires read-only access through a firewall you control. Loading data in requires write access, careful permission scoping, and a connection path that your network team will approve for inbound traffic.
The Problem
Most ETL documentation assumes your destination is a cloud data warehouse. When your destination is an on-premise MySQL database, you face a different set of constraints. Your database sits behind a corporate firewall with no public IP. Your network team controls inbound rules. Your DBA owns the MySQL user accounts. And your ETL tool, which may run in a cloud environment, needs a stable, authenticated path to write rows into a table that lives on hardware in your data center.
The temptation is to open a port, whitelist the ETL tool's IP range, and move on. That works in some environments. In others, the IP range is too broad, the firewall rules are locked down, or the ETL vendor's IP list changes without notice. Getting this connection right the first time saves hours of debugging and a security conversation you would rather not have.
What You'll Need
- Network access details: your MySQL server's internal IP or hostname, the port (default 3306), and your firewall's current inbound rules
- DBA access or the ability to request a new MySQL user with specific grants
- SSH access to a bastion or jump host if your network requires tunneled connections
- Your ETL tool's outbound IP range or SSH public key (check your vendor's documentation)
- A target database and table in MySQL where data will land (the table can be empty; the database must exist)
How to Connect an ETL Pipeline to an On-Premise MySQL Database: Step-by-Step
Step 1: Assess Your Network Setup and Choose a Connection Method
Before touching any ETL configuration, map the network path between your ETL tool and your MySQL server. The connection method you choose depends on what your firewall allows and what your security team will approve.
What to do:
- Identify whether your MySQL server has a publicly routable IP or sits entirely on a private network
- Check whether your ETL tool publishes a static list of outbound IPs; if so, request that your network team evaluate an inbound whitelist rule for port 3306
- If a direct whitelist is not feasible, identify whether a bastion host or jump server exists on your network with both external SSH access and internal MySQL connectivity; this is your SSH tunnel entry point
- If neither option works (the server has no inbound path at all), plan for a reverse SSH tunnel: the MySQL server initiates an outbound SSH connection to an intermediate host, and your ETL tool connects to that intermediate host
- Document the chosen method and the specific hostnames, ports, and IP addresses involved before proceeding
Output of this step: A written decision on connection method (direct whitelist, SSH tunnel, or reverse SSH tunnel) with the specific network addresses and ports that will be used.
Step 2: Create a Dedicated MySQL User with Minimum Required Permissions
A dedicated MySQL user for your ETL pipeline scopes write access to exactly the tables the pipeline needs. It also makes it easy to revoke access later without touching other service accounts.
What to do:
- Connect to MySQL as a DBA-level user on the server
- Create a new MySQL user scoped to the connection source your ETL tool will come from. For a direct connection, use the ETL tool's IP address as the host. For an SSH tunnel connection, scope the user to localhost or 127.0.0.1 as the host. Use a strong, randomly generated password and store it in your secrets manager immediately.
- Grant only the permissions the pipeline requires. For loading data into a specific table, that means INSERT, UPDATE, and SELECT (for upsert logic) on the target table only. Run FLUSH PRIVILEGES after granting to ensure the changes take effect.
- If your ETL tool needs to create or alter tables during schema evolution, add CREATE and ALTER grants scoped to the target database only
- Store the credentials in your secrets manager, not in a config file or environment variable that gets committed to version control
Output of this step: A MySQL user with the minimum grants needed for the ETL pipeline to write to the target table, and credentials stored securely.
Step 3: Configure the ETL Tool Connection to Your On-Prem MySQL Instance
With a connection method chosen and a MySQL user ready, you can now configure the destination connector in your ETL tool. The fields and labels vary by tool, but the underlying parameters are consistent.
What to do:
- Open your ETL tool's destination configuration and select MySQL as the destination type
- Enter the connection parameters based on your chosen method:
-
Direct whitelist: use the MySQL server's public or NAT IP, port 3306, and the etl_writer credentials
-
SSH tunnel: enter the bastion host's public IP and SSH port (usually 22), provide the SSH private key or password, then enter the MySQL server's internal IP and port 3306 as the "remote host" fields; the ETL tool will route the MySQL connection through the SSH tunnel
-
Reverse SSH tunnel: enter the intermediate host's address and the local port that the reverse tunnel is forwarding to MySQL
- Set the database name to the specific database containing your target table
- Set SSL/TLS to required if your MySQL server is configured with require_ssl; if not, confirm with your DBA whether plaintext is acceptable over the chosen connection path
- Save the configuration without testing yet; you will test in the next step
Output of this step: A saved destination connector configuration pointing to your on-premise MySQL instance via the chosen connection method.
Where Integrate.io helps: Integrate.io's MySQL destination connector supports both direct connections and SSH tunnel configuration from the same setup screen. You can enter the bastion host details and MySQL internal address in separate fields, and the platform handles the tunneling without requiring you to set up a local SSH client or manage port forwarding manually.
Step 4: Test Connectivity and Validate Write Access
A saved configuration is not a working connection. This step confirms that your ETL tool can reach MySQL and that the etl_writer user can actually write rows, not just authenticate.
What to do:
- Use your ETL tool's built-in "Test Connection" function to verify that the network path is open and authentication succeeds; a timeout here points to a firewall or tunnel misconfiguration, while an authentication error points to the MySQL user setup
- If the connection test passes, validate write access by running a manual test through the same connection path: insert a test row into your target table, query it back to confirm it landed correctly, then delete it to clean up. This confirms INSERT, SELECT, and optionally DELETE permissions are working end-to-end.
- If you intentionally excluded DELETE from the user's grants (because your pipeline never deletes rows), skip the delete step and confirm the INSERT and SELECT work
- If the write fails with a permissions error, re-check the GRANT statement from Step 2; the user host binding (127.0.0.1 vs localhost vs the actual IP) is a common mismatch
Output of this step: Confirmed evidence that the ETL tool can open a connection to the MySQL server and that the etl_writer user can insert and query rows in the target table.
Where Integrate.io helps: Integrate.io surfaces the exact MySQL error code in the connection test result, which makes diagnosing host binding mismatches or missing grants faster than reading raw connection logs from a tunnel client.
Step 5: Run a Sample Load and Verify Data in MySQL
With connectivity confirmed, run a small, controlled data load through the full ETL pipeline before scheduling production runs. This catches schema mismatches, data type coercions, and encoding issues before they affect real data.
What to do:
- Configure your ETL pipeline to load a small batch of records (100-500 rows) from the source into your on-prem MySQL destination table
- Run the pipeline manually and watch the logs; note the row count reported by the ETL tool as "written" or "loaded"
- Connect to MySQL directly and run a COUNT query on the target table to get the actual row count loaded
- If the counts match, spot-check 5-10 rows by querying specific values you know should appear in the source data
- If counts diverge, check whether the pipeline is performing upserts (which can update existing rows without increasing the count) and whether the ETL tool's "rows written" metric counts updates separately from inserts
- Verify that VARCHAR columns have not been truncated (compare a long string value in MySQL against the source), that DATE or DATETIME fields landed with the correct timezone, and that any NULL values in the source appear as NULL (not as empty strings or zeros) in MySQL
Output of this step: A verified batch of sample records in the on-prem MySQL table, with row count and spot-checked values confirming that the data matches the source.
Step 6: Set Up Credential Rotation and Connection Monitoring
A working connection is only as reliable as its credentials and the network path it depends on. Rotating credentials on a schedule and alerting on connection failures prevents a single expired password or closed firewall rule from silently breaking your pipeline.
What to do:
- Set a reminder or calendar event to rotate the etl_writer password every 90 days; on rotation, update the password in MySQL, update it in your secrets manager, and update the ETL destination connector configuration before the old password is invalidated
- If your ETL tool supports referencing secrets from an external vault (AWS Secrets Manager, HashiCorp Vault, or similar), configure it to pull credentials at runtime rather than storing them in the connector configuration directly
- Enable pipeline failure notifications in your ETL tool so that any connection error sends an alert to your team; connection failures to on-prem MySQL often happen silently if there is no monitoring (a firewall rule change can close the path without warning)
- Log the connection test result on a schedule: some teams run a nightly no-op query through the ETL connector just to confirm the path is open before the actual pipeline runs
- Document the rotation process in your team's runbook: who owns the MySQL user, which systems reference the credentials, and the exact steps to rotate without downtime
Output of this step: A credential rotation schedule, alerts configured for connection failures, and a documented rotation runbook your team can follow without the original setup engineer in the room.
Common Mistakes to Avoid
-
Whitelisting 0.0.0.0/0 on port 3306 to get the connection working quickly: this exposes your MySQL port to the public internet. Whitelist only the ETL tool's specific IP range, or use an SSH tunnel instead of a direct connection.
-
Creating the MySQL user with a wildcard host: the % wildcard allows connections from any host. Scope the user to the specific IP or 127.0.0.1 (for tunnel connections) from the start.
-
Granting ALL PRIVILEGES to the ETL user: the pipeline needs INSERT, UPDATE, and SELECT on specific tables. Granting all privileges gives the ETL tool the ability to drop tables or modify user accounts, which is not acceptable for a service account.
-
Storing the MySQL password in the ETL connector's UI without a secrets reference: if your ETL tool stores credentials in its own database, a platform breach exposes your MySQL password. Use a secrets manager integration if your tool supports it.
-
Skipping the sample load verification in Step 5: the connection test only confirms authentication, not data integrity. A VARCHAR(100) column silently truncates strings longer than 100 characters with no pipeline error; you only catch this by inspecting actual rows.
-
Not documenting the SSH tunnel configuration: SSH tunnels involve a bastion host, a key pair, and specific port forwarding rules. When the bastion host is rebuilt or the key pair rotates, an undocumented tunnel breaks the pipeline and takes hours to reconstruct.
Conclusion
Connecting an ETL pipeline to an on-premise MySQL database as a destination requires more deliberate setup than pointing a pipeline at a cloud warehouse, but the process is repeatable and auditable when done in sequence. By choosing the right network path first, scoping MySQL permissions tightly, and verifying data at the row level before going to production, teams can run reliable on-premise MySQL data pipelines without cloud migration. Integrate.io's MySQL destination connector handles SSH tunnel configuration natively, which removes one of the more operationally complex parts of this setup. Once the connection is stable and monitored, the same pattern scales to additional tables or databases without repeating the network and security work from scratch.