Skip to content

Commit da93499

Browse files
feat: Provide script to upsert an app setting within an Azure App Service (#268)
Co-authored-by: Stijn Moreels <9039753+stijnmoreels@users.noreply.github.com> Co-authored-by: Pim Simons <pim.simons@codit.eu>
1 parent 48213bf commit da93499

12 files changed

Lines changed: 500 additions & 0 deletions

docs/preview/01-index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ For more granular packages we recommend reading the documentation.
1919
# Features
2020

2121
* Automate Azure API Management tasks ([powershell](features/powershell/azure-api-management))
22+
* Automate Azure App Service tasks ([powershell](features/powershell/azure-app-service))
2223
* Automate Azure Data Factory tasks ([powershell](features/powershell/azure-data-factory))
2324
* Automate Azure DevOps tasks ([powershell](features/powershell/azure-devops))
2425
* Automate Azure Integration Account tasks ([powershell](features/powershell/azure-integration-account))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
title: "Azure App Service"
3+
layout: default
4+
---
5+
6+
# Azure App Service
7+
8+
This module provides the following capabilities:
9+
- [Set an app setting within an Azure App Service](#set-an-app-setting-within-an-azure-app-service)
10+
11+
## Installation
12+
13+
To have access to the following features, you have to import the module:
14+
15+
```powershell
16+
PS> Install-Module -Name Arcus.Scripting.AppService
17+
```
18+
19+
## Set an app setting within an Azure App Service
20+
21+
Create/update a single application setting within an Azure App Service.
22+
23+
| Parameter | Mandatory | Description |
24+
| ----------------------------- | ----------- | ----------------------------------------------------------------------------------------------------- |
25+
| `ResourceGroupName` | yes | The name of the Azure resource group where the Azure Integration Account is located. |
26+
| `AppServiceName` | yes | The name of the Azure App Service where the application setting will be created/updated. |
27+
| `AppServiceSettingName` | yes | The name of the application setting that will be created/updated. |
28+
| `AppServiceSettingValue` | yes | The value of the application setting that will be created/updated. |
29+
| `PrintSettingValuesIfVerbose` | no | Indicator (switch) whether the values of the application settings will be written to the verbose log. |
30+
31+
**Example**
32+
33+
Setting an application setting within an Azure App Service.
34+
```powershell
35+
PS> Set-AzAppServiceSetting -ResourceGroupName 'my-resource-group' -AppServiceName 'my-app-service' -AppServiceSettingName 'my-app-setting' -AppServiceSettingValue 'my-value'
36+
# Checking if the App Service with name 'my-app-service' can be found in the resource group 'my-resource-group'
37+
# App service has been found
38+
# Extracting the existing application settings
39+
# Setting the application setting 'my-app-setting'
40+
# Successfully set the application setting 'my-app-setting' of the App Service 'my-app-service' within resource group 'my-resource-group'
41+
```
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#
2+
# Module manifest for module 'module'
3+
#
4+
# Generated by: Arcus
5+
#
6+
# Generated on: 5/29/2020 10:12:26 AM
7+
#
8+
9+
@{
10+
11+
# Script module or binary module file associated with this manifest.
12+
RootModule = 'Arcus.Scripting.AppService.psm1'
13+
14+
# Version number of this module.
15+
ModuleVersion = '#{Package.Version}#'
16+
17+
# ID used to uniquely identify this module
18+
GUID = 'ef97d51b-87bb-4daa-b97c-b59f08da8009'
19+
20+
# Author of this module
21+
Author = 'Arcus'
22+
23+
# Company or vendor of this module
24+
CompanyName = ''
25+
26+
# Copyright statement for this module
27+
Copyright = '(c) 2020 Arcus. All rights reserved.'
28+
29+
# Description of the functionality provided by this module
30+
Description = 'Scripts related to Azure App Service'
31+
32+
# Minimum version of the Windows PowerShell engine required by this module
33+
PowerShellVersion = '5.1'
34+
35+
# Name of the Windows PowerShell host required by this module
36+
# PowerShellHostName = ''
37+
38+
# Minimum version of the Windows PowerShell host required by this module
39+
# PowerShellHostVersion = ''
40+
41+
# Minimum version of Microsoft .NET Framework required by this module
42+
# DotNetFrameworkVersion = ''
43+
44+
# Minimum version of the common language runtime (CLR) required by this module
45+
# CLRVersion = ''
46+
47+
# Processor architecture (None, X86, Amd64) required by this module
48+
# ProcessorArchitecture = ''
49+
50+
# Modules that must be imported into the global environment prior to importing this module
51+
RequiredModules = @(@{ModuleName='Az.Websites'; ModuleVersion='2.9.0'})
52+
53+
# Assemblies that must be loaded prior to importing this module
54+
# RequiredAssemblies = @()
55+
56+
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
57+
# ScriptsToProcess = @()
58+
59+
# Type files (.ps1xml) to be loaded when importing this module
60+
# TypesToProcess = @()
61+
62+
# Format files (.ps1xml) to be loaded when importing this module
63+
# FormatsToProcess = @()
64+
65+
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
66+
# NestedModules = @()
67+
68+
# Functions to export from this module
69+
FunctionsToExport = @(
70+
'Set-AzAppServiceSetting')
71+
72+
# Cmdlets to export from this module
73+
CmdletsToExport = '*'
74+
75+
# Variables to export from this module
76+
VariablesToExport = '*'
77+
78+
# Aliases to export from this module
79+
AliasesToExport = '*'
80+
81+
# List of all modules packaged with this module
82+
# ModuleList = @()
83+
84+
# List of all files packaged with this module
85+
# FileList = @()
86+
87+
# Private data to pass to the module specified in RootModule/ModuleToProcess
88+
PrivateData = @{
89+
90+
PSData = @{
91+
92+
# Tags applied to this module. These help with module discovery in online galleries.
93+
Tags = 'Azure','AppService', 'Arcus'
94+
95+
# A URL to the license for this module.
96+
LicenseUri = 'https://github.com/arcus-azure/arcus.scripting/blob/master/LICENSE'
97+
98+
# A URL to the main website for this project.
99+
ProjectUri = 'https://github.com/arcus-azure/arcus.scripting'
100+
101+
# A URL to an icon representing this module.
102+
IconUri = 'https://raw.githubusercontent.com/arcus-azure/arcus/master/media/arcus.png'
103+
104+
# ReleaseNotes of this module
105+
ReleaseNotes = 'https://github.com/arcus-azure/arcus.scripting/releases/tag/v#{Package.Version}#'
106+
107+
# Prerelease string of this module
108+
# Prerelease = ''
109+
110+
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
111+
# RequireLicenseAcceptance = $false
112+
113+
# External dependent modules of this module
114+
# ExternalModuleDependencies = @()
115+
116+
} # End of PSData hashtable
117+
118+
} # End of PrivateData hashtable
119+
120+
121+
# HelpInfo URI of this module
122+
# HelpInfoURI = ''
123+
124+
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
125+
# DefaultCommandPrefix = ''
126+
127+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<#
2+
.Synopsis
3+
Sets the value of an application setting within an Azure App Service.
4+
5+
.Description
6+
The Set-AzAppServiceSetting cmdlet sets the value of an application setting within an Azure App Service.
7+
8+
.Parameter ResourceGroupName
9+
The name of the of resource group under which the App Service exists.
10+
11+
.Parameter AppServiceName
12+
The name of the App Service.
13+
14+
.Parameter AppServiceSettingName
15+
The name of the application setting.
16+
17+
.Parameter AppServiceSettingValue
18+
The value to be used for the application setting.
19+
20+
.Parameter PrintSettingValuesIfVerbose
21+
Indicate whether or not to print the values of the current application settings in the verbose logging.
22+
#>
23+
function Set-AzAppServiceSetting {
24+
param(
25+
[Parameter(Mandatory = $true)][string] $ResourceGroupName = $(throw "Resource group name is required"),
26+
[Parameter(Mandatory = $true)][string] $AppServiceName = $(throw = "App Service name is required"),
27+
[Parameter(Mandatory = $true)][string] $AppServiceSettingName = $(throw "App Service setting name is required"),
28+
[Parameter(Mandatory = $true)][string] $AppServiceSettingValue = $(throw "App Service value is required"),
29+
[Parameter(Mandatory = $false)][switch] $PrintSettingValuesIfVerbose = $false
30+
)
31+
32+
if($PrintSettingValuesIfVerbose) {
33+
. $PSScriptRoot\Scripts\Set-AzAppServiceSetting.ps1 -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -AppServiceSettingName $AppServiceSettingName -AppServiceSettingValue $AppServiceSettingValue -PrintSettingValuesIfVerbose
34+
} else {
35+
. $PSScriptRoot\Scripts\Set-AzAppServiceSetting.ps1 -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -AppServiceSettingName $AppServiceSettingName -AppServiceSettingValue $AppServiceSettingValue
36+
}
37+
38+
}
39+
40+
Export-ModuleMember -Function Set-AzAppServiceSetting
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4+
<SchemaVersion>2.0</SchemaVersion>
5+
<ProjectGuid>{342747e9-6406-4da8-b238-37335adba79c}</ProjectGuid>
6+
<OutputType>Exe</OutputType>
7+
<RootNamespace> Arcus.Scripting.AppService</RootNamespace>
8+
<AssemblyName> Arcus.Scripting.AppService</AssemblyName>
9+
<Name>Arcus.Scripting.AppService</Name>
10+
</PropertyGroup>
11+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12+
<DebugSymbols>true</DebugSymbols>
13+
<DebugType>full</DebugType>
14+
<Optimize>false</Optimize>
15+
<OutputPath>bin\Debug\</OutputPath>
16+
<DefineConstants>DEBUG;TRACE</DefineConstants>
17+
<ErrorReport>prompt</ErrorReport>
18+
<WarningLevel>4</WarningLevel>
19+
</PropertyGroup>
20+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
21+
<DebugType>pdbonly</DebugType>
22+
<Optimize>true</Optimize>
23+
<OutputPath>bin\Release\</OutputPath>
24+
<DefineConstants>TRACE</DefineConstants>
25+
<ErrorReport>prompt</ErrorReport>
26+
<WarningLevel>4</WarningLevel>
27+
</PropertyGroup>
28+
<ItemGroup>
29+
<Folder Include="Scripts\" />
30+
</ItemGroup>
31+
<ItemGroup>
32+
<Compile Include="Arcus.Scripting.AppService.psd1" />
33+
<Compile Include="Arcus.Scripting.AppService.psm1" />
34+
<Compile Include="Scripts\Set-AzAppServiceSetting.ps1" />
35+
</ItemGroup>
36+
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
37+
<Target Name="Build" />
38+
<Import Project="$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets" Condition="Exists('$(MSBuildExtensionsPath)\PowerShell Tools for Visual Studio\PowerShellTools.targets')" />
39+
</Project>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
param(
2+
[Parameter(Mandatory = $true)][string] $ResourceGroupName = $(throw "Resource group name is required"),
3+
[Parameter(Mandatory = $true)][string] $AppServiceName = $(throw "App Service name is required"),
4+
[Parameter(Mandatory = $true)][string] $AppServiceSettingName = $(throw "App Service setting name is required"),
5+
[Parameter(Mandatory = $true)][string] $AppServiceSettingValue = $(throw "App Service value is required"),
6+
[Parameter(Mandatory = $false)][switch] $PrintSettingValuesIfVerbose = $false
7+
)
8+
9+
Write-Host "Checking if the App Service with name '$AppServiceName' can be found in the resource group '$ResourceGroupName'"
10+
$appService = Get-AzWebApp -ResourceGroupName $ResourceGroupName -Name $AppServiceName -ErrorAction Ignore
11+
12+
if ($appService -eq $null) {
13+
throw "No App Service with name '$AppServiceName' could be found in the resource group '$ResourceGroupName'"
14+
}
15+
16+
Write-Host "Azure App service has been found for name '$AppServiceName' in the resource group '$ResourceGroupName'"
17+
Write-Host "Extracting the existing application settings from Azure App Service"
18+
$appServiceSettings = $appService.SiteConfig.AppSettings
19+
20+
$existingSettings = @{ }
21+
Write-Verbose "Existing Azure App Service application settings:"
22+
foreach ($setting in $appServiceSettings) {
23+
$existingSettings[$setting.Name] = $setting.value
24+
if ($PrintSettingValuesIfVerbose) {
25+
Write-Verbose "$($setting.Name): $($setting.Value)"
26+
} else {
27+
Write-Verbose "$($setting.Name)"
28+
}
29+
}
30+
31+
$existingSettings[$AppServiceSettingName] = $AppServiceSettingValue
32+
33+
Write-Host "Setting the application setting '$AppServiceSettingName'"
34+
try
35+
{
36+
$updatedAppService = Set-AzWebApp -ResourceGroupName $ResourceGroupName -Name $appServiceName -AppSettings $existingSettings
37+
38+
Write-Verbose "Updated Azure App Service settings:"
39+
foreach ($setting in $updatedAppService.SiteConfig.AppSettings) {
40+
if ($PrintSettingValuesIfVerbose) {
41+
Write-Verbose "$($setting.Name): $($setting.Value)"
42+
} else {
43+
Write-Verbose "$($setting.Name)"
44+
}
45+
}
46+
} catch {
47+
throw "The Azure App Service settings could not be updated. Details: $($_.Exception.Message)"
48+
}
49+
50+
Write-Host "Successfully set the application setting '$AppServiceSettingName' of the Azure App Service '$AppServiceName' within Azure resource group '$ResourceGroupName'"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Import-Module -Name $PSScriptRoot\..\Arcus.Scripting.AppService -ErrorAction Stop
2+
3+
InModuleScope Arcus.Scripting.AppService {
4+
Describe "Arcus Azure App Service integration tests" {
5+
BeforeEach {
6+
$config = & $PSScriptRoot\Load-JsonAppsettings.ps1 -fileName "appsettings.json"
7+
& $PSScriptRoot\Connect-AzAccountFromConfig.ps1 -config $config
8+
}
9+
Context "Setting an Azure App Service application setting" {
10+
It "Try to set an application setting to unexisting App Service fails" {
11+
# Arrange
12+
$ResourceGroupName = $config.Arcus.ResourceGroupName
13+
$AppServiceName = "unexisting-appservice"
14+
$AppServiceSettingName = "somesetting"
15+
$AppServiceSettingValue = "somevalue"
16+
17+
# Act
18+
{ Set-AzAppServiceSetting -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -AppServiceSettingName $AppServiceSettingName -AppServiceSettingValue $AppServiceSettingValue -ErrorAction Stop } |
19+
Should -Throw
20+
}
21+
It "Creating a new application setting and setting its value succeeds" {
22+
# Arrange
23+
$ResourceGroupName = $config.Arcus.ResourceGroupName
24+
$AppServiceName = $config.Arcus.AppService.Name
25+
$AppServiceSettingName = "setting-$([System.Guid]::NewGuid())"
26+
$AppServiceSettingValue = [guid]::NewGuid()
27+
28+
try {
29+
# Act
30+
Set-AzAppServiceSetting -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -AppServiceSettingName $AppServiceSettingName -AppServiceSettingValue $AppServiceSettingValue
31+
32+
# Assert
33+
$actual = Get-AzWebApp -ResourceGroupName $ResourceGroupName -Name $AppServiceName
34+
$actual | Should -Not -BeNullOrEmpty
35+
36+
$settings = @{ }
37+
foreach ($setting in $actual.SiteConfig.AppSettings) {
38+
$settings[$setting.Name] = $setting.value
39+
}
40+
41+
$settings[$AppServiceSettingName] | Should -BeExactly $AppServiceSettingValue
42+
} finally {
43+
$appService = Get-AzWebApp -ResourceGroupName $ResourceGroupName -Name $AppServiceName
44+
$appServiceSettings = $appService.SiteConfig.AppSettings
45+
46+
$settingsWithoutTestSetting = @{ }
47+
foreach ($setting in $appServiceSettings) {
48+
if ($setting.Name -ne $AppServiceSettingName) {
49+
$settingsWithoutTestSetting[$setting.Name] = $setting.value
50+
}
51+
}
52+
53+
Set-AzWebApp -ResourceGroupName $ResourceGroupName -Name $appServiceName -AppSettings $settingsWithoutTestSetting
54+
}
55+
}
56+
It "Update an existing application setting and setting its value succeeds" {
57+
# Arrange
58+
$ResourceGroupName = $config.Arcus.ResourceGroupName
59+
$AppServiceName = $config.Arcus.AppService.Name
60+
$AppServiceSettingName = "existing-setting"
61+
$AppServiceSettingValue = [guid]::NewGuid()
62+
63+
# Act
64+
Set-AzAppServiceSetting -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -AppServiceSettingName $AppServiceSettingName -AppServiceSettingValue $AppServiceSettingValue
65+
66+
# Assert
67+
$actual = Get-AzWebApp -ResourceGroupName $ResourceGroupName -Name $AppServiceName
68+
$actual | Should -Not -BeNullOrEmpty
69+
70+
$settings = @{ }
71+
foreach ($setting in $actual.SiteConfig.AppSettings) {
72+
$settings[$setting.Name] = $setting.value
73+
}
74+
75+
$settings[$AppServiceSettingName] | Should -BeExactly $AppServiceSettingValue
76+
}
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)