RoleEnvironment.Changing event doesn't trigger in WorkerRole - azure

So, I have Azure project with 3 WebRoles and 1 WorkerRole. In each project I have subscription on RoleEnvironment.Changing and RoleEnvironment.Changed events. In WebRole everything is fine, but in WorkerRole these events don't want to trigger.
Мoreover when I change setting of some WebRole, WorkerRole is also recycling everytime
WorkerRole run another x86 proccess inside and script on startup
Azure SDK 1.7 is used
<WorkerRole name="MyService" vmsize="Medium" enableNativeCodeExecution="true">
<Startup>
<Task commandLine="startup.cmd" taskType="simple" executionContext="elevated" />
</Startup>
<Runtime executionContext="elevated" />
<Imports>
<Import moduleName="Diagnostics" />
<Import moduleName="RemoteAccess" />
</Imports>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="8081" />
<InputEndpoint name="TCPEndpoint" protocol="tcp" port="10101" localPort="10100" />
<InternalEndpoint name="InternalEndpoint" protocol="http" />
</Endpoints>
<ConfigurationSettings>
<Setting name="StorageConnectionString" />
<Setting name="TransactionLogsBlobContainer" />
</ConfigurationSettings>
<LocalResources>
<LocalStorage name="DiagnosticStore" cleanOnRoleRecycle="false" sizeInMB="8192" />
</LocalResources>
</WorkerRole>
Does anybody have any idea what could be going on?
Thanks

I've had a similar issue and found that changing the taskType of the Startup Task from elevated to background solved my problem. I'd recommend starting there.
<Startup>
<Task commandLine="startup.cmd" executionContext="elevated" taskType="background"></Task>
</Startup>

For worker roles, you must define an internal endpoint (even if you don't actually use it), in order to get certain events.
IE, add this to your CSDef:
More details here: http://blogs.msdn.com/b/windowsazure/archive/2011/01/04/responding-to-role-topology-changes.aspx

Related

Azure Cloud Service - no environment variables being set

The roles in my Cloud Service aren't getting any custom environment variables set. --Meaning if I enumerate the results of a call to Environment.GetEnvironmentVariables(), only the standard environment variables are set (things like PATH or the user id).
When I debug the Cloud Service locally using the emulator, the envvars are there, so I'm kind of at a loss here.
The relevant .csdef:
<WebRole name="..." vmsize="Small">
<ConfigurationSettings>
<Setting name="FirstSetting" />
<Setting name="AnotherSetting" />
</ConfigurationSettings>
<Runtime>
<Environment>
<Variable name="FirstSettingEnvVar">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[#name='FirstSetting']/#value" />
</Variable>
<Variable name="SecondSettingEnvVar">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[#name='SecondSetting']/#value" />
</Variable>
</Environment>
</Runtime>
and the relevant .cscfg:
<Role name="...">
<Instances count="2" />
<ConfigurationSettings>
<Setting name="FirstSetting" value="ABCD" />
<Setting name="SecondSetting" value="WXYZ" />
</ConfigurationSettings>
</Role>

Azure cloud service definition problems

I have a cloud service which was running fine for a while after upgrading to Azure 2.0 SDK. It has now mysteriously stopped working. I am getting this in the Azure machines event log.
The application '/' belonging to site '19369254' has an invalid
AppPoolId 'ddcc23fe-8eee-4412-a4dd-56b50e18d9f2' set.
Therefore, the application will be ignored.
Followed by :
Site 19369254 was disabled because the root application defined for the site is
invalid. See the previous event log message for information about why the
root application is invalid.
and :
A process serving application pool 'ddcc23fe-8eee-4412-a4dd-56b50e18d9f2'
terminated unexpectedly. The process id was '3696'.
The process exit code was '0x103'.
My service definition:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="SMEEDI.Cloud" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2013-03.2.0">
<WebRole name="SMEEDI.Portal" enableNativeCodeExecution="true">
<Startup>
<Task commandLine="startup.cmd" executionContext="elevated" taskType="simple"></Task>
</Startup>
<ConfigurationSettings>
<Setting name="DiagnosticsConnectionString" />
<Setting name="DataConnectionString" />
<Setting name="BaseUrl" />
<Setting name="DatabaseConnectionString" />
<Setting name="Environment" />
</ConfigurationSettings>
<Sites>
<Site name="Smeedi_WebRole" physicalDirectory="..\..\..\SMEEDI.Portal">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="RemoteAccess" />
<Import moduleName="RemoteForwarder" />
</Imports>
</WebRole>
</ServiceDefinition>
How could this suddenly stop working?
What is wrong with the service definition?
The error you are receiving should have nothing to do with the CSDEF file. It appears to be an issue with the configuration of IIS on the Azure instance.
You can try to reimage the instance from the Azure portal or log into the instance to do further troubleshooting. If you choose to remote in, I would examine the IIS configuration, specifically the Application Pools and virtual directories, especially the path since you are changing it in the CSDEF.
Azure should take care of that configuration on its own, which is why reimage or delete and redeploy may be a better first step.

Configuring SSL endpoints for node.js worker roles on Azure

I've set up a node.js app to run on worker roles (not web roles) on Azure cloud services. Everything was working fine with the standard app running on HTTP.
Now I'm trying to get it running over SSL on HTTPS, and have successfully followed the instructions at http://www.windowsazure.com/en-us/develop/nodejs/common-tasks/enable-ssl-worker-role/ but it has not produced the correct results!
Now when accessing the url over either HTTP or HTTPS the connection times out and nothing is returned.
Is there anything I might be missing or any steps that aren't in the guide linked above?
One thing I did notice in the guide was whether the line...
<InputEndpoint name="HttpIn" protocol="tcp" port="443" />
... should in fact be HttpsIn instead? Though changing this doesn't seem to make a huge amount of difference.
Update: here are some of my configuration files
ServiceConfiguration.cloud.cscfg
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" serviceName="*removed*" osFamily="2" osVersion="*" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
<Role name="WorkerRole1">
<ConfigurationSettings />
<Instances count="1" />
<Certificates>
<Certificate name="certificateName" thumbprint="*removed*" thumbprintAlgorithm="sha1" />
</Certificates>
</Role>
</ServiceConfiguration>
ServiceDefinition.csdef
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="*removed*" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WorkerRole name="WorkerRole1" vmsize="ExtraSmall">
<Startup>
<Task commandLine="setup_worker.cmd > log.txt" executionContext="elevated">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
<Variable name="RUNTIMEID" value="node" />
<Variable name="RUNTIMEURL" value="http://az413943.vo.msecnd.net/node/0.8.4.exe" />
</Environment>
</Task>
<Task commandLine="node.cmd .\startup.js" executionContext="elevated" />
</Startup>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
<InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="certificateName" />
</Endpoints>
<Certificates>
<Certificate name="certificateName" storeLocation="LocalMachine" storeName="My" />
</Certificates>
<Runtime>
<Environment>
<Variable name="PORT">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[#name='HttpIn']/#port" />
</Variable>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
</Environment>
<EntryPoint>
<ProgramEntryPoint commandLine="node.cmd .\server.js" setReadyOnProcessStart="true" />
</EntryPoint>
</Runtime>
</WorkerRole>
</ServiceDefinition>
I have also tried various variations on these (with fewer extra tags and attributes) and nothing seems to work.
The protocol values you provided are HttpIn and HttpsIn. You shall use these values only for ASP.NET Web Roles!! When you run 3rd party web servers on Worker Roles you shall only use tcp as value for protocol attribute!! changing this is the easiest way to make things not working! Could you switch them back to tcp, remove the certificate attribute from the Https Endpoint and try again?
Also, the default sample app server.js listens to only one port. Which is being passed by the environment value PORT defined for the startup task. There you shall reference the HttpsIn endpoint if you want HTTPS traffic. Unfortunately I don't know whether node.js can handle both http AND https traffic with this simple setup.
UPDATE
Please use the following .csconfig file (replace the content of all .csconfig files you see in the folder with the content I provide):
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="*removed*" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WorkerRole name="WorkerRole1" vmsize="ExtraSmall">
<Startup>
<Task commandLine="setup_worker.cmd > log.txt" executionContext="elevated">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
<Variable name="RUNTIMEID" value="node" />
<Variable name="RUNTIMEURL" value="http://az413943.vo.msecnd.net/node/0.8.4.exe" />
</Environment>
</Task>
<Task commandLine="node.cmd .\startup.js" executionContext="elevated" />
</Startup>
<Endpoints>
<InputEndpoint name="HttpsIn" protocol="https" port="443" />
</Endpoints>
<Certificates>
<Certificate name="certificateName" storeLocation="LocalMachine" storeName="My" />
</Certificates>
<Runtime>
<Environment>
<Variable name="PORT">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[#name='HttpsIn']/#port" />
</Variable>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
</Environment>
<EntryPoint>
<ProgramEntryPoint commandLine="node.cmd .\server.js" setReadyOnProcessStart="true" />
</EntryPoint>
</Runtime>
</WorkerRole>
</ServiceDefinition>
Also, please provide the code in your server.js file - at least the first 10 lines where the binding is done. And also after the changes, please execute the following command line and tell us what is the result:
c:>telnet [your_cloud_service].cloudapp.net 443
And also please confirm that you have the .pfx file in the folder where you are executing the powershell commands.

Publish-AzureServiceProject Node.js to Windows Server 2012

I'm trying to publish a Node.js package to Azure using the Powershell "Publish-AzureServiceProject" cmdlet.
With the default osFamily="2" (Windows Server 2008 R2) it works as expected but when I publish using osFamily="3" (Windows Server 2012) I get the following error:
The feature named NetFx35 that is required by the uploaded package is
not available in the OS * chosen for the deployment.
Obviously I'm not using .Net but 3.5 is the default that prevents me to upload the package.
To specify .Net 4.5 I read that I need to create a roleproperties.txt file containing:
TargetFrameWorkVersion=v4.5
and pass it via a /rolePropertiesFile to cspack.
However since I'm not calling cspack myself, how can I pass that option through Publish-AzureServiceProject to cspack? Or is there another workaround?
Currently my ServiceDefinition looks like this:
<?xml version="1.0"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Foo" upgradeDomainCount="1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WorkerRole name="Bar">
<Imports>
<Import moduleName="RemoteForwarder" />
<Import moduleName="RemoteAccess" />
</Imports>
<Startup>
<Task commandLine="setup_worker.cmd > log.txt" executionContext="elevated">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
<Variable name="RUNTIMEID" value="node" />
<Variable name="RUNTIMEURL" value="http://nodertncu.blob.core.windows.net/node/0.6.20.exe" />
</Environment>
</Task>
</Startup>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="tcp" port="80" />
</Endpoints>
<Runtime>
<Environment>
<Variable name="PORT">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[#name='HttpIn']/#port" />
</Variable>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
</Environment>
<EntryPoint>
<ProgramEntryPoint commandLine="runnode.cmd" setReadyOnProcessStart="true" />
</EntryPoint>
</Runtime>
</WorkerRole>
</ServiceDefinition>
So currently, there's a bit of work you need to do to get OSFamily=3 working with non-.Net roles. Essentially, you need to run cspack yourself to create a package and specify a roleProperties file that allows you to target .Net 4.5 (yes, even though you're not using .Net at all, you need to convince the cspack tool that you're using .Net 4.5).
Here are the steps:
Go create a new node project with a web role.
Modify the cscfg to set OS Family = 3.
Drop the below roleproperties.txt into the root of the service.
Launch the "Windows Azure Command Prompt" and then go the service root folder.
Run this command: cspack ServiceDefinition.csdef /role:WebRole1;WebRole1 /sites:WebRole1;Web;WebRole1 /rolePropertiesFile:WebRole1;RoleProperties.txt /out:package.cspkg
Log in to the portal and create a service / upload the cspkg manually
The contents of roleproperties.txt:
TargetFrameworkVersion=v4.5
As Node SDK builds the package without using cspack.exe (to keep platform independent architecture) you can not use "/rolePropertiesFile" option.
As workaround, you can setup the targetFrameworkVersion setting using Runtime -> EntryPoint -> NetFxEntryPoint -> targetFrameworkVersion="v4.5" in your ServiceDefinition as below example:
<?xml version="1.0"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NodeAvkash" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole1" vmsize="ExtraSmall">
<Imports />
<Startup>
<Task commandLine="setup_web.cmd > log.txt" executionContext="elevated">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
<Variable name="RUNTIMEID" value="node;iisnode" />
<Variable name="RUNTIMEURL" value="http://nodertncu.blob.core.windows.net/node/0.6.20.exe;http://nodertncu.blob.core.windows.net/iisnode/0.1.21.exe" />
</Environment>
</Task>
</Startup>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
</Sites>
<Runtime executionContext="elevated">
<EntryPoint>
<NetFxEntryPoint assemblyName="WebRole1.dll" targetFrameworkVersion="v4.5" />
</EntryPoint>
</Runtime>
</WebRole>
</ServiceDefinition>

Azure - permissions running ReportViewer

I'm successfully running a console app on a web role which runs at the correct time, and will send a test email successfully:
net start "task scheduler"
net user scheduler SecretP#ssw0rd /add
net localgroup Administrators scheduler /add
schtasks /create /SC WEEKLY /D THU /ST 17:30 /TN WariCheckNewFeed /TR %~dp0ConsoleAppToCallWebPage.exe /F /RU scheduler /RP SecretP#ssw0rd
Problem: when it gets to:
ReportParameter startAndEndDateStringParam = new ReportParameter("StartAndEndDateString", startAndEndDateString);
LocalReport reportSummaryPDF = new LocalReport();
reportSummaryPDF.ReportPath = "MerchantCampaignSummary.rdlc";
reportSummaryPDF.SetParameters(new ReportParameter[] { campaignName, merchantNameParam, totalRedeemed, startAndEndDateStringParam });
reportSummaryPDF.DataSources.Clear();
reportSummaryPDF.DataSources.Add(datasource1);
reportSummaryPDF.DataSources.Add(datasource2);
I get:
Application: ConsoleAppToCallWebPage.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: Microsoft.Reporting.WinForms.LocalProcessingException
Stack:
at Microsoft.Reporting.WinForms.LocalReport.EnsureExecutionSession()
at Microsoft.Reporting.WinForms.LocalReport.SetParameters(System.Collections.Generic.IEnumerable`1<Microsoft.Reporting.WinForms.ReportParameter>)
at ConsoleAppToCallWebPage.Program.SendMerchantSummaryAndBreakdownReports(System.String, System.Guid, System.Guid)
at ConsoleAppToCallWebPage.Program.Main(System.String[])
DLLS are Version 10 of ReportViewer from my Win7 64 bit machine.
If I RDP onto the Azure web instance, I can successfully run the console app from e:\approot\startuptasks\consoleapptocallwebpage.exe
Feels like permissions!
<WebRole name="Web" vmsize="Small" enableNativeCodeExecution="true">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
<Site name="WebMVCAdmin" physicalDirectory="c:\publishWebMVCAdmin">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" hostHeader="pvadmin8.mateerit.co.nz" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="DiagnosticsConnectionString" />
<Setting name="DataConnectionString" />
<Setting name="SQLAzureRetryCountMaximum" />
<Setting name="SQLAzureRetryDelaymSec" />
</ConfigurationSettings>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="RemoteAccess" />
<Import moduleName="RemoteForwarder" />
</Imports>
<Startup>
<Task commandLine="StartupTasks\addScheduledTaskRunner.cmd" executionContext="elevated" taskType="simple" />
<Task commandLine="StartupTasks\disableTimeout.cmd" executionContext="elevated" />
</Startup>
</WebRole>
The answer was that running as a scheduled task the reportviewer was looking in the wrong directory for the rdlc file!
reportSummaryPDF.ReportPath = #"e:\approot\bin\StartupTasks\myreport.rdlc";
http://blog.smarx.com/posts/windows-azure-startup-tasks-tips-tricks-and-gotchas
http://www.voiceoftech.com/swhitley/index.php/2011/07/windows-azure-task-scheduler/
Running locally on Win7 scheduled tasks helped to debug.

Resources