Azure: Is there any way to deploy different instance sizes for test/production

孤街浪徒 提交于 2019-11-27 11:57:16
Igorek

There are a few ways to do this... Simpler way is to do a little "hacking" of the CCPROJ file:

1) create a clone of the CSDEF file for every environment that matches the Configuration Name (Release/Debug/QA/UAT/etc): ServiceDefinition.Release.csdef, ServiceDefinition.Debug.csdef, etc.

2) Add those files manually to the CCPROJ file by using a notepad editor

3) Define a Pre-Build Event command that copies the ServiceDefinition.$(ConfigurationName).csdef into ServiceDefintion.csdef

voila, now your ServiceDefintion will adapt to whatever configuration you're using.

If you want to get fancier or see more details, check out this blog entry that can help you switch all sorts of settings in unison

http://www.paraleap.com/blog/post/Managing-environments-in-a-distributed-Azure-or-other-cloud-based-NET-solution.aspx

Edit: Here is a config that works. Notice that other files are included as type "None" instead of ServiceDefinition to avoid the multiple definitions error.

  <ItemGroup>
    <ServiceConfiguration Include="ServiceConfiguration.Local.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Development 1.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Development 2.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Local Dev 1.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Local Dev 2.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.QA 1.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.QA 2.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Pre-Production 1.cscfg" />
    <ServiceConfiguration Include="ServiceConfiguration.Production.cscfg" />
    <ServiceDefinition Include="ServiceDefinition.csdef" />
    <None Include="ServiceDefinition.Local.csdef" />
    <None Include="ServiceDefinition.Development 1.csdef" />
    <None Include="ServiceDefinition.Development 2.csdef" />
    <None Include="ServiceDefinition.Local Dev 1.csdef" />
    <None Include="ServiceDefinition.Local Dev 2.csdef" />
    <None Include="ServiceDefinition.QA 1.csdef" />
    <None Include="ServiceDefinition.QA 2.csdef" />
    <None Include="ServiceDefinition.Pre-Production 1.csdef" />
    <None Include="ServiceDefinition.Production.csdef" />
  </ItemGroup>

You can use the Web Publishing TransformXml MSBuild task to transform only the parts of the ServiceDefinition you want (like you can do now with Web.Config).

  • Create a ServiceDefinition.[BuildConfigName].csdef file next to the ServiceDefinition.csdef file (you'll probably need to do this in File Explorer)
  • Create the transform file like you'd created a Web.config transform. I explicitly set the root namespace, just in case, so my root element is:
  <ServiceDefinition name="Cloud.JobsWorker" 
          xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" 
          xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
          schemaVersion="2013-10.2.2">
  • Manually add it to your ccproj using:
  <ServiceDefinition Include="ServiceDefinition.csdef" />
  <None Include="ServiceDefinition.Release.csdef" />
  • At the bottom of your project include:
  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <PropertyGroup>
    <ServiceDefinitionTransform>ServiceDefinition.$(Configuration).csdef</ServiceDefinitionTransform>
  </PropertyGroup>
  <Target Name="TransformServiceDefinition" BeforeTargets="ResolveServiceDefinition" Condition="exists('$(ServiceDefinitionTransform)')">
    <!-- Generate transformed service config in the intermediate directory -->
    <TransformXml Source="@(ServiceDefinition)" Destination="$(IntermediateOutputPath)%(Filename)%(Extension)" Transform="$(ServiceDefinitionTransform)" />
    <!--Force build process to use the transformed configuration file from now on.-->
    <ItemGroup>
      <ServiceDefinition Remove="ServiceDefinition.csdef" />
      <ServiceDefinition Include="$(IntermediateOutputPath)ServiceDefinition.csdef" />
    </ItemGroup>
  </Target>

When you package or publish your cloud app, your csdef should be transformed depending on the build config you're using.

This is adapted from here: http://blogs.staykov.net/2011/06/windows-azure-configuration-settings.html

Kobynet

Using transformation as David Faivre suggested is much cleaner and without the overhead to update all files after adding single property.

This is the transformation xml for changing vm size:

<?xml version="1.0"?>
<ServiceDefinition name="CloudServiceName" 
                   xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6" 
                   xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <WorkerRole name="WorkerRoleName.Role" vmsize="Medium" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</ServiceDefinition>

VM size is handled in the ServiceDefinition.csdef file, which is something you can't edit at run or deploy time. You would need to change the setting in the .csdef, repackage your solution, and then redeploy.

One solution may be to have multiple Windows Azure deployment projects set up. One project would be your "test" project that has the .csdef configured to use a XS. Another project would be the "production" project that uses a larger instance. This would allow you to use the standard Windows Azure / Visual Studio tools to manage the project - which may be nice depending on your process.

Oleksii Iaroshchuk

David Faivre proposed a good solution. Few comments from me:

  1. If your ServiceDefinition file contains links to some directories (e.g. section), than there will be an error caused by the fact that transformed file is in intermediate directory. For my use I solved this problem by placing transformed file alongside original ServiceDefinition.csdef (don't forget to add *.transformed into .gitignore):

<TransformXml Source="@(ServiceDefinition)" Destination="ServiceDefinition.csdef.transformed" Transform="$(ServiceDefinitionTransform)" />

  1. $(Configuration) variable corresponds to Build configuration (Debug, Release etc.). If you want to have profile specific transformation (corresponding to ServiceConfiguration..cscfg), you need to use $(TargetProfile) variable:

<ServiceDefinitionTransform>ServiceDefinition.$(TargetProfile).csdef</ServiceDefinitionTransform>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!