Chapter 18Lesson 01180–240 min

Database, SSH, Filesystem, Process, and Infrastructure Automation Patterns: Core Concepts and Mental Model

Build a safe Robot Framework infrastructure-automation mental model that separates database connections and transactions, SSH trust, filesystem ownership, child processes, and evidence lifecycles.

DatabaseLibrary 2.4.1SQLiteSSH trustProcessOwnership

Learning objectives

  • Trace an infrastructure-facing Robot keyword across resource, database/SSH/process/filesystem boundary, assertion, and result evidence.
  • Separate database connection/transaction state, SSH connection/trust state, filesystem ownership, child-process lifetime, Robot variables, and result artifacts.
  • Explain why target allowlists and cleanup ownership are prerequisites, not optional hardening after the script works.
  • Recognize current DatabaseLibrary, SSHLibrary, Process, and OperatingSystem version/security boundaries.
  • Design read-first, mutate-second infrastructure checks that remain safe under local reruns and CI.

Current compatibility baseline — verified 2026-08-31. Robot Framework 7.4.2 is the stable course baseline. The mandatory database layer uses robotframework-databaselibrary 2.4.1, which requires Python 3.8.1+ and Robot Framework 5.0.1+; the lab uses Python's built-in sqlite3 driver, so no database server is required. SSHLibrary 3.8.0 is still the latest stable PyPI release and 3.8.1rc1 remains prerelease. Its stable Paramiko implementation accepts unknown host keys with AutoAddPolicy; therefore real SSH is optional here and never used as the mandatory production-security pattern. The required path is local/free: SQLite, Robot standard OperatingSystem/Process, synthetic files, and a loopback-equivalent SSH simulation. No public host, production database, paid service, Pabot, CI provider, or container runtime is required.

1. The problem: an integration check can become an administration script

Chapter 17 deliberately kept HTTP state inside a loopback fixture. Infrastructure automation raises the stakes because a database statement, filesystem deletion, process termination, or SSH command can change state outside the Robot process. The same syntax can be harmless against a disposable SQLite file and destructive against a production database. The difference is target, privilege, ownership, and lifecycle, not the keyword name.

Robot Framework is valuable here as an orchestration and evidence layer. It should make a small integration contract readable: connect to an explicitly allowed target, inspect current state, perform one bounded mutation, verify the exact outcome, and roll back or delete only resources created by this run. It should not become a generic fleet-management replacement for Terraform, Ansible, Salt, or operating-system administration tooling.

2. Read-only preflight before any mutation

python --version
python -m robot --version
python -m pip show robotframework-databaselibrary robotframework-sshlibrary
# Python stdlib SQLite version:
python -c "import sqlite3; print(sqlite3.sqlite_version)"
# Record the intended Robot output directory before the suite creates scratch state.

Nothing above changes a database, process, or filesystem target. Record Python/Robot/library versions, current working directory, output directory, and intended target identifiers. In the mandatory path the database is a file that will be created under Robot's run-specific output directory; there is no public host and no remote credential.

3. Mental model: infrastructure state is a set of independent lifecycles

Robot orchestration boundary
flowchart TD
A[Robot suite] --> B[Domain infrastructure resource]
B --> C1[DatabaseLibrary]
B --> C2[OperatingSystem]
B --> C3[Process]
B -. optional .-> C4[SSHLibrary]
C1 --> D1[SQLite connection / transaction]
C2 --> D2[Owned filesystem]
C3 --> D3[Child process]
C4 --> D4[SSH connection + trust]
D1 --> E[Assertions]
D2 --> E
D3 --> E
D4 --> E
E --> F[output.xml / log.html]

Each branch has a different owner. Closing a database connection does not terminate a child process. Removing a file does not roll back a database transaction. Closing an SSH connection does not prove a remote command left no state behind. Robot variables merely reference these stores; they do not unify them. The result model records observations but is not itself the external state.

4. Terms and ownership before mutation

Term Meaning Owner / lifetime
Database connection Python DB-API connection registered by DatabaseLibrary Library connection store; close explicitly
Transaction Pending database changes between transaction boundaries Database driver/connection
SSH connection Authenticated network channel and active connection index/alias SSHLibrary/Paramiko
SSH trust Decision that the remote host key represents the intended host Client trust store/policy; separate from authentication
Filesystem state Files/directories on the machine running Robot Operating system; ownership must be proven
Child process Program spawned by Process with its own rc/stdout/stderr/lifetime OS process table + Process library
Target allowlist Explicit set of permitted hosts/paths/databases Project governance/configuration
Evidence Rows, rc/stdout/stderr, path tree, logs, output.xml Run artifacts; retain independently of external state

5. DatabaseLibrary: query adapter plus explicit connection lifecycle

DatabaseLibrary 2.4.1 is an external Robot library. It does not ship database engines or all drivers; it calls a Python DB-API module. For SQLite, the driver is Python's built-in sqlite3, making it ideal for a disposable course fixture.

*** Settings ***
Library    DatabaseLibrary

*** Test Cases ***
Read Local Database
    Connect To Database    sqlite3    database=${DB_PATH}    alias=labdb
    ${rows}=    Query    SELECT name, state FROM inventory    return_dict=${True}    alias=labdb
    Log    ${rows}
    Disconnect From Database    alias=labdb

The alias identifies library connection state; it is not the database transaction itself. DatabaseLibrary's query/execute keywords normally manage commit/rollback around their operation. The no_transaction option disables that wrapper when a lab deliberately needs to observe pending transaction state. Treat that option as an advanced contract, not a speed flag.

6. SQL text and data are different trust boundaries

A test parameter such as a user name is data. It must not become executable SQL syntax through string concatenation. DatabaseLibrary exposes a parameters argument so the underlying DB driver can bind values.

${params}=    Create List    alpha
${rows}=    Query
...    SELECT id, name, state FROM inventory WHERE name = ?
...    parameters=${params}
...    return_dict=${True}
...    alias=labdb

The placeholder style depends on the database driver. SQLite uses ?. A PostgreSQL or Oracle driver may use a different parameter style. The invariant is the same: keep the statement structure constant and bind values separately.

7. Filesystem state needs an ownership proof

A path inside ${OUTPUTDIR} is convenient, but location alone does not prove ownership. The suite must refuse to reuse a pre-existing scratch directory, mark ownership only after successful creation, normalize the path before destructive cleanup, and delete only the exact owned root.

${root}=    Normalize Path    ${OUTPUTDIR}${/}scratch-rf18
${exists}=    Run Keyword And Return Status    Directory Should Exist    ${root}
Should Be Equal    ${exists}    ${False}
Create Directory    ${root}
VAR    ${OWNED_ROOT}    ${True}    scope=SUITE

This is deliberately stricter than “delete and recreate.” A stale directory is evidence that a prior run or another process owns something there. Failing preflight is safer than silently erasing it.

8. Process is structured execution; shell text is not the default

Robot Framework's Process library passes a program and arguments to the operating system and returns a result object with return code, stdout, stderr, and optional redirected paths. Keep shell=False unless a shell is genuinely required and controlled. This preserves argument boundaries and avoids a large class of command-injection problems.

${result}=    Run Process    ${PYTHON}    -c    print("rf18-ok")
Should Be Equal As Integers    ${result.rc}    0
Should Be Equal    ${result.stdout}    rf18-ok
Should Be Empty    ${result.stderr}

For high-volume child output, redirect stdout/stderr to files rather than retaining unbounded output in memory. Chapter 08 already established that Process is preferred over deprecated OperatingSystem Run-style command keywords.

9. SSH has two separate security questions: who are you, and who is the host?

Authentication proves the client identity to the server. Host-key verification proves the server identity to the client. A password or private key can authenticate perfectly while the client is connected to the wrong host.

Current stable caveat: SSHLibrary 3.8.0 uses Paramiko AutoAddPolicy for missing host keys. That accepts unknown hosts rather than enforcing a pre-provisioned trust decision. For this reason the mandatory chapter path simulates the SSH contract locally. Do not infer that “SSH encrypted the traffic” means the host identity was verified.

If your organization needs real Robot-driven SSH, establish the host-key policy outside the test first, use a disposable non-production host, least-privilege account, explicit command allowlist, and a library/client stack whose trust behavior satisfies policy. Never solve a host-key failure by disabling verification.

10. DevOps connection: integration evidence, not fleet administration

Good Robot integration check Poor administration pattern
Verify a migration produced expected rows in disposable DB Run arbitrary DDL against a configured production DB
Start a local fixture and verify rc/output Kill processes by broad name or PID pattern
Create/remove one owned scratch tree Recursive delete from cwd or user-provided path
Read-only command on allowlisted disposable host Ad-hoc remote package/service administration
Preserve output.xml and external-state evidence Delete logs after repair to make rerun look clean

Knowledge check

Why is a Robot variable containing a database alias not “the transaction”?

Why does an SSH password not prove the server identity?

Why should a scratch directory pre-existence make setup fail?

What evidence should a Process call expose?

What is the chapter’s main safety rule?

11. Summary and bridge

Infrastructure-facing Robot automation works when state stores remain explicit: database connection/transaction, SSH session/trust, filesystem tree, child process, Robot scope, and result artifact. Lesson 2 turns this model into a fully disposable SQLite/filesystem/process workflow with an SSH simulation and concrete before/after evidence.

Next lesson

Database, SSH, Filesystem, Process, and Infrastructure Automation Patterns: Guided Hands-On Workflow

Continue with Database, SSH, Filesystem, Process, and Infrastructure Automation Patterns: Guided Hands-On Workflow. It builds directly on the state, evidence, and operating assumptions established here, so carry those constraints forward rather than treating the next page as an isolated topic.

References and version anchors

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.