Back to Top

Deploying ASP.NET and Windows Service Applications with Otter

This tutorial is outdated. This was originally written is for Otter v2, which is not the current version of Otter. Stay tuned, an updated tutorial will be coming soon!

This tutorial will walk through the process of deploying a Windows Service application package from a ProGet Universal Feed to a server that will be set up and provisioned within Otter. A simple application setup like this is often the first step towards incremental adoption of a robust, Infrastructure as Code practice.

Packaging up an Application

Before deploying an application using Otter, you need to bundle all of the executables, DLL’s, configuration files, installation scripts, etc. Anything the application needs will be put into a package.

  • This is most easily done by directly packaging your executables as part of a build process in a build tool like Jenkins
  • You can also use proget.exe, or your own script to create a Universal Package (.upack) file.
  • You can also use OctoPack, installed on a project-by-project basis from within Visual Studio.
  • You can also get your package in ProGet manually by uploading the file from the ProGet web UI, or by simply placing it in the drop folder for ProGet to pick up.

Once a package is created, simply push it to the Feed Endpoint URL in ProGet using NuGet.exe, proget.exe, or a simple HTTP POST.

Note: if you publish an OctoPacked NuGet package, it will be automatically converted by the ProGet server to a Universal Package.

However the package gets there, the end result will look something like this:

ProGet User Interface

Using Otter to Deploy the Service

After Otter has been downloaded and installed, start by adding resource credentials.

The first is the ProGet endpoint (in case you set it up as an authenticated feed), and the second is the Windows or Active Directory account that the service will un under (alternatively, you can just configure the service to use Network Service instead).

  1. Admin > Resources Credentials
  2. Create Credential > ProGet > Save Credential
  3. (Optional) Create Credential > Windows > Save Credential

After creating the resource credentials, simply add the local server (or configure an agent on a remote server) and then create a configuration plan for that server.

  1. Servers > Create Server
  2. Name it localhost and select “Local” for the “Agent type:” > Save Server
  3. Click on newly created server
  4. Under Configuration Plan, click “create” link

Otter makes it easy to create configuration plans using its visual editor, allowing you to drag-and-drop elements to create a plan and only edit the parts you need. Otter’s Ensure Windows Service, Ensure IIS App Pool, and other operations offer all of the configuration options available, allowing for total control when needed.

Otter Configuration Interface

A sample plan is shown below using four elements contained in a General Block that will deploy this service. Notice that there is parity between the Visual Editor version and the OtterScript version.

Otter Visual Editor OtterScript example

As soon as you save this plan, Otter’s execution engine will first perform a “collection run.”

In this run, the ensure operations will only gather configuration from a server, and then store that configuration and report if it is different from the desired configuration. Since this is the first time the configuration is run, this will put server in drift status.

Servers in Drift

From there, you can schedule a job to remediate the drift. When a remediation job is run, the “blocks” where configuration drift was detected will run. So in this case, the first step will be to stop the service so that the changed files can be copied as needed. Since the last operation is Ensure-Service, and we want to ensure the Status is Running, the service will be restarted as its final step.

A server can also be set to auto-remediate, so that any time configuration is drifted, Otter will automatically run the entire plan again to bring the drifted servers back into the expected status.

Since this deployment is happening in an Infrastructure as Code methodology, and using ensure statements, it is continuously monitored. In short, an ensure statement:

  1. defines a desired state of configuration
  2. gathers configuration information from a server
    1. If the actual and desired configuration differ
    2. Then configures or otherwise changes something on a server

This means if a new version of the application is pushed to ProGet, because the Ensure-Package statement was used with the qualifier latest, Otter will see that the configuration on the server is not as defined, and the server will be considered in drift status. At this point, redeploying just takes a remediation job, or can be set to auto-remediate.

On the same note, if you change a setting in the application’s .config file (note: this could also be defined as an environment, role, or server variable), it will also cause a drift status.

Next Infrastructure as Code steps with Otter

This tutorial is just a quick preview of what an Infrastructure as Code methodology can offer; from here, there’s a lot more to explore!

Server Roles

In the example above, a single server was directly configured; however, it would have been just as easy to create the plan as a server role plan to allow for provisioning multiple servers at the same time with the same plan, and increased flexibility.

Using Assets & Templates

Templates are plans stored as assets that can be executed by other plans similar to calling a function in traditional code. Combined with the power of variables and resource credentials, templates can be used to ensure various configurations with minimal duplication across server or server role configuration plans.

Drift Status Notice

As noted, Otter continuously monitors your servers for configuration drift and can either:

  • only report drift, noting specifically which items differ from the desired state
  • automatically remediate drift, and bring the server to the desired configuration state

This option is configurable per server, and monitoring can be set at specific intervals, determined by your infrastructure priority.

When report only is configured, you can schedule a configuration job to run immediately or at some time in the future.

You can even run a configuration job as a simulation, so that no changes are made to the drifted server, but a log is created with changes that would have been made. This is often a must-have for complex, or multi-role configurations to assist in testing, but might not be needed for simple applications.

Not just for Windows Services and ASP.NET Applications

Of course, a plan like this isn’t limited to .NET and Windows; it would be the same for any application package in any language.

Jenkins, TeamCity, and other CI tools can bundle files into formats that can easily be .upack formatted and then stored in ProGet, allowing for easy expansion no matter what build platform is being used.