win_iis_webbinding rewrite (#33958)

* Begin rewrite of win_iis_webbinding
Add integration testing, check mode and idempotency
Add support for SNI
Fix replacing SSL cert on existing bindings

* finished up initial rewrite of win_iis_webbinding

* updated test to remove tests as filters

* updated win_iis_webbinding docs

* fix more doc/formatting issues win_iis_webbinding

* Removed string empty defaults for certs. Added a few new helpful
comments.

* Revert "Removed string empty defaults for certs. Added a few new helpful"

This reverts commit 48f35faea8.
This commit is contained in:
nwsparks 2018-01-01 19:30:18 -05:00 committed by ansibot
parent e3b49a7aeb
commit 0a3da471f5
11 changed files with 2153 additions and 171 deletions

View file

@ -1,131 +1,454 @@
#!powershell
# (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
# Copyright: (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#Requires -Module Ansible.ModuleUtils.Legacy
# WANT_JSON
# POWERSHELL_COMMON
$params = Parse-Args -arguments $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
$params = Parse-Args $args;
$name = Get-AnsibleParam $params -name "name" -failifempty $true
$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website'
$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent"
$host_header = Get-AnsibleParam $params -name "host_header"
$protocol = Get-AnsibleParam $params -name "protocol"
$port = Get-AnsibleParam $params -name "port"
$ip = Get-AnsibleParam $params -name "ip"
$certificatehash = Get-AnsibleParam $params -name "certificate_hash" -default $false
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -default "MY"
$host_header = Get-AnsibleParam $params -name "host_header" -type str
$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http'
$port = Get-AnsibleParam $params -name "port" -default '80'
$ip = Get-AnsibleParam $params -name "ip" -default '*'
$certificateHash = Get-AnsibleParam $params -name "certificate_hash" -type str -default ([string]::Empty)
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -type str -default ([string]::Empty)
$sslFlags = Get-AnsibleParam $params -name "ssl_flags" -default '0' -ValidateSet '0','1','2','3'
$result = @{
changed = $false
}
#################
### Functions ###
#################
function Create-BindingInfo {
$ht = @{
'bindingInformation' = $args[0].bindingInformation
'ip' = $args[0].bindingInformation.split(':')[0]
'port' = [int]$args[0].bindingInformation.split(':')[1]
'hostheader' = $args[0].bindingInformation.split(':')[2]
#'isDsMapperEnabled' = $args[0].isDsMapperEnabled
'protocol' = $args[0].protocol
'certificateStoreName' = $args[0].certificateStoreName
'certificateHash' = $args[0].certificateHash
}
#handle sslflag support
If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2')
{
$ht.sslFlags = 'not supported'
}
Else
{
$ht.sslFlags = [int]$args[0].sslFlags
}
Return $ht
}
# Used instead of get-webbinding to ensure we always return a single binding
# pass it $binding_parameters hashtable
function Get-SingleWebBinding {
$bind_search_splat = @{
'name' = $args[0].name
'protocol' = $args[0].protocol
'port' = $args[0].port
'ip' = $args[0].ip
'hostheader' = $args[0].hostheader
}
# if no bindings exist, get-webbinding fails with an error that can't be ignored via error actions on older systems
# let's ignore that specific error
If (-not $bind_search_splat['hostheader'])
{
Try {
Get-WebBinding @bind_search_splat | Where-Object {$_.BindingInformation.Split(':')[-1] -eq [string]::Empty}
}
Catch {
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
{
Throw $_.Exception.Message
}
}
}
Else
{
Try {
Get-WebBinding @bind_search_splat
}
Catch {
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
{
Throw $_.Exception.Message
}
}
}
}
Function Get-CertificateSubjects {
Param (
[string]$CertPath
)
If (-Not (Test-Path $CertPath) )
{
Fail-Json -obj $result -message "Unable to locate certificate at $CertPath"
}
$cert = get-item $CertPath
If ([version][System.Environment]::OSVersion.Version -ge [version]6.2)
{
$cert.DnsNameList.unicode
}
Else
{
$san = $cert.extensions | Where-Object {$_.Oid.FriendlyName -eq 'Subject Alternative Name'}
If ($san)
{
$san.Format(1) -split '\r\n' | Where-Object {$_} | ForEach-Object {
($_ -split '=')[-1]
}
}
Else
{
If ($cert.subject -like "*,*")
{
($cert.Subject | Select-String "CN=(.*?),?").matches.groups[-1].value
}
Else
{
$cert.subject -replace "CN=",''
}
}
}
}
#############################
### Pre-Action Validation ###
#############################
$os_version = [version][System.Environment]::OSVersion.Version
# Ensure WebAdministration module is loaded
If ($os_version -lt [version]'6.1')
{
Try {
Add-PSSnapin WebAdministration
}
Catch {
Fail-Json -obj $result -message "The WebAdministration snap-in is not present. Please make sure it is installed."
}
}
Else
{
Try {
Import-Module WebAdministration
}
Catch {
Fail-Json -obj $result -message "Failed to load WebAdministration module. Is IIS installed? $($_.Exception.Message)"
}
}
# ensure website targetted exists. -Name filter doesn't work on 2k8r2 so do where-object instead
$website_check = get-website | Where-Object {$_.name -eq $name}
If (-not $website_check)
{
Fail-Json -obj $result -message "Unable to retrieve website with name $Name. Make sure the website name is valid and exists."
}
# if OS older than 2012 (6.2) and ssl flags are set, fail. Otherwise toggle sni_support
If ($os_version -lt [version]'6.2')
{
If ($sslFlags -ne 0)
{
Fail-Json -obj $result -message "SNI and Certificate Store support is not available for systems older than 2012 (6.2)"
}
$sni_support = $false #will cause the sslflags check later to skip
}
Else
{
$sni_support = $true
}
# make sure ssl flags only specified with https protocol
If ($protocol -ne 'https' -and $sslFlags -gt 0)
{
Fail-Json -obj $result -message "SSLFlags can only be set for HTTPS protocol"
}
# validate certificate details if provided
# we don't do anything with cert on state: absent, so only validate present
If ($certificateHash -and $state -eq 'present')
{
If ($protocol -ne 'https')
{
Fail-Json -obj $result -message "You can only provide a certificate thumbprint when protocol is set to https"
}
#apply default for cert store name
If (-Not $certificateStoreName)
{
$certificateStoreName = 'my'
}
#validate cert path
$cert_path = "cert:\LocalMachine\$certificateStoreName\$certificateHash"
If (-Not (Test-Path $cert_path) )
{
Fail-Json -obj $result -message "Unable to locate certificate at $cert_path"
}
#check if cert is wildcard and update results with useful info.
$cert_subjects = Get-CertificateSubjects $cert_path
$result.certificate_subjects = $cert_subjects
If ($cert_subjects | Where-Object {$_ -match '^\*'})
{
$cert_is_wildcard = $true
$result.cert_is_wildcard = $cert_is_wildcard
}
Else
{
$cert_is_wildcard = $false
$result.cert_is_wildcard = $cert_is_wildcard
}
If ($os_version -lt [version]6.2 -and $host_header -and -not $cert_is_wildcard)
{
Fail-Json -obj $result -message "You cannot specify host headers with SSL unless it is a wildcard certificate."
}
Elseif ($os_version -ge [version]6.2 -and $host_header -and (-not $cert_is_wildcard -and $sslFlags -eq 0))
{
Fail-Json -obj $result -message "You cannot specify host headers with SSL unless it is a wildcard certificate or SNI is enabled."
}
}
# make sure binding info is valid for central cert store if sslflags -gt 1
If ($sslFlags -gt 1 -and ($certificateHash -ne [string]::Empty -or $certificateStoreName -ne [string]::Empty))
{
Fail-Json -obj $result -message "You set sslFlags to $sslFlags. This indicates you wish to use the Central Certificate Store feature.
This cannot be used in combination with certficiate_hash and certificate_store_name. When using the Central Certificate Store feature,
the certificate is automatically retrieved from the store rather than manually assigned to the binding."
}
# make sure host_header: '*' only present when state: absent
If ($host_header -match '^\*$' -and $state -ne 'absent')
{
Fail-Json -obj $result -message "host_header: '*' can only be used in combinaiton with state: absent"
}
##########################
### start action items ###
##########################
# create binding search splat
$binding_parameters = @{
Name = $name
};
Protocol = $protocol
Port = $port
IPAddress = $ip
}
If ($host_header) {
# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip)
If ($host_header)
{
$binding_parameters.HostHeader = $host_header
}
If ($protocol) {
$binding_parameters.Protocol = $protocol
}
If ($port) {
$binding_parameters.Port = $port
}
If ($ip) {
$binding_parameters.IPAddress = $ip
}
# Ensure WebAdministration module is loaded
if ((Get-Module "WebAdministration" -ErrorAction SilentlyContinue) -eq $null){
Import-Module WebAdministration
}
function Create-Binding-Info {
return @{
"bindingInformation" = $args[0].bindingInformation
"certificateHash" = $args[0].certificateHash
"certificateStoreName" = $args[0].certificateStoreName
"isDsMapperEnabled" = $args[0].isDsMapperEnabled
"protocol" = $args[0].protocol
"sslFlags" = $args[0].sslFlags
}
}
# Result
$result = @{
changed = $false
parameters = $binding_parameters
matched = @()
removed = @()
added = @()
};
# Get bindings matching parameters
$curent_bindings = Get-WebBinding @binding_parameters
$curent_bindings | Foreach {
$result.matched += Create-Binding-Info $_
Try {
$current_bindings = Get-SingleWebBinding $binding_parameters
}
Catch {
Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)"
}
try {
# Add
if (-not $curent_bindings -and $state -eq 'present') {
################################################
### Remove binding or exit if already absent ###
################################################
If ($current_bindings -and $state -eq 'absent')
{
Try {
# will remove multiple objects in the case of * host header
$current_bindings | Remove-WebBinding -WhatIf:$check_mode
$result.changed = $true
}
Catch {
Fail-Json -obj $result -message "Failed to remove the binding from IIS - $($_.Exception.Message)"
}
# removing bindings from iis may not also remove them from iis:\sslbindings
$result.operation_type = 'removed'
$result.binding_info = $current_bindings | ForEach-Object {Create-BindingInfo $_}
Exit-Json -obj $result
}
ElseIf (-Not $current_bindings -and $state -eq 'absent')
{
# exit changed: false since it's already gone
Exit-Json -obj $result
}
################################
### Modify existing bindings ###
################################
<#
since we have already.binding_info the parameters available to get-webbinding,
we just need to check here for the ones that are not available which are the
ssl settings (hash, store, sslflags). If they aren't set we update here, or
exit with changed: false
#>
ElseIf ($current_bindings)
{
#ran into a strange edge case in testing where I was able to retrieve bindings but not expand all the properties
#when adding a self-signed wildcard cert to a binding. it seemed to permanently break the binding. only removing it
#would cause the error to stop.
Try {
$null = $current_bindings | Select-Object *
}
Catch {
Fail-Json -obj $result -message "Found a matching binding, but failed to expand it's properties (get-binding | FL *). In testing, this was caused by using a self-signed wildcard certificate. $($_.Exception.Message)"
}
# check if there is a match on the ssl parameters
If ( ($current_bindings.sslFlags -ne $sslFlags -and $sni_support) -or
$current_bindings.certificateHash -ne $certificateHash -or
$current_bindings.certificateStoreName -ne $certificateStoreName)
{
# match/update SNI
If ($current_bindings.sslFlags -ne $sslFlags -and $sni_support)
{
Try {
Set-WebBinding -Name $name -IPAddress $ip -Port $port -HostHeader $host_header -PropertyName sslFlags -value $sslFlags -whatif:$check_mode
$result.changed = $true
}
Catch {
Fail-Json -obj $result -message "Failed to update sslFlags on binding - $($_.Exception.Message)"
}
# Refresh the binding object since it has been changed
Try {
$current_bindings = Get-SingleWebBinding $binding_parameters
}
Catch {
Fail-Json -obj $result -message "Failed to refresh bindings after setting sslFlags - $($_.Exception.Message)"
}
}
# match/update certificate
If ($current_bindings.certificateHash -ne $certificateHash -or $current_bindings.certificateStoreName -ne $certificateStoreName)
{
If (-Not $check_mode)
{
Try {
$current_bindings.AddSslCertificate($certificateHash,$certificateStoreName)
}
Catch {
Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)"
}
}
}
$result.changed = $true
$result.operation_type = 'updated'
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
Exit-Json -obj $result #exit changed true
}
Else
{
$result.operation_type = 'matched'
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
Exit-Json -obj $result #exit changed false
}
}
########################
### Add new bindings ###
########################
ElseIf (-not $current_bindings -and $state -eq 'present')
{
If ($certificateHash)
{
<#
Make sure a valid binding is specified. It's possible for another site to have a binding on the same IP:PORT. If
we bind to that same ip port without hostheader/sni it will cause a collision. Note, this check only matters for
https. Http will generate an error when new-webbinding is called if there is a conflict, unlike https.
I couldn't think of a good way to handle scenarios involving wildcards. There's just too many to think about and I
wouldn't want to potentially hard fail valid scenarios here that I did not consider...so those can still collide. We just skip
validation anytime an existing binding is a wildcard.
If a collision does occur, the website will be stopped. To help with this we'll return the website state into results.
#>
#use this instead of get-webbinding. on 2k8r2 get-webbinding fails with an error if a site with no bindings exists
$binding_matches = (Get-Website).bindings.collection | Where-Object {$_.BindingInformation -eq "$ip`:$port`:"}
#get dns names for all certs in matching bindings
$subjects = Foreach ($binding in $binding_matches)
{
$cert_path = "cert:\localmachine\$($binding.certificatestorename)\$($binding.certificatehash)"
Get-CertificateSubjects $cert_path
}
#skip validating scenarios where existing certs are wildcard
If (-not ($subjects | Where-Object {$_ -match "^\*"}))
{
If ($sslFlags -eq 0 -and $binding_matches -and $os_version -gt [version]6.2)
{
Fail-Json -obj $result -message "A conflicting binding has been found on the same ip $ip and port $port. To continue, you will either have to remove the offending binding or enable sni"
}
ElseIf ($binding_matches -and $os_version -lt [version]6.2)
{
Fail-Json -obj $result -message "A conflicting binding has been found on the same ip $ip and port $port. To continue you will need to remove the existing binding or assign a new IP or Port to this one"
}
}
}
# add binding. this creates the binding, but does not apply a certificate to it.
Try
{
If (-not $check_mode)
{
If ($sni_support)
{
New-WebBinding @binding_parameters -SslFlags $sslFlags -Force
}
Else
{
New-WebBinding @binding_parameters -Force
# Select certificate
if($certificateHash -ne $FALSE) {
$ip = $binding_parameters["IPAddress"]
if((!$ip) -or ($ip -eq "*")) {
$ip = "0.0.0.0"
}
$port = $binding_parameters["Port"]
if(!$port) {
$port = 443
}
$result.port = $port
$result.ip = $ip
Push-Location IIS:\SslBindings\
Get-Item Cert:\LocalMachine\$certificateStoreName\$certificateHash | New-Item "$($ip)!$($port)"
Pop-Location
}
$result.added += Create-Binding-Info (Get-WebBinding @binding_parameters)
$result.changed = $true
}
# Remove
if ($curent_bindings -and $state -eq 'absent') {
$curent_bindings | foreach {
Remove-WebBinding -InputObject $_
$result.removed += Create-Binding-Info $_
}
$result.changed = $true
}
}
catch {
Fail-Json $result $_.Exception.Message
Catch
{
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
Fail-Json -obj $result -message "Failed at creating new binding (note: creating binding and adding ssl are separate steps) - $($_.Exception.Message)"
}
# add certificate to binding
If ($certificateHash -and -not $check_mode)
{
Try {
$new_binding = get-webbinding -Name $name -IPAddress $ip -port $port -Protocol $protocol -hostheader $host_header
$new_binding.addsslcertificate($certificateHash,$certificateStoreName)
}
Catch {
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)"
}
}
$result.changed = $true
$result.operation_type = 'added'
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
Exit-Json $result
}

View file

@ -1,22 +1,9 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
# Copyright: (c) 2017, Henrik Wallström <henrik@wallstroms.nu>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {'metadata_version': '1.1',
@ -28,7 +15,7 @@ DOCUMENTATION = r'''
---
module: win_iis_webbinding
version_added: "2.0"
short_description: Configures a IIS Web site.
short_description: Configures a IIS Web site binding.
description:
- Creates, Removes and configures a binding to an existing IIS Web site
options:
@ -36,66 +23,51 @@ options:
description:
- Names of web site
required: true
default: null
aliases: []
aliases: [website]
state:
description:
- State of the binding
choices:
- present
- absent
required: false
default: null
aliases: []
default: present
port:
description:
- The port to bind to / use for the new site.
required: false
default: null
aliases: []
default: 80
ip:
description:
- The IP address to bind to / use for the new site.
required: false
default: null
aliases: []
default: '*'
host_header:
description:
- The host header to bind to / use for the new site.
required: false
default: null
aliases: []
- For state absent, you can use c('*') here to remove all bindings for a particular
protocol/ip/port combination.
protocol:
description:
- The protocol to be used for the Web binding (usually HTTP, HTTPS, or FTP).
required: false
default: null
aliases: []
default: http
certificate_hash:
description:
- Certificate hash for the SSL binding. The certificate hash is the unique identifier for the certificate.
required: false
default: null
aliases: []
- Certificate hash (thumbprint) for the SSL binding. The certificate hash is the unique identifier for the certificate.
certificate_store_name:
description:
- Name of the certificate store where the certificate for the binding is located.
required: false
default: "My"
aliases: []
author: Henrik Wallström
default: "my"
ssl_flags:
description:
- This parameter is only valid on Server 2012 and newer.
- Primarily used for enabling and disabling server name indication (SNI).
- Set to c(0) to disable SNI.
- Set to c(1) to enable SNI.
version_added: "2.5"
author:
- Noah Sparks (@nwsparks)
- Henrik Wallström
'''
EXAMPLES = r'''
- name: Return binding information for an existing host
win_iis_webbinding:
name: Default Web Site
- name: Return the HTTPS binding information for an existing host
win_iis_webbinding:
name: Default Web Site
protocol: https
- name: Add a HTTP binding on port 9090
win_iis_webbinding:
name: Default Web Site
@ -112,20 +84,76 @@ EXAMPLES = r'''
win_iis_webbinding:
name: Default Web Site
protocol: https
state: present
- name: Add a HTTPS binding and select certificate to use
win_iis_webbinding:
name: Default Web Site
protocol: https
port: 443
certificate_hash: B0D0FA8408FC67B230338FCA584D03792DA73F4C
state: present
- name: Website https biding to specific port
- name: Add a HTTPS binding with host header and SNI enabled
win_iis_webbinding:
name: Default Web Site
protocol: https
port: 443
host_header: test.com
ssl_flags: 1
certificate_hash: D1A3AF8988FD32D1A3AF8988FD323792DA73F4C
state: present
- name: Remove all https bindings on port 443
win_iis_webbinding:
name: Default Web Site
protocol: https
port: 443
host_header: '*'
state: absent
'''
RETURN = r'''
cert_is_wildcard:
description:
- Tells you if the certificate you are using is a wildcard
returned: when certificate_hash is defined
type: boolean
sample: false
version_added: "2.5"
certificate_subjects:
description:
- All of the subject names for the certificate you are using
returned: when certificate_hash is defined
type: list
sample: ["*.test.com","test.com"]
version_added: "2.5"
website_state:
description:
- The state of the website being targetted
- Can be helpful in case you accidentally cause a binding collision
which can result in the targetted site being stopped
returned: always
type: string
sample: "Started"
version_added: "2.5"
operation_type:
description:
- The type of operation performed
- Can be removed, updated, matched, or added
returned: on success
type: string
sample: "removed"
version_added: "2.5"
binding_info:
description:
- Information on the binding being manipulated
returned: on success
type: dictionary
sample: |-
"binding_info": {
"bindingInformation": "127.0.0.1:443:",
"certificateHash": "FF3910CE089397F1B5A77EB7BAFDD8F44CDE77DD",
"certificateStoreName": "MY",
"hostheader": "",
"ip": "127.0.0.1",
"port": 443,
"protocol": "https",
"sslFlags": "not supported"
}
version_added: "2.5"
'''

View file

@ -0,0 +1 @@
windows/ci/group2

View file

@ -0,0 +1,30 @@
test_iis_site_name: default web site
http_vars:
protocol: http
port: 80
ip: '*'
http_header_vars:
protocol: http
port: 80
ip: '*'
header: test.com
https_vars:
protocol: https
port: 443
ip: '*'
https_header_vars:
protocol: https
port: 443
ip: '*'
header: test.com
ssl_flags: 1
https_wc_vars:
protocol: https
port: 443
ip: '127.0.0.1'
header: wc.test.com

View file

@ -0,0 +1,122 @@
#!powershell
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#Requires -Module Ansible.ModuleUtils.Legacy
#
$params = Parse-Args -arguments $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website'
#$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent"
$host_header = Get-AnsibleParam $params -name "host_header" -type str
$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http'
$port = Get-AnsibleParam $params -name "port" -type int -default '80'
$ip = Get-AnsibleParam $params -name "ip" -default '*'
$certificateHash = Get-AnsibleParam $params -name "certificate_hash" -type str
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -type str
$sslFlags = Get-AnsibleParam $params -name "ssl_flags" -type int -default '0' -ValidateSet '0','1','2','3'
$result = @{
changed = $false
}
function Create-BindingInfo {
$ht = @{
'bindingInformation' = $args[0].bindingInformation
'ip' = $args[0].bindingInformation.split(':')[0]
'port' = [int]$args[0].bindingInformation.split(':')[1]
'hostheader' = $args[0].bindingInformation.split(':')[2]
'isDsMapperEnabled' = $args[0].isDsMapperEnabled
'protocol' = $args[0].protocol
'certificateStoreName' = $args[0].certificateStoreName
'certificateHash' = $args[0].certificateHash
}
#handle sslflag support
If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2')
{
$ht.sslFlags = 'not supported'
}
Else
{
$ht.sslFlags = [int]$args[0].sslFlags
}
Return $ht
}
# Used instead of get-webbinding to ensure we always return a single binding
# pass it $binding_parameters hashtable
function Get-SingleWebBinding {
$bind_search_splat = @{
'name' = $args[0].name
'protocol' = $args[0].protocol
'port' = $args[0].port
'ip' = $args[0].ip
'hostheader' = $args[0].hostheader
}
# if no bindings exist, get-webbinding fails with an error that can't be ignored via error actions on older systems
# let's ignore that specific error
If (-not $bind_search_splat['hostheader'])
{
Try {
Get-WebBinding @bind_search_splat | Where-Object {$_.BindingInformation.Split(':')[-1] -eq [string]::Empty}
}
Catch {
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
{
Throw $_.Exception.Message
}
}
}
Else
{
Try {
Get-WebBinding @bind_search_splat
}
Catch {
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
{
Throw $_.Exception.Message
}
}
}
}
# create binding search splat
$binding_parameters = @{
Name = $name
Protocol = $protocol
Port = $port
IPAddress = $ip
}
# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip)
If ($host_header)
{
$binding_parameters.HostHeader = $host_header
}
# Get bindings matching parameters
Try {
$current_bindings = Get-SingleWebBinding $binding_parameters
}
Catch {
Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)"
}
If ($current_bindings)
{
Try {
$binding_info = Create-BindingInfo $current_bindings
}
Catch {
Fail-Json -obj $result -message "Failed to create binding info - $($_.Exception.Message)"
}
$result.binding = $binding_info
}
exit-json -obj $result

View file

@ -0,0 +1,74 @@
- name: failure check bind with host header but no wc or sni
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: test.com
protocol: https
ip: '*'
port: 443
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
ssl_flags: 0
register: failure
failed_when:
- failure.msg != "You cannot specify host headers with SSL unless it is a wildcard certificate."
- failure.msg != "You cannot specify host headers with SSL unless it is a wildcard certificate or SNI is enabled."
- debug:
var: failure
verbosity: 1
- block:
- name: get all websites from server
raw: powershell.exe "(get-website).name"
register: existing_sites
- name: ensure all sites are removed for clean testing
win_iis_website:
name: "{{ item }}"
state: absent
with_items:
- "{{ existing_sites.stdout_lines }}"
- name: add sites
win_iis_website:
name: "{{ item.name }}"
state: started
ip: 127.0.0.1
port: "{{ item.port }}"
physical_path: c:\inetpub\wwwroot
with_items:
- {name: testconflict1, port: 8080}
- {name: testconflict2, port: 8081}
- name: add https binding to testconflict1
win_iis_webbinding:
name: testconflict1
state: present
protocol: https
port: 443
ip: 127.0.0.1
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
- name: add https binding to testconflict2 (expect failure)
win_iis_webbinding:
name: testconflict2
state: present
protocol: https
ip: 127.0.0.1
port: 443
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: failure
failed_when: '"A conflicting binding has been found on the same ip" not in failure.msg'
- debug:
var: failure
verbosity: 1
always:
- name: remove websites
win_iis_website:
name: "{{ item }}"
state: absent
with_items:
- testconflict1
- testconflict2

View file

@ -0,0 +1,372 @@
#cm add
#changed true, check nothing present
- name: CM add http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
check_mode: yes
- name: CM get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: get_http_no_header
changed_when: false
- name: CM add http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
check_mode: yes
- name: CM get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: get_http_header
changed_when: false
- name: CM assert changed, but not added
assert:
that:
- http_no_header is changed
- http_no_header.binding_info is none
- get_http_no_header.binding is not defined
- http_header is changed
- http_header.binding_info is none
- get_http_header.binding is not defined
#add
#changed true, new bindings present
- name: add http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: get_http_no_header
changed_when: false
- name: add http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: get_http_header
changed_when: false
- name: assert changed and added
assert:
that:
- http_no_header is changed
- http_no_header.binding_info is defined
- http_no_header.operation_type == 'added'
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
- http_no_header.binding_info.port == {{ http_vars.port }}
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
- http_header is changed
- http_header.binding_info is defined
- http_header.operation_type == 'added'
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
- http_header.binding_info.port == {{ http_header_vars.port }}
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
#add idem
#changed false
- name: idem add http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
- name: idem add http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
- name: idem assert not changed
assert:
that:
- http_no_header is not changed
- http_header is not changed
#modify
#can't test modify for http, it will add a new binding instead since
#there's no way to match existing bindings against the new parameters
#cm remove
#changed true, bindings still present
- name: cm remove http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
check_mode: yes
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: get_http_no_header
changed_when: false
- name: cm remove http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
check_mode: yes
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: get_http_header
changed_when: false
- name: cm remove assert changed, but still present
assert:
that:
- http_no_header is changed
- http_no_header.binding_info is defined
- http_no_header.operation_type == 'removed'
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
- http_no_header.binding_info.port == {{ http_vars.port }}
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
- get_http_no_header.binding is defined
- get_http_no_header.binding.ip == "{{ http_vars.ip }}"
- get_http_no_header.binding.port == {{ http_vars.port }}
- get_http_no_header.binding.protocol == "{{ http_vars.protocol }}"
- http_header is changed
- http_header.binding_info is defined
- http_header.operation_type == 'removed'
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
- http_header.binding_info.port == {{ http_header_vars.port }}
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
- get_http_header.binding is defined
- get_http_header.binding.ip == "{{ http_header_vars.ip }}"
- get_http_header.binding.port == {{ http_header_vars.port }}
- get_http_header.binding.protocol == "{{ http_header_vars.protocol }}"
- get_http_header.binding.hostheader == "{{ http_header_vars.header }}"
#remove
#changed true, bindings gone
- name: remove http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: get_http_no_header
changed_when: false
- name: remove http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: get_http_header
changed_when: false
- name: remove assert changed and gone
assert:
that:
- http_no_header is changed
- http_no_header.operation_type == 'removed'
- http_no_header.binding_info is defined
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
- http_no_header.binding_info.port == {{ http_vars.port }}
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
- get_http_no_header.binding is not defined
- http_header is changed
- http_header.binding_info is defined
- http_header.operation_type == 'removed'
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
- http_header.binding_info.port == {{ http_header_vars.port }}
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
- get_http_header.binding is not defined
#remove idem
#change false, bindings gone
- name: idem remove http binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: http_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ http_vars.protocol }}"
ip: "{{ http_vars.ip }}"
port: "{{ http_vars.port }}"
register: get_http_no_header
changed_when: false
- name: idem remove http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: http_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ http_header_vars.header }}"
protocol: "{{ http_header_vars.protocol }}"
ip: "{{ http_header_vars.ip }}"
port: "{{ http_header_vars.port }}"
register: get_http_header
changed_when: false
- name: idem remove assert changed and gone
assert:
that:
- http_no_header is not changed
- http_no_header.binding_info is not defined
- get_http_no_header.binding is not defined
- http_header is not changed
- http_header.binding_info is not defined
- get_http_header.binding is not defined
#bulk remove cm
#add multiple bindings - verify they're present
- name: bulk add http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ item }}"
protocol: http
ip: '*'
port: 80
register: http_header
with_items:
- test1.com
- test2.com
- test3.com
- name: assert that 3 bindings were added
assert:
that:
- http_header is changed
- http_header | json_query('results[*].binding_info') | length == 3
#cm remove with host_header: '*' - verify changed true and that bulk remove tries to get them all
#remove with host_header: '*'
- name: bulk remove http binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: '*'
protocol: http
ip: '*'
port: 80
register: http_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ item }}"
protocol: http
ip: '*'
port: 80
register: get_http_header
changed_when: false
with_items:
- test1.com
- test2.com
- test3.com
- name: bulk remove assert that bindings are gone
assert:
that:
- http_header is changed
- http_header.binding_info | length == 3

View file

@ -0,0 +1,459 @@
##############
### CM Add ###
##############
#changed true, check nothing present
- name: CM add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
check_mode: yes
- name: CM get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: CM add https binding with header and SNI
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
ssl_flags: 1
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_header
check_mode: yes
- name: CM get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: CM assert changed, but not added
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'added'
- https_no_header.binding_info is none
- get_https_no_header.binding is not defined
- https_header is changed
- https_header.operation_type == 'added'
- https_header.binding_info is none
- get_https_header.binding is not defined
###########
### Add ###
###########
#changed true, new bindings present
- name: add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: add https binding with header SNI
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
ssl_flags: 1
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: assert changed and added
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'added'
- https_no_header.binding_info is defined
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.hostheader == ''
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- https_header is changed
- https_header.operation_type == 'added'
- https_header.binding_info is defined
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
- https_header.binding_info.port == {{ https_header_vars.port }}
- https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- https_header.binding_info.sslFlags == 1
################
### Idem Add ###
################
#changed false
- name: idem add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: https
ip: '*'
port: 443
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
- name: idem add https binding with header and SNI
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: test.com
protocol: https
ip: '*'
port: 443
ssl_flags: 1
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_header
- name: idem assert not changed
assert:
that:
- https_no_header is not changed
- https_header is not changed
#################
### CM Modify ###
#################
# changed true, verify no changes occurred
#modify sni
- name: CM modify https binding with header, change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
ssl_flags: 1
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_header
check_mode: yes
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: CM assert changed but old cert
assert:
that:
- https_header is changed
- https_header.operation_type == 'updated'
- https_header.binding_info is defined
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
- https_header.binding_info.port == {{ https_header_vars.port }}
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
- https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- https_header.binding_info.sslFlags == 1
- get_https_header.binding is defined
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
- get_https_header.binding.port == {{ https_header_vars.port }}
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
- get_https_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- get_https_header.binding.sslFlags == 1
##############
### Modify ###
##############
# modify ssl flags
- name: modify https binding with header, change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
ssl_flags: 1
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: modify assert changed and new cert
assert:
that:
- https_header is changed
- https_header.operation_type == 'updated'
- https_header.binding_info is defined
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
- https_header.binding_info.port == {{ https_header_vars.port }}
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
- https_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
- https_header.binding_info.sslFlags == 1
- get_https_header.binding is defined
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
- get_https_header.binding.port == {{ https_header_vars.port }}
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
- get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
- get_https_header.binding.sslFlags == 1
###################
### Idem Modify ###
###################
#changed false
#idem modify ssl flags
- name: idem modify https binding with header, enable SNI and change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
ssl_flags: 1
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_header
- name: idem assert not changed
assert:
that:
- https_header is not changed
#################
### CM Remove ###
#################
#changed true, bindings still present
- name: cm remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
check_mode: yes
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: cm remove https binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: https_header
check_mode: yes
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: cm remove assert changed, but still present
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'removed'
- https_no_header.binding_info is defined
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding is defined
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
- get_https_no_header.binding.port == {{ https_vars.port }}
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- https_header is changed
- https_header.binding_info is defined
- https_header.operation_type == 'removed'
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
- https_header.binding_info.port == {{ https_header_vars.port }}
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
- get_https_header.binding is defined
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
- get_https_header.binding.port == {{ https_header_vars.port }}
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
- get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
##############
### remove ###
##############
#changed true, bindings gone
- name: remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: remove https binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: https_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: remove assert changed and gone
assert:
that:
- https_no_header is changed
- https_no_header.binding_info is defined
- https_no_header.operation_type == 'removed'
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding is not defined
- https_header is changed
- https_header.binding_info is defined
- https_header.operation_type == 'removed'
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
- https_header.binding_info.port == {{ https_header_vars.port }}
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
- get_https_header.binding is not defined
###################
### remove idem ###
###################
#change false, bindings gone
- name: idem remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: idem remove https binding with header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: https_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
host_header: "{{ https_header_vars.header }}"
protocol: "{{ https_header_vars.protocol }}"
ip: "{{ https_header_vars.ip }}"
port: "{{ https_header_vars.port }}"
register: get_https_header
changed_when: false
- name: idem remove assert changed and gone
assert:
that:
- https_no_header is not changed
- https_no_header.binding_info is not defined
- get_https_no_header.binding is not defined
- https_header is not changed
- https_header.binding_info is not defined
- get_https_header.binding is not defined

View file

@ -0,0 +1,423 @@
##############
### CM Add ###
##############
#changed true, check nothing present
- name: CM add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
check_mode: yes
- name: CM get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: CM assert changed, but not added
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'added'
- https_no_header.binding_info is none
- get_https_no_header.binding is not defined
###########
### Add ###
###########
#changed true, new bindings present
- name: add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
- name: assert changed and added
assert:
that:
- https_no_header is changed
- https_no_header.binding_info is defined
- https_no_header.operation_type == 'added'
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- https_no_header.binding_info.hostheader == ''
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
################
### Idem Add ###
################
#changed false
- name: idem add https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
register: https_no_header
- name: idem assert not changed
assert:
that:
- https_no_header is not changed
#################
### CM Modify ###
#################
# changed true, verify no changes occurred
#modify sni
- name: CM modify https binding change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_no_header
check_mode: yes
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: CM assert changed but old cert
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'updated'
- https_no_header.binding_info is defined
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
- get_https_no_header.binding is defined
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
- get_https_no_header.binding.port == {{ https_vars.port }}
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
##############
### Modify ###
##############
# modify ssl flags
- name: modify https binding, change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_no_header
- name: get binding info header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: modify assert changed and new cert
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'updated'
- https_no_header.binding_info is defined
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
- get_https_no_header.binding is defined
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
- get_https_no_header.binding.port == {{ https_vars.port }}
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding.hostheader == ''
- get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
###################
### Idem Modify ###
###################
#changed false
#idem modify ssl flags
- name: idem modify https binding and change cert
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: present
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
register: https_header
- name: idem assert not changed
assert:
that:
- https_header is not changed
#################
### CM Remove ###
#################
#changed true, bindings still present
- name: cm remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
check_mode: yes
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: cm remove assert changed, but still present
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'removed'
- https_no_header.binding_info is defined
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
- get_https_no_header.binding is defined
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
- get_https_no_header.binding.port == {{ https_vars.port }}
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
##############
### remove ###
##############
#changed true, bindings gone
- name: remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: remove assert changed and gone
assert:
that:
- https_no_header is changed
- https_no_header.operation_type == 'removed'
- https_no_header.binding_info is defined
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
- https_no_header.binding_info.port == {{ https_vars.port }}
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
- get_https_no_header.binding is not defined
###################
### remove idem ###
###################
#change false, bindings gone
- name: idem remove https binding no header
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: https_no_header
- name: get binding info no header
test_get_webbindings:
name: "{{ test_iis_site_name }}"
protocol: "{{ https_vars.protocol }}"
ip: "{{ https_vars.ip }}"
port: "{{ https_vars.port }}"
register: get_https_no_header
changed_when: false
- name: idem remove assert changed and gone
assert:
that:
- https_no_header is not changed
- https_no_header.binding_info is not defined
- get_https_no_header.binding is not defined
##################
### WC Testing ###
##################
# Unfortunately this does not work due to some strange errors
# that are caused when using a self signed wildcard cert.
# I'm leaving this here in case someone finds a solution in the
# future.
# - name: add https binding wildcard with header
# win_iis_webbinding:
# name: "{{ test_iis_site_name }}"
# state: present
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}"
# register: https_header
# - name: assert changed and added
# assert:
# that:
# - https_header is changed
# - https_header.added is defined
# - https_header.added.ip == "{{ https_wc_vars.ip }}"
# - https_header.added.port == {{ https_wc_vars.port }}
# - https_header.added.protocol == "{{ https_wc_vars.protocol }}"
# - https_header.added.hostheader == "{{ https_wc_vars.header }}"
# - https_header.added.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
# - name: idem add https binding wildcard with header
# win_iis_webbinding:
# name: "{{ test_iis_site_name }}"
# state: present
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}"
# register: https_header
# - name: cm remove wildcard https binding
# win_iis_webbinding:
# name: "{{ test_iis_site_name }}"
# state: absent
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: https_header
# check_mode: yes
# - name: get binding info header
# test_get_webbindings:
# name: "{{ test_iis_site_name }}"
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: get_https_header
# changed_when: false
# - name: cm remove assert changed, but still present
# assert:
# that:
# - https_header is changed
# - https_header.removed is defined
# - https_header.removed.ip == "{{ https_wc_vars.ip }}"
# - https_header.removed.port == {{ https_wc_vars.port }}
# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
# - https_header.removed.hostheader == "{{ https_wc_vars.header }}"
# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
# - get_https_header.binding is defined
# - get_https_header.removed.ip == "{{ https_wc_vars.ip }}"
# - get_https_header.removed.port == {{ https_wc_vars.port }}
# - get_https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
# - get_https_header.removed.hostheader == "{{ https_wc_vars.header }}"
# - get_https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
# - name: remove wildcard https binding
# win_iis_webbinding:
# name: "{{ test_iis_site_name }}"
# state: absent
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: https_header
# - name: get binding info header
# test_get_webbindings:
# name: "{{ test_iis_site_name }}"
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: get_https_header
# changed_when: false
# - name: remove assert changed and gone
# assert:
# that:
# - https_header is changed
# - https_header.removed is defined
# - https_header.removed.ip == "{{ https_wc_vars.ip }}"
# - https_header.removed.port == {{ https_wc_vars.port }}
# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
# - https_header.removed.hostheader == "{{ https_wc_vars.header }}"
# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
# - get_https_header.binding is not defined
# - name: idem remove wildcard https binding
# win_iis_webbinding:
# name: "{{ test_iis_site_name }}"
# state: absent
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: https_header
# - name: get binding info header
# test_get_webbindings:
# name: "{{ test_iis_site_name }}"
# host_header: "{{ https_wc_vars.header }}"
# protocol: "{{ https_wc_vars.protocol }}"
# ip: "{{ https_wc_vars.ip }}"
# port: "{{ https_wc_vars.port }}"
# register: get_https_header
# changed_when: false
# - name: idem remove assert changed and gone
# assert:
# that:
# - https_header is not changed
# - https_header.removed is not defined
# - get_https_header.binding is not defined

View file

@ -0,0 +1,62 @@
---
# Cannot use win_feature to install IIS on Server 2008.
# Run a brief check and skip hosts that don't support
# that operation
#seems "raw" is the only module that works on 2008 non-r2. win_command and win_shell both failed
- name: register os version (seems integration tests don't gather this fact)
raw: powershell.exe "gwmi Win32_OperatingSystem | select -expand version"
register: os_version
changed_when: False
- block:
- include_tasks: setup.yml
- include_tasks: http.yml
- include_tasks: https-lt6.2.yml
when: os_version.stdout_lines[0] | version_compare('6.2','lt')
- include_tasks: https-ge6.2.yml
when: os_version.stdout_lines[0] | version_compare('6.2','ge')
- include_tasks: failures.yml
always:
- name: get all websites from server
raw: powershell.exe "(get-website).name"
register: existing_sites
- name: ensure all sites are removed for clean testing
win_iis_website:
name: "{{ item }}"
state: absent
with_items:
- "{{ existing_sites.stdout_lines }}"
- name: cleanup certreq files
win_file:
path: "{{ item }}"
state: absent
with_items:
- c:\windows\temp\certreq1.txt
- c:\windows\temp\certreq2.txt
- c:\windows\temp\certreqwc.txt
- c:\windows\temp\certreqresp1.txt
- c:\windows\temp\certreqresp2.txt
- c:\windows\temp\certreqrespwc.txt
- name: remove certs
raw: 'remove-item cert:\localmachine\my\{{ item }} -force -ea silentlycontinue'
with_items:
- "{{ thumbprint1.stdout_lines[0] }}"
- "{{ thumbprint2.stdout_lines[0] }}"
- "{{ thumbprint_wc.stdout_lines[0] }}"
- name: remove IIS features after test
win_feature:
name: Web-Server
state: absent
includ_sub_features: True
include_management_tools: True
register: feature_uninstall
- name: reboot after feature install
win_reboot:
when: feature_uninstall.reboot_required
when: os_version.stdout_lines[0] | version_compare('6.1','gt')

View file

@ -0,0 +1,88 @@
- name: reboot before feature install to ensure server is in clean state
win_reboot:
- name: ensure IIS features are installed
win_feature:
name: Web-Server
state: present
includ_sub_features: True
include_management_tools: True
register: feature_install
- name: reboot after feature install
win_reboot:
when: feature_install.reboot_required
- name: get all websites from server
raw: powershell.exe "(get-website).name"
register: existing_sites
- name: ensure all sites are removed for clean testing
win_iis_website:
name: "{{ item }}"
state: absent
with_items:
- "{{ existing_sites.stdout_lines }}"
- name: add testing site {{ test_iis_site_name }}
win_iis_website:
name: "{{ test_iis_site_name }}"
physical_path: c:\inetpub\wwwroot
- name: ensure all bindings are removed prior to starting testing
win_iis_webbinding:
name: "{{ test_iis_site_name }}"
state: absent
protocol: "{{ item.protocol }}"
port: "{{ item.port }}"
host_header: '*'
with_items:
- {protocol: http, port: 80}
- {protocol: https, port: 443}
- name: copy certreq file
win_copy:
content: |-
[NewRequest]
Subject = "CN={{ item.name }}"
KeyLength = 2048
KeyAlgorithm = RSA
MachineKeySet = true
RequestType = Cert
dest: "{{ item.dest }}"
with_items:
- {name: test.com, dest: 'c:\windows\temp\certreq1.txt'}
- {name: test1.com, dest: 'c:\windows\temp\certreq2.txt'}
- {name: '*.test.com', dest: 'c:\windows\temp\certreqwc.txt'}
- name: make sure response files are absent
win_file:
path: "{{ item }}"
state: absent
with_items:
- 'c:\windows\temp\certreqresp1.txt'
- 'c:\windows\temp\certreqresp2.txt'
- 'c:\windows\temp\certreqrespwc.txt'
- name: create self signed cert from certreq
win_command: certreq -new -machine {{ item.req }} {{ item.resp }}
with_items:
- {req: 'c:\windows\temp\certreq1.txt', resp: 'c:\windows\temp\certreqresp1.txt'}
- {req: 'c:\windows\temp\certreq2.txt', resp: 'c:\windows\temp\certreqresp2.txt'}
- {req: 'c:\windows\temp\certreqwc.txt', resp: 'c:\windows\temp\certreqrespwc.txt'}
- name: register certificate thumbprint1
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test.com"})[0].Thumbprint'
register: thumbprint1
- name: register certificate thumbprint2
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test1.com"})[0].Thumbprint'
register: thumbprint2
- name: register certificate thumbprint_wc
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=*.test.com"})[0].Thumbprint'
register: thumbprint_wc
- debug: var=thumbprint1.stdout
- debug: var=thumbprint2.stdout
- debug: var=thumbprint_wc.stdout