Date: 2026-05-11
Time: 15:12
Local execution is FTL2's simplest operational mode, where modules run directly on the same machine via subprocess rather than over SSH. It requires ansible_connection: local in the inventory and uses LocalModuleRunner instead of RemoteModuleRunner. This mode is ideal for development testing, single-machine administration, and learning FTL2 fundamentals without network complexity.
LocalModuleRunner is used instead of RemoteModuleRunner when connection type is "local"ansible_connection: local is the inventory directive that triggers local modeansiblepythoninterpreter must point to a valid Python 3.11+ path on the systemCLI pattern: ftl2 -m <module> -i <inventory> [-a "<key=value args>"]
| Command | Purpose |
|---------|---------|
| ftl2 -m ping -i inventory.yml | Test connectivity (returns "ping": "pong") |
| ftl2 -m setup -i inventory.yml | Gather system facts (OS, memory, CPU) |
| ftl2 -m file -i inventory.yml -a "path=/tmp/x state=touch" | Create a file |
| ftl2 -m file -i inventory.yml -a "path=/tmp/x state=absent" | Remove a file |
| ftl2 -m shell -i inventory.yml -a "cmd='echo Hello'" | Run a shell command |
| ftl2 -m copy -i inventory.yml -a "src=/tmp/a dest=/tmp/b" | Copy a file |
Inventory configuration:
all:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3
ansible_connection: local-m / -a CLI pattern used across all execution modesRemoteModuleRunneransibleconnection, ansiblepython_interpreter) use Ansible-compatible namingansibleconnection: local (not connectiontype or similar)LocalModuleRunner, remote uses RemoteModuleRunnerping module returns {"changed": false, "ping": "pong"} — note changed: falseshell module returns {"changed": true, "stdout": "...", "stderr": "...", "rc": 0} — note changed: truefile module uses state=touch to create and state=absent to remove-a flag as space-separated key=value pairsansiblepythoninterpreter path, missing module (wrong working directory), permission denied on protected paths