For domain-joined Windows systems, use AD CS certificate auto-enrollment for routine issuance and renewal, then use Ansible to configure templates, validate certificate state, trigger enrollment where necessary, and perform application-specific binding.
Recommended design
Separate the automation into three layers:
- CA configuration
- Manage AD CS certificate templates with
microsoft.ad.cs_template. - Manage Authority Information Access (AIA) and Certificate Revocation List Distribution Point (CDP) entries with
microsoft.ad.cs_authority. - The
microsoft.adcollection manages these AD CS configuration objects, but it does not provide a complete certificate enrollment/renewal module.^1^
- Manage AD CS certificate templates with
- Endpoint enrollment and renewal
- Prefer Group Policy auto-enrollment for domain-joined computers.
- Use Ansible with
Get-Certificateorcertreqwhen a request needs custom subject/SAN values, explicit timing, or integration into a larger deployment workflow.
- Installation and application binding
- AD CS enrollment installs the certificate into the selected Windows certificate store.
- Use Ansible to inspect the installed certificate and configure the consuming service, such as an IIS HTTPS binding.
-
ansible.windows.win_certificate_storecan import, export, or remove certificates, but does not create certificate requests.^2^
1. Prepare AD CS
Before automating enrollment:
- Publish the required template on the enterprise CA.
- Grant the requesting computer or user Read and Enroll permissions.
- Grant the issuing CA Read permission on the template.
- Determine whether the certificate belongs in the current-user, local-computer, or service-account store.
- Ensure the target can reach AD DS and the issuing enterprise CA.
Administrative elevation does not replace template enrollment permissions.^3^
For machine certificates, normally enroll directly on the target machine so that the private key is created in that machine’s context.
2. Enable native automatic renewal
For ordinary domain-joined servers, create and link a dedicated GPO to the appropriate server OU:
- Open Group Policy Management.
- Edit the dedicated GPO.
- Go to: Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies.
- Open Certificate Services Client – Auto-Enrollment.
- Set Configuration Model to Enabled.
- Enable:
- Renew expired certificates, update pending certificates, and remove revoked certificates
- Update certificates that use certificate templates
- Link the GPO to the target OU.
- Use Ansible to run
gpupdate /forceif immediate application is required.
These settings allow certificates based on configured templates to be issued and renewed automatically.^4^
3. Ansible enrollment pattern
The following pattern checks for a matching, non-expiring machine certificate and enrolls only when one is absent or within 30 days of expiration:
- name: Maintain AD CS machine certificate
hosts: windows_servers
gather_facts: false
tasks:
- name: Enroll when certificate is missing or expiring
ansible.windows.win_powershell:
script: |
$limit = (Get-Date).AddDays(30)
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object {
$_.Subject -eq 'CN={{ inventory_hostname }}' -and
$_.NotAfter -gt $limit
} | Select-Object -First 1
if (-not $cert) {
Get-Certificate -Template 'WebServer' `
-DnsName '{{ inventory_hostname }}' `
-CertStoreLocation 'Cert:\LocalMachine\My'
$Ansible.Changed = $true
} else {
$Ansible.Changed = $false
}
Adjust the subject/SAN test so that it uniquely identifies your template’s certificate. Get-Certificate submits the request and installs an issued certificate into the specified My store; pending requests are instead placed in the corresponding request store.^5^
When executed through PowerShell remoting, enrollment can require delegation because the remote target may need to authenticate onward to AD CS. In that case, native auto-enrollment or a local scheduled task is generally preferable to embedding privileged credentials in the playbook.^5^
Custom CSR workflow
When an approved INF file is required, automate the documented certreq sequence:
certreq -new -machine requestconfig.inf certrequest.req
certreq -submit certrequest.req certnew.cer
certreq -accept -machine certnew.cer
If the request is pending, retain the request ID and retrieve it after approval:
certreq -retrieve <RequestID> certnew.cer
certreq -accept -machine certnew.cer
For machine certificates, the INF must use MachineKeySet = TRUE, and generation and acceptance must occur in the same machine context.^3^ An existing valid certificate can also be renewed with certreq -enroll -cert ... renew; expired certificates cannot be renewed and must be replaced.^6^
Non-domain or disconnected systems
If targets cannot use direct Active Directory enrollment, conditionally deploy Certificate Enrollment Policy Web Service and Certificate Enrollment Web Service. CES supports enrollment and renewal for non-domain computers or domain computers disconnected from the domain, but requires an enterprise CA, HTTPS certificate, supported authentication, and additional service-account/delegation configuration.^7^
After each enrollment, validate:
- Intended certificate store
- Subject and SAN
- EKU
- Expiration
- Complete trusted chain
-
HasPrivateKey - Access to the private key by the application’s runtime identity
Then update the application binding and restart only the service or application pool that must reload the certificate.
References
- Microsoft.Ad — Ansible Community Documentation
- ansible.windows.win_certificate_store module – Manages the certificate ...
- Request and Renew AD CS Certificates - Windows Server
- Configure auto-enrollment of certificates for Network Policy Server
- Submits a certificate request to an enrollment server using specified parameters and installs the resulting certificate in the local machine's personal certific...
- certreq
- Configure the Certificate Enrollment Web Service