Last active
January 1, 2016 10:29
-
-
Save udawtr/8132029 to your computer and use it in GitHub Desktop.
このPowerShellスクリプトモジュールは、WindowsAzureクラウドサービスへデプロイするための機能を提供します。ステージングが空であれば、新規デプロイを行い。そうでなければ、更新デプロイを行います。デプロイ処理中に *.cscfgファイル内の接続文字列を書き変えてプロダクションとステージングで同じ接続文字列を使うことを回避します。例えば、MyConnectionStringという名前で接続文字列を*.cscfgに定義しているとして、そこに使用するストレージアカウントがstorage1またはstorage2であるなら、自動的にプロダクションと衝突しないほうのストレージアカウントを選んで更新します。This PS Script Module provide the funct…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Publish-AzureCloud | |
{ | |
param( | |
[Parameter(Mandatory=$true)] | |
[string] | |
$ServiceName, | |
[Parameter(Mandatory=$true)] | |
[string] | |
$SubscriptionId, | |
[Parameter(ValueFromPipeline=$true,Mandatory=$true)] | |
[System.Security.Cryptography.X509Certificates.X509Certificate] | |
$Certificate, | |
[Parameter(Mandatory=$true)] | |
[string] | |
$Package, | |
[Parameter(Mandatory=$true)] | |
[string] | |
$Configuration, | |
[Parameter(Mandatory=$true)] | |
[string] | |
$Label, | |
[Parameter(Mandatory=$true)] | |
[string] | |
$UploadStorageName, | |
[string[]] | |
$SwapStorageAccountNames, | |
[string[]] | |
$SwapStorageConnectionStrings, | |
[string] | |
$SwapStorageConfigName | |
) | |
process | |
{ | |
$servicename = $ServiceName | |
$sub = $SubscriptionId | |
$cert = $Certificate | |
$package = $Package | |
$cfg = $Configuration | |
$label = $Label | |
$storagename = $UploadStorageName | |
$swapaccounts = $SwapStorageAccountNames | |
$swapconnections = $SwapStorageConnectionStrings | |
$swapconf = $SwapStorageConfigName | |
Export-WebConfig $package | |
$webConfigPath = Join-Path ((pwd).Path) "Web.config" | |
Check-SessionState $webConfigPath | |
$ErrorActionPreference = "Stop" | |
Import-AzureSDK | |
Set-AzureSubscription -SubscriptionName mysub -SubscriptionId $sub -Certificate $cert -CurrentStorageAccount $storagename | |
Select-AzureSubscription mysub | |
#Get current configuration | |
echo "Checking the existence of the deployment $servicename (Staging) ..." | |
Get-AzureDeployment $servicename -Slot staging -OutVariable out -ErrorAction SilentlyContinue | Out-Null | |
$st = $out[0].Status | |
if( $st -eq $NULL ) | |
{ | |
echo "The deployment $servicename (Staging) is NOT existed." | |
echo "Checking the existence of the deployment $servicename (Production) ..." | |
Get-AzureDeployment $servicename -Slot production -OutVariable out2 -ErrorAction SilentlyContinue | Out-Null | |
$st2 = $out2[0].Status | |
if( $st2 -eq $NULL ) | |
{ | |
echo "The deployment $servicename (Production) is NOT existed." | |
$conf = $NULL | |
} | |
else | |
{ | |
echo "The deployment $servicename (Production) is already EXISTED." | |
$conf = [xml]$out2[0].Configuration | |
} | |
} | |
else | |
{ | |
echo "The deployment $servicename (Staging) is already EXISTED." | |
$conf = [xml]$out.Configuration | |
} | |
if( $conf -eq $NULL ) | |
{ | |
echo 'Donot modify storage account because we have no deployments.' | |
$newcfg = (Resolve-Path $cfg) | |
} | |
else | |
{ | |
#Determine new connection | |
$accountname = Get-StorageAccountName -conf $conf -swapconf $swapconf | |
if( $accountname -eq $NULL ) | |
{ | |
echo "Failed to detect current storage account name of $SwapStorageConfigName" | |
exit | |
} | |
echo "Current storage account is $accountname" | |
$connection1 = $swapconnections[0] | |
$connection2 = $swapconnections[1] | |
$accountname1 = $swapaccounts[0] | |
$accountname2 = $swapaccounts[1] | |
if( $st -eq $NULL ) | |
{ | |
#in case of staging is NOT existed | |
if( ($conf -eq $NULL) -or ($accountname -eq $accountname2) ) | |
{ | |
$connection = $connection1 | |
echo "New storage account (Staging) is $accountname1" | |
} | |
elseif($accountname -eq $accountname1 ) | |
{ | |
$connection = $connection2 | |
echo "New storage account (Staging) is $accountname2" | |
} | |
else | |
{ | |
echo 'Cannot detect storage accountname. failed.' | |
exit | |
} | |
} | |
else | |
{ | |
#in case of staging is EXISTED | |
if( $accountname -eq $accountname1 ) | |
{ | |
$connection = $connection1 | |
echo "New storage account (Staging) is $accountname1" | |
} | |
elseif($accountname -eq $accountname2 ) | |
{ | |
$connection = $connection2 | |
echo "New storage account (Staging) is $accountname2" | |
} | |
else | |
{ | |
echo 'Cannot detect storage accountname. failed.' | |
exit | |
} | |
} | |
#Modify new configuration | |
$newconf = [xml](Get-Content (Resolve-Path $cfg)) | |
$ret = Set-ConnectionString -newconf $newconf -swapconf $swapconf -connection $connection | |
if( $ret -eq $false ) | |
{ | |
echo "Failed to detect $swapconf at $cfg" | |
exit | |
} | |
$newcfg = (Resolve-Path $cfg) | |
echo "Save midifed configuration file to $newcfg" | |
#echo $newconf.outerxml | |
$newconf.Save($newcfg) | |
} | |
#Check existings staging deployment | |
$st = $out[0].Status | |
if( $st -eq $NULL ) | |
{ | |
#NewDeploy(Deploying->Suspended) | |
echo "New-Deployment $servicename (Staging) Starting..." | |
New-AzureDeployment -Label "$label" -ServiceName $servicename -Slot staging -Package (Resolve-Path $package) -Configuration $newcfg | |
echo "New-Deployment $servicename (Staging) Completed." | |
} | |
else | |
{ | |
#UpdateDeploy | |
echo "Update-Deployment $servicename (Staging) Starting..." | |
Set-AzureDeployment -Upgrade -label "$label" -Servicename $servicename -Slot staging -package (Resolve-Path $package) -configuration $newcfg -force | |
echo "Update-Deployment $servicename (Staging) Completed." | |
} | |
#Get Staging URL | |
Get-StagingURL $servicename | |
} | |
} | |
function Check-SessionState($path) | |
{ | |
#Check-up Web.config | |
$webcfg = [xml](Get-Content $path) | |
$smode = $webcfg.configuration."system.web".sessionState.mode | |
$smode = $smode.ToLower().Trim() | |
if( $smode -eq "inproc" ){ | |
echo "[Error]The session mode is InProc. This mode cause some error at multi server environment." | |
exit | |
} elseif($smode -eq ""){ | |
echo "[Error]Fail to detect the session mode." | |
exit | |
} else { | |
echo "The session mode is $smode." | |
} | |
} | |
function Export-WebConfig($package) | |
{ | |
$cspkg_path = (Resolve-Path $package).Path | |
$cspkg_path_zip = $cspkg_path + ".zip" | |
$sh = New-Object -ComObject Shell.Application | |
#Copy *.cspkg => *.cspkg.zip | |
Copy-Item -Path $cspkg_path -Destination $cspkg_path_zip | |
#Get *.ccsx | |
$cssx = $sh.NameSpace($cspkg_path_zip).Items() | Where-Object { $_.Path.EndsWith(".cssx") } | |
$cssx | ForEach-Object { | |
#ref http://technet.microsoft.com/en-us/library/ee176633.aspx | |
$sh.NameSpace((pwd).Path).CopyHere($_, 0x14) | |
#Rename *.cssx => *.cssx.zip | |
$cssx_path = (Resolve-Path $_.Name).Path | |
$cssx_path_zip = $cssx_path + ".zip" | |
Rename-Item -Path $cssx_path -NewName $cssx_path_zip | |
#Get Web.config | |
$webConfig = $sh.NameSpace($cssx_path_zip + "\approot").Items() | Where-Object { $_.Path.EndsWith("Web.config") } | |
if( $webConfig -ne $NULL ) | |
{ | |
#ref http://technet.microsoft.com/en-us/library/ee176633.aspx | |
$sh.NameSpace((pwd).Path).CopyHere($webConfig, 0x14) | |
} | |
#Remove *.cssx.zip | |
Remove-Item -Path $cssx_path_zip | |
} | |
#Remove *.cspkg.zip | |
Remove-Item -Path $cspkg_path_zip | |
} | |
function Import-AzureSDK | |
{ | |
$path1 = 'C:\Program Files\Microsoft SDKs\Windows Azure\PowerShell\Azure' | |
$path2 = 'C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure' | |
If( Test-Path $path1 ) | |
{ | |
Get-ChildItem "$path1\*.psd1" | ForEach-Object {Import-Module $_} | |
return | |
} | |
If( Test-Path $path2 ) | |
{ | |
Get-ChildItem "$path2\*.psd1" | ForEach-Object {Import-Module $_} | |
return | |
} | |
echo "Failed to find the path of Windows Azure PowerShell. To install, visit http://www.windowsazure.com/ja-jp/downloads/" | |
exit | |
} | |
function Get-StorageAccountName($conf, $swapconf) | |
{ | |
foreach($role in $conf.ServiceConfiguration.Role) | |
{ | |
foreach($setting in $role.ConfigurationSettings.Setting) | |
{ | |
if( $setting.name -eq $swapconf) | |
{ | |
$accountname = $setting.value.Split(';')[1].Split('=')[1].Trim().ToLower() | |
return $accountname | |
} | |
} | |
} | |
return $NULL | |
} | |
function Set-ConnectionString($newconf, $swapconf, $connection) | |
{ | |
$flag = $false | |
foreach($role in $newconf.ServiceConfiguration.Role) | |
{ | |
foreach($setting in $role.ConfigurationSettings.Setting) | |
{ | |
if( $setting.name -eq $swapconf) | |
{ | |
$setting.value = $connection | |
$flag = $true | |
} | |
} | |
} | |
return $flag | |
} | |
function Get-StagingURL($servicename) | |
{ | |
echo "Get URL of the Deployment $servicename (Staging) " | |
Get-AzureDeployment -slot staging -servicename $servicename -outvariable out | |
$url = $out[0].Url | |
echo "New staging URL is $url" | |
$env:STAGINGURL=$url | |
$ErrorActionPreference = "SilentlyContinue" | |
$cli = New-Object System.Net.WebClient | |
$script:success = $FALSE | |
#Check for new url is available | |
:label do{ | |
trap{ | |
echo "Cannot reached ... " | |
$script:success = $FALSE | |
continue | |
} | |
sleep 30 | |
$script:success = $TRUE | |
$cli.DownloadString($url) | Out-Null | |
}while( $script:success -eq $FALSE) | |
if( $script:success -eq $TRUE ){ echo "OK. New URL is already rechable." } else { echo "NG" } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Import-Module (Resolve-Path "AzureCloudPublisher.psm1") | |
$servicename = "my azure cloud service name" | |
$sub = "my azure subscription id" | |
$cert = Get-Item cert:\CurrentUser\My\<Thumb print of management certification> | |
$package = "path of *.cspkg" | |
$cfg= "path of *.cscfg" | |
$label = "label of this deploy" | |
$storagename = "storage-to-upload-package" | |
$swapaccounts = 'storage1', 'storage2' | |
$swapconnections = | |
'DefaultEndpointsProtocol=https;AccountName=storage1;AccountKey=*******', | |
'DefaultEndpointsProtocol=https;AccountName=storage2;AccountKey=******' | |
$swapconf = "MyConnectionString" | |
Publish-AzureCloud -ServiceName $servicename -SubscriptionId $sub -Certificate $cert -Package $package -Configuration $cfg -Label $label -UploadStorageName $storagename -SwapStorageAccountNames $swapaccounts -SwapStorageConnectionStrings $swapconnections -SwapStorageConfigName $swapconf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Probably the error processo of Get-AzureDeployment was changed.
If Staging or Production slot has no deployment, previously Get-AzureDeployment return just emty.
But now I get Error and this script will stop.
So I add the option -ErrorAction SilentlyContinue.
Second change is about connection string modification.
If you have more than two roles in one cloud service, previous version of this script don't update all of connection strings. Just changed first one.I fixed this problem in this version.