Skip to content

Playbook Examples

Common patterns and examples for using solti-matrix-mgr collection.

Prerequisites

Source credentials before running any playbook:

source ~/.secrets/LabMatrix

Room Management

Create a room with custom settings

- name: Create project room
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_access_token: "{{ lookup('env', 'MATRIX_ACCESS_TOKEN') }}"

  tasks:
    - name: Create room
      jackaltx.solti_matrix_mgr.synapse_room:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "#project-alpha:example.com"
        room_name: "Project Alpha"
        room_alias_name: "project-alpha"
        topic: "Discussion for Project Alpha"
        state: present
        admins:
          - "@alice:example.com"
        moderators:
          - "@bob:example.com"
      register: room_result

    - debug:
        msg: "Room created: {{ room_result.room.room_id }}"

Delete a room programmatically

- name: Cleanup test rooms
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"
    rooms_to_delete:
      - "#test-room-1:example.com"
      - "#test-room-2:example.com"

  tasks:
    - name: Resolve room aliases
      ansible.builtin.uri:
        url: "{{ matrix_homeserver_url }}/_matrix/client/v3/directory/room/{{ item | urlencode }}"
        method: GET
        headers:
          Authorization: "Bearer {{ matrix_admin_token }}"
        status_code: 200
      register: room_lookups
      loop: "{{ rooms_to_delete }}"
      ignore_errors: true

    - name: Delete rooms
      ansible.builtin.uri:
        url: "{{ matrix_homeserver_url }}/_synapse/admin/v2/rooms/{{ item.json.room_id }}"
        method: DELETE
        headers:
          Authorization: "Bearer {{ matrix_admin_token }}"
          Content-Type: "application/json"
        body_format: json
        body:
          purge: true
          block: false
        status_code: 200
      loop: "{{ room_lookups.results }}"
      when: item is succeeded
      register: deletions

    - debug:
        msg: "Deleted {{ deletions.results | selectattr('changed') | list | length }} rooms"

User Management

Create a bot user with no rate limits

- name: Setup logger bot
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"

  tasks:
    - name: Create bot user
      jackaltx.solti_matrix_mgr.synapse_user:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@solti-logger:example.com"
        password: "{{ bot_password }}"
        displayname: "SOLTI Logger Bot"
        ratelimit_override:
          messages_per_second: 0
          burst_count: 0
        state: present
      register: bot_user

    - debug:
        msg: "Bot created: {{ bot_user.user.name }}"

Audit all users on the homeserver

- name: Audit homeserver users
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"

  tasks:
    - name: Get server info
      jackaltx.solti_matrix_mgr.synapse_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        gather:
          - users
          - rooms
          - version
        limit: 1000
      register: server_info

    - name: Display summary
      debug:
        msg:
          - "Server version: {{ server_info.version.server_version | default('N/A') }}"
          - "Total users: {{ server_info.users_total }}"
          - "Total rooms: {{ server_info.rooms_total }}"

    - name: Find admin users
      set_fact:
        admins: "{{ server_info.users | selectattr('admin', 'equalto', true) | list }}"

    - debug:
        msg: "Admin users: {{ admins | map(attribute='name') | list }}"

Token Management

Audit and cleanup old tokens weekly

- name: Weekly token cleanup
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"
    token_max_age: 30  # days

  tasks:
    - name: Get all admin devices
      jackaltx.solti_matrix_mgr.synapse_device_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@admin:example.com"
      register: all_devices

    - name: Find orphaned devices
      jackaltx.solti_matrix_mgr.synapse_device_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@admin:example.com"
        older_than_days: 0  # Never used
      register: orphaned

    - name: Find old ansible tokens
      jackaltx.solti_matrix_mgr.synapse_device_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@admin:example.com"
        user_agent_filter: "ansible-httpget"
        older_than_days: "{{ token_max_age }}"
      register: old_tokens

    - name: Generate report
      debug:
        msg:
          - "Total devices: {{ all_devices.total_devices }}"
          - "Orphaned: {{ orphaned.matched_count }}"
          - "Old ansible tokens: {{ old_tokens.matched_count }}"

    - name: Cleanup orphaned devices
      jackaltx.solti_matrix_mgr.synapse_device_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@admin:example.com"
        older_than_days: 0
        revoke_matched: true
      when: orphaned.matched_count > 0

    - name: Cleanup old tokens
      jackaltx.solti_matrix_mgr.synapse_device_info:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_admin_token }}"
        user_id: "@admin:example.com"
        user_agent_filter: "ansible-httpget"
        older_than_days: "{{ token_max_age }}"
        revoke_matched: true
      when: old_tokens.matched_count > 0

Single-use token pattern

- name: List rooms with single-use token
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"

  tasks:
    - name: Query rooms
      ansible.builtin.uri:
        url: "{{ matrix_homeserver_url }}/_synapse/admin/v1/rooms"
        method: GET
        headers:
          Authorization: "Bearer {{ matrix_admin_token }}"
        status_code: 200
      register: rooms_response

    - debug:
        msg: "Total rooms: {{ rooms_response.json.total_rooms }}"

  post_tasks:
    - name: Revoke token after use
      ansible.builtin.uri:
        url: "{{ matrix_homeserver_url }}/_matrix/client/v3/logout"
        method: POST
        headers:
          Authorization: "Bearer {{ matrix_admin_token }}"
        status_code: 200
      when: cleanup_token | default(false) | bool
      ignore_errors: true
      no_log: true

Usage:

ansible-playbook playbook.yml -e "cleanup_token=true"

Event Posting

Post verification results to Matrix room

- name: Post test results to Matrix
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_access_token: "{{ lookup('env', 'MATRIX_ACCESS_TOKEN') }}"
    matrix_room_id: "{{ lookup('env', 'MATRIX_ROOM_ID') }}"

  tasks:
    - name: Run tests
      command: pytest tests/
      register: test_result
      ignore_errors: true

    - name: Post results to Matrix
      jackaltx.solti_matrix_mgr.matrix_event:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "{{ matrix_room_id }}"
        event_type: "m.room.message"
        content:
          msgtype: "m.text"
          body: |
            Test run completed
            Status: {{ 'PASSED' if test_result.rc == 0 else 'FAILED' }}
            Exit code: {{ test_result.rc }}
        state: present

Structured event with custom fields

- name: Post deployment notification
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_access_token: "{{ lookup('env', 'MATRIX_ACCESS_TOKEN') }}"
    matrix_room_id: "#deployments:example.com"

  tasks:
    - name: Post deployment event
      jackaltx.solti_matrix_mgr.matrix_event:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "{{ matrix_room_id }}"
        event_type: "com.example.deployment"
        content:
          service: "api-server"
          version: "v1.2.3"
          environment: "production"
          deployed_by: "ansible"
          timestamp: "{{ ansible_date_time.iso8601 }}"
        state: present

Advanced Patterns

Conditional room creation

- name: Ensure project rooms exist
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_access_token: "{{ lookup('env', 'MATRIX_ACCESS_TOKEN') }}"
    projects:
      - name: "alpha"
        display_name: "Project Alpha"
        admins: ["@alice:example.com"]
      - name: "beta"
        display_name: "Project Beta"
        admins: ["@bob:example.com"]

  tasks:
    - name: Create rooms for each project
      jackaltx.solti_matrix_mgr.synapse_room:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "#project-{{ item.name }}:example.com"
        room_name: "{{ item.display_name }}"
        room_alias_name: "project-{{ item.name }}"
        state: present
        admins: "{{ item.admins }}"
      loop: "{{ projects }}"
      register: room_results

    - debug:
        msg: "Created/verified {{ projects | length }} project rooms"

Multi-step room setup with verification

- name: Setup and verify room
  hosts: localhost
  gather_facts: false

  vars:
    matrix_homeserver_url: "{{ lookup('env', 'MATRIX_HOMESERVER_URL') }}"
    matrix_access_token: "{{ lookup('env', 'MATRIX_ACCESS_TOKEN') }}"
    matrix_admin_token: "{{ lookup('env', 'MATRIX_ADMIN_TOKEN') }}"

  tasks:
    - name: Create room
      jackaltx.solti_matrix_mgr.synapse_room:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "#verified-room:example.com"
        room_name: "Verified Room"
        room_alias_name: "verified-room"
        state: present
        admins: ["@admin:example.com"]
      register: room_creation

    - name: Verify room state
      ansible.builtin.uri:
        url: "{{ matrix_homeserver_url }}/_synapse/admin/v1/rooms/{{ room_creation.room.room_id }}/state"
        method: GET
        headers:
          Authorization: "Bearer {{ matrix_admin_token }}"
        status_code: 200
      register: room_state

    - name: Extract power levels
      set_fact:
        power_levels: "{{ room_state.json.state | selectattr('type', 'equalto', 'm.room.power_levels') | map(attribute='content') | first }}"

    - name: Verify admin has correct power level
      assert:
        that:
          - power_levels.users['@admin:example.com'] == 100
        fail_msg: "Admin power level incorrect!"
        success_msg: "Room verified successfully"

    - name: Post success message
      jackaltx.solti_matrix_mgr.matrix_event:
        homeserver_url: "{{ matrix_homeserver_url }}"
        access_token: "{{ matrix_access_token }}"
        room_id: "{{ room_creation.room.room_id }}"
        event_type: "m.room.message"
        content:
          msgtype: "m.notice"
          body: "Room setup and verification complete ✓"
        state: present

See Also