<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Zhiliang Xu's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/zhiliang_xus_blog/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/zhiliang_xus_blog/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:10:50 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Run Shadowsocks in Azure Container Instances</title>
      <link>https://docs.microsoft.com/archive/blogs/zhiliang_xus_blog/run-shadowsocks-in-azure-container-instances</link>
      <pubDate>Thu, 04 Jan 2018 05:51:17 GMT</pubDate>
      <dc:creator><![CDATA[Zhiliang Xu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/zhiliang_xus_blog/?p=45</guid>
      <description><![CDATA[VPN is very useful in mainland China, and Shadowsocks is a popular proxy server. Now that...]]></description>
      <content:encoded><![CDATA[VPN is very useful in mainland China, and <a href="https://shadowsocks.org">Shadowsocks</a> is a popular proxy server. Now that <a href="https://hub.docker.com/r/oddrationale/docker-shadowsocks/">Shadowsocks has docker support</a>, and we can host docker containers on Azure, it becomes very easy to deploy Shadowsocks on Azure. In this post, I'll show you how to deploy a Shadowsocks server on <a href="https://azure.microsoft.com/en-us/services/container-instances/">Azure Container Instances</a> in <strong>just one command</strong>.

I assume that you already have an Azure subscription at hand and there is at least one <a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-portal">resource group</a> in it. <a href="https://azure.microsoft.com/en-in/free/">Create a free one</a> if you haven't yet.

To run the command to create a running Shadowsocks server, go to <a href="https://portal.azure.com">Azure Portal</a>, click the Cloud Shell icon in the top bar.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/cloud_shell_icon.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/01/cloud_shell_icon.png" alt="Cloud Shell Icon" class="alignnone size-medium" /></a>

In the Cloud Shell that pops up at the bottom, make sure <strong>Bash</strong> is selected since the command is in Azure CLI. Type the below command.
<pre>az container create -g shadowsocks --name shadowsocks1 --image oddrationale/docker-shadowsocks --ip-address public --ports 8388 --command-line "/usr/local/bin/ssserver -k password1"</pre>
<a href="https://msdnshared.blob.core.windows.net/media/2018/01/cloud_shell_cmd2.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/01/cloud_shell_cmd2.png" alt="Cloud Shell Command" class="alignnone size-medium" /></a>

In the above command,
<ul>
 	<li><a href="https://docs.microsoft.com/en-us/cli/azure/container"><code>az container create</code></a> indicates Azure to create an Azure Container Instance.</li>
 	<li><code>-g shadowsocks</code> specifies the resource group name. My resource group name is shadowsocks, but yours can be different. The resource group has to be in West US, East US or West Europe, since Azure Container Instance is not available in other regions yet.</li>
 	<li><code>--name shadowsocks1</code> specifies the container instance's name. Yours can be different.</li>
 	<li><code>--image oddrationale/docker-shadowsocks</code> specifies to use the Docker image <a href="https://hub.docker.com/r/oddrationale/docker-shadowsocks/">oddrationale/docker-shadowsocks</a> on Docker Hub.</li>
 	<li><code>--ip-address public</code> The IP address of the container instance must be public so that you can connect to it from your client phone or desktop.</li>
 	<li><code>--ports 8388</code> Opens port 8388 to the public, which is the port where Shadowsocks server works on by default. It is equivalant to <code>-e 8388 -p 8388:8388</code> if you use <code>docker run</code> command.</li>
 	<li><code>--command-line "/usr/local/bin/ssserver -k password1"</code> indicates to run ssserver (Shadowsocks server) when the container starts. <code>-k password1</code> specifies the password when you connect to the server. Use your own strong password (don't use simple ones, and avoid special characters like '$').</li>
</ul>
Running the above script in Cloud Shell will return a JSON object, which means the creation is successful.

To verify that the Shadowsocks server is running well, navigate to the container group that you created and check its <strong>STATE</strong>. It should be <strong>Running</strong> if everything went smooth. Remember the IP address, which you will use when you connect to the server.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/container_running1.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/01/container_running1.png" alt="Container Running" class="alignnone size-medium" /></a>

With just one command, we've got a Shadowsocks server running in Azure Container Instance.

Just for completeness, I'll show you how to use connect to the server from iOS.
<ol>
 	<li>Install <a href="https://itunes.apple.com/us/app/shadowrocket/id932747118">Shadowrocket</a> from App Store. When first run, you need to grant permission to the app to write VPN settings. Other Shadowsocks client apps also work.</li>
 	<li>Add a server and fill in the <strong>Host</strong>, <strong>Port</strong> and <strong>Password</strong> fields accordingly. Leave other fields as default.</li>
 	<li>Toggle the connect button to connect to the Shadowsocks server.</li>
 	<li>Now you can open Google from mainland China!</li>
</ol>
<img src="https://msdnshared.blob.core.windows.net/media/2018/01/WeChat-Image_20180104115941.png" alt="Add Server" class="alignnone size-medium" width="240" /> <img src="https://msdnshared.blob.core.windows.net/media/2018/01/WeChat-Image_20180104115949.png" alt="Connect" class="alignnone size-medium" width="240" /> <img src="https://msdnshared.blob.core.windows.net/media/2018/01/WeChat-Image_20180104132409.png" alt="Google" class="alignnone size-medium" width="240" />]]></content:encoded>
    </item>
    <item>
      <title>Build a Google Reverse Proxy Site on Azure Web App in Less than 3 Minutes</title>
      <link>https://docs.microsoft.com/archive/blogs/zhiliang_xus_blog/build-a-google-reverse-proxy-site-on-azure-web-app-in-less-than-3-minutes</link>
      <pubDate>Tue, 19 Jan 2016 05:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Zhiliang Xu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/zhiliang_xus_blog/2016/01/19/build-a-google-reverse-proxy-site-on-azure-web-app-in-less-than-3-minutes/</guid>
      <description><![CDATA[Recently I live in China, where many popular websites, such as Google and Facebook, are not...]]></description>
      <content:encoded><![CDATA[<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Recently I live in China, where many popular websites, such as Google and Facebook, are not accessible. So I write this article to share the easiest way to make these sites accessible by using Microsoft Azure. I'll use Google as the example.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">In this article, I will first explain why I choose to use Azure Web App, which is followed by the step-by-step guidance. And finally, the article ends with explanation about the configurations indetail.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-size: large;font-weight: bold">There Are Many Ways to Make These Sites Accessible</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">1. Set up a </span><a href="http://blogs.msdn.com/b/lighthouse/archive/2013/07/30/how-deploy-sstp-and-l2tp-vpn-in-windows-azure-windows-server-2012.aspx"><span style="font-family: Calibri;font-size: 11pt">VPN by using Azure Virtual Machine</span></a><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">.</span></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">2. Create an </span><a href="https://azure.microsoft.com/en-us/documentation/articles/cdn-create-new-endpoint/"><span style="font-family: Calibri;font-size: 11pt">Azure CDN</span></a><span style="font-family: Calibri;font-size: 11pt"> with Google as the origin server.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">3. Host a REST service, such as </span><a href="http://stackoverflow.com/questions/25145098/how-to-set-up-web-api-routing-for-a-proxy-controller"><span style="font-family: Calibri;font-size: 11pt">Web API</span></a><span style="font-family: Calibri;font-size: 11pt">, on Web Role or Web App as a relay.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">4. Use </span><a href="http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing"><span style="font-family: Calibri;font-size: 11pt">ARR and URL Rewrite modules</span></a><span style="font-family: Calibri;font-size: 11pt"> in IIS to set up a reverse proxy service in a virtual machine.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">5. Use </span><a href="http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing"><span style="font-family: Calibri;font-size: 11pt">ARR and URL Rewrite modules</span></a><span style="font-family: Calibri;font-size: 11pt"> to build a reverse proxy service Web App.</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Approach 1 is the ultimate solution, which allows you to access any public website (be aware of DNS cache poisoning, though). However it requires you to create a virtual machine and purchase a certificate if you want to share it with others. Not everyone likes it.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Approach 2 is simple but it doesn't work for server redirection or references to the backend server with absolute URL.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Approach 3 requires to write some code, which can be tedious.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Approach 4 also requires to create a virtual machine, which is more expensive.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Approach 5 is the most lightweight approach. So I will share this approach in detail. How lightweight it is? Well, nothing other than a web browser is required, and you don't even need an Azure subscription to go through the steps below.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-size: large;font-weight: bold">When Do You Want to Build A Reverse Proxy on Azure Web App?</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">1. The backend website is publicly accessible from Azure, but is not accessible in your region.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">2. You can access Microsoft Azure global instance.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">3. You have an Azure subscription (global instance) or you are willing to create one.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">4. You probably want to share the site with others.</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-size: large;font-weight: bold">Step-by-step Guidance</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">(If you already have an Azure subscription, and know <a href="https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-get-started/">how to create a Web App</a>, you can go to step 3 directly.)</p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">1. Go to </span><a href="https://tryappservice.azure.com"><span style="font-family: Calibri;font-size: 11pt">https://tryappservice.azure.com</span></a><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal"> in your web browser. In</span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: bold"> Select your app</span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal"> section, choose </span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: bold">Web App</span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">, and click </span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: bold">Next</span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal"> button.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8117.Select_your_app.png" alt="" border="0" /></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">2. In </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Select a template and create your Web App</span><span style="font-family: Calibri;font-size: 11pt"> section, choose </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Empty Site</span><span style="font-family: Calibri;font-size: 11pt">, and click </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Create</span><span style="font-family: Calibri;font-size: 11pt"> button. When asked to log in, use your Microsoft Account.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1777.Select_a_template_and_create_your_Web_App.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1777.Select_a_template_and_create_your_Web_App.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">3. Now your web app is created. In my case, it is </span><a href="https://efe73b37-0ee0-4-231-b9ee.azurewebsites.net/"><span style="font-family: Calibri;font-size: 11pt">https://efe73b37-0ee0-4-231-b9ee.azurewebsites.net/</span></a><span style="font-family: Calibri;font-size: 11pt"> (it is a temporary one, and won't be available when you read this article). I will use "xyz" to replace the "efe73b37-0ee0-4-231-b9ee" part below. You will have a similar one which is different in the first part of the domain name. </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Don't visit your new site yet!</span><span style="font-family: Calibri;font-size: 11pt"> If you happen to do so, refer to steps a-d.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0257.Your_web_app_has_been_created.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0257.Your_web_app_has_been_created.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">4. Go to the SCM (</span><a href="http://blogs.msdn.com/b/benjaminperkins/archive/2014/03/24/using-kudu-with-windows-azure-web-sites.aspx"><span style="font-family: Calibri;font-size: 11pt">Kudu</span></a><span style="font-family: Calibri;font-size: 11pt">) site of your web app: </span><a href="https://xzy.scm.azurewebsites.net/"><span style="font-family: Calibri;font-size: 11pt">https://xzy.scm.azurewebsites.net/</span></a><span style="font-family: Calibri;font-size: 11pt">. Not that you need to insert "scm." before "azurewebsite.net". This is the administration site for your web app.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">5. Navigate to </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Debug console -</span><span style="font-family: Calibri;font-size: 11pt">&gt; </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">CMD</span><span style="font-family: Calibri;font-size: 11pt">.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0358.Debug_console_CMD.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0358.Debug_console_CMD.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">6. Navigate to </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">site</span><span style="font-family: Calibri;font-size: 11pt"> folder.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4784.site.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4784.site.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">7. In the CMD console, run </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">echo 1 &gt; applicationHost.xdt</span><span style="font-family: Calibri;font-size: 11pt"> to create the applicationHost.xdt file.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2425.create_applicationHost.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2425.create_applicationHost.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">8. You will see the file </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">applicationHost.xdt  </span><span style="font-family: Calibri;font-size: 11pt">created. Click the </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Edit</span><span style="font-family: Calibri;font-size: 11pt"> icon to edit it.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4276.edit_applicationHost.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4276.edit_applicationHost.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">9. Replace all contents in the editor with below text (also available </span><a href="https://github.com/zhiliangxu/reverse_proxy/blob/master/applicationHost.xdt"><span style="font-family: Calibri;font-size: 11pt">here</span></a><span style="font-family: Calibri;font-size: 11pt">). Then click the </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Save</span><span style="font-family: Calibri;font-size: 11pt"> button.</span></p>

<pre class="scroll"><code class="html"> &lt;?xml version="1.0"?&gt;
 &lt;configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"&gt;
 &lt;system.webServer&gt;
 &lt;proxy xdt:Transform="InsertIfMissing" enabled="true" preserveHostHeader="false" reverseRewriteHostInResponseHeaders="false" /&gt;
 &lt;rewrite&gt;
 &lt;allowedServerVariables&gt;
 &lt;add name="HTTP_ACCEPT_ENCODING" xdt:Transform="InsertIfMissing" /&gt;
 &lt;add name="HTTP_X_ORIGINAL_HOST" xdt:Transform="InsertIfMissing" /&gt;
 &lt;/allowedServerVariables&gt;
 &lt;/rewrite&gt;
 &lt;/system.webServer&gt;
 &lt;/configuration&gt;</code></pre>
<span><strong>Note</strong> revised on 1/14/2018, changing <code class="html">Insert</code> to <code class="html">InsertIfMissing</code> for <code class="html">HTTP_ACCEPT_ENCODING</code> and <code class="html">HTTP_X_ORIGINAL_HOST</code> as advised by David Ebbo.</span>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2210.save_applicationHost.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2210.save_applicationHost.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">10. Navigate to </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">wwwroot</span><span style="font-family: Calibri;font-size: 11pt"> folder.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8228.wwwroot.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8228.wwwroot.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">11. In the CMD console, run </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">echo 1 &gt; web.config</span><span style="font-family: Calibri;font-size: 11pt"> to create the web.config file.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1373.create_webconfig.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1373.create_webconfig.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">12. You will see the file </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">web.config </span><span style="font-family: Calibri;font-size: 11pt">created. Click the </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Edit</span><span style="font-family: Calibri;font-size: 11pt"> icon to edit it.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7870.edit_webconfig.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7870.edit_webconfig.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">13. Replace all contents in the editor with below text (also available </span><a href="https://github.com/zhiliangxu/reverse_proxy/blob/master/web.config"><span style="font-family: Calibri;font-size: 11pt">here</span></a><span style="font-family: Calibri;font-size: 11pt">). Then click the </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Save</span><span style="font-family: Calibri;font-size: 11pt"> button.</span></p>

<pre class="scroll"><code class="html">&lt;configuration&gt;
 &lt;system.webServer&gt;
 &lt;httpErrors errorMode="Detailed" /&gt;
 &lt;rewrite&gt;
 &lt;rules&gt;
 &lt;rule name="ForceSSL" stopProcessing="true"&gt;
 &lt;match url="^(.*)" /&gt;
 &lt;conditions&gt;
 &lt;add input="{HTTPS}" pattern="^off$" ignoreCase="true" /&gt;
 &lt;/conditions&gt;
 &lt;action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /&gt;
 &lt;/rule&gt;
 &lt;rule name="ProxyGStatic" stopProcessing="true"&gt;
 &lt;match url="^gstatic/(.*)" /&gt;
 &lt;action type="Rewrite" url="https://encrypted-tbn1.gstatic.com/{R:1}" /&gt;
 &lt;serverVariables&gt;
 &lt;set name="HTTP_ACCEPT_ENCODING" value="" /&gt;
 &lt;set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" /&gt;
 &lt;/serverVariables&gt;
 &lt;/rule&gt;
 &lt;rule name="ProxySSLGStatic" stopProcessing="true"&gt;
 &lt;match url="^sslgstatic/(.*)" /&gt;
 &lt;action type="Rewrite" url="https://ssl.gstatic.com/{R:1}" /&gt;
 &lt;serverVariables&gt;
 &lt;set name="HTTP_ACCEPT_ENCODING" value="" /&gt;
 &lt;set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" /&gt;
 &lt;/serverVariables&gt;
 &lt;/rule&gt;
 &lt;rule name="Proxy" stopProcessing="true"&gt;
 &lt;match url="(.*)" /&gt;
 &lt;action type="Rewrite" url="https://www.google.com.sg/{R:1}" /&gt;
 &lt;serverVariables&gt;
 &lt;set name="HTTP_ACCEPT_ENCODING" value="" /&gt;
 &lt;set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" /&gt;
 &lt;/serverVariables&gt;
 &lt;/rule&gt;
 &lt;/rules&gt;
 &lt;outboundRules&gt;
 &lt;preConditions&gt;
 &lt;preCondition name="IsHTML"&gt;
 &lt;add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" /&gt;
 &lt;/preCondition&gt;
 &lt;preCondition name="IsJson"&gt;
 &lt;add input="{RESPONSE_CONTENT_TYPE}" pattern="^application/json" /&gt;
 &lt;/preCondition&gt;
 &lt;/preConditions&gt;
 &lt;rule name="ChangeReferencesToOriginalUrl" preCondition="IsHTML"&gt;
 &lt;match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^https://www.google.com.sg/(.*)" /&gt;
 &lt;action type="Rewrite" value="https://{HTTP_X_ORIGINAL_HOST}/{R:1}" /&gt;
 &lt;/rule&gt;
 &lt;rule name="ChangeReferencesToOriginalUrlInJson" patternSyntax="ExactMatch" preCondition="IsJson"&gt;
 &lt;match pattern="www.google.com.sg" /&gt;
 &lt;action type="Rewrite" value="{HTTP_X_ORIGINAL_HOST}" /&gt;
 &lt;/rule&gt;
 &lt;rule name="ChangeGStaticReferencesToOriginalUrl" preCondition="IsHTML"&gt;
 &lt;match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^https://encrypted-tbn[0-9].gstatic.com/(.*)" /&gt;
 &lt;action type="Rewrite" value="https://{HTTP_X_ORIGINAL_HOST}/gstatic/{R:1}" /&gt;
 &lt;/rule&gt;
 &lt;rule name="ChangeGStaticReferencesToOriginalUrlInJson" preCondition="IsJson"&gt;
 &lt;match pattern="encrypted-tbn[0-9]\.gstatic\.com" /&gt;
 &lt;action type="Rewrite" value="{HTTP_X_ORIGINAL_HOST}/gstatic" /&gt;
 &lt;/rule&gt;
 &lt;rule name="ChangeSSLGstaticReferencesToOriginalUrl" patternSyntax="ExactMatch" preCondition="IsHTML"&gt;
 &lt;match pattern="ssl.gstatic.com" /&gt;
 &lt;action type="Rewrite" value="{HTTP_X_ORIGINAL_HOST}/sslgstatic" /&gt;
 &lt;/rule&gt;
 &lt;rule name="RewriteBackendRelativeUrlsInRedirects" preCondition="IsHTML"&gt;
 &lt;match serverVariable="RESPONSE_LOCATION" pattern="^https://www.google.com.sg/(.*)" /&gt;
 &lt;action type="Rewrite" value="https://{HTTP_X_ORIGINAL_HOST}/{R:1}" /&gt;
 &lt;/rule&gt;
 &lt;/outboundRules&gt;
 &lt;/rewrite&gt;
 &lt;/system.webServer&gt;
 &lt;/configuration&gt;</code></pre>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3733.save_webconfig.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3733.save_webconfig.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">14. Now you can browse </span><a href="https://xyz.azurewebsites.net/"><span style="font-family: Calibri;font-size: 11pt">https://xyz.azurewebsites.net/</span></a><span style="font-family: Calibri;font-size: 11pt">. Voila! The main page of Google is displayed. </span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8015.Google.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8015.Google.png" alt="" border="0" /></a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">If you have visited the site before editing applicationHost.xdt file, you need to do the following steps to restart the web app, since applicationHost.xdt is only processed when the web app starts.</p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">a. Navigate to </span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: bold">Process Explorer</span><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal">.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt;font-style: normal;font-weight: normal"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5432.Process_explorer.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5432.Process_explorer.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">b. Press </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Properties..</span><span style="font-family: Calibri;font-size: 11pt"> button for the w3wp.exe (the one without "scm").</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4621.Process_explorer_properties.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4621.Process_explorer_properties.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">c. In the Properties pop up window, press the red </span><span style="font-family: Calibri;font-size: 11pt;font-weight: bold">Kill</span><span style="font-family: Calibri;font-size: 11pt"> button.</span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7888.kill.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7888.kill.png" alt="" border="0" /></a></span></p>
<p style="margin-top: 0px;margin-bottom: 0px;vertical-align: middle"><span style="font-family: Calibri;font-size: 11pt">d. Now you can visit </span><a href="https://efe73b37-0ee0-4-231-b9ee.azurewebsites.net/"><span style="font-family: Calibri;font-size: 11pt">https://efe73b37-0ee0-4-231-b9ee.azurewebsites.net/</span></a><span style="font-family: Calibri;font-size: 11pt">. Refresh for several times (with Ctrl + F5 in IE to avoid content caching) if you still see the old page. The w3wp.exe process will be recreated automatically when you visit the site.</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-size: large;font-weight: bold">Explanations in Detail</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">The reverse proxy Web App works in the way illustrated as below.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8468.BigPicture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8468.BigPicture.png" alt="" border="0" /></a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">User sends the request to your web app <a href="https://xyz.azurewebsites.net">https://xyz.azurewebsites.net</a>. When the request reaches your web app, the URL rewrite rules configured in your web app kick in. The request's URL is changed to <a href="https://www.google.com">https://www.google.com</a>, Accept-Encoding HTTP header is cleared, and then the modified request is forwarded to Google.
Google sends back the uncompressed response to your web app. Your web app scans the response and replaces references from <a href="https://www.google.com/*">https://www.google.com/*</a> to <a href="https://xyz.azurewebsites.net/*">https://xyz.azurewebsites.net/*</a>, as well as other minor changes, and then sends back the modified response to the user. The users see the response as if your web app hosts a clone of Google site.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold">Step 1-3:</span> A Web App created with <a href="https://tryappservice.azure.com/">Try Azure App Service</a> lasts for only one hour for you to play with. If you find this approach useful, why not start with a <a href="https://azure.microsoft.com/en-us/pricing/free-trial/">free Azure subscription</a> today?</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold">Step 7: ApplicationHost.xdt</span> is an Web App extension for you to transform the ApplicationHost.config file of your website. For more details, read <a href="https://azure.microsoft.com/en-us/documentation/articles/web-sites-transform-extend/">this article</a>.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold">Step 9:</span> The <span style="font-weight: bold">proxy </span>tag is to enable revere proxy functionality of <a href="http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing">Application Request Routing</a>. The <span style="font-weight: bold">allowedServerVariables </span>tag is to enable server variables to be set in URL Rewrite rules. I will discuss URL Rewrite rules in detail when explaining step 13. Without this <span style="font-weight: bold">allowedServerVariables </span>tag, you will get URL Write Module Error such as 'The server variable "HTTP_ACCEPT_ENCODING" is not allowed to be set. Add the server variable name to the allowed server variable list.'</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8877.url_rewrite_module_error.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8877.url_rewrite_module_error.png" alt="" border="0" /></a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold">Step 13: Web.config</span> file is used mainly to describe URL Rewrite rules. See <a href="http://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference">this article</a> for how to write rules for URL Rewrite 2.0.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-weight: bold">httpErrors</span> tag is to turn on debug information in case there is any URL Rewrite module error. The rules, except ForceSSL, in <span style="font-weight: bold">rules</span> (inbound rules) tag define how the web request is pre-processed before forwarded to Google.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ForceSSL</span> is to redirect HTTP traffic to HTTPS endpoint for your site.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ProxyGStatic</span> is to rewrite URL of <a href="https://xyz.azurewebsites.net/gstatic/*">https://xyz.azurewebsites.net/gstatic/*</a> to <a href="https://encrypted-tbn1.gstatic.com/*">https://encrypted-tbn1.gstatic.com/*</a>. This is used together with the outbound rules <span style="font-weight: bold">ChangeGStaticReferencesToOriginalUrl </span>and <span style="font-weight: bold">ChangeGStaticReferencesToOriginalUrlInJson</span>. <span style="font-weight: bold">ProxySSLGStatic</span> is for similar purpose.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">Proxy</span> is to rewrite URL of <a href="https://xyz.azurewebsites.net/*">https://xyz.azurewebsites.net/*</a> to <a href="https://www.google.com/*">https://www.google.com/*</a>. This is the key of the configurations. All other rules are just to improve user experience of the web app.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">The <span style="font-weight: bold">serverVariables</span> tags in inbound rules are used to clear the Accept-Encoding HTTP header and save the host name. It is important to clear the Accept-Encoding HTTP header, or otherwise you cannot execute outbound rules since the content returned by Google is compressed. I configured <span style="font-weight: bold">allowedServerVariables</span> in<span style="font-weight: bold"> applicationHost.xdt</span> so that these server variables can be set in URL Rewrite rules.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">The rules in <span style="font-weight: bold">outboundRules</span> tag defines how the web responses from Google are post-processed in the web app before sent back to user.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ChangeReferencesToOriginalUrl</span> is to change references (such as hyperlinks, images) to Google in the HTML responses to go through your web app.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ChangeReferencesToOriginalUrlInJson</span> is to change all references to Google in JSON responses to your web app.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ChangeGStaticReferencesToOriginalUrl</span> is to change references (such as hyperlinks, images) to <a href="https://encrypted-tbn[0-9].gstatic.com/*">https://encrypted-tbn[0-9].gstatic.com/*</a> in the HTML responses to <a href="https://xzy.azurewebsites.net/gstatic/*">https://xzy.azurewebsites.net/gstatic/*</a> virtual directory of your web app. It is supported by the <span style="font-weight: bold">ProxyGStatic </span>inbound rule.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ChangeGStaticReferencesToOriginalUrlInJson</span> is to change all references to <a href="https://encrypted-tbn[0-9].gstatic.com/*">https://encrypted-tbn[0-9].gstatic.com/*</a> in JSON responses to the <a href="https://xzy.azurewebsites.net/gstatic/">https://xzy.azurewebsites.net/gstatic/*</a> virtual directory of your web app. It is supported by the <span style="font-weight: bold">ProxyGStatic </span>inbound rule.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">ChangeSSLGstaticReferencesToOriginalUrl</span> is to change all references to ssl.gstatic.com to the <a href="https://xzy.azurewebsites.net/sslgstatic/*">https://xzy.azurewebsites.net/sslgstatic/*</a> virtual directory of your web app. It is supported by the <span style="font-weight: bold">ProxySSLGStatic </span>inbound rule.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">Rule <span style="font-weight: bold">RewriteBackendRelativeUrlsInRedirects</span> is to change location of 301/302 redirection to your web app if it is originally <a href="https://www.google.com/*">https://www.google.com/*</a>.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt">The two pre-conditions in <span style="font-weight: bold">preCondition</span> tag, <span style="font-weight: bold">IsHTML</span> and <span style="font-weight: bold">IsJson</span>, are used by the outbound rules to check if the response content type is HTML or JSON, respectively.</p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><span style="font-size: large;font-weight: bold">References</span></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="https://tomssl.com/2015/06/15/create-your-own-free-reverse-proxy-with-azure-web-apps/">https://tomssl.com/2015/06/15/create-your-own-free-reverse-proxy-with-azure-web-apps/</a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="http://ruslany.net/2014/05/using-azure-web-site-as-a-reverse-proxy/">http://ruslany.net/2014/05/using-azure-web-site-as-a-reverse-proxy/</a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="http://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference">http://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-20-configuration-reference</a></p>
<p style="margin: 0in;font-family: Calibri;font-size: 11pt"><a href="http://stackoverflow.com/questions/15926203/iis-as-a-reverse-proxy-compression-of-rewritten-response-from-backend-server">http://stackoverflow.com/questions/15926203/iis-as-a-reverse-proxy-compression-of-rewritten-response-from-backend-server</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Build a test environment of SQL Server 2012 AlwaysOn Availability Group from scratch</title>
      <link>https://docs.microsoft.com/archive/blogs/zhiliang_xus_blog/build-a-test-environment-of-sql-server-2012-alwayson-availability-group-from-scratch</link>
      <pubDate>Mon, 03 Mar 2014 19:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Zhiliang Xu]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/zhiliang_xus_blog/2014/03/03/build-a-test-environment-of-sql-server-2012-alwayson-availability-group-from-scratch/</guid>
      <description><![CDATA[Recently I started learn SQL Server 2012 AlwaysOn Availability Group (AG). After reading some online...]]></description>
      <content:encoded><![CDATA[Recently I started learn SQL Server 2012 AlwaysOn Availability Group (AG). After reading some online documents, I couldn't wait to create my own Availability Group to practice it. Meanwhile, I had lots of trials and failures and learned a lot of new knowledge, and that's why I want to share the process. If you are also new to AG and want to get your hands wet with it, just follow me:)

Overall, there are 3 steps.
<ul>
	<li>Install Windows Servers and setup a test domain.</li>
	<li>Setup a Windows Failover Cluster.</li>
	<li>Create an AlwaysOn Availability Group.</li>
</ul>
Why do I need to setup a test domain? Well, because the title contains words "from scratch". And, more importantly, I don't have permission to create failover cluster object on my corporate domain. I believe that's the common case for most of the developers in a big company. So, let's start the details with server and domain setup. If you already have 2 servers in the same domain ready to use,<em> and</em> you also have permission to create Failover Clusters, you can skip step 1.

<strong>1. Install Windows Servers and setup a test domain</strong>

1.1. Install 3 servers with <strong>Windows Server 2012 R2 Datacenter </strong>edition. Name them <strong>SqlTestDC</strong>, <strong>SqlTest01</strong> and <strong>SqlTest02</strong>. <strong>SqlTestDC </strong>is the domain controller, while <strong>SqlTest01</strong> and <strong>SqlTest02</strong> are the AG replicas. I host all these 3 servers on my Hyper-V server.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5707.HyperV.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5707.HyperV.png" alt="" border="0" /></a>

1.2 Create the test Active Directory forest on <strong>SqlTestDC</strong>. Log on <strong>SqlTestDC</strong>, start <strong>PowerShell</strong> <strong>as Administrator</strong>, and run the below commands.
<pre class="scroll"><code class="csharp">Get-WindowsFeature AD-Domain-Services | Install-WindowsFeature
</code><code class="csharp">Get-WindowsFeature RSAT-ADDS-Tools | Install-WindowsFeature
Import-Module ADDSDeployment 
Install-ADDSForest -DomainName <span style="background-color: #ffff00">SqlTestDOM.contoso.com</span> -DomainNetbiosName <span style="background-color: #ffff00">SqlTestDOM</span> -DomainMode Win2012 -ForestMode Win2012 -DatabasePath "C:\Windows\NTDS" -SysvolPath "C:\Windows\SYSVOL" -LogPath "C:\Windows\NTDS" -InstallDns:$true -SafeModeAdministratorPassword $(ConvertTo-SecureString "<span style="background-color: #ffff00">&lt;password&gt;</span>" -AsPlainText -Force) -NoRebootOnCompletion:$false -Force</code></pre>
You can replace the highlighted parts with your own values. For the password, make it complex enough, "V3RYstr0n9Pa$$w0rd" is a good example.

SqlTestDC will be rebooted automatically and after that, log on it by user <span style="color: #000000"><strong>SqlTestDOM\Administra</strong>t<strong>or</strong>.</span>

<span style="color: #000000">To learn more about the parameters in creating an Active Directory forest, refer to this help page: <a href="http://technet.microsoft.com/library/hh974720(v=wps.620).aspx">http://technet.microsoft.com/library/hh974720(v=wps.620).aspx</a></span><span style="color: #000000">. To learn more about the Windows feature identifiers, refer to this document: <a href="http://technet.microsoft.com/en-us/library/cc732757.aspx">http://technet.microsoft.com/en-us/library/cc732757.aspx</a>.</span>

<span style="color: #000000">1.3 Change the <strong>DNS server</strong> for <strong>SqlTest01</strong> and <strong>SqlTest02</strong> to the IP address of <strong>SqlTestDC</strong>. Suppose that the IPv4 address of SqlTestDC is 157.59.140.111, then the DNS server address on SqlTest01 and SqlTest02 should be changed to 157.59.140.111.</span>

<span style="color: #000000"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8468.SqlTest01DNS.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8468.SqlTest01DNS.png" alt="" border="0" /></a></span>

<span style="color: #000000">1.4 Join <strong>SqlTest01</strong> and <strong>SqlTest02</strong> to <strong>SqlTestDOM.contoso.com</strong> domain. When prompt for credential, use <strong>SqlTestDOM\Administrator</strong>. After joined to <strong>SqlTestDOM.contoso.com</strong> domain, the System page of SqlTest01 should look like below screenshot. SqlTest02 is similar.</span>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2502.SqlTest01System.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2502.SqlTest01System.png" alt="" border="0" /></a>

After restarting, log on to SqlTest01 and SqlTest02 as user <strong>SqlTestDOM\Administrator</strong>.

1.5 Turn off<strong> Windows Firewall</strong> on all the three servers. This is a shortcut to avoid connection failure when setting up AG. This is valid only on test servers. On your production servers, open required ports instead.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7245.SqlTest01Firewall.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7245.SqlTest01Firewall.png" alt="" border="0" /></a>

<strong>2. Setup a Windows Failover Cluster</strong>

<span style="color: #000000">2.1 Install <strong>Failover Clustering</strong> feature on <strong>SqlTest01</strong> and <strong>SqlTest02</strong>. In Server Manager, click<strong> Add Roles and Features</strong>, and check <strong>Failover Clustering</strong> feature and click <strong>Next</strong> and then <strong>Install</strong>.</span>

<span style="color: #000000"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1300.SqlTest01FailoerClusteringFeature.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1300.SqlTest01FailoerClusteringFeature.png" alt="" border="0" /></a></span>

2.2 After Failover Clustering feature is installed on SqlTest01 and SqlTest02, go to SqlTest01 and open <strong>Failover Cluster Manager</strong>. Right click <strong>Failover Cluster Manager </strong>node, and select <strong>Validate Configuration...</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7462.SqlTest01FailoverClusterManager.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7462.SqlTest01FailoverClusterManager.png" alt="" border="0" /></a>

2.3 Follow the <strong>Validate a Configuration Wizard</strong>. Add <strong>SqlTest01</strong> and <strong>SqlTest02</strong> to <strong>Selected servers</strong>, and click <strong>Next</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1207.SqlTest01SelectServers.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1207.SqlTest01SelectServers.png" alt="" border="0" /></a>

2.4 Select <strong>Run all tests (recommended)</strong> in <strong>Testing Options</strong> page and press <strong>Next</strong>, and <strong>Next</strong> again on the <strong>Confirmation</strong> page.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4405.SqlTest01TestingOptions.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4405.SqlTest01TestingOptions.png" alt="" border="0" /></a>

2.5 Now tests are running to validate the failover cluster.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3583.SqlTest01Validating.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3583.SqlTest01Validating.png" alt="" border="0" /></a>

2.6 The validation summary will be shown shortly. Click <strong>View Report...</strong> to check if there is any error.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0336.SqlTest01Summary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0336.SqlTest01Summary.png" alt="" border="0" /></a>

In the validation report I got, there are several warnings, which relate to network and disk. They are not critical. So I just move on with Failover Cluster creation. Here is the validation report I got <a href="http://msdnblog.blob.core.windows.net/sqlag/FailoverClusterValidationReport.mht">http://msdnblog.blob.core.windows.net/sqlag/FailoverClusterValidationReport.mht</a>

2.7 Make sure that <strong>Create the cluster now using the validated nodes...</strong> is checked on the summary page above. Click <strong>Finish</strong> to create the Windows Failover Cluster.

2.8 Follow <strong>Create Cluster Wizard</strong>. On <strong>Access Point for Administering the Cluster</strong> page, input your desired <strong>Cluster Name</strong>. I use <strong>SqlTest</strong>. Click <strong>Next</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7318.SqlTest01ClusterName.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7318.SqlTest01ClusterName.png" alt="" border="0" /></a>

2.8 On the Confirmation page, make sure that <strong>Add all eligible storage to the cluster</strong> is checked, and click <strong>Next</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3487.SqlTest01ClusterConfirmation.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3487.SqlTest01ClusterConfirmation.png" alt="" border="0" /></a>

2.9 Now <strong>Create Cluster Wizard</strong> is creating the new cluster for you.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6558.SqlTest01CreatingNewCluster.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6558.SqlTest01CreatingNewCluster.png" alt="" border="0" /></a>

Wait for a while and you will be told that "<strong>You have successfully completed the Create Cluster Wizard</strong>". Click <strong>View Report...</strong> to view the report, and then click <strong>Finish</strong> to dismiss the wizard. Here is the report that I got <a href="http://msdnblog.blob.core.windows.net/sqlag/CreateClusterSummaryReport.mht">http://msdnblog.blob.core.windows.net/sqlag/CreateClusterSummaryReport.mht</a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7206.SqlTest01CreatingClusterSummary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7206.SqlTest01CreatingClusterSummary.png" alt="" border="0" /></a>

Congratulation! Now you have created a failover cluster! One big step closer to the success of Availability Group creation:)

2.10 Now you can view the cluster <strong>SqlTest.SqlTestDOM.contoso.com</strong> in <strong>Failover Cluster Manager</strong>, on both <strong>SqlTest01</strong> and <strong>SqlTest02</strong>. And <strong>SqlTest01</strong> and <strong>SqlTest02 </strong>are in the<strong> Nodes </strong>of the failover cluster. Note that we only finished the Create Cluster Wizard on SqlTest01.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6840.SqlTest02SqlTestCluster.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6840.SqlTest02SqlTestCluster.png" alt="" border="0" /></a>

2.11 (Optional) add a <strong>file share quorum</strong> to the failover cluster. It is necessary if you want your AG to support failover with data loss. Right click on the cluster name <strong>SqlTest.SqlTestDOM.contoso.com</strong>, and select <strong>More Actions</strong> &gt; <strong>Configure Cluster Quorum Settings</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0815.SqlTest01ConfigureClusterQuorumSettings.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0815.SqlTest01ConfigureClusterQuorumSettings.png" alt="" border="0" /></a>

Follow the Configure Cluster Quorum Wizard.

On <strong>Select Quorum Configuration Option</strong> page, choose <strong>Select the quorum witness</strong>, and click <strong>Next</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7455.SqlTest01SelectQuorumOption.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7455.SqlTest01SelectQuorumOption.png" alt="" border="0" /></a>

Create a share folder on SqlTestDC, and make sure Read/Write permissions are granted to SqlTestDOM\Administrator. Input the <strong>File Share Path</strong> on <strong>Configure File Share Witness</strong> page. I use<strong> <a href="//\\SQLTESTDC\Users\Administrator\Documents\Share">\\SQLTESTDC\Users\Administrator\Documents\Share</a></strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0028.SqlTest01FileShareWitness.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0028.SqlTest01FileShareWitness.png" alt="" border="0" /></a>

Click <strong>Next</strong> on <strong>Confirmation</strong> page.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7711.SqlTest01ConfirmFileShareWitness.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7711.SqlTest01ConfirmFileShareWitness.png" alt="" border="0" /></a>

You will be told that "<strong>You have successfully configured the quorum settings for the cluster</strong>" shortly.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3326.SqlTest01ConfigureClusterQuorumSettingsSummary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3326.SqlTest01ConfigureClusterQuorumSettingsSummary.png" alt="" border="0" /></a>

We are done with the failover cluster creation and configuration at this moment. Let's move on to SQL Server installation and AG creation, which is the most exciting part!

<strong>3. Create an AlwaysOn Availability Group</strong>

3.1 Install <strong>SQL Server 2012 Enterprise Edition</strong> on <strong>SqlTest01</strong> and <strong>SqlTest02</strong>. According to "Features Supported by the Editions of SQL Server 2012" (<a href="http://msdn.microsoft.com/en-us/library/cc645993.aspx">http://msdn.microsoft.com/en-us/library/cc645993.aspx</a>), <strong>SQL Server 2012 Enterprise Edition</strong> is the only choice.

3.2 After installation of <strong>SQL Server 2012 Enterprise Edition</strong>, change the Log On account of SQL Server to SqlTestDOM\Administrator. To do so, open <strong>SQL Server Configuration Manager</strong>, choose <strong>SQL Server Services</strong>, and right click <strong>SQL Server (MSSQLSERVER)</strong>, choose<strong> Properties</strong> in the context manual.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0312.SqlTest01SQLServerProperty.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0312.SqlTest01SQLServerProperty.png" alt="" border="0" /></a>

Under <strong>Log On </strong>tab, select <strong>This account:</strong>, and input <strong>SqlTestDOM\Administrator</strong> and its password.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6013.SqlTest01ChangeSQLAccount.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6013.SqlTest01ChangeSQLAccount.png" alt="" border="0" /></a>

3.3 Verify that the <strong>AlwaysOn Availability Group</strong> is enabled on <strong>SqlTest01</strong> and <strong>SqlTest02</strong>. To do so, open <strong>SQL Server Configuration Manager</strong>, choose <strong>SQL Server Services</strong>, and right click <strong>SQL Server (MSSQLSERVER)</strong>, choose<strong> Properties</strong> in the context manual, and <strong>SQL Server (MSSQLSERVER)\Properties</strong>. Under <strong>AlwaysOn High Availability</strong> tab, ensure that the <strong>Enable AlwaysOn Availability Groups</strong> check box is checked.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6232.SqlTest01EnableAG.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6232.SqlTest01EnableAG.png" alt="" border="0" /></a>

3.4 Connect to SQL Server engine on <strong>SqlTest01</strong> via<strong> SQL Server Management Studio. </strong>Create a database on <strong>SqlTest01</strong>. Name it <strong>AGTest01</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0003.SqlTest01NewDB.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0003.SqlTest01NewDB.png" alt="" width="173" height="179" border="0" /></a>

3.5 Right click database node <strong>AGTest01</strong>, click <strong>Properties…</strong>, and go to <strong>Options</strong> page. Change the <strong>Recovery model</strong> to <strong>Full</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3487.SqlTest01DBFullRecovery.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3487.SqlTest01DBFullRecovery.png" alt="" border="0" /></a>

3.6 Create a full backup for <strong>AGTest01</strong>. Right click database node <strong>AGTest01</strong>, click <strong>Task</strong> &gt; <strong>Back Up…</strong>. Leave the settings on <strong>Back Up Database - AGTest01</strong> as their default values, and click <strong>OK</strong>. When prompted that the backup was created successfully, click <strong>OK</strong> to dismiss.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3034.SqlTest01BackUpDB.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3034.SqlTest01BackUpDB.png" alt="" border="0" /></a>

3.7 Finally, we are ready to create the first Availability Group. Whew...

On <strong>SqlTest01</strong>, right click <strong>AlwaysOn High Availability</strong>, and click <strong>New Availability Group Wizard…</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0842.SqlTest01NewAG.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0842.SqlTest01NewAG.png" alt="" border="0" /></a>

On the <strong>Specify Name</strong> page, insert the <strong>Availability group name</strong> that you like. I will call it <strong>MyAG01</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0513.SqlTest01NewAGSpecifyName.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/0513.SqlTest01NewAGSpecifyName.png" alt="" border="0" /></a>

Check database <strong>AGTest01</strong> on <strong>Select Databases</strong> page. Only databases with Full Recovery Model and a full back up meet the requirements to join an Availability Group.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3022.SqlTest01NewAGSelectDatabases.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3022.SqlTest01NewAGSelectDatabases.png" alt="" border="0" /></a>

On <strong>Specify Replica</strong> page, add <strong>SqlTest01</strong> and <strong>SqlTest02</strong> to <strong>Replicas</strong> tab. Don't worry about the Automatic Failover and Synchronous Commit settings at this moment. You will be able to configure them after the AG is created.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6505.SqlTest01NewAGSpecifyReplicas.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6505.SqlTest01NewAGSpecifyReplicas.png" alt="" border="0" /></a>

Make sure that the <strong>Endpoint URL</strong>s in <strong>Endpoints</strong> tab are using port <strong>5022</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4520.SqlTest01NewAGEndpoints.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4520.SqlTest01NewAGEndpoints.png" alt="" border="0" /></a>

Leave the default settings in <strong>Backup References</strong> tab unchanged.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6866.SqlTest01NewAGBackupPreferences.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6866.SqlTest01NewAGBackupPreferences.png" alt="" border="0" /></a>

On <strong>Listener</strong> page, input the <strong>Listener DNS Name </strong>you like (I use <strong>MyAG01</strong>), input 1433 as Port, <strong>DHCP</strong> as <strong>Network Mode</strong>, and choose the IPv4 subnet. I choose to use DHCP because I don't have the permission to reserve a static IP address in the DHCP server.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1134.SqlTest01NewAGListener.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1134.SqlTest01NewAGListener.png" alt="" border="0" /></a>

On <strong>Select Data Synchronization</strong> page, <strong>choose</strong> Full and specify a <strong>shared network location</strong>. I use a share folder on SqlTestDC, but you can use anyone as long as the SQL Server service account has read and write permissions to that share folder.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1033.SqlTest01NewAGInitDataSync.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1033.SqlTest01NewAGInitDataSync.png" alt="" border="0" /></a>

Run validations on <strong>Validation</strong> page. Make sure there is no error.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5556.SqlTest01NewAGValidation.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5556.SqlTest01NewAGValidation.png" alt="" border="0" /></a>

On <strong>Summary</strong> page, you can get the SQL script to create the AG by clicking <strong>Script</strong> &gt; <strong>File...</strong>. Here is the script that I got <a href="http://msdnblog.blob.core.windows.net/sqlag/NewAvailabilityGroup.sql">http://msdnblog.blob.core.windows.net/sqlag/NewAvailabilityGroup.sql</a>.

Click <strong>Finish</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4478.SqlTest01NewAGSummary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4478.SqlTest01NewAGSummary.png" alt="" border="0" /></a>

Wow! You have successfully created your first Availability Group! Click <strong>Close</strong> on the <strong>Results</strong> page.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2781.SqlTest01NewAGResults.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2781.SqlTest01NewAGResults.png" alt="" border="0" /></a>

3.8 If you go to the <strong>Failover Cluster Manager</strong> on <strong>SqlTest01</strong> and <strong>SqlTest02</strong>, you will find that there is an entry named <strong>MyAG01</strong> created automatically under the <strong>Nodes</strong> of the failover cluster <strong>SqlTest.SqlTestDOM.contoso.com</strong>. The name <strong>MyAG01</strong> matches the one we specified for <strong>Listener DNS Name</strong> when we created the AG.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8562.SqlTest01FailoverClusterManagerNewRole.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8562.SqlTest01FailoverClusterManagerNewRole.png" alt="" border="0" /></a>

3.9 Open <strong>DNS Manager</strong> on <strong>SqlTestDC</strong>, and you will find a new Host (A) has been created automatically. Its name, <strong>MyAG01</strong>, matches the <strong>Listener DNS Name</strong> when we used when creating the AG.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1104.SqlTestDCDNSManager.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/1104.SqlTestDCDNSManager.png" alt="" border="0" /></a>

3.10 You can <strong>ping</strong> <strong>MyAG01</strong> within your local network. The ping can succeed only when the Primary replica is alive. That means it is the primary replica server that is responding.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3771.SqlTestDCPingMyAG01.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/3771.SqlTestDCPingMyAG01.png" alt="" border="0" /></a>

3.11 View <strong>SqlTest01</strong> and <strong>SqlTest02</strong> from <strong>SQL Server Management Studio</strong>. Note that <strong>SqlTest01</strong> is the <strong>Primary</strong> server in the AG, while <strong>SqlTest02</strong> is the <strong>Secondary</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7282.SqlTest0102AG.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7282.SqlTest0102AG.png" alt="" border="0" /></a>

3.12 If you attempt to expand the database node <strong>AGTest01</strong> on <strong>SqlTest02</strong>, you will get an error that "The database AGTest01 is not accessible." That is because Readable Secondary is set to "No" for SqlTest02.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2043.SqlTest02DBNotAccessible.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/2043.SqlTest02DBNotAccessible.png" alt="" border="0" /></a>

3.13 Let's do a failover now. On <strong>SqlTest01</strong>, right click the node <strong>MyAG01</strong> (Primary), and select <strong>Failover...</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4466.SqlTest01Failover.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/4466.SqlTest01Failover.png" alt="" border="0" /></a>

On the <strong>Select New Primary Replica</strong> page, you will see a warning. By <strong>clicking Data loss, Warnings(1)</strong>, the details of the warning is displayed. It complains about that replica SqlTest02 has some databases that are not synchronized. That's because we left the <strong>Synchronous Commit</strong> box unchecked on the <strong>Specify Replica </strong>page in step 3.7. Although it is still possible to do a failover with data loss, let's cancel the failover now. Click the <strong>Cancel</strong> button.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5430.SqlTest01FailoverSelectNewPrimary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5430.SqlTest01FailoverSelectNewPrimary.png" alt="" border="0" /></a>

3.14 Right click the AG node <strong>MyAG01 (Primary)</strong> on <strong>SqlTest01</strong>. On the <strong>General</strong> page, change the <strong>Availability Mode</strong> to <strong>Synchronous commit</strong> for <strong>SqlTest02</strong>. Click <strong>OK</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8371.SqlTest02SyncCommit.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8371.SqlTest02SyncCommit.png" alt="" border="0" /></a>

3.15 Now, if you try to failover again, there will be no warnings.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5618.SqlTest01FailoverNoDataLoss.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/5618.SqlTest01FailoverNoDataLoss.png" alt="" border="0" /></a>

Click <strong>Next</strong>. On <strong>Connect to Replica</strong> page, click <strong>Connect...</strong> and connect to <strong>SqlTest02</strong> with account <strong>SqlTestDOM\Administrator</strong>. The <strong>Next</strong> button is not enabled until you are able to connect to SqlTest02.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8284.SqlTest01FailoverConnect.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/8284.SqlTest01FailoverConnect.png" alt="" border="0" /></a>

On the Summary page, you can save the SQL script for AG failover by selecting <strong>File</strong> &gt; <strong>Script...</strong>. Here is the script I got <a href="http://msdnblog.blob.core.windows.net/sqlag/AGFailover.sql">http://msdnblog.blob.core.windows.net/sqlag/AGFailover.sql</a>

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7181.SqlTest01FailoverSummary.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/7181.SqlTest01FailoverSummary.png" alt="" border="0" /></a>

Click <strong>Finish</strong> and the failover will complete shortly.

<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6505.SqlTest01FailoverResults.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/63/97/6505.SqlTest01FailoverResults.png" alt="" border="0" /></a>

3.16 Let's write some C# code to connect to the database in AG MyAG01. Assume that you've created a table called Table1 in database AGTest01.
<pre class="scroll"><code class="csharp">public static void Main(string[] args)
</code><code class="csharp">{
 string connectionString = "Data Source=<span style="background-color: #ffff00">MyAG01</span>;Initial Catalog=AGTest01;Connection TimeOut=60;Max Pool Size=1000;Integrated Security=SSPI;persist security info=False";

 using (SqlConnection connection = new SqlConnection(connectionString))
 {
 connection.Open();
 Console.WriteLine("DataSource: {0}", connection.DataSource);
 
 using (SqlCommand sqlCommand = connection.CreateCommand())
 {
 sqlCommand.CommandText = "SELECT * FROM Table1";
 sqlCommand.CommandType = CommandType.Text;
 
 sqlCommand.ExecuteReader();
 }
 }
 }</code></pre>
Run this application on SqlTestDC, and you will see the output is "<strong>MyAG01</strong>", i.e., the Listener DNS name. BTW, that is different from SQL Mirroring, in which the DataSource is the current principal server.

3.17 Now you can play with Availability Group by yourself. Try various <strong>Availability Mode</strong>s, <strong>Failover Mode</strong>s, replica readability settings, adding more databases and/or more replicas, etc. Before that, don't forget to take a checkpoint for the servers, so that you can rollback to the current status easily. Enjoy!]]></content:encoded>
    </item>
  </channel>
</rss>