Inspired by this article, I decided to try DNS-based Environment Determination (DBED).
DBED is an Configuration Management technique by which you can minimize the effort/overhead of maintaining mulitple Technical Operation Environments (DEV, TEST, QA, UAT etc.). The problem that DBED intends to solve is proliferation of configuration changes growing as carthesian product of number-of-Environments times number-of-Dependencies-Between-Services. So if you have 2 environments with 2 web services and a SQL Server, you’d have to manage total of 4 configuration entries. This quickly grows out of hand when you have to manage 20 interrelated services across 5-6 environments. The promise of DBED is to deploy same exact configuration of a service to each of the environment-specific servers and have it know which servers its dependencies live on. Hence the name: environment-aware configuration.
The approach is to create a subdomain for each of the environments (e.g. dev.internal.company.com, qa.internal.company.com etc.) and then in each subdomain create bunch of aliases to various servers, (e.g. mainsql.dev.internal.com –> DB123.internal.company.com, mainsql.qa.internal.com –> DB456.internal.company.com etc.). These aliases (unqualified by the full domain suffix) is what you then point to in your config files. But how to “route” the request to a different subdomain based on the requesting server’s environment? By modifying that server’s DNS suffix sequence! Here’s how (assuming your DNS is on Windows):
First, get your IT/NOC/Admin department’s buy-in and support. Indeed, you’ll need permissions to access your Domain Controller (this is where DNS Server typically runs on) and/or Active Directory (if you take the Group Policy route, more on this later). Alternatively, if you can bring up your own DNS Server and have enough rights to point your non-PROD servers to it, you may be able to stay self-sufficient a bit longer.
Second is to connect to the DNS Server and create new Primary Zone, under one of the subdomains you control. For example in my case we had internal domain called Tech1.Corp.Local under which I created Cloud1.Tech.Corp.Local, Cloud2.Tech.Corp.Local etc. You should also create “Delegation” records in the parent subdomain (Tech.Corp.Local) to point to the same server (unless your CloudX zones will be on a different DNS Server). Simple scenarios (e.g. a client PC directly asking for name resolution) will work even without Delegation records, but more advanced scenarios like recursive queries made by other DNS servers may be broken. Then again, if you are in a complex DNS environment you’ll probably require specialist’s help anyway. Alternatively you can create the environment subdomains directly in the existing zone (Tech.Corp.Local) as opposed to creating bunch of new zones. If you do that you don’t need to create delegation records. It actually does not make hell lot of a difference whether to do subdomains or delegations. With delegations you’ll have an option of easily moving the separate zones to another DNS server whereas with subdomains you’ll have to recreate them by hand.
Third is to create CNAME (Canonical Name) records in your environment zones (or domains) to map your aliases to the actual names of the servers. The reason we’re creating CNAME and not A records is to avoid creating a hard link to the servers’ IP addresses. Instead, CNAME simply redirects DNS lookup from the alias to an existing name. This way your aliases will keep working even if the servers’ IP addresses change. Once you’re done you should have something similar to the picture above. Repeat this for each environment.
Finally, you will need to modify the DNS suffix sequence on each of the servers in each environment. In the Network settings, under TCP/IP 4, Advanced, DNS tab; there’s an option for searching various domains. By default it’s set to use only the primary connection suffix (domain); but you can switch it to use a list you set (make sure you include all the domains you want it to search). When resolving “maindb” without any domain, it’ll iterate through the list until it finds a resolution. Of course, this doesn’t work if you specify a full FQDN in your config file. In my cloud example, my suffix list needs to have Cloud1.Tech1.Corp.Local at the top, followed by Tech1.Corp.Local (followed by my cloud provider’s suffix). With this setup an unqualified name will first try to resolve in the Cloud1, and then in the Tech1. This allows our aliases to map to corresponding environments, while still keeping all other names functional. If RDPing into each server and modifying its DNS settings feels like a pain (which it is!) you may try to use Active Directory’s Group Policies to push the suffix list to corresponding servers. I was told it’s possible but as I have not tried it myself I will “leave it as an exercise” for you. UPDATE: As explained here DNS Suffix Search List can be modified remotely from command line by doing wmic /node:[machine] nicconfig call SetDNSSuffixSearchOrder (Cloud1.Tech.Corp.Local,Tech.Corp.Local) and you can also use wmic /node:[machine] nicconfig get DNSDomainSuffixSearchOrder to verify it.
Once all of the above is done, restarting either of the servers should not be required, just try pinging both your new aliases as well as regular names and make sure everything works. Now point your configs to aliases and enjoy environment-aware configuration!