Skip to content

Non-HTTP/HTTPS site bindings are not able to be changed, but are attempted to be removed - #68

Open
KBerstene wants to merge 7 commits into
ansible-collections:mainfrom
KBerstene:too-many-bindings
Open

Non-HTTP/HTTPS site bindings are not able to be changed, but are attempted to be removed#68
KBerstene wants to merge 7 commits into
ansible-collections:mainfrom
KBerstene:too-many-bindings

Conversation

@KBerstene

@KBerstene KBerstene commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
SUMMARY

Non-HTTP/HTTPS site bindings, such as net.tcp, are not able to be changed using the website module, but the module attempts to remove them, since they cannot be listed in the list of bindings to set.

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

plugins/modules/website.ps1

ADDITIONAL INFORMATION

I have an IIS server running Exchange. It uses several types of protocols: http, https, net.tcp, net.pipe, and others. When trying to configure bindings, the only options available are http and https. Currently the way that existing site bindings are populated is using a method that will list all bindings, regardless of protocol. Example here:

> (Get-ItemProperty -LiteralPath "IIS:\Sites\$($site.Name)").Bindings.Collection
protocol        bindingInformation sslFlags
--------        ------------------ --------
http            *:80:                     0
net.tcp         808:*                     0
net.msmq        localhost                 0
msmq.formatname localhost                 0
net.pipe        *                         0
http            127.0.0.1:80:             0
https           *:443:                    0
https           127.0.0.1:443:            0

Since net.tcp and the other unsupported protocols cannot be added to the bindings list in a task, they will get added to the $toRemove list and

Here is an example task:

- name: "Re-create HTTPS bindings"
  microsoft.iis.website:
    name: "Default Web Site"
    bindings:
      set:
        -   certificate_hash: ''
            certificate_store_name: ''
            hostname: myhost.example.com
            ip: '*'
            port: 80
            protocol: http
            use_ccs: false
            use_sni: false
        -   certificate_hash: 0C03CBC3D77D62E4694A6349409C219E9D8DA5E5
            certificate_store_name: My
            hostname: myhost.example.com
            ip: '*'
            port: 443
            protocol: https
            use_ccs: false
            use_sni: false
    state: restarted

Additionally, since the way the bindings filtered into $toRemove are removed does not include a protocol and only works off of the bindingInformation, this can remove the HTTP and HTTPS bindings that were just modified.

This can be fixed by modifying the way that existing site bindings are populated so that it filters the bindings by only the supported protocols. Alternatively, it could be changed to use the Get-WebBinding cmdlet instead, but that will only pull up three protocols: HTTP, HTTPS, and FTP. There may be another way to edit the net.tcp and other protocols if needed, but they're not available using that method.

This does mean that the bindings list will not perfectly reflect the list of bindings passed into set:, but since the module does not support other protocols at this time (e.g. FTP is feature requested in #42), the options are either to remove configurations we can't modify or ignore them—this is the "ignore them until they're supported" option.

Edit: It turns out that there's an issue that the tests have hung up on that means that the IndexOf at line 255 appears to be invalid? I can't figure out why, so I've converted to using Get-WebBinding and Set-WebBinding because it can edit the correct binding without having to use an indexing function like Set-ItemProperty requires.

@centosinfra-prod-github-app

Copy link
Copy Markdown

@KBerstene
KBerstene force-pushed the too-many-bindings branch from 8e99c91 to fb5824c Compare July 23, 2026 17:54
@centosinfra-prod-github-app

Copy link
Copy Markdown

@centosinfra-prod-github-app

Copy link
Copy Markdown

@KBerstene

Copy link
Copy Markdown
Contributor Author

My apologies for the multiple pushes; I'm trying to figure out why the Windows Server tests are failing. Piping an object into Where-Object shouldn't be changing its object type; I'm not even sure if this is an issue with the single line I'm trying to change.

@centosinfra-prod-github-app

Copy link
Copy Markdown

@KBerstene

Copy link
Copy Markdown
Contributor Author

My apologies, I cannot figure out why the tests are failing. It is as though the $site_bindings.IndexOf($site_edit) line is attempting to run on the (Get-ItemProperty -LiteralPath "IIS:\Sites\$($site.Name)").Bindings object instead of the (Get-ItemProperty -LiteralPath "IIS:\Sites\$($site.Name)").Bindings.Collection object. I'll have to revert to trying the Get-WebBinding cmdlet and if that doesn't work, I am lost for a solution as the code is working correctly on Server 2019 and 2022 in my environment and I can't reproduce the error the test is throwing.

@centosinfra-prod-github-app

Copy link
Copy Markdown

…)"` into `Set-WebBinding -Name $site.Name` in order to eliminate IndexOf and pass tests
@centosinfra-prod-github-app

Copy link
Copy Markdown

@KBerstene

KBerstene commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Okay, I've converted to using Get-/Set-WebBinding and it's passing the tests in the location it was failing before. I am pretty sure that where it is failing now is when the module is trying to assert that it's been able to change the binding's protocol—I'm pretty sure changing the protocol isn't allowed and cannot get it to work directly in PowerShell on my machine. I don't know if these tests were implemented after that code was originally written and it has just been hiding until now. I believe the only way to resolve this is to remove the if ($site_edit.protocol -ne $user_edit.protocol) section, unless someone else can confirm that the protocol can be changed using another method (I also tested with the original Set-ItemProperty method and it did not work on my local machine, just silently failed to do anything instead of throwing an error).

@jborean93

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jborean93

Copy link
Copy Markdown
Collaborator

So the test that is failing is this one

- name: change website binding protocol and sslFlags
microsoft.iis.website:
name: "{{ test_website_name }}"
bindings:
add:
- ip: '127.0.1.1'
port: 8091
hostname: 'microsoft.iis.website.com'
- ip: '127.0.2.1'
port: 8092
hostname: 'microsoft.iis.website.net'
protocol: https
use_sni: true
use_ccs: false
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
certificate_store_name: "MY"
- name: change website binding protocol and sslFlags info
microsoft.iis.website_info:
name: "{{ test_website_name }}"
register: website_info
- assert:
that:
- website is not changed
- website_info.site[0].bindings[1].ip == "127.0.1.1"
- website_info.site[0].bindings[1].port == 8091
- website_info.site[0].bindings[1].hostname == "microsoft.iis.website.com"
- website_info.site[0].bindings[2].ip == "127.0.2.1"
- website_info.site[0].bindings[2].port == 8092
- website_info.site[0].bindings[2].hostname == "microsoft.iis.website.net"
- website_info.site[0].bindings[2].protocol == "https"
- website_info.site[0].bindings[2].use_sni == true
- website_info.site[0].bindings[2].use_ccs == false
- website_info.site[0].bindings[2].certificate_hash == thumbprint1.stdout_lines[0]
- website_info.site[0].bindings[2].certificate_store_name == "MY"

Specifically it is this check (and subsequent assertions for this binding) that is failing website_info.site[0].bindings[2].protocol == "https". When we look at the raw info returned it is

{
  "changed": false,
  "exists": true,
  "site": [
    {
      "application_pool": "TestWebSitePool",
      "bindings": [
        {
          "certificate_hash": "",
          "certificate_store_name": "",
          "hostname": "acme.com",
          "ip": "127.0.0.1",
          "port": 8080,
          "protocol": "http",
          "use_ccs": false,
          "use_sni": false
        },
        {
          "certificate_hash": "",
          "certificate_store_name": "",
          "hostname": "microsoft.iis.website.com",
          "ip": "127.0.1.1",
          "port": 8091,
          "protocol": "http",
          "use_ccs": false,
          "use_sni": false
        },
        {
          "certificate_hash": "",
          "certificate_store_name": "",
          "hostname": "microsoft.iis.website.net",
          "ip": "127.0.2.1",
          "port": 8092,
          "protocol": "http",
          "use_ccs": false,
          "use_sni": true
        }
      ],
      "name": "TestWebSite",
      "physical_path": "C:\\wwwroot\\websites\\my-test-website-alt",
      "site_id": 99,
      "state": "Started"
    }
  ]
}

We can see that bindings[2] (the 3rd entry because this is indexed by 0) is not https and does not have the certificate hash/store information set.

This would indicate that the changes made in this PR has broken the logic for adding/modifying a HTTPS binding. It seems like in this case it's actually modifying an existing binding by changing 127.0.2.1:8092 from a HTTP to HTTPS binding based on the previous tests assertions. I can somewhat understand that putting it under add may be confusing that it modifies an existing binding but we do document that the unique identifier for a binding is the ip:port:hostname so it's just ensuring that the binding matches the desired configuration based on the provided id. The module will need to continue operating that way to ensure that we don't break anybody relying on that behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants