Ansible Windows IIS — Deploy Web Applications

Introduction

Deploy Web Applications. Ansible manages Windows hosts over WinRM, providing the same declarative automation as Linux. This guide covers the ansible.windows and community.windows collections for Windows automation.

Prerequisites

# Install Windows collections
ansible-galaxy collection install ansible.windows community.windows

# Install pywinrm on the controller
pip install pywinrm
# Inventory for Windows hosts
all:
  hosts:
    win01:
      ansible_host: 192.168.1.100
      ansible_user: Administrator
      ansible_password: "{{ vault_win_password }}"
      ansible_connection: winrm
      ansible_winrm_transport: ntlm
      ansible_winrm_server_cert_validation: ignore
      ansible_port: 5986

Basic Windows Tasks

---
- name: Deploy Web Applications
  hosts: windows
  tasks:
    - name: Gather Windows facts
      ansible.windows.setup:

    - name: Display Windows version
      ansible.builtin.debug:
        msg: "{{ ansible_os_name }} {{ ansible_os_version }}"

    - name: Ensure required Windows features
      ansible.windows.win_feature:
        name: "{{ item }}"
        state: present
      loop:
        - Web-Server
        - Web-Mgmt-Tools

Configuration Management

    - name: Configure Windows settings
      ansible.windows.win_regedit:
        path: HKLM:\SOFTWARE\MyApp
        name: Setting1
        data: enabled
        type: string

    - name: Manage Windows services
      ansible.windows.win_service:
        name: W3SVC
        start_mode: auto
        state: started

    - name: Copy configuration files
      ansible.windows.win_copy:
        src: files/config.xml
        dest: C:\App\config.xml

Software Installation

    - name: Install software via Chocolatey
      chocolatey.chocolatey.win_chocolatey:
        name:
          - git
          - vscode
          - python3
          - 7zip
        state: present

    - name: Install MSI package
      ansible.windows.win_package:
        path: C:\Temp\installer.msi
        state: present
        arguments: /quiet /norestart

    - name: Install from URL
      ansible.windows.win_package:
        path: https://example.com/setup.exe
        product_id: '{product-guid}'
        arguments: /S

Windows Updates

    - name: Install Windows updates
      ansible.windows.win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        reboot: true
        reboot_timeout: 3600
      register: update_result

    - name: Show update results
      ansible.builtin.debug:
        msg: "Installed {{ update_result.installed_update_count }} updates"

PowerShell Integration

    - name: Run PowerShell script
      ansible.windows.win_powershell:
        script: |
          Get-Service | Where-Object {Status -eq 'Running'} |
            Select-Object -Property Name, DisplayName |
            ConvertTo-Json
      register: services

    - name: Execute remote PowerShell script
      ansible.windows.win_powershell:
        script: "{ lookup('file', 'scripts/setup.ps1') }"
        parameters:
          Environment: production
          Verbose: true

Scheduled Tasks

    - name: Create scheduled task
      community.windows.win_scheduled_task:
        name: DailyMaintenance
        description: Daily maintenance scripts
        actions:
          - path: powershell.exe
            arguments: -File C:\Scripts\maintenance.ps1
        triggers:
          - type: daily
            start_boundary: '2026-01-01T03:00:00'
        username: SYSTEM
        run_level: highest
        state: present

Firewall Rules

    - name: Configure Windows Firewall
      community.windows.win_firewall_rule:
        name: "{{ item.name }}"
        localport: "{{ item.port }}"
        action: allow
        direction: in
        protocol: tcp
        state: present
        enabled: true
      loop:
        - { name: 'Allow HTTP', port: 80 }
        - { name: 'Allow HTTPS', port: 443 }
        - { name: 'Allow RDP', port: 3389 }

Troubleshooting

IssueSolution
WinRM connection refusedRun winrm quickconfig on Windows host
Certificate errorSet ansible_winrm_server_cert_validation: ignore
Access deniedCheck user has admin privileges
TimeoutIncrease ansible_winrm_operation_timeout_sec
PowerShell execution policySet Set-ExecutionPolicy RemoteSigned

Best Practices

  1. Use WinRM over HTTPS (port 5986) in production
  2. Store credentials in Ansible Vault — never plaintext
  3. Test with win_ping before running playbooks
  4. Use Chocolatey for software management when possible
  5. Reboot handling — use win_reboot module with proper timeout

Conclusion

Ansible provides comprehensive Windows automation through the ansible.windows and community.windows collections. From software installation to Group Policy management, the same playbook-driven approach works across both Linux and Windows infrastructure.