问题
I have a Python Cloud Service running on Microsoft Azure which should be using a different Storage Account (for blob storage and queues) when it's running in dev vs. staging vs. production.
I'd rather not hard-code the Storage Account credentials, but get them from the environment. Alternatively I would like an environment variable or something that indicates whether I'm in staging or production. When I try print(os.environ)
I don't see any azure storage credentials, nor a value that indicates staging or production.
Is there any way to achieve this?
回答1:
I'm answering my own question, since I've used a combination of solutions to make something that works for me.
I was able to define my settings in multiple ServiceConfiguration files, such as ServiceConfiguration.Local.cscfg
, ServiceConfiguration.Dev.cscfg
and ServiceConfiguration.Production.cscfg
. Under <ConfigurationSettings>
, add <Setting name="settingname" value="settingvalue" />
, or use the interface in Visual Studio. When publishing you can then pick which configuration file to use, without having to modify any code. Added advantage is that these settings can also be modified via the Azure portal after the service has been published. See this post and this post.
The next challenge is to inject these variables into the Python environment. Unlike variables that are defined in ServiceDefinition.csdef
, the configuration settings are not available to the Python environment. They are however stored in a DLL somewhere, can be accessed and injected into the Python environment using some C# method calls (I'm pretty ignorant about this whole process, I just followed this post) . Just add these lines to LaunchWorker.ps1
, anywhere before iex "py $worker_command"
:
# search for the Dll
$Splathashtable = @{
'Path' = "$env:windir\Microsoft.NET\assembly\";
'Filter' = 'Microsoft.WindowsAzure.ServiceRuntime.dll';
'Include' = '*.dll'
}
$dllfile = Get-ChildItem @Splathashtable -Recurse | Select-Object -Last 1
# selecting only one object, in case of multiple results
# add the DLL to the current PowerShell session
Add-Type -Path $dllfile.FullName
# Call the Static method on the class to retrieve the setting value
$Setting = [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetConfigurationSettingValue('settingname')
# add setting to environment
[Environment]::SetEnvironmentVariable('settingname', $Setting)
Now you'll find the setting to be available in Python through os.environ.get('SETTINGNAME')
回答2:
You can set custom runtime variables in ServiceDefinition.csdef
file, then you can invoke it leveraging os.environ.get('MY_ENV_NAME')
.
E.G.
The content of ServiceDefinition.csdef
should be:
<WorkerRole name="WorkerRole1" vmsize="Small">
<ConfigurationSettings>
...
</ConfigurationSettings>
<Startup>
...
</Startup>
<Runtime>
<Environment>
<Variable name="MY_ENV_NAME" value="my_value" />
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
</Variable>
</Environment>
...
</Runtime>
...
</WorkerRole>
You can refer to http://blog.toddysm.com/2011/03/what-environment-variables-can-you-use-in-windows-azure.html for more detail.
来源:https://stackoverflow.com/questions/34591436/azure-environment-variables-in-python-cloud-service