Your First Productive Polycrate Workspace: A Checklist for Getting Started
TL;DR A well-named, clearly structured Polycrate workspace is half the battle: a consistent name …
Diese Serie zeigt Schritt für Schritt, wie Ansible mit Polycrate zu einer strukturierten, teilbaren und compliance-fähigen Automatisierungsplattform wird – von den Grundlagen bis zu Enterprise-Szenarien.
pywinrm chaos, no local installations, no version debates within the team.win_service, win_updates), pywinrm, and the matching Ansible bundle—no custom Dockerfile, no manual ansible-galaxy installs for typical use. You only configure the workspace, inventory, and playbooks.secrets.poly and secured via built-in workspace encryption with age—not in inventory.yml.Many Windows admins view Ansible skeptically:
pywinrm, OpenSSL—I don’t want to deal with all that locally.”Technically, Ansible is an excellent tool, especially for Windows:
ansible.windows and community.windows.What hurts in practice is something else:
Dependency Problem:
Maintaining the same Python/Ansible/WinRM versions on every admin laptop and jump box is exhausting—and security-sensitive.
Playbook Proliferation:
Five different script folders, slightly different playbooks, no one knows what’s “official.”
Secrets Everywhere:
Passwords in inventory.yml, in group_vars, in scripts—and then comes the audit.
Polycrate addresses these issues:
ansible.windows.* playbooks you need no extra Dockerfile.poly and no manual ansible-galaxy collection install ansible.windows. Only if you need additional collections do you extend the image (e.g. community.windows).age ensures you can securely store passwords in secrets.poly without an extra vault solution.In this post, we’ll build this step by step—with a focus on Windows admins without cloud-native experience.
Before Ansible can communicate with your Windows servers via Polycrate, WinRM must be properly configured. We focus on:
On the target server (e.g., Windows Server 2022), open PowerShell as Administrator:
winrm quickconfigIf the service is not running, you will be asked if it should be configured. Confirm this.
This usually sets up an HTTP listener on port 5985. For Ansible over the internet or in sensitive networks, you should disable HTTP and use HTTPS.
For testing and small environments, a self-signed certificate is sufficient. In a domain, you should use a certificate from your corporate PKI.
Self-Signed Example:
$newCert = New-SelfSignedCertificate `
-DnsName "win01.acme-corp.com" `
-CertStoreLocation "Cert:\LocalMachine\My"Note the thumbprint:
$newCert.ThumbprintIn production environments, replace this step with a server certificate issued by your CA.
First, check existing HTTP listeners:
winrm enumerate winrm/config/ListenerCreate an HTTPS listener with your certificate (insert thumbprint):
$thumb = "<YOUR_THUMBPRINT>"
winrm create winrm/config/Listener?Address=*+Transport=HTTPS `
"@{Hostname=`"win01.acme-corp.com`"; CertificateThumbprint=`"$thumb`"}"If an HTTPS listener already exists, you can alternatively adjust it with winrm set.
Check security settings:
winrm get winrm/configImportant points:
AllowUnencrypted should be false.Service/Auth, Basic should ideally be false, NTLM/Kerberos are preferable.The standard port for WinRM over HTTPS is 5986. Open the port in the Windows Firewall:
New-NetFirewallRule `
-Name "WINRM_HTTPS_IN" `
-DisplayName "WinRM over HTTPS" `
-Protocol TCP `
-LocalPort 5986 `
-Direction Inbound `
-Action AllowDepending on the environment, you can restrict access to certain subnets or management servers.
From an admin machine (or a jump box), you can test if HTTPS works with PowerShell:
Test-WsMan win01.acme-corp.com -UseSSLIf this works, the technical foundations for Ansible are in place. With plain Ansible, you would now install Python, Ansible, pywinrm, and SSL libraries and configure them accordingly.
With Polycrate, you skip this part entirely—bringing us to the workspace.
We create a simple Polycrate workspace that manages your Windows servers.
In the root directory of your workspace is the workspace.poly:
name: acme-corp-automation
organization: acme
blocks:
- name: windows-baseline
from: windows-baseline
config:
windows_group: "windows"What’s happening here:
name: The name of your workspace, e.g., your team or project.blocks: List of block instances. We have a block windows-baseline that comes from a local directory ./blocks/windows-baseline.config.windows_group: The host group this block refers to by default.More about workspaces can be found in the Workspace Documentation.
Directly in the workspace root is inventory.yml. As in Multi-server management with Ansible inventories, all hosts live under all.hosts; under children, the windows group references them by name only—shared WinRM settings go in the group vars (no per-host duplication):
all:
hosts:
win01.acme-corp.com: {}
win02.acme-corp.com: {}
children:
windows:
hosts:
win01.acme-corp.com:
win02.acme-corp.com:
vars:
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_port: 5986
ansible_winrm_server_cert_validation: ignoreImportant:
ansible_connection: winrm tells Ansible to use WinRM.ansible_winrm_transport: ntlm chooses NTLM as the auth method (suitable for many classic Windows environments).ansible_winrm_server_cert_validation: ignore is useful for self-signed certificates. In production environments, you should validate certificates correctly.No passwords in the inventory. They will be placed in secrets.poly.
Further details on Ansible integration can be found in the Ansible Documentation for Polycrate.
Polycrate comes with workspace encryption with age built-in. You don’t need to run an external vault tool to securely store passwords.
In the workspace root, create a file secrets.poly:
win_admin_user: "acme-admin"
win_admin_password: "SuperSecurePassword123!"Before you commit this file to Git, encrypt the workspace:
polycrate workspace encryptDetails can be found in the Workspace Encryption Documentation.
Polycrate makes these secrets available in the playbook as workspace.secrets.*. We’ll use this to set ansible_user and ansible_password—without storing them in the inventory.
Now we define our Windows block. The directory ./blocks/windows-baseline contains at least:
block.polybaseline.yml (Windows base configuration)patches.yml (Windows patch management)name: windows-baseline
version: 0.1.0
kind: generic
config:
windows_group: "windows"
actions:
- name: baseline
description: "Windows base configuration (services, features, registry, software)"
playbook: baseline.yml
- name: patches
description: "Windows patch management with win_updates"
playbook: patches.ymlkind: generic is suitable for classic Ansible blocks.actions, you define descriptive actions, each executing a playbook.config.windows_group, you can centrally control the target group.Best practices for blocks can be found in the Block Best Practices and the Blocks Documentation.
You always execute an action with the same schema:
polycrate run windows-baseline baselineor:
polycrate run windows-baseline patchesPolycrate starts a container with your defined toolchain, loads the workspace including encrypted secrets, and runs Ansible within it. You do not need to have Ansible, Python, or pywinrm installed on your laptop.
Now it gets concrete: We write the playbook baseline.yml and use modules from ansible.windows and community.windows.
- name: Apply Windows Baseline
hosts: "{{ block.config.windows_group }}"
gather_facts: false
vars:
ansible_user: "{{ workspace.secrets.win_admin_user }}"
ansible_password: "{{ workspace.secrets.win_admin_password }}"
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_port: 5986
ansible_winrm_server_cert_validation: ignore
tasks:
- name: Ensure 'Spooler' service is running
ansible.windows.win_service:
name: Spooler
start_mode: auto
state: started
- name: Install 'Web-Server' (IIS) feature
ansible.windows.win_feature:
name: Web-Server
state: present
include_sub_features: true
restart: false
- name: Allow Remote Desktop via registry key
ansible.windows.win_regedit:
path: HKLM:\System\CurrentControlSet\Control\Terminal Server
name: fDenyTSConnections
data: 0
type: dword
- name: Install Chocolatey (if not present)
ansible.windows.win_chocolatey:
state: present
- name: Install 7zip via Chocolatey
ansible.windows.win_chocolatey:
name: 7zip
state: present
- name: Install custom MSI package
ansible.windows.win_package:
path: "\\fileserver.acme-corp.com\software\MyApp.msi"
product_id: "{12345678-ABCD-1234-ABCD-1234567890AB}"
state: presentWhat’s happening here:
hosts: We use the group from block.config.windows_group, i.e., windows. This way, you can use the same block in another workspace with a different group.vars: We set connection parameters (user/password, WinRM details) from workspace.secrets.*. That is the core idea: no plaintext passwords in the inventory.ansible.windows.win_service: The “Spooler” service must be running and set to start automatically. The module belongs to ansible.windows (not ansible-core); it is already included in the default Polycrate image (see TL;DR and “Polycrate addresses these issues”).ansible.windows.win_feature: Installs the IIS role including subfeatures.ansible.windows.win_regedit: Enables Remote Desktop (classic example).ansible.windows.win_chocolatey: Installs Chocolatey and then a package.ansible.windows.win_package: Installs an MSI from a central share.You would write a similar playbook with plain Ansible—Ansible is fine here. The difference is everything around it:
ansible.windows and community.windows locally.pywinrm and SSL dependencies cleanly.With Polycrate, all of that ships in the bundled Ansible container (see python-requirements.txt / Polycrate Dockerfile: ansible bundle, pywinrm, additional Galaxy collections). Only if you need more collections do you extend the image (e.g. Dockerfile.poly). Your colleagues only need Polycrate and Docker—no local Python tuning.
Patches are a typical use case Windows admins want to automate cleanly—including controlled reboots.
- name: Install Windows patches
hosts: "{{ block.config.windows_group }}"
gather_facts: false
vars:
ansible_user: "{{ workspace.secrets.win_admin_user }}"
ansible_password: "{{ workspace.secrets.win_admin_password }}"
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_port: 5986
ansible_winrm_server_cert_validation: ignore
tasks:
- name: Install security and critical updates
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
state: installed
reboot: yes
register: update_result
- name: Reboot if required
ansible.windows.win_reboot:
msg: "Rebooting for Windows updates."
pre_reboot_delay: 60
post_reboot_delay: 120
when: update_result.reboot_requiredExplanation:
ansible.windows.win_updates controls which updates to install; category_names lets you filter.reboot: yes allows win_updates to initiate a reboot if needed.ansible.windows.win_reboot handles the reboot in the Ansible context and waits until the host is reachable again.From a Windows admin’s perspective, this is where Ansible shines: you can build a reproducible patch playbook and roll it out monthly via a Polycrate workflow, for example.
More on workflows: Workflows documentation.
Imagine building the same setup with plain Ansible—without Polycrate:
On your admin laptop:
pip or the package manager).pywinrm and requests-ntlm.ansible.windows and community.windows collections.ansible.cfg (inventory path, WinRM defaults, etc.).On your colleagues’ laptops:
In documentation:
pip install …”).With Polycrate, the picture changes:
pywinrm, collections, etc. live in a container image.Dockerfile.poly) and share it with the team.The block model adds structure:
baseline, patches).Technical details: Registry documentation and PolyHub.
No. Ansible over WinRM with ansible_connection: winrm and ansible_winrm_transport: ntlm also works for workgroup servers, as long as:
In a domain you can additionally use Kerberos, which is often preferable. For getting started, NTLM is often simpler, especially in mixed environments.
You have several options:
inventory.yml and only pull the password from secrets.poly.secrets.poly (e.g. win_admin_user_dmz, win_admin_user_internal) and use block.config in the block to choose which account to use.Polycrate gives you enough flexibility with workspace.secrets.* and block.config.* without scattering passwords in plaintext files. See best practices.
If you already have a working Ansible setup, Polycrate mainly adds:
secrets.poly and encrypted workspace directories without extra tools.For many teams, the first step is lift-and-shift of existing playbooks into a block and clean up gradually. We describe migration paths in other posts in this series.
More questions? See our FAQ.
What did we cover in this post?
inventory.yml, workspace.poly, secrets.poly, and a Windows block (block.poly).ansible.windows and community.windows to manage services, features, registry, software, and updates—without a local Ansible install.age and secrets in secrets.poly instead of inventory.yml.For Windows teams, this is often where automation turns from “occasional scripts” into a repeatable, shareable, auditable platform.
We regularly help teams with setups like this:
If you want a practical, hands-on introduction with your team, our Windows automation workshop covers WinRM basics through scalable patch management with Polycrate.
TL;DR A well-named, clearly structured Polycrate workspace is half the battle: a consistent name …
TL;DR Plain Ansible is a powerful tool for ad-hoc automation, quick scripts, and simple setups – but …
TL;DR Most environments are hybrid: Windows servers for AD, file services, and specialized …