Saturday, February 28, 2015

Using Custom Script in Azure Linux VM

Pre-requisite: Ensure that the Linux Agent is installed on the VM (instructions can be found at: http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-agent-user-guide/ )

Used: Ubunutu OS



Create a shell script

Create a file “script.sh” with the below content:
#!/bin/bash
ls -ltrah / >> myfile.txt

 
Upload script to blob container
Check “Upload all files in a folder to a Container in Azure” post.
Upload “script.sh” to a container called “script”.

PowerShell Script



###################Disclaimer########################################

 

# The script is provided ASIS. Feel free to modify as per your need #

 

#####################################################################

clear screen

 

 

#global preference

#$ErrorActionPreference = "Stop"

$nl=[Environment]::NewLine

 

$bgcolor="Gray"

$fgcolor="Cyan"

 

############user defined variables ###################

$vmName='dpubuntudevrnd'

$cloudsvcName = 'dpubuntudevrnd'

$storageAccountName = 'sawestusdp'

$scriptContainer = 'script'

$scriptName = 'script.sh'

 

#“1.*” ensures that you are using the latest version

$customExtensionName = 'CustomScriptForLinux' 

$customPublisher = 'Microsoft.OSTCExtensions' 

$customVersion = '1.*'

 

###################Display message########################

function Display-Message ($message, $message2) {

    Display-Message_NoLineBreak $message, $message2

    $nl

}

function Display-ErrorMessage ($myError) {

    Write-Host "Error: $myError" -BackgroundColor Red -ForegroundColor $fgcolor

 

   #Show-ErrorDetails

    $Error.Clear();

    $nl

}

function Display-Message_NoLineBreak ($message, $message2) {

    if ($message2 -ne $null) {

        Write-Host $message $message2 -BackgroundColor DarkBlue -ForegroundColor $fgcolor

    } else {

        Write-Host $message $message2 -BackgroundColor $bgcolor -ForegroundColor $fgcolor

    }

}

 

####################End of Display message################

 

########check if there is an active azure account#########

function Handle-AzureAccount () {

    $currentAzureAccount=Get-AzureAccount

    if ($currentAzureAccount -eq $null) {

        Add-AzureAccount

    }

}

########end check if there is an active azure account#########

 

##################Collect User Response################

function Collect-UserResponse ($message) {

    Display-ErrorMessage $message

    Read-Host 'Press <Enter> to continue or Ctrl+C to Abort'

}

##################end of Collecting User Response######

 

#add your account

Display-Message "Going to add account..."

Handle-AzureAccount

Display-Message "Added account."

 

#ensure that you are in service management mode

Display-Message "Going to switch to service management mode..."

Switch-AzureMode -Name AzureServiceManagement

 

 

###########Find default subscription##########

$subscriptionName = ""

foreach ($sub in Get-AzureSubscription)

{

    if ($sub.IsDefault -eq "True")

    {

        $subscriptionName = $sub.SubscriptionName

    }

}

Display-Message "Default Subscription:" $subscriptionName

Pause

 

#set default subscription and the storage account

Display-Message "Going to set the default Subscription"

Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccountName $storageAccountName

Display-Message "Default Subscription and Storage Account set"

#print the subscription

Display-Message "Going to print azure subscription."

Get-AzureSubscription

Pause

 

# Get the storage account key and context

Display-Message "Going to collect Storage Account key..."

$storageAccountKey = (Get-AzureStorageKey -StorageAccountName $storageAccountName).Primary

Display-Message "Storage Key $storageAccountKey"

Pause

 

#get storage contxt

Display-Message "Going to collect Storage context..."

$storageCtx = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey

Display-Message "Storage context collected: $storageCtx"

Pause

 

#storage location and the specific .sh script

Display-Message "Prepare the configuration..."

$fullPathToScript="$($storageCtx.BlobEndPoint)$scriptContainer/$scriptName"

Display-Message "fullPathToScript: $fullPathToScript"

$shellConfig = "{`"fileUris`":[`"$fullPathToScript`"], `"commandToExecute`": `"sh $scriptName`" }"

Display-Message "Shell configuration: $shellConfig"

#Storage configuration

$storageConfig = "{`"storageAccountName`": `"$storageAccountName`",`"storageAccountKey`":`"$storageAccountKey`"}"

Display-Message "storageConfig: $storageConfig"

Pause

 

#get the vm

Display-Message "Going to get the VM details..."

$vm = Get-AzureVM -ServiceName "$cloudsvcName" -Name "$vmName"

Display-Message "VM: $vm"

 

#deploy the extension

Display-Message "Going to deploy the VM extension..."

Set-AzureVMExtension -ExtensionName $customExtensionName -VM  $vm -Publisher $customPublisher -Version $customVersion -PrivateConfiguration $storageConfig -PublicConfiguration $shellConfig  | Update-AzureVM

Display-Message "VM extension deployed."

VM logs
Check /var/log/waagentlog
2015/03/01 06:35:36 Found Plugin: Microsoft.OSTCExtensions.CustomScriptForLinux version: 1.2
2015/03/01 06:35:36 Found RuntimeSettings for Microsoft.OSTCExtensions.CustomScriptForLinux V 1.2
2015/03/01 06:35:36 Spawned customscript.py -enable PID 1829
2015/03/01 06:35:36 CustomScript started to handle.
2015/03/01 06:35:36 [CustomScript-0.0]cwd is /var/lib/waagent/Microsoft.OSTCExtensions.CustomScriptForLinux-1.2
2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]Change log file to /var/log/azure/Microsoft.OSTCExtensions.CustomScriptForLinux/1.2/extension.log
2015/03/01 06:35:41 enableCommand completed.
2015/03/01 06:35:41 SetHandlerState: Microsoft.OSTCExtensions.CustomScriptForLinux-1.2, Enabled
2015/03/01 06:35:41 Enable completed for Microsoft.OSTCExtensions.CustomScriptForLinux-1.2
2015/03/01 06:35:41 Processing completed for Microsoft.OSTCExtensions.CustomScriptForLinux-1.2
2015/03/01 06:35:41 Finished processing ExtensionsConfig.xml

Check /var/log/azure/Microsoft.OSTCExtensions.CustomScriptForLinux/1.2/extension.log

2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]sequence number is 0
2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]setting file path is/var/lib/waagent/Microsoft.OSTCExtensions.CustomScriptForLinux-1.2/config/0.settings
2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]JSON config: {"runtimeSettings":[{"handlerSettings":{"protectedSettingsCertThumbprint":"2B7F0F8959C00CCAE3A4461DDC1CCC80CFA322BE","protectedSettings":"MIICSgYJKoZIhvcNAQcDoIICOzCCAjcCAQAxggFxMIIBbQIBADBVMEExPzA9BgoJkiaJk/IsZAEZFi9XaW5kb3dzIEF6dXJlIFNlcnZpY2UgTWFuYWdlbWVudCBmb3IgRXh0ZW5zaW9ucwIQWqpa9Q3NsYZOxzie/WhnmjANBgkqhkiG9w0BAQEFAASCAQAVY2iSsZ8pYpOtYwFDGwc02Yqq/WcdDkwevVjzbi7i5fwWqJCYutfy1O+9VRMK7uBO+8OK8Y0Xc2JkhdNaOajL9QK7C43D3F51agmyFQVGHMSrJjD+OlwauvR47Aji5XtvJpSnqZT8I4gqLP+WPnh0w01mzQEkke8vGMuHSaQf0PC27Bs0Yv0yAyIgkDdaqHi+q7FGYIcx6MUwOYOMSXOCSjICnHonMlmmK6PEMyTRXNl4hs0SuSyxMj/tGxGS3gMKZAMSJHoJDq+mASQfPLWAgtuU/vNoMLJbeMMIhML6XbEE1xe6Nu2TKq1J1S8Q6yzpqmRovhK7b0gTmkbLhjj2MIG8BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECPv0BpHStSFSgIGYy4TQ+glOpTHgA8z76yrsbUrosFtQ3jQO8pa8orgyZi7hukriujwYSWpAUQM4EJYAI/w/W79V4z4hDf9ScJtj93Bb6NzZkX/ivY9xxtNghd67/3lPtd0K8i7647mhje0LUYrXjmx3KdJVvfWKZlzuBm0B3YOsItErSIYQB29RZLwZ4cfkfryHYy+Sdqpkvy40HfMxoGMtsHk=","publicSettings":{"fileUris":["https://sawestusdp.blob.core.windows.net/script/script.sh"], "commandToExecute": "sh script.sh" }}}]}
2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]Config decoded correctly.
2015/03/01 06:35:36 [Microsoft.OSTCExtensions.CustomScriptForLinux-1.0]Current sequence number, 0, is not greater than the sequnce number of the most recent executed configuration. Exiting.

cd /var/lib/waagent/Microsoft.OSTCExtensions.CustomScriptForLinux-1.2/download/0

Content of ls –ltrah should be there J
 



 

Monday, February 23, 2015

Azure CDN with a Cloud Service in VM



Pre-requisite:
·        Setup a cloud service (in VM*) :- <mycloudapp>.cloudapp.net
·        Setup CDN :- <mycdn>.vo.msecnd.net
o   Select origin domain as Cloud Service <mycloudapp>
o   Pay attention to “Enable Query String”
o   Optionally pay attention to “Enable HTTPS”
o   Optionally pay attention to Manage Domains
·        Browser with a either a plugin or a request/response capture tool **

(*) à Should work with Cloud PaaS as well.
(**) à FireFox LiveHttpHeader, Fiddler for IE, WireShark, etc.
Steps:
1.      Setup up content:
a.      Directory structure :- <wwwroot>/cdn/images/ (“/cdn” makes CDN communicate with Cloud Service
b.      Content :- apple.jpg (or any image of your choice J)
c.      Html content :- edit index.html (<img src="http://< mycdn>.vo.msecnd.net/images/apple.jpg" alt="Red Delicious Apple" height="100" width="100">) (“http” or “https” :- take care. Azure CDN doesn’t support custom domain with SSL)
2.      Check live httpd log :- tail -f /var/log/httpd/access_log
3.      Launch a FireFox browser
4.      Launch Browser Req/Res :- In FireFox use HttpLiveHeader
a.      Check httpd log (#2) :- Should two requests
                                                    i.     <some ip> - - [<timestampe>] "GET /index.html?v=1 HTTP/1.1" 200 113 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
                                                   ii.     <some ip> - - [<timestampe>] "GET /cdn/images/apple.jpg HTTP/1.1" 200 721759 "http://dpasuswest.cloudapp.net/index.html?asdfasdf" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
b.      Check Browser Req/res log (#4)
                                                    i.     Ensure that there two req/res one for <mycloudapp> host and the other for < mycdn>
a.      You will notice that Browser doesn’t send any request to <mycloudapp> because its cached J (We got hit by browser cache Yikes...)
7.      View source and collect the CDN URL (http://<mycdn>.vo.msecnd.net/images/apple.jpg)
a.      You will notice that httpd log registered a request with the above url.
a.      You will notice that httpd log doesn’t show any request
b.      You will get a 304 from <mycdn> (Content is served from CDN).