Skip to content

Commit

Permalink
Migrate win_iis_webapplication module to new microsoft.iis repository (
Browse files Browse the repository at this point in the history
…#9)

* Migrate win_iis_webapplication module to new microsoft.iis repository

* Initial commit

* Fix up docs after migration (#95)

* Fix up docs after migration

* Fix up sanity errors

* fix up sanity ignores (#97)

* fix up sanity ignores

* Bump ansible-windows dep

* Fix bad change for win_region

* Fix devel sanity checks - ci_complete (#331)

* docs(win_iis_webapppool.ps1): update to include example on how to set No Managed Code for .Net compatibility (#556)

* Upgrade ansible-lint and fix problems (#565)

* Expand connection plugins used in CI (#577)

Expands the testing matrix of the Windows connection plugins used in CI
to cover all the supported connections of Windows.

* fixing portion where building app pools with the word value fails. (#587)

* fixing portion where building app pools with the word value fails.

* Create 588-win_iis_webapppool.yaml

* Migrate win_iis_webapplication module to new microsoft.iis repository

---------

Co-authored-by: Jordan Borean <[email protected]>
Co-authored-by: Irum Malik <[email protected]>
Co-authored-by: AnsibleJosh <[email protected]>
  • Loading branch information
4 people authored Jan 22, 2025
1 parent 56f5a0b commit c67e9a9
Show file tree
Hide file tree
Showing 14 changed files with 844 additions and 0 deletions.
138 changes: 138 additions & 0 deletions plugins/modules/web_application.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!powershell

# Copyright: (c) 2015, Henrik Wallström <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

#AnsibleRequires -CSharpUtil Ansible.Basic

$spec = @{
options = @{
name = @{ type = "str"; required = $true }
site = @{ type = "str"; required = $true }
state = @{ type = "str"; default = "present"; choices = "absent", "present" }
physical_path = @{ type = "str"; aliases = @("path") }
application_pool = @{ type = "str" }
connect_as = @{ type = "str"; choices = "specific_user", "pass_through" }
username = @{ type = "str" }
password = @{ type = "str"; no_log = $true }
}
supports_check_mode = $true
}

$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
$name = $module.Params.name
$site = $module.Params.site
$state = $module.Params.state
$physical_path = $module.Params.physical_path
$application_pool = $module.Params.application_pool
$connect_as = $module.Params.connect_as
$username = $module.Params.username
$password = $module.Params.password
$check_mode = $module.CheckMode

if ($connect_as -eq 'specific_user') {
if (-not $username) {
$module.FailJson("missing required arguments: username")
}
if (-not $password) {
$module.FailJson("missing required arguments: password")
}
}

# Ensure WebAdministration module is loaded
if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) {
Import-Module WebAdministration
}

# Application info
$application = Get-WebApplication -Site $site -Name $name
$website = Get-Website -Name $site

# Set ApplicationPool to current if not specified
if (!$application_pool) {
$application_pool = $website.applicationPool
}

try {
# Add application
if (($state -eq 'present') -and (-not $application)) {
if (-not $physical_path) {
$module.FailJson("missing required arguments: physical_path")
}
if (-not (Test-Path -LiteralPath $physical_path)) {
$module.FailJson("specified folder must already exist: '$physical_path'")
}

$application_parameters = @{
Name = $name
PhysicalPath = $physical_path
Site = $site
ApplicationPool = $application_pool
}

if (-not $check_mode) {
$application = New-WebApplication @application_parameters -Force
}
$module.Result.changed = $true
}

# Remove application
if ($state -eq 'absent' -and $application) {
$application = Remove-WebApplication -Site $site -Name $name -WhatIf:$check_mode
$module.Result.changed = $true
}

$application = Get-WebApplication -Site $site -Name $name
if ($application) {

# Change Physical Path if needed
if ($physical_path) {
if (-not (Test-Path -LiteralPath $physical_path)) {
$module.FailJson("specified folder must already exist: '$physical_path'")
}

$folder = Get-Item -LiteralPath $physical_path
if ($folder.FullName -ne $application.PhysicalPath) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -name physicalPath -value $physical_path -WhatIf:$check_mode
$module.Result.changed = $true
}
}

# Change Application Pool if needed
if ($application_pool) {
if ($application_pool -ne $application.applicationPool) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -name applicationPool -value $application_pool -WhatIf:$check_mode
$module.Result.changed = $true
}
}

# Change username and password if needed
$app_user = Get-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName'
$app_pass = Get-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password'
if ($connect_as -eq 'pass_through') {
if ($app_user -ne '') {
Clear-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName' -WhatIf:$check_mode
$module.Result.changed = $true
}
if ($app_pass -ne '') {
Clear-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password' -WhatIf:$check_mode
$module.Result.changed = $true
}
}
elseif ($connect_as -eq 'specific_user') {
if ($app_user -ne $username) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName' -Value $username -WhatIf:$check_mode
$module.Result.changed = $true
}
if ($app_pass -ne $password) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password' -Value $password -WhatIf:$check_mode
$module.Result.changed = $true
}
}
}
}
catch {
$module.FailJson($_.Exception.Message, $_)
}

$module.ExitJson()
94 changes: 94 additions & 0 deletions plugins/modules/web_application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
# Copyright: (c) 2024, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

DOCUMENTATION:
module: web_application
short_description: Configures IIS web applications
description: >
Creates, removes, and configures IIS web applications.
requirements:
- C(IISAdministration) PowerShell module
options:
name:
description:
- Name of the web application.
type: str
required: true
site:
description:
- Name of the site on which the application is created.
type: str
required: true
state:
description:
- State of the web application.
- If C(absent), the web application will be removed.
- If C(present), the web application will be created if not already present.
type: str
choices:
- absent
- present
default: present
physical_path:
description:
- The physical path on the remote host to use for the new application.
- The specified folder must already exist.
type: str
aliases:
- path
application_pool:
description:
- The application pool in which the new site executes.
- If not specified, the application pool of the current website will be used.
type: str
connect_as:
description:
- The type of authentication to use for this application. Either C(pass_through) or C(specific_user).
- If C(pass_through), IIS will use the identity of the user or application pool identity to access the file system or network.
- If C(specific_user), IIS will use the credentials provided in I(username) and I(password) to access the file system or network.
- If not specified, the default is C(pass_through) and an existing application will not be modified.
type: str
choices:
- pass_through
- specific_user
username:
description:
- Specifies the user name of an account that can access configuration files and content for this application.
- Required when I(connect_as) is set to C(specific_user).
type: str
password:
description:
- The password associated with I(username).
- Required when I(connect_as) is set to C(specific_user).
type: str
seealso:
- module: microsoft.iis.web_app_pool
- module: microsoft.iis.website
- module: microsoft.iis.web_application_info
author:
- Henrik Wallström (@henrikwallstrom)

EXAMPLES: |
- name: Add ACME web application on IIS.
microsoft.iis.web_application:
name: api
site: acme
state: present
physical_path: C:\apps\acme\api
- name: Change connect_as to be specific user.
microsoft.iis.web_application:
name: api
site: acme
connect_as: specific_user
username: acmeuser
password: acmepassword
- name: Delete ACME web application on IIS.
microsoft.iis.web_application:
state: absent
name: api
site: acme
RETURN: {}
102 changes: 102 additions & 0 deletions plugins/modules/web_application_info.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!powershell

# Copyright: (c) 2024, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)


#AnsibleRequires -CSharpUtil Ansible.Basic

function Get-ConnectAsInfo {
param (
[string] $site,
[string] $appName
)

# Construct the IIS path
$appPath = "IIS:\Sites\$($site)\$($appName)"

# Get the properties of the web application or virtual directory
$appProperties = Get-ItemProperty -LiteralPath $appPath

# Determine the Connect-As mode
if ($appProperties.userName -and $appProperties.userName -ne "") {
$connect_as = "specific_user"
$username = $appProperties.userName
}
else {
$connect_as = "pass_through"
$username = ""
}
return @{
connect_as = $connect_as
username = $username
}
}
$spec = @{
options = @{
name = @{ type = "str" }
site = @{ type = "str" }
}
supports_check_mode = $true
}

$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
$name = $module.Params.name
$site = $module.Params.site

$module.Result.exists = $false
$module.Result.applications = @()

try {
# Ensure WebAdministration module is loaded
if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) {
Import-Module WebAdministration
}
}
catch {
$module.FailJson("Failed to load WebAdministration module, Exception: $($_.Exception.Message)", $_)
}

try {
$getParams = @{}
if ($name) {
$getParams.Name = $name
}
if ($site) {
$getParams.Site = $site
}
$applications = Get-WebApplication @getParams
}
catch {
$module.FailJson("Failed to get web applications, Exception: $($_.Exception.Message)", $_)
}
if ($null -ne $applications) {
$module.Result.exists = $true
}

try {
$module.Result.applications = @(
foreach ($application in $applications) {
# Get site name from the application object
$site_name = $application.GetParentElement().Attributes["name"].Value
$app_name = $application.Path.TrimStart('/')

# Fetch Connect-As information once
$connectAsInfo = Get-ConnectAsInfo -site $site_name -appName $app_name
@{
name = $app_name
site = $site_name
connect_as = $connectAsInfo.connect_as
username = $connectAsInfo.username
application_pool = $application.ApplicationPool
physical_path = $application.PhysicalPath
enabled_protocols = $application.EnabledProtocols
}
}
)
}
catch {
$module.FailJson("Failed to get application details, Exception: $($_.Exception.Message)", $_)
}

$module.ExitJson()
Loading

0 comments on commit c67e9a9

Please sign in to comment.