Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps

Visual Clues to Website Environment Under IIS

4.95/5 (4 votes)
27 Mar 2018CPOL4 min read 8.6K  
Detection and reporting of website environment under IIS
This tip demonstrates how to link the environment to the IIS webserver. An alternative (or additional) may be to query some other attribute such as the database connection string.

Introduction

Most real-world websites exist in more than one environment - typically at least development, some form of test, and production. However, when using the site, it's not always apparent which of these environments is being displayed. Non-technical users may not take note of URLs, or a development machine may have DNS mapping so that the URL is identical to a live environment. This article describes one way to have pages identify the site version they're running from (using site-specific colours, logos or texts) whilst removing any need to modify source or configuration files when promoting source through the environments.

Background

Changing source code when migrating between environments (e.g., development to QA, User Acceptance to Production) always introduces risk, creates additional work and effectively negates some of the benefits of testing. However, having pages identical in appearance across environments can also be a major risk, especially where staff have access to more than one environment. Live data can be lost if people assume the site is a test version, or important live updates can be left languishing uselessly in test systems.

This article demonstrates a simple method of firstly detecting the actual environment (based on IIS' site ID), and then using CSS within a site's master page(s) to make some distinctive change(s) dependent on site, such as piece of text on each page, or changing the page background colour. Such changes bring the user's attention to the site they've connected to, particularly if it is one they would not normally access.

Here is identical code running on two different website instances in IIS:

Running in the development environment   Running in the production environment

Internet Information Services (IIS) assigns a numeric ID to each website being served by that instance. So where a single server hosts development, UAT and production sites (for example), you can be sure of unique instance IDs for each site. Where multiple servers are involved (either different servers for each environment, or in a web farm scenario), then it may be necessary to create some "dummy" websites - which need not even be active - to ensure IDs are unique between environments. When using webfarms, you may find multiple IDs relate to the same environment; that's fine and can be dealt with by using the appropriate CSS selectors.

Using the Code

There are effectively two steps to implementing this functionality.

First, identify the IIS website ID. This is trivial, since it's available via the INSTANCE_ID server variable in the Request object:

VB.NET
dim ServerEnvironment As String = Request.ServerVariables("INSTANCE_ID")

To avoid having to code this in every page, I put this code in the Master page. In fact, it's not even necessary to put it in code behind, since we do nothing with it other than include the instance ID as a class name for the page's BODY tag:

HTML
// BODY tag in the site's master pa
<body class="SITE<%=Request.ServerVariables("INSTANCE_ID") %>">

Here, we append the website instance ID to the classname for the body tag.

Having got the instance ID into the body's classname, we can now use CSS to make some site-specific changes so the user can identify the environment they're working in. It's up to you - and your users - how you go about this, but here are some suggestions (that assume the CSS is in a file included in all the site's pages)... in these examples, site ID 20 is the development environment, 24 is UAT, and 28 is production.

CSS
/* Selectors only present in DEV system */
.SITE20 {                                                    
    background-color: lightcyan;                   /* change BODY element background colour */
}
.SITE20 header .logo {
    background-image:url(/images/devsite.png);/* change the logo in the header element */
}
.SITE20 header .logo:after {
    content:'DEVELOPMENT SYSTEM';             /* Include some explicit text after logo */
    position:fixed;
    top:10px;
    right:10px;
}

/* Selectors only present in UAT system */
.SITE24 {                                                    
    background-color: lightyellow;
}
.SITE24 header .logo {
    background-image:url(/images/uatsite.png);
}
.SITE24 header .logo:after {
    content:'UAT SYSTEM';
    position:fixed;
    top:10px;
    right:10px;
}

/* Selectors only present in PRD system */
.SITE28 {                                                    
    background-color: white;
}
.SITE28 header .logo {
    background-image:url(/images/prodsite.png);
}
.SITE28 header .logo:after {
    content:'PRODUCTION SYSTEM';
    position:fixed;
    top:10px;
    right:10px;
}

Each site will, to ensure minimal changes between sites, include all three versions of the logo in its /images/ folder.

If running in a webfarm with multiple IDs per environment (e.g., production environment is in instance ID 28 on one server, but ID 14 on another), just adjust the CSS selectors accordingly, e.g.

CSS
.SITE28, .SITE14

Finally, it may be worth adding some "default" CSS that will display an "unknown" environment tag if there's no CSS selector matching the current instance ID; this will help flag up that the code is running in an unexpected environment or that there's been a change to the IIS configuration.

CSS
/* No site selector; will be overridden by more specific CSS if site exists */
body {
    background-color: blue;
}
header .logo { 
    background-image:url(/images/unknownsite.png);
}
header .logo:after { 
    content:'UNKNOWN SYSTEM';
    color: red;
    position:fixed;
    top:10px;
    right:10px;
}

Points of Interest

It's probably best to keep the visual indications reasonably subtle, yet clear enough to be noticeable if "out of the ordinary". As a developer, you will be used (in the above example) to seeing a pale cyan background; if you see pale yellow or white, it will seem "different" and you'll be aware you are dealing with live data.

If using a textual indicator, (typically via an ":after" pseudo-element), then it may be best to use position:fixed so that the text is always visible on-screen even when content is scrolled.

This tip demonstrates linking the environment to the IIS webserver. An alternative (or additional) may be to query some other attribute such as the database connection string. This can provide some reassurance that the system identified through the URL is pointing at the correct database; nothing worse than having your UAT system inadvertently pointed to your live database!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)