Skip to content

YAML Examples

These examples are pulled from the Create ROOT Domain Controller (DC) plugin — one of the most full-featured plugins on the platform. Each snippet highlights a specific pattern you’ll use in your own plugins.

The most basic pattern — just tasks with no play headers:

- name: Install DNS Server feature
ansible.windows.win_feature:
name: DNS
include_management_tools: yes
state: present
- name: Install Active Directory Domain Services
ansible.windows.win_feature:
name: AD-Domain-Services
include_management_tools: yes
state: present

Parameters defined in the UI are referenced with {{ ParamName }}:

- name: Rename computer
ansible.windows.win_hostname:
name: "{{ Hostname }}"
- name: Create new AD forest domain (DC promo)
ansible.windows.win_domain:
dns_domain_name: "{{ DomainNameFQDN }}"
safe_mode_password: "Password1!"
register: ad

Chain set_fact calls to compute defaults from parameters. This lets scenario architects provide minimal input while your plugin fills in the rest:

- name: Normalize StaticIP (whitespace-safe)
ansible.builtin.set_fact:
_static_ip_clean: "{{ StaticIP | default('') | trim }}"
- name: Derive default gateway from StaticIP (x.y.z.1)
ansible.builtin.set_fact:
default_gateway: "{{ (_static_ip_clean.split('.')[0:3] + ['1']) | join('.') if _static_ip_clean != '' else '' }}"
- name: Apply gateway override
ansible.builtin.set_fact:
effective_gateway: "{{ (IPGateway | default(default_gateway, true)) | trim }}"
- name: Derive upstream DNS (prefer IPDNS; fallback to effective gateway)
ansible.builtin.set_fact:
upstream_DNS: "{{ (IPDNS | default(effective_gateway, true)) | trim }}"

Here StaticIP is the only required parameter. IPGateway and IPDNS are optional overrides — if not set, they’re derived from the static IP.

Embed parameters directly into PowerShell script blocks:

- name: Set DNS forwarder to gateway
ansible.windows.win_powershell:
script: |
$gw = '{{ upstream_DNS }}'
Set-DnsServerForwarder -IPAddress $gw -PassThru

A more complex example — configuring a static IP with full PowerShell logic, using multiple parameters:

- name: Ensure static IPv4 and Disable IPv6
ansible.windows.win_powershell:
script: |
$alias = 'Ethernet'
$ip = '{{ StaticIP | default("") | trim }}'
$gw = '{{ effective_gateway | default("") | trim }}'
$mask = 24
$maskInput = '{{ IPSubnetMask | default("") | trim }}'
# Disable IPv6
Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | ForEach-Object {
Disable-NetAdapterBinding -Name $_.Name -ComponentID ms_tcpip6 -ErrorAction SilentlyContinue
}
# ... IP configuration logic ...
Set-DnsClientServerAddress -InterfaceAlias $alias -ServerAddresses ("{{ upstream_DNS }}") -ErrorAction Stop

CSV parameters come from the UI grid and may contain BOM characters or carriage returns. Always normalize before parsing:

- name: Normalize CSV-style variables
ansible.builtin.set_fact:
CreateOUs: "{{ CreateOUs | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
CreateGroups: "{{ CreateGroups | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"
CreateUsers: "{{ CreateUsers | default('') | regex_replace('^\\ufeff','') | regex_replace('\\r','') | trim }}"

Then parse into Ansible records:

- name: Parse CSV into records
ansible.builtin.set_fact:
ou_records: >-
{{ (CreateOUs | length > 0) | ternary(CreateOUs | community.general.from_csv, []) }}
user_records: >-
{{ (CreateUsers | length > 0) | ternary(CreateUsers | community.general.from_csv, []) }}

See CSV Parameters for the full CSV workflow including writing to disk and bulk PowerShell processing.

Verify your plugin actually worked by registering output and using failed_when:

- name: Confirm domain controller is active
ansible.windows.win_powershell:
script: |
$domain = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History").MachineDomain
if (-not [string]::IsNullOrWhiteSpace($domain)) { Write-Host "SUCCESS" } else { Write-Host "FAILED" }
register: dc_check
failed_when: "'FAILED' in dc_check.output"

This pattern is useful for catching silent failures — tasks that technically succeed (exit code 0) but didn’t actually produce the expected result.