Install Observe Agent using Ansible on Windows

Note

These instructions apply to tenants created on or after June 6, 2025. Interested in upgrading to the new experience? Open Docs & Support → Contact Support in the product and let us know.

This page provides instructions for installing the Observe Agent on Windows systems via Ansible to collect metrics, logs, and application telemetry—including OpenTelemetry traces—and forward them to Observe.

Once you follow instructions, here’s how the directory layout should look.

/etc/ansible/
├─ hosts/
│   ├─ windows.aws_ec2.ini          # ← inventory
│   └─ group_vars/
│       └─ windows.yaml              # creds + overrides
├─ roles/
│   └─ agent/
│       ├─ tasks/
│       │   ├─ main.yaml            # imports install_with_ps1.yaml
│       │   ├─ install_with_ps1.yaml
│       │   └─ update_config.yaml
│       └─ templates/
│           └─ observe-agent.yaml.j2
├─ install-observe-agent-windows.yaml
├─ update-observe-agent-windows.yaml    # ← update playbook
└─ uninstall-observe-agent-windows.yaml    # ← uninstall playbook

Prerequisites

  1. Install Ansible on your control node. The control node used on this page is Ubuntu 24.04.

  2. Install the Python WinRM client libraries on the control node.

python -m pip install "pywinrm>=0.4.3" requests requests-ntlm
  1. Create an inventory file (/etc/ansible/hosts/windows.aws_ec2.ini) on the control node

; --------------------------
; WINDOWS INVENTORY EXAMPLE
; --------------------------

[win_proxy_servers]
ansible-managed-node-2 ansible_host=172.31.34.10

[win_load_balancer]
ansible-managed-node-1 ansible_host=172.31.35.121

[windows:children]
win_proxy_servers
win_load_balancer

[windows:vars]
; use WinRM instead of ssh
ansible_connection=winrm
; 5986 = HTTPS listener (recommended)
ansible_port=5986
ansible_winrm_scheme=https
; escape backslash in INI
ansible_user=Administrator
; store in Ansible Vault in real life 
ansible_password=<YOUR_PASSWORD>
; or ntlm / credssp / basic   
ansible_winrm_transport=ntlm
; OK for self-signed lab certs
ansible_winrm_server_cert_validation=ignore  
  1. Enable WinRM HTTPS on each Windows host (run once). If your control node can already reach the managed Windows hosts over WinRM, you can skip directly to Step 5.

### 1. Create a self-signed cert (CN & SAN = computer name + FQDN)

$dnsName   = "$env:COMPUTERNAME"
$dnsFqdn   = "$env:COMPUTERNAME.$((Get-WmiObject Win32_ComputerSystem).Domain)"
$cert = New-SelfSignedCertificate `
          -DnsName $dnsName,$dnsFqdn `
          -CertStoreLocation Cert:\LocalMachine\My `
          -KeyLength 2048 `
          -NotAfter (Get-Date).AddYears(3) `
          -FriendlyName "WinRM HTTPS"
### 2. Remove any old HTTPS listeners (optional cleanup)
Get-ChildItem WSMan:\Localhost\Listener | Where-Object { $_.Keys -match 'Transport=HTTPS' } | Remove-Item -Recurse -Force

### 3. Bind the new cert to an HTTPS listener on all addresses
New-Item -Path WSMan:\Localhost\Listener `
         -Transport HTTPS `
         -Address * `
         -CertificateThumbprint $cert.Thumbprint `
         -Force

### 4. Remove any half-created rule so we start clean
Get-NetFirewallRule -DisplayName 'WinRM HTTPS (TCP 5986)' -ErrorAction SilentlyContinue |
    Remove-NetFirewallRule

### 5. Create a fresh inbound rule that allows ALL profiles
New-NetFirewallRule -DisplayName 'WinRM HTTPS (TCP 5986)' `
    -Name 'WinRM-HTTPS-TCP-5986' `
    -Protocol TCP -LocalPort 5986 `
    -Direction Inbound -Action Allow `
    -Profile Any

### 6. Verify
winrm enumerate winrm/config/listener
Test-NetConnection -ComputerName $env:COMPUTERNAME -Port 5986
  1. Test connectivity

ansible windows -i /etc/ansible/hosts/windows.aws_ec2.ini -m ansible.windows.win_ping

A successful check returns output similar to:

ansible-managed-node-2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
ansible-managed-node-1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
  1. Create windows.yaml under /etc/ansible/hosts/group_vars.

Replace <YOUR_INGEST_TOKEN> with your instance’s ingest token you create from the Add Data for Windows page (ex: a1b2c3d4e5f6g7h8i9k0:l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6) and <YOUR_OBSERVE_COLLECTION_ENDPOINT> with your instance’s collection endpoint (ex: https://123456789012.collect.observeinc.com/). For more information on configuring the agent, see Configuration.

YOUR_OBSERVE_COLLECTION_ENDPOINT: "<YOUR_OBSERVE_COLLECTION_ENDPOINT>"
YOUR_INGEST_TOKEN: "<YOUR_INGEST_TOKEN>"

Installation

Install the Observe Agent

  1. Create install_with_ps1.yaml under /etc/ansible/roles/agent/tasks/

############################################################
# roles/agent/tasks/install_with_ps1.yaml  (ZIP workflow)
############################################################
- name: Ensure staging directory exists
  ansible.windows.win_file:
    path: C:\Temp\Observe
    state: directory

# 1. Download the latest Observe Agent ZIP
- name: Download latest Observe Agent ZIP
  ansible.windows.win_get_url:
    url: https://github.com/observeinc/observe-agent/releases/latest/download/observe-agent_Windows_x86_64.zip
    dest: C:\Temp\Observe\observe-agent.zip
    force: yes

# 2. Download install.ps1
- name: Download install.ps1
  ansible.windows.win_get_url:
    url: https://github.com/observeinc/observe-agent/releases/latest/download/install.ps1
    dest: C:\Temp\Observe\install.ps1
    force: yes

# 3. Run the script (enable TLS 1.2 first)
- name: Run install.ps1 with token, endpoint, and zip_dir
  ansible.windows.win_shell: |
    [Net.ServicePointManager]::SecurityProtocol = 'Tls, Tls11, Tls12, Ssl3'
    C:\Temp\Observe\install.ps1 `
      -observe_token "{{ YOUR_INGEST_TOKEN }}" `
      -observe_collection_endpoint "{{ YOUR_OBSERVE_COLLECTION_ENDPOINT }}" `
      -zip_dir "C:\Temp\Observe\observe-agent.zip"
  args:
    executable: powershell.exe
  register: ps_install

# 4. Reboot only when the script returns 3010
- name: Reboot if install.ps1 returned 3010
  ansible.windows.win_reboot:
  when: ps_install.rc == 3010

# 5. Make sure the service is up (covers non-reboot cases)
- name: Ensure ObserveAgent service is running
  ansible.windows.win_service:
    name: ObserveAgent
    start_mode: auto
    state: started
  1. Create main.yaml under /etc/ansible/roles/agent/tasks/

---
- import_tasks: install_with_ps1.yaml
  1. Create install-observe-agent-windows.yaml

---
# install-observe-agent-windows.yaml
#
# Launch from the control node:
#
#   ansible-playbook install-observe-agent-windows.yaml \
#     -i /etc/ansible/hosts/windows.aws_ec2.ini \
#     --ask-vault-pass            # only if token / password are vaulted
#
# What this playbook does
# ─────────────────────────────────────────────────────────
# • Targets every host in the [windows] group (defined in
#   windows.aws_ec2.ini).
# • Loads variables from /etc/ansible/hosts/group_vars/windows.yaml
#   – YOUR_OBSERVE_COLLECTION_ENDPOINT
#   – YOUR_INGEST_TOKEN
# • Executes the “agent” role, whose sole task-file
#   (install_with_ps1.yaml) does:
#     1. Download the latest install.ps1 from GitHub
#     2. Run the script with token & endpoint
#        – If the agent is missing, it installs it.
#        – If the agent is older, it upgrades in place.
#     3. Reboot only when the script returns exit-code 3010
#
# Idempotent: re-running the playbook simply ensures the
# agent is at the newest version and running.

- name: Install or upgrade Observe Agent on Windows fleet
  hosts: windows
  gather_facts: no      # WinRM fact-gathering not required here

  roles:
    - agent              # looks under /etc/ansible/roles/agent/
  1. Use ansible-playbook to install the Observe Agent with install-observe-agent-windows.yaml. A typical command looks like this:

$ ansible-playbook install-observe-agent-windows.yaml -i /etc/ansible/hosts/windows.aws_ec2.ini

PLAY [Install or upgrade Observe Agent on Windows fleet] **********************************************************************************************************************************************************

TASK [agent : Ensure staging directory exists] ********************************************************************************************************************************************************************
ok: [ansible-managed-node-2]
ok: [ansible-managed-node-1]

TASK [agent : Download latest Observe Agent ZIP] ******************************************************************************************************************************************************************
ok: [ansible-managed-node-2]
ok: [ansible-managed-node-1]

TASK [agent : Download install.ps1] *******************************************************************************************************************************************************************************
ok: [ansible-managed-node-2]
ok: [ansible-managed-node-1]

TASK [agent : Run install.ps1 with token, endpoint, and zip_dir] **************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

TASK [agent : Reboot if install.ps1 returned 3010] ****************************************************************************************************************************************************************
skipping: [ansible-managed-node-2]
skipping: [ansible-managed-node-1]

TASK [agent : Ensure ObserveAgent service is running] *************************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

PLAY RECAP ********************************************************************************************************************************************************************************************************
ansible-managed-node-1     : ok=5    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ansible-managed-node-2     : ok=5    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 

Configure the Observe Agent

  1. The installation PowerShell script will automatically start the agent for you. You can find the observe-agent.yaml config file in the ${Env:Programfiles}\Observe\observe-agent directory. To push custom settings with Ansible, create observe-agent.yaml.j2 under /etc/ansible/roles/agent/templates. The following example will collect metrics about the processes running on the host system. Adjust the template as needed for your own logging, forwarding, or telemetry requirements. For more information on configuring the agent, see Configuration.

# Observe data token (ex: a1b2c3d4e5f6g7h8i9k0:l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6)
token: "{{ YOUR_INGEST_TOKEN }}"

# Target Observe collection url (ex: https://123456789012.collect.observeinc.com/)
observe_url: "{{ YOUR_OBSERVE_COLLECTION_ENDPOINT }}"

health_check:
    enabled: true
    endpoint: localhost:13133
    path: /status

internal_telemetry:
    enabled: true
    metrics:
        enabled: true
        host: localhost
        port: 8888
        level: detailed
    logs:
        enabled: true
        level: ${env:OTEL_LOG_LEVEL}

# Debug mode - Sets agent log level to debug
debug: false

# collect metrics and logs pertaining to the agent itself
self_monitoring:
  enabled: true

# collect metrics and logs about the host system
host_monitoring:
  enabled: true
  # collect logs of all running processes from the host system
  logs:
    enabled: true
  metrics:
    # collect metrics about the host system
    host:
      enabled: true
    # collect metrics about the processes running on the host system
    process:
      enabled: true

# Enable forwarding of local app metrics and traces
forwarding:
  enabled: true
  metrics:
    output_format: otel

# otel_config_overrides:
#   exporters:
#     debug:
#       verbosity: detailed
#       sampling_initial: 5
#       sampling_thereafter: 200
#   service:
#     pipelines:
#       metrics:
#         receivers: [hostmetrics]
#         processors: [memory_limiter]
#         exporters: [debug]
  1. Create update_config.yaml under /etc/ansible/roles/agent/tasks/

- name: Make sure config dir exists
  ansible.windows.win_file:
    path: "{{ lookup('env','SystemDrive') }}\\Program Files\\Observe\\observe-agent"
    state: directory

- name: Render observe-agent.yaml
  ansible.windows.win_template:
    src: /etc/ansible/roles/agent/templates/observe-agent.yaml.j2
    dest: "{{ lookup('env','SystemDrive') }}\\Program Files\\Observe\\observe-agent\\observe-agent.yaml"
    force: yes
  notify: restart observe agent
  1. Create update-observe-agent-windows.yaml

---
# update-observe-agent-windows.yaml
#
# Push the rendered observe-agent.yaml to every Windows host.
# The service restarts only when the file content changes.
#
#   ansible-playbook update-observe-agent-windows.yaml \
#     -i /etc/ansible/hosts/windows.aws_ec2.ini \
#     --ask-vault-pass          # only if secrets are vaulted

- name: Update Observe Agent configuration on Windows hosts
  hosts: windows
  gather_facts: no

  tasks:
    - name: Render config template and restart when needed
      import_tasks: /etc/ansible/roles/agent/tasks/update_config.yaml

  handlers:
    - name: restart observe agent
      ansible.windows.win_service:
        name: ObserveAgent
        state: restarted
  1. Use ansible-playbook to apply your custom settings of the Observe Agent with update-observe-agent-windows.yaml. A typical command looks like this:

$ ansible-playbook update-observe-agent-windows.yaml -i /etc/ansible/hosts/windows.aws_ec2.ini --flush-cache --diff

PLAY [Update Observe Agent configuration on Windows hosts] ********************************************************************************************************************************************************

TASK [Make sure config dir exists] ********************************************************************************************************************************************************************************
ok: [ansible-managed-node-2]
ok: [ansible-managed-node-1]

TASK [Render observe-agent.yaml] **********************************************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

RUNNING HANDLER [restart observe agent] ***************************************************************************************************************************************************************************
--- before
+++ after
@@ -18,6 +18,6 @@
     "service_type": "win32_own_process",
     "sid_info": "none",
     "start_mode": "auto",
-    "state": "started",
+    "state": "restarted",
     "username": "NT AUTHORITY\\SYSTEM"
 }

changed: [ansible-managed-node-2]
--- before
+++ after
@@ -18,6 +18,6 @@
     "service_type": "win32_own_process",
     "sid_info": "none",
     "start_mode": "auto",
-    "state": "started",
+    "state": "restarted",
     "username": "NT AUTHORITY\\SYSTEM"
 }

changed: [ansible-managed-node-1]

PLAY RECAP ********************************************************************************************************************************************************************************************************
ansible-managed-node-1     : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ansible-managed-node-2     : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Configure application instrumentation

Once the Observe Agent is deployed, configure your application instrumentation or set the OTEL_EXPORTER_OTLP_ENDPOINT environment variable to one of the following addresses to send application telemetry including traces to the Observe Agent.

Note

When setting up the endpoint to send traces, make sure you use the path that your OTLP library requires. Some libraries need traces to go to /v1/traces, while others expect them at the root path /.

  • OTLP/HTTP endpoint: http://localhost:4318

  • OTLP/grpc endpoint: http://localhost:4317

Learn more about how to instrument your app

Uninstall the Observe Agent

  1. Create uninstall-observe-agent-windows.yaml

---
# uninstall-observe-agent-windows.yaml
# Completely removes the Observe Agent from Windows hosts.
#
#   ansible-playbook uninstall-observe-agent-windows.yaml \
#     -i /etc/ansible/hosts/windows.aws_ec2.ini

- name: Uninstall Observe Agent completely
  hosts: windows
  gather_facts: no

  tasks:
    # 1 ── Stop & disable the service (ignore if it’s already gone)
    - name: Stop ObserveAgent service
      ansible.windows.win_service:
        name: ObserveAgent
        state: stopped
        start_mode: disabled
      ignore_errors: yes

    # 2 ── Delete the service definition so it can’t restart
    - name: Remove ObserveAgent service entry
      ansible.windows.win_service:
        name: ObserveAgent
        state: absent
      ignore_errors: yes

    # 3 ── Kill any stray process that still has the binary open
    - name: Kill leftover observe-agent.exe processes (if any)
      ansible.windows.win_shell: |
        $p = Get-Process observe-agent -ErrorAction SilentlyContinue
        if ($p) { $p | Stop-Process -Force }
        exit 0                       # ← forces exit-code 0
      args:
        executable: powershell.exe

    # 4 ── Force-remove Program Files\Observe on the remote host
    - name: Remove C:\Program Files\Observe tree (force)
      ansible.windows.win_shell: |
        $pf = $env:ProgramFiles
        $path = Join-Path $pf 'Observe'
        if (Test-Path $path) {
          Remove-Item -LiteralPath $path -Recurse -Force
        }
      args:
        executable: powershell.exe

    # 5 ── Optional: wipe configs / logs
    # - name: Remove %ProgramData%\Observe
    #   ansible.windows.win_shell: |
    #     $pd = $env:ProgramData
    #     $path = Join-Path $pd 'Observe'
    #     if (Test-Path $path) {
    #       Remove-Item -LiteralPath $path -Recurse -Force
    #     }
    #   args:
    #     executable: powershell.exe
  1. Use ansible-playbook to uninstall the Observe Agent with uninstall-observe-agent-windows.yaml. A typical command looks like this:

$ ansible-playbook uninstall-observe-agent-windows.yaml -i /etc/ansible/hosts/windows.aws_ec2.ini

PLAY [Uninstall Observe Agent completely] *************************************************************************************************************************************************************************

TASK [Stop ObserveAgent service] **********************************************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

TASK [Remove ObserveAgent service entry] **************************************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

TASK [Kill leftover observe-agent.exe processes (if any)] *********************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

TASK [Remove C:\Program Files\Observe tree (force)] ***************************************************************************************************************************************************************
changed: [ansible-managed-node-2]
changed: [ansible-managed-node-1]

PLAY RECAP ********************************************************************************************************************************************************************************************************
ansible-managed-node-1     : ok=4    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ansible-managed-node-2     : ok=4    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Upgrade the Observe Agent

Use ansible-playbook to upgrade the Observe Agent with install-observe-agent-windows.yaml. The script will stop the service before installing the new version of the agent and restarting the service.

$ ansible-playbook install-observe-agent-windows.yaml   -i /etc/ansible/hosts/windows.aws_ec2.ini

Next steps

Use both the Log Explorer and the Metric Explorer to monitor your systems. To analyze your trace data, explore both the Trace Explorer and the Service Explorer

For additional installation patterns and advanced examples, see the Observe Windows Ansible Playbook