OpenBSD Handbook

    Theme
    • Part I. Install & Configure
      • Introduction
      • Installing OpenBSD
      • The X Window System
      • Networking
      • System Configuration
      • OpenBSD Basics
      • Managing Software: Packages and Ports
    • Part II. Daily Operations
      • Graphical Environments
      • Multimedia
      • Printing
      • Linux Compatibility
      • Windows Compatibility
      • Games
    • Part III. System Administration
      • Virtualization
      • Storage and File Systems
      • Updating and Upgrading
      • Localization
      • The OpenBSD Boot Process
      • Security
    • Part IV. Networking & Daemons
      • Services
        • Database
          • MariaDB
          • PostgreSQL
          • Redis
          • memcached
        • Directory
          • YP (NIS)
          • LDAP
        • File
          • NFS
          • Samba
        • FTP Services
          • ftpd
          • ProFTPD
          • vsftpd
          • Pure-FTPd
          • TFTP
        • Mail
          • smtpd
          • Dovecot
          • Postfix
          • Exim
          • Rspamd
        • Name
          • Unbound
          • NSD
          • BIND
        • Networking
          • OpenBGPD
          • rad
          • DHCP
          • slaacd
        • Web
          • Apache
          • nginx
          • httpd
          • relayd
        • Logging
          • syslogd
        • Monitoring
          • SNMP
        • Remote Access
          • Audit OpenSSH
          • sshd
        • File Synchronization
          • rsync
        • Messaging
          • RabbitMQ
        • Time
          • NTP
      • PF
        • pfctl cheat sheet
        • PF Anchors
        • PF Filter Rules
        • PF Forwarding
        • PF Lists and Macros
        • PF Load Balancing
        • PF Logging
        • PF NAT
        • PF Options
        • PF Policies
        • PF Shortcuts
        • PF Tables
      • Advanced Networking
        • High Availability and State Replication
        • Multi-WAN and Policy-Based Routing
        • VPN and Cryptographic Tunneling
        • Classic and Lightweight Tunnels
        • IPv6 at Scale
        • QoS and Traffic Shaping
        • MPLS and Label Distribution
        • Network Services at Scale
        • Virtualization and Host Networking
        • Large-Scale L2 and L3 Design
        • Telemetry, Logging, and Flow Export
        • Hardening and Operational Safety
        • Reference Architectures
        • Troubleshooting Playbooks
      • Serial Communication
    • Part V. Miscellaneous
      • Virtualization Cheat Sheet
      • OpenBSD Cheatsheet
      • How-to Guides
        • Complete the First 30 Minutes After Installation
        • Check Hardware Compatibility Before Installing
        • Bootstrap Wi-Fi Firmware Without Ethernet
        • Set Up OpenBSD as a Laptop or Workstation
        • Configure Laptop Power Management
        • Run OpenBSD as a Virtual Machine Guest
        • Install OpenBSD on a VPS or Cloud Server
        • Install OpenBSD with Full-Disk Encryption
        • Troubleshoot Web Browsers on OpenBSD
        • Create an Administrator Account with doas and SSH Keys
        • Establish a Conservative Security Baseline
        • Manage OpenBSD with Ansible
        • Recover Access and Reset the Root Password
        • Collect OpenBSD Diagnostic Evidence
        • Configure Secure Remote Access with OpenSSH
        • Set Up WordPress
        • Build Third-Party Software from Ports
        • Use FIDO Security Keys with OpenSSH
        • Build OpenBSD from Source
        • Configure Wi-Fi Roaming and Wired Failover
        • Dual-Boot OpenBSD on a UEFI System
        • Troubleshoot PF, NAT, and Routing
        • Automate OpenBSD Installation with Autoinstall and PXE
        • Route Multiple VLANs with PF
        • Configure a Road-Warrior WireGuard VPN
        • Troubleshoot Package Installation and Update Failures
        • Route IPv6 Networks without NAT
        • Schedule Recurring Maintenance
        • Plan a Docker Workload Migration to OpenBSD
        • Build a Mail Server with OpenSMTPD, Dovecot, and Rspamd
        • Build a Simple Router and Firewall
        • Monitor an OpenBSD System
        • Back Up and Restore an OpenBSD System
        • Configure softraid RAID1
        • Recover an OpenBSD System That Does Not Boot
        • Install Z shell (zsh)
      • OpenBSD for Linux Users
      • OpenBSD for FreeBSD Users
      • OpenBSD for macOS Users
    • OpenBSD FAQ
    • Package Search
      • Synopsis
      • Define the Trust Boundary
      • Install Python on the Managed Node
      • Create the Inventory
      • Configure doas Deliberately
      • Install the OpenBSD Collection Support
      • Run an Idempotent Package Playbook
      • Manage Configuration Safely
      • Diagnose Failures

      Manage OpenBSD with Ansible

      Synopsis #

      Ansible can manage OpenBSD over SSH, but most modules require a packaged Python interpreter on each managed node. Privileged tasks also require an explicit doas(1) policy. This guide prepares one node, proves unprivileged operation, adds controlled privilege elevation, and runs an idempotent package example.

      Ansible is not an OpenBSD base-system component. The controller, ansible-core, and collections have their own support cycles. Confirm their current OpenBSD notes before upgrading an automation environment.

      Define the Trust Boundary #

      An automation controller can distribute commands and files to every managed node. Protect its SSH keys, inventory, vault material, logs, and backups accordingly. Use a dedicated named account on managed nodes and do not permit direct root SSH login.

      Before automation, establish:

      • a working console or independent recovery path;
      • a verified named administrator account;
      • a host-key verification process;
      • a backup of every file the first playbook will manage;
      • a small initial host group rather than the entire fleet.

      Create an Administrator Account and Configure Secure Remote Access provide the OpenBSD access baseline.

      Install Python on the Managed Node #

      Ansible’s raw module can operate without Python, but ordinary modules cannot. On the managed OpenBSD node, search the current package set and install the Python 3 meta-package selected for that release:

      $ pkg_info -Q python
        # Inspect available Python package stems
      # pkg_add python%3
        # Install the current Python 3 package selected by the package tools
      $ /usr/local/bin/python3 --version
        # Confirm the stable interpreter path used by inventory
      

      If package selection is ambiguous, choose the maintained Python 3 package explicitly rather than hard-coding a minor version from an older guide. Keep Python updated with the rest of the installed packages.

      Create the Inventory #

      On the Ansible controller, create an inventory file such as inventory.ini:

      [openbsd]
      router1.example.net ansible_user=automation
      
      [openbsd:vars]
      ansible_python_interpreter=/usr/local/bin/python3
      ansible_become=true
      ansible_become_method=doas
      ansible_become_user=root
      

      The host name, account, and grouping are examples. Use verified DNS or addresses and retain SSH host-key checking. Do not use ansible_ssh_common_args to disable host-key verification.

      Test SSH before invoking Ansible:

      $ ssh automation@router1.example.net
      

      Then test the Python module path without privilege elevation:

      $ ansible openbsd -i inventory.ini -m ansible.builtin.ping -e ansible_become=false
      

      Ansible’s ping module tests module execution; it does not send ICMP echo requests.

      Configure doas Deliberately #

      Ansible normally executes temporary module code as the target user. A command-specific doas.conf rule cannot authorize arbitrary privileged modules safely. Choose one of these models:

      1. Require the automation account’s password and run playbooks with --ask-become-pass.
      2. Grant passwordless elevation to a tightly protected automation account and treat its SSH key as a root credential.
      3. Avoid general elevation and use narrowly designed raw tasks that match command-specific rules, accepting reduced module functionality.

      For the interactive-password model, add this rule to /etc/doas.conf on the managed node:

      permit automation as root
      

      Parse the policy and test the exact identity with doas(1) :

      # doas -C /etc/doas.conf
        # Parse the complete policy without executing a command
      $ doas -u root id
        # Confirm authentication and target identity from the automation account
      

      Run privileged playbooks with --ask-become-pass. A nopass rule should be adopted only after the root-equivalent trust decision is documented and the account is restricted to dedicated keys, controlled source addresses where practical, and monitored use.

      Install the OpenBSD Collection Support #

      The community.general.openbsd_pkg module is distributed in the community.general collection and is not part of ansible-core. Install and record the collection on the controller:

      $ ansible-galaxy collection install community.general
      $ ansible-galaxy collection list community.general
      

      Pin collection versions in the automation project’s requirements file when repeatable controller builds are required.

      Run an Idempotent Package Playbook #

      Create openbsd-baseline.yml on the controller:

      ---
      - name: Maintain a small OpenBSD package baseline
        hosts: openbsd
        gather_facts: true
        become: true
      
        tasks:
          - name: Ensure rsync is installed
            community.general.openbsd_pkg:
              name: rsync
              state: present
      
          - name: Record the managed node release
            ansible.builtin.command: uname -a
            register: openbsd_uname
            changed_when: false
      
          - name: Display the managed node release
            ansible.builtin.debug:
              var: openbsd_uname.stdout
      

      Run syntax and dry-run checks first:

      $ ansible-playbook -i inventory.ini openbsd-baseline.yml --syntax-check
        # Parse inventory and playbook structure
      $ ansible-playbook -i inventory.ini openbsd-baseline.yml --check --diff --ask-become-pass --limit router1.example.net
        # Preview the first managed node
      $ ansible-playbook -i inventory.ini openbsd-baseline.yml --ask-become-pass --limit router1.example.net
        # Apply only after the preview and recovery plan are acceptable
      

      Check mode is a prediction and not every module can model all changes. Keep the first production run limited and inspect the resulting package and log state on the node.

      Manage Configuration Safely #

      For each managed file:

      • render to a temporary path or use module validation where available;
      • preserve owner, group, and mode explicitly;
      • notify a handler only when content changes;
      • validate daemon syntax before reload;
      • keep the previous remote session and recovery route available;
      • avoid overwriting package examples or local secrets without a documented merge policy.

      Do not automate sysupgrade, PF replacement, disk operations, or SSH authentication changes as a first playbook. Establish idempotence, limits, serial rollout, and recovery on low-risk state before expanding authority.

      Diagnose Failures #

      Use -vvv only in protected logs because output can contain paths, variables, command lines, and remote data. Separate SSH, Python interpreter, become, module, and target-command failures. Confirm the same SSH account and doas action manually on the affected node before changing playbook logic.

      Report a bug
      • Synopsis
      • Define the Trust Boundary
      • Install Python on the Managed Node
      • Create the Inventory
      • Configure doas Deliberately
      • Install the OpenBSD Collection Support
      • Run an Idempotent Package Playbook
      • Manage Configuration Safely
      • Diagnose Failures