我开发了一个webapp(api),它托管在azure中,使用vsts进行ci/cd/版本控制。
我想让这个api的客户(所有者)能够在wwwroot下更新各种配置/数据文件,但是我希望这些文件处于版本控制之下(真理之源-api源代码的单独存储库)。在存储库中创建/更新/删除其中一个文件会导致在webapp中上载/删除该文件(在wwwroot下的文件夹中)。
修改(创建/删除)其中一个文件不应触发(webapp的)完全重新部署
我怎样才能做到这一点?到目前为止,我已经考虑了一个git产品的vsts发布管道,但是我没有看到一个低摩擦的方式来在azurewebapp中进行更改(kuduapi似乎有点复杂和繁重)
**编辑:**示例powershell脚本,用于同步webapp中的配置文件,其中包含生成人工制品(仅在必要时调用put/delete)。
# The idea behind this script is to synchronize the configuration files on the server with what's in the repo, only updating files where necessary
param (
[string]$resourceGroupName = "XXX",
[Parameter(Mandatory=$true)][string]$webAppName,
[Parameter(Mandatory=$true)][string]$latestConfigFilesPath
)
function Get-AzureRmWebAppPublishingCredentials($resourceGroupName, $webAppName, $slotName = $null) {
if ([string]::IsNullOrWhiteSpace($slotName)) {
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
} else {
$resourceType = "Microsoft.Web/sites/slots/config"
$resourceName = "$webAppName/$slotName/publishingcredentials"
}
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force
return $publishingCredentials
}
function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName, $slotName = $null) {
$publishingCredentials = Get-AzureRmWebAppPublishingCredentials $resourceGroupName $webAppName $slotName
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}
function Get-KuduInode($kuduHref) {
return Invoke-RestMethod -Uri $kuduHref `
-Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
-Method GET `
-ContentType "application/json"
}
function Get-AllFilesUnderKuduHref($kuduHref) {
$result = @()
$inodes = (Get-KuduInode $kuduHref)
Foreach ($inode in $inodes) {
if ($inode.mime -eq "inode/directory") {
$result += (Get-AllFilesUnderKuduHref $inode.href)
} else {
$result += $inode.href
}
}
return $result
}
function Get-LocalPathForUri([System.Uri]$uri) {
$latestConfigFilesUri = [System.Uri]$latestConfigFilesPath
$localFileUri = [System.Uri]::new($latestConfigFilesUri, $uri)
return $localFileUri.LocalPath
}
function Get-RemoteUri([System.Uri]$uri) {
return [System.Uri]::new($configurationHref, $uri)
}
function Files-Identical($uri) {
$localFilePath = Get-LocalPathForUri $uri
$localFileHash = Get-FileHash $localFilePath -Algorithm MD5
# Download the remote file so that we can calculate the hash. It doesn't matter that it doesn't get cleaned up, this is running on a temporary build server anyway.
$temporaryFilePath = "downloded_kudu_file"
$remoteFileUri = [System.Uri]::new($configurationHref, $uri)
Invoke-RestMethod -Uri $remoteFileUri `
-Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
-Method GET `
-OutFile $temporaryFilePath `
-ContentType "multipart/form-data"
$remoteFileHash = Get-FileHash $temporaryFilePath -Algorithm MD5
return $remoteFileHash.Hash -eq $localFileHash.Hash
}
function CalculateRelativePath([System.Uri]$needle, [System.Uri]$haystack) {
return $haystack.MakeRelativeUri($needle).ToString();
}
function Put-File([System.Uri]$uri) {
Write-Host "Uploading file $uri"
$localFilePath = Get-LocalPathForUri $uri
$remoteFileUri = Get-RemoteUri $uri
Invoke-RestMethod -Uri $remoteFileUri `
-Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
-Method PUT `
-InFile $localFilePath `
-ContentType "multipart/form-data"
}
function Delete-File([System.Uri]$uri) {
Write-Host "Deleting file $uri"
$remoteFileUri = Get-RemoteUri $uri
Invoke-RestMethod -Uri $remoteFileUri `
-Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} `
-Method DELETE `
}
# Script begins here
$configurationHref = [System.Uri]"https://$webAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/Configuration/"
$kuduApiAuthorisationToken = Get-KuduApiAuthorisationHeaderValue -resourceGroupName $resourceGroupName -webAppName $webAppName
$filenamesOnServer = Get-AllFilesUnderKuduHref $configurationHref $kuduApiAuthorisationToken | % { $configurationHref.MakeRelativeUri($_).OriginalString }
Write-Host "Files currently on server" $filenamesOnServer
$filesCurrentlyInRepo = Get-ChildItem -Path $latestConfigFilesPath -Recurse -File
$filenamesInRepo = $filesCurrentlyInRepo | Select-Object -ExpandProperty FullName | % { CalculateRelativePath $_ $latestConfigFilesPath}
Write-Host "Files currently in repo" $filenamesInRepo
$intersection = $filenamesOnServer | ?{$filenamesInRepo -contains $_}
Write-Host "Intersection: " $intersection
$onlyOnServer = $filenamesOnServer | ?{-Not($filenamesInRepo -contains $_)}
$onlyInRepo = $filenamesInRepo | ?{-Not($filenamesOnServer -contains $_)}
Write-Host "Only on server" $onlyOnServer
Write-Host "Only in repo" $onlyInRepo
Write-Host
Foreach ($uri in $onlyInRepo) {
Put-File $uri
}
Foreach ($uri in $onlyOnServer) {
Delete-File $uri
}
Foreach ($uri in $intersection) {
if (-Not (Files-Identical $uri)) {
Write-Host "Configuration file $uri needs updating"
Put-File $uri
} else {
Write-Host "Configuration file $uri is identical, skipping"
}
}
Write-Host "Sync complete"
1条答案
按热度按时间daupos2t1#
使用azure应用程序服务部署任务,您可以将文件上载到应用程序服务,但不能删除文件(取消选中“使用web部署发布”选项并在包或文件夹输入框中指定文件夹路径)。
因此,更好的方法是使用kuduapi在构建/发布期间删除/上载文件。
有关于使用kudu api的线程和博客:
如何使用powershell脚本访问azure中的kudu
使用powershell和kudu api与azure web apps虚拟文件系统交互