<?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>Mani Bindra’s Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/manibindra/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/manibindra/feed.xml</link>
    <description>“Much to Learn, there still is. “ – Master Yoda</description>
    <lastBuildDate>Wed, 17 Apr 2019 04:06:53 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Setting up vscode to use the docker extension with bash for windows as terminal shell</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/setting-up-vscode-to-use-the-docker-extension-with-bash-for-windows-as-terminal-shell</link>
      <pubDate>Wed, 01 Nov 2017 20:49:16 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=475</guid>
      <description><![CDATA[I have been using the vscode with the docker extension on my MAC for quite some time now. I wanted...]]></description>
      <content:encoded><![CDATA[I have been using the <strong>vscode</strong> with the <strong>docker extension</strong> on my MAC for quite some time now. I wanted to replicate similar setup on my <strong>windows</strong> machine, using my preferred <strong>bash shell</strong> as the integrated <strong>vscode terminal shell</strong>. After making the configurations described in this post you will be able to execute command like <strong>docker-compose</strong> from within <strong>vscode</strong> (using the <strong>docker extension</strong>) and the <strong>docker</strong> commands will be executed by <strong>vscode</strong> in <strong>bash</strong> for windows as the terminal shell. I use this very often for running docker-compose to check application is working fine when composed (inner loop of containerized development) on my dev machine, and after verifying that it is working fine I commit and push / submit pull request to the git branch from where the image builds and other flows are triggered (outerloop of containerized development). The animated gif below shows what the final outcome after the configurations described in the rest of this post are done.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/outcome-optimized.gif"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/outcome-optimized.gif" alt="" width="80%" height="auto" class="alignnone size-full wp-image-485" /></a>

For this post I am assuming that you are using a <strong>windows 10</strong> machine, you have vscode installed and you have docker engine running on your windows machine ( using <strong>docker</strong> for <strong>windows</strong> or <strong>docker-machine</strong> or <strong>minikube</strong>). Following configurations need to be done:
<ol>
 	<li><strong>Enable bash for windows</strong> : Follow the steps mentioned in <a target="_blank" href="https://msdn.microsoft.com/en-us/commandline/wsl/install-win10?f=255&amp;MSPPError=-2147217396" rel="noopener noreferrer">Enable bash for Windows</a>. Once you have bash has been configured we can proceed with the next steps.<br class="spacer_" /><br class="spacer_" /></li>
 	<li><strong>Installing docker client for bash on windows</strong>: Follow the steps mention in <a target="_blank" href="https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#install-docker-ce-1" rel="noopener noreferrer">Install docker client for bash on windows</a>. The commands executed by me are shown below (please follow link for latest instructions)<code>
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo apt-get update
sudo apt-get install docker-ce
</code><br class="spacer_" /></li>
 	<li><strong>Installing docker-compose for bash on windows</strong>: Follow the steps mention in <a target="_blank" href="https://docs.docker.com/compose/install/#install-compose" rel="noopener noreferrer">Install docker-compose in bash on windows</a>. The commands executed by me are shown below (please follow link for latest instructions)<code>
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
</code><br class="spacer_" /></li>
 	<li><strong>Configuring bash using .bashrc to connect to the docker daemon running on the windows machine</strong>: This step will differ depending on how the docker engine is running on your machine, i.e. whether you are using docker for windows, docker-machine, or minikube. If you dont have any of these then would recommend you install docker for windows following the steps mentioned in the link <a href="https://docs.docker.com/docker-for-windows/install/" rel="noopener" target="_blank">Install docker for windows</a>. Depending on the engine you will need to make different enteries in your ~/.bashrc file, lets take a look:<br class="spacer_" />
<ul><br class="spacer_" />
 	<li>If using <strong>minikube</strong>: We first fire the command <strong>minikube docker-env</strong> command, and then set the corresponding environment variables in our bash for windows ~/.bashrc file. You can execute the following minikube command from cmdshell , powershell or gitbash i.e. from where ever you normally execute minikube commands <br class="spacer_" /><code>
$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="C:\Users\username\.minikube\certs"
export DOCKER_API_VERSION="1.23"
# Run this command to configure your shell:
# eval $(minikube docker-env)
</code> Now we set corresponding values in the ~/bashrc file. We will need to change the value of the DOCKER_CERT_PATH, as C:\ is mounted as /mnt/c for bash on windows .
<code>
# value set at bottom of ~/.bashrc
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/mnt/c/Users/username/.minikube/certs"
export DOCKER_API_VERSION="1.23"
</code><br class="spacer_" /></li>
 	<li>If using <strong>docker for windows</strong>: In this case first we can open docker for windows settings and enable the "
Expose daemon on tcp://localhost:2375 without TLS" option (Note when enabling this you need to aware about possibility of remote execution attacks). Once this option has been enabled you can add the following to the end of the ~/.bashrc file <code>
export DOCKER_HOST=tcp://0.0.0.0:2375
</code><br class="spacer_" /></li>
 	<li>if using <strong>docker-machine</strong>: Similar to the minikube steps we will first execute <strong>docker-machine env machine-name</strong> command, and then set the environment variables in the ~/.bashrc file. <code>
$ docker-machine env dmach
SET DOCKER_TLS_VERIFY=1
SET DOCKER_HOST=tcp://192.168.99.102:2376
SET DOCKER_CERT_PATH=C:\Users\username\.docker\machine\machines\dmach
SET DOCKER_MACHINE_NAME=dmach
SET COMPOSE_CONVERT_WINDOWS_PATHS=true
REM Run this command to configure your shell:
REM     @FOR /f "tokens=*" %i IN ('docker-machine env dmach') DO @%i
</code>. We will modify the DOCKER_CERT_PATH and then set the environment variables as follows:
<code>
# value set at bottom of ~/.bashrc
export DOCKER_TLS_VERIFY=1
export DOCKER_HOST=tcp://192.168.99.102:2376
export DOCKER_CERT_PATH=/mnt/c/Users/username/.docker/machine/machines/dmach
export DOCKER_MACHINE_NAME=dmach
export COMPOSE_CONVERT_WINDOWS_PATHS=true
</code><br class="spacer_" /></li>
</ul>
We can verify if we have configured this step correctly by <strong>opening a new bash shell</strong> and typing <strong>docker ps</strong>, this should show us the currently running containers.</li>
 	<li><strong>Installing the vscode docker extension</strong>: You can read more about the vscode docker extension at <a href="https://github.com/Microsoft/vscode-docker" target="_blank">vscode docker extension</a>. To install you can press F1 in vscode and type "ext install vscode-docker". Alternately you can use the vscode extensions tab to install the extension.</li>
 	<li><strong>Configuring vscode to use bash as the default terminal shell</strong>: Press Ctrl+, or go File-&gt;Preferences-&gt;Settings. Then add the value below to the JSON file <code>"terminal.integrated.shell.windows": "C:\\Windows\\sysnative\\bash.exe"</code>. After this step if you open up a new terminal in vscode a bash shell should open up.  <a href="https://msdnshared.blob.core.windows.net/media/2017/11/vscode-setting.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/11/vscode-setting.png" alt="" width="80%" height="auto" class="alignnone size-full wp-image-505" /></a> . </li>
</ol>

That is it, configuration done. You can now type <strong>Ctrl+Shift+P</strong> type <strong>docker</strong>, this will show you the possible docker commands including docker-compose command to execute, once the command is selected it will get executed it will get executed in the vscode bash shell.

Thanks for reading my post. I hope you liked it. Please feel free to write your comments and views about the same over here or at <a href="https://twitter.com/maniSbindra">@manisbindra</a>.]]></content:encoded>
    </item>
    <item>
      <title>Using the VSTS Packer Task and Replace Tokens Task</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/using-the-vsts-packer-task-and-replace-tokens-task</link>
      <pubDate>Thu, 24 Aug 2017 20:46:52 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=455</guid>
      <description><![CDATA[In my post How to continuously deploy web application to Azure VM Scale sets using VSTS and Packer?...]]></description>
      <content:encoded><![CDATA[In my post <a href="https://blogs.msdn.microsoft.com/manibindra/2016/12/26/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer/" target="_blank">How to continuously deploy web application to <strong>Azure</strong> VM Scale sets using <strong>VSTS</strong> and <strong>Packer</strong>?</a> shell script tasks were used to bake <strong>Azure</strong> VM image using <strong>packer</strong> and to <strong>Replace tokens</strong> for VM username and VM password in the ARM template parameter file. In this post we will replace these shell script tasks by The <strong>Build immutable image</strong> (using Packer) task, and the <strong>Replace tokens</strong> tasks. As compared to the previous release pipeline the new release pipeline is much cleaner and much more easier to understand and manage.

In case you have not gone through the previous post the code and build file can be found at my <a target="_blank" href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release">github repo</a> . Lets have a look at the modified release pipeline.

<p style="text-align: center"><strong>Release Overview</strong></p>
<img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/with-packer-task/release-overview.png" alt="Build and Release Pipeline Overview" width="60%" height="auto" class="aligncenter" />

The first step of the release packages the latest application files into an Azure <strong>VHD</strong> <strong>image</strong> using the <strong>packer task</strong>, this VM image (vhd) is stored in the configured storage account. Next we use the <strong>replace tokens task</strong> to replace tokens in the <a href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release/blob/master/build-files/azuredeploy.parameters.json" target="_blank">Azure Deployment Parameters File</a>. After this the Azure Group deployment task is used to push the new VM image (with latest application code baked in) to the <strong>VM Scale set</strong>. The last two steps are for UI testing (Using php unit and selenium in this case), and Load testing (using JMeter).

In this post we are <strong>not</strong> going to look at the UI Testing and Load testing tasks as there is no change to these tasks as compared to my previous post. 

<strong>Please Note : The VSTS VM Scale Sets (VMSS) task is also available now, The deployment pipeline is even more simpler if the VSTS Packer task and the VSTS VMSS tasks are used together. See the <a href="https://blogs.msdn.microsoft.com/devops/2017/05/15/deploying-applications-to-azure-vm-scale-sets/" target="_blank">Post</a> on how to use these tasks together to bake custom VM Image and update VM Scale Set Image. </strong>

Let us look at the  other tasks in more detail :
<ol>
	<li><strong>Build immutable image using packer</strong>: In this step we use the Build immutable image task. We pass the path to the <a href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release/blob/master/build-files/packer-files/phpapp-packer.json">phpapp-packer.json</a> file to this task. We will need VSTS Variables ARM_SUBSCRIPTION_ID, ARM_CLIENT_ID, ARM_CLIENT_SECRET, and ARM_TENANT_ID to be set. You can revisit my <a href="https://blogs.msdn.microsoft.com/manibindra/2016/12/26/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer/" target="_blank">post</a> to find out how to get value of these variables. Additionally we provide name of VSTS variable (IMAGEURI) to this task, this variable needs to be created in VSTS. Once the VM image is baked the task will save the image uri for the baked VM image to this variable (IMAGEURI). Screenshot below shows configuration of this task:

<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/with-packer-task/packer-build-task.png" alt="Bake VM Image using Packer" width="80%" height="auto" /></div></li>
	<li><strong>Replace Tokens Task</strong>: This task replace tokens in the  <a href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release/blob/master/build-files/azuredeploy.parameters.json" target="_blank">Azure Deployment Parameters File</a> with values from VSTS variables. 
Snippet below is from parameters file:
<code>"adminUsername": {
      "value": "@@VMUSERNAME@@"
    },
    "imageUri":{
      "value": "@@IMAGEURI@@"
    },
    "adminPassword": {
      "value": "@@VMPASSWORD@@"
    }</code>
The replace token task will replace token @@VMUSERNAME@@ with value of the VSTS variable VMUSERNAME, similarly token @@IMAGEURI@@ will be replaced by the VSTS variable IMAGEURI value, which was set by the previous packer task.

screenshot below shows configuration of this task:

<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/with-packer-task/replace-tokens.png" alt="Replace Tokens" width="80%" height="auto" /></div>
</li>
	<li><strong>Azure Resource Group Deployment Task</strong>: This task will update the VM Image associated with the VM Scaleset. The ARM template file <a href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release/blob/master/build-files/azuredeploy.json" target="_blank">azuredeploy.json</a> and parameter file (where tokens have been replaced by variables by previous task) are passed to this task.

Screenshot below shows configuration of this task:

<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/with-packer-task/azure-group-deployment.png" alt="Azure Group Deployment" width="80%" height="auto" /></div>
</li>

</ol>

Thanks for reading my blog. I hope you liked it. Please feel free to write your comments and views about the same over here or at <a href="https://twitter.com/maniSbindra">@manisbindra</a>.]]></content:encoded>
    </item>
    <item>
      <title>Integrating VSTS with different communication channels (Slack, Skype etc) using BotFramework and LUIS</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/integrating-vsts-with-different-communication-channels-slack-skype-etc-using-botframework-and-luis</link>
      <pubDate>Mon, 27 Feb 2017 21:21:51 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=446</guid>
      <description><![CDATA[Early last year (Jan 2016), a few months before the Microsoft Bot Framework had released I had...]]></description>
      <content:encoded><![CDATA[Early last year (Jan 2016), a few months before the <strong>Microsoft Bot Framework</strong> had released I had written the post <a target="_blank" href="https://blogs.msdn.microsoft.com/manibindra/2016/12/26/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer/">Why integrate <strong>Visual Studio Team Services</strong>(<strong>VSTS</strong>) with <strong>Slack</strong>? How do I customize <strong>VSTS</strong> / <strong>Slack</strong> integrations?</a> . There were a couple of major drawbacks with this bot :
<ul>
 	<li>The bot relied on pattern matching for <strong>intent</strong> detection. Which means if the exact pattern was not found the intent would be missed</li>
 	<li>The bot was utilized the node-slack-client library and only connected to the slack channel. If I wanted to connect the bot to a different channel like skype I would need to use channel specific connectors to connect the bot, which would mean more work</li>
</ul>
Let us Look at how the <strong>Microsoft Bot Framework</strong>, and <strong>Language Understanding and Intelligence Service</strong> (<strong>LUIS</strong>) mitigate these issues. The github repository for this solution is <a href="https://github.com/manisbindra/vsts-bot" target="_blank">https://github.com/manisbindra/vsts-bot</a>

Let us look a the key differences in this solution :
<ul>
 	<li>The file <a target="_blank" href="https://github.com/maniSbindra/vsts-bot/blob/master/vsts-bot-LUIS-model.json">vsts-bot-LUIS-model.json</a> is the <strong>LUIS</strong> Model to recognize intents and entities associated with this application. This model can be imported when creating your application at <a href="http://luis.ai">luis.ai</a> . In the old version of the application patterns like "/task #(\d{1,9})(.*)/i" (view task/issue pattern) were used to identify user intents. In this version LUIS identify intents based on the training utterances shown in the LUIS model JSON file</li>
 	<li>Since This version of the application is built using the Microsoft Bot Framework, after we have built our bot we can separately enable the bot on the several supported channels including <strong>slack</strong>, <strong>skype</strong>, <strong>facebook messenger</strong> etc</li>
 	<li>Interaction with VSTS is similar to the earlier version of the bot except the fact that earlier version of code was in coffeescript, and this one is in javascript</li>
 	<li>The main entry point of this solution is the <a target="_blank" href="https://github.com/maniSbindra/vsts-bot/blob/master/app.js">app.js</a> file. The key lines of code are shown below :
<code>
var builder = require('botbuilder');
var restify = require('restify');
var request = require('request');
</code>
builder represents the Microsoft <strong>Botframework</strong> nodejs SDK which has abstractions for communicating with the <strong>Bot Connector</strong> (which connects bot to various channels) and also abstractions to communicate with LUIS to get the intents and associated entities. restify is used to expose a REST endpoint which the bot connector can use to communicate with our bot. request library will be used to make call to the VSTS REST endpoints.

<code>
// Bind to REST endpoint where the Bot Connector will communicate with our bot
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 4141, function () {
console.log('%s listening to %s', server.name, server.url);
});
.
.
// Create chat bot which can be linked to various channels like slack and skype
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
.
// Initialize the LUIS intent recognizer
// This Url can be obtained by uploading or creating your model from the LUIS portal: https://www.luis.ai/
const LuisModelUrl = process.env.LUIS_MODEL_URL;
.
// Main dialog with LUIS
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
.
// If User greeted the bot, i.e. LUIS identified the intent as greeting the send message to user
.matches('greeting', (session, args) =&gt; {
session.send('Hi There');
})
.
.
// Similar code for other intents
// Simlarly match next set of events and perform actions</li>
</code>
 	<li>This version of the bot acts on an additional intent "userfacingissue". When user confirms this intent the bot creates an issue in VSTS</li>
</ul>
<br class="spacer_" />
<br class="spacer_" />

Thanks for reading my blog. I hope you liked it. Please feel free to write your comments and views about the same over here or at @manisbindra.]]></content:encoded>
    </item>
    <item>
      <title>How to continuously deploy web application to Azure VM Scale sets using VSTS and Packer?</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer</link>
      <pubDate>Mon, 26 Dec 2016 11:09:37 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=425</guid>
      <description><![CDATA[Azure VM Scale sets are a great way to deploy identical set of VMs (based on same VM image) in true...]]></description>
      <content:encoded><![CDATA[<strong>Azure</strong> <strong>VM Scale sets</strong> are a great way to deploy identical set of VMs (based on same <strong>VM image</strong>) in true autoscale. When one wants to change a application deployed to <strong>VM Scale sets</strong>, one common approach is to <strong>bake</strong> a new VM Image with the latest application code built in, and then update the <strong>VM scale set</strong> to use this modified image. Performing this task manually can be error prone, time consuming, and often only few individuals in the team can perform this task.

In this post we see one way in which we can set <strong>continuous deployment</strong> to an environment (called QA in the sample) when using <strong>VM scale sets</strong>, which means that every time the application is modified and code is merged in the configured <strong>git</strong> branch, the latest application is deployed to the <strong>VM Scale set</strong>. The <strong>Visual Studio Team Services</strong> (<strong>VSTS</strong>) release pipeline shown in our example can be enhanced to include more environments including production. We use <strong>packer</strong> in our release pipeline to continuously <strong>bake</strong> the <strong>VM image</strong> with latest application code, each time there is an application update. For details of configuring <strong>packer</strong> with Azure you can refer to my post <a target="_blank" href="http://blogs.msdn.microsoft.com/manibindra/2016/11/18/how-to-create-an-immutable-azure-vm-image-for-an-application-using-packer-and-ansible/">using Packer with Azure </a> .

<strong>The sample application code (php web application), the build / release scripts (including packer file, UI and load test files), and the <strong>VSTS</strong> release template can be found at my <a target="_blank" href="https://github.com/maniSbindra/vsts-packer-vmss-php-webapp-release">github repo</a></strong>.
<p style="text-align: center"><strong>Build and Release Pipeline Overview</strong></p>
<img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/build-release-overview.png" alt="Build and Release Pipeline Overview" width="80%" height="auto" class="aligncenter" />

Will give overview of the solution before diving into into some of the details. The <strong>VSTS</strong> build is triggered each time code is merged into the master branch of the repository. The <strong>VSTS</strong> build in the sample is a simple one which just publishes files needed for the release. Successful build then triggers a release. The first step of the release packages the latest application files into an Azure <strong>VHD</strong> <strong>image</strong> using <strong>packer</strong>, this VM image (vhd) is stored in the configured storage account. Next we use the <strong>azure cli</strong> group deployment command to push the new VM image (with latest application code baked in) to the <strong>VM Scale set</strong>. The last two steps are for UI testing (Using php unit and selenium in this case), and Load testing (using JMeter). At the end of each successful release, the VM scale set has the latest application code.

<strong>Please Note : The VSTS VMSS task and VSTS Packer tasks are now available, The deployment pipeline is much more simpler if these tasks are used together. See the <a href="https://blogs.msdn.microsoft.com/devops/2017/05/15/deploying-applications-to-azure-vm-scale-sets/" target="_blank">Post</a> on how to use these tasks together to bake custom VM Image and update VM Scale Set Image. </strong>

Now let us dive into some of the details of our build and release configurations.
<ol class="with-image">
 	<li><strong>Configuring the custom linux agent for build and release:</strong> Have a look at the link <a href="https://www.visualstudio.com/es-es/docs/build/admin/agents/v2-linux" target="_blank">VSTS Custom Linux Agent</a></li> to create you own linux agent
 	<li><strong>Configuring the custom agent to execute <strong>Packer</strong>:</strong> Information on installing latest <strong>Packer</strong> executable can be found at <a href="https://www.packer.io/downloads.html" target="_blank">install packer</a>. The script below shows installation of packer version 0.12.0 .
<strong> (Note : Built in VSTS packer task is now available, You don't need to configure agent to use packer if you are planning to use that task. You can read my <a href="https://blogs.msdn.microsoft.com/manibindra/2017/08/24/using-the-vsts-packer-task-and-replace-tokens-task/" target="_blank">post</a> to configure the built in VSTS Packer task)</strong>
<code>
sudo apt-get install unzip
wget https://releases.hashicorp.com/packer/0.12.0/packer_0.12.0_linux_amd64.zip
unzip packer_0.12.0_linux_amd64.zip
sudo mv packer /usr/bin/packer
</code>
</li>
 	<li><strong>Configuring the custom agent to execute phpunit and selenium scripts:</strong> Follow the <a href="https://phpunit.de/manual/current/en/installation.html" target="_blank">link </a> to install <strong>phpunit</strong> (only if you are using a php based application) and then you can move it to /usr/bin/phpunit. You can use the <a href="https://medium.com/@griggheo/running-selenium-webdriver-tests-using-firefox-headless-mode-on-ubuntu-d32500bb6af2#.6a3ma9zcg" target="_blank">link </a> to install <strong>firefox</strong>. You can use the <a href="https://www.namekdev.net/2016/08/selenium-server-without-x-window-system-xvfb/" target="_blank">link</a> to install <strong>xvfb</strong> and <strong>selenium</strong> stand alone as a service. Once these tools are installed on the agent, we are good to configure the release pipeline.</li>
 	<li><strong>Build configuration :</strong> For simplicity the build is configured to publish all files are folders in the repository.
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/vsts-build.PNG" alt="Build configuration" width="60%" height="auto" /></div></li>
 	<li><strong>Configuring the Release. The file VSTS-Release-Def.json under the build-files folder has the sample release definition which can be imported in <strong>VSTS</strong> </strong>:
<ul>
 	<li>A new release is configured to be created on each successful build.
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/vsts-release-triggers.PNG" alt="VSTS Release Triggers" width="60%" height="auto" /></div></li>
 	<li>Following are the environment variables which are configured for the release. The ARM_CLIENT_ID, ARM_RESOURCE_GROUP, ARM_STORAGE_ACCOUNT, ARM_SUBSCRIPTION_ID, and ARM_TENANT_ID are used by <strong>packer</strong> to save the baked VM Image VHD into the configured Azure storage account. ADMIN_USERNAME, and ADMIN_PASSWORD are the the logon credentials for the <strong>VM scale set</strong> VMs. DEPLOYMENT_RESOURCE_GROUP is the resource group where the <strong>VM scale set</strong> is deployed. These are passed to the different tasks in the release (as we will see when we go through each task in detail).
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/environment-variables-for-release.PNG" alt="Release Variables for Environment" width="60%" height="auto" /></div></li>
 	<li>Bake <strong>VM image</strong> with latest application updates baked in, using <strong>packer</strong>: In this step we use the execute shell script task to call the build-vm-image.sh file, and pass it the parameters required by packer to create the vm image in the configured Azure storage account.Image below shows configuration of this shell script step:
(<strong> Note : Built in VSTS packer task is now available, to use that task instead you can read my post <a href="https://blogs.msdn.microsoft.com/manibindra/2017/08/24/using-the-vsts-packer-task-and-replace-tokens-task/" target="_blank">Using the VSTS Packer Task and Replace Tokens Task</a> </strong>)
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/release-bake-vm-image-packer.PNG" alt="Bake VM Image using Packer" width="60%" height="auto" /></div>
Following code block shows key lines from the shell script. The environment variables are passed as positional parameters to the script in this example:
<code>export ARM_CLIENT_ID=$1
export ARM_CLIENT_SECRET=$2
export ARM_RESOURCE_GROUP=$3
export ARM_STORAGE_ACCOUNT=$4
export ARM_SUBSCRIPTION_ID=$5
export ARM_TENANT_ID=$6
export ADMIN_USERNAME=$7
export ADMIN_PASSWORD=$8
packer build ./packer-files/phpapp-packer.json 2&gt;&amp;1 | tee packer-build-output.log</code>

The <strong>packer</strong> build configuration file php-packer.json has all the configuration to enable <strong>packer</strong> to package the latest application code and bake the VM image (including base VM image and Azure region). Following configuration section from the packer configuration file demonstrates how the application dist folder is copied into the baked image using the file provisioner:
<code>
"provisioners": [
.
.
{
"type": "file",
"source": "../dist",
"destination": "/tmp/dist"
},
.
.
.
]</code>

In the example other than file and shell script provisioners, we have used the <strong>ansible</strong> provisioner, but packer supports several other provisioners like <strong>chef</strong>, <strong>puppet</strong>, <strong>powershell</strong> etc. The output of the packer build command is written to the file packer-build-command-output.log. Packer writes the image uri of the newly created vhd in the format :
<code>OSDiskUri: https://*********/system/Microsoft.Compute/Images/images/packer-osDisk.5a892bb0-*********-410f-8198-92c8b140390e.vhd</code> (see file packer-build-output.log for complete output of packer build command)</li>
 	<li>Replace image uri in ARM template deployment parameters file, with uri of vhd generated by <strong>packer</strong> in preceding step.
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/overwrite-group-deployment-parameters.PNG" alt="Overwrite Image Uri Parameter value" width="60%" height="auto" /></div>
The shell script overwrite-azure-deployment-parameters.sh is invoked, which parses the packer out log file to retrieve the uri of the newly created vhd. it then replaces the parameter value azuredeploy.parameters.json file. Code extract of file is shown below :


<code>export imageodisk=$(cat packer-build-output.log | grep OSDiskUri: | awk '{print $2}')

sed -i 's/@@VMUSERNAME@@/'"$ADMIN_USERNAME"'/g' azuredeploy.parameters.json
sed -i 's/@@VMPASSWORD@@/'"$ADMIN_PASSWORD"'/g' azuredeploy.parameters.json
sed -i 's|@@IMAGEURI@@|'"$imageodisk"'|g' azuredeploy.parameters.json</code> 
<strong>Note : The VSTS VMSS task is now available, if the VSTS Packer task is used along with the VSTS VMSS task then this step and the next step "Push updated VM image to VM scale set" may not be required. See the <a href="https://blogs.msdn.microsoft.com/devops/2017/05/15/deploying-applications-to-azure-vm-scale-sets/" target="_blank">Post</a> on how to use these tasks. </strong></li>
 	<li>Push updated VM image to VM scale set using <strong>Azure Cli</strong> group deployment: This is done by using the Azure cli task which calls the deploy-vm-image.sh file and passes the resource group where the VM Scale set is deployed.
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/push-new-vm-image-to-vmscaleset.PNG" alt="push new vm image to vm scale set" width="60%" height="auto" /></div>
This script then executes the azure group deployment command passing it the ARM template and parameters file. The script is shown below :
<code>azure group deployment create -f azuredeploy.json -e azuredeploy.parameters.json -g $1 -n rocdashdeploy$2</code></li>
 	<li>Execute <strong>Selenium</strong> based Smoke test on Application.
<div><img src="https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/execute-phpunit-selenium-unit-tests.PNG" alt="Execute UI Smoke tests" width="60%" height="auto" /></div>
<strong>Phpunit</strong> is used to then execute the site smoke tests:
<code>phpunit $1site-smoke-test.php $2</code></li>
 	<li>Execute Load tests on Application
<div>&lt;img src=&quot;https://raw.githubusercontent.com/maniSbindra/vsts-packer-vmss-php-webapp-release/master/images/execute-jmeter-load-tests.PNG&quot; alt=&quot;Execute <strong>JMeter</strong> Load tests on application" width="60%" height="auto" /&gt;</div>
The <strong>JMeter</strong> Load test execution task then fires JMeter Load Tests against the site site using the JMX file site-load-test.jmx (which has duration assertions) .</li>
</ul>
</li>
</ol>
In the sample used for this post all tasks are executed the same QA environment. This <strong>Release</strong> configuration can be enhanced by adding other environments like Performance and Volume Testing envrionment (where the load test can be moved), etc.

Thanks for reading my blog. I hope you liked it. Please feel free to write your comments and views about the same over here or at <a href="https://twitter.com/maniSbindra">@manisbindra</a>.]]></content:encoded>
    </item>
    <item>
      <title>How to create an immutable Azure VM image for an application using packer and ansible</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/how-to-create-an-immutable-azure-vm-image-for-an-application-using-packer-and-ansible</link>
      <pubDate>Fri, 18 Nov 2016 16:00:31 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=405</guid>
      <description><![CDATA[In this post I will discuss about how build immutable VM images using packer and ansible with latest...]]></description>
      <content:encoded><![CDATA[In this post I will discuss about how build immutable VM images using <strong>packer</strong> and <strong>ansible</strong> with latest application code baked in. In my subsequent <a href="http://blogs.msdn.microsoft.com/manibindra/2016/12/26/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer/">post</a> I discuss how we can combine this with Visual studio team services to create a continuous deployment pipeline to provision new <strong>Azure</strong> <strong>VM scaleset </strong> / or update existing <strong>VM scaleset</strong> based on the <strong>VM image</strong> created using <strong>packer</strong>.

In the diagram below I have highlighted areas which this particular post will focus on.

<img src="https://raw.githubusercontent.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/master/images/packer-build.png" width="80%" height="auto" alt="Azure VM image build with latest application code using packer" class="size-large" />

<a href="https://www.packer.io/">Packer</a> is a tool from HashiCorp for creating machine and container images for various platforms. In a typical flow each time application code changes (or at desired interval), a packer build is triggered which would create a new VM Image (with the latest application code baked in) in the configured Azure storage (when using the packer azurerm builder). This image can then be used by deployment pipelines to refresh the desired environments with the latest application code. If you wanted to revert to a previous version of the application in an environment you could rollback by creating VMs based on the previously created VM Image.

The beauty with packer is that that it supports a number of <a href="https://www.packer.io/docs/templates/builders.html">builders</a> including azurerm, docker, virtualbox etc, and a number of <a href="https://www.packer.io/docs/templates/provisioners.html">provisioners</a> including chef, puppet, ansible etc. So as an example you can create a VM image, a docker container image and a virtual box image (for a developers VM) which are almost similar in terms of infrastructure. Packer also gives us complete environment change tracebility as this is truly infrastructure as code.

For packer installation see <a href="https://www.packer.io/docs/installation.html">Packer installation instructions</a>.

Let us see how easy it is to create the VM image for a sample php application. The code repository is on <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo">my github repo</a>.
I have considered a simple single file <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/index.php">(index.php) php application</a> . The packer file <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/phpapp-packer.json">phpapp-packer.json</a> creates the VM image, and this packer file uses the ansible file <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/phpapp-packer-ansible-provisioner.yml">phpapp-packer-ansible-provisioner.yml</a> for provisioning the VM.

&nbsp;

Let us first take a look at some of the important lines from <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/phpapp-packer.json">phpapp-packer.json</a>
<code>"variables": {
"tenant_id": "{{env `ARM_TENANT_ID`}}",
"client_id": "{{env `ARM_CLIENT_ID`}}",
"client_secret": "{{env `ARM_CLIENT_SECRET`}}",
"resource_group": "{{env `ARM_RESOURCE_GROUP`}}",
"storage_account": "{{env `ARM_STORAGE_ACCOUNT`}}",
"subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}"
}
</code>In above lines the packer file variables are set from corresponding environment variable. The link <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/linux/build-image-with-packer">https://docs.microsoft.com/en-us/azure/virtual-machines/linux/build-image-with-packer</a> gives details on how to get values for these variables to enable packer builds in azure.

<code>
23 "os_type": "Linux",
24 "image_publisher": "Canonical",
25 "image_offer": "UbuntuServer",
26 "image_sku": "16.04.0-LTS",
</code>Above lines specify the base image sku, which is Ubuntu 16.04.

<code>
32 "provisioners": [
34 {
35 "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
36 "inline": [
37 "apt-get update",
38 "apt-get upgrade -y",
39 "apt-get install ansible -y"
40</code>

41 ],
42 "inline_shebang": "/bin/sh -x",
43 "type": "shell"
44 },
45 {
46 "type": "ansible-local",
47 "playbook_file": "./phpapp-packer-ansible-provisioner.yml"
48 }

In the provisioners array, we first have a shell script provisioner where we are installing ansible, and then we have an ansible-local provisioner, to which we pass our ansible playbook to install our PHP application.

Next let us look some of the key lines from the <a href="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/phpapp-packer-ansible-provisioner.yml">phpapp-packer-ansible-provisioner.yml</a> ansible playbook, which ultimately provisions the PHP application
<code>
4 tasks:
5 - name: Install Packages
6 apt: name={{ item }} update_cache=yes state=present
7 with_items:
8 - apache2
9 - libapache2-mod-php
10 - git
11 - curl
</code> In the above lines we install the dependencies which we need for setting up our php application

<code>
14 - name: Git Clone Repo
15 git: repo=https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo.git dest=/opt/phpapp update=yes force=yes accept_hostkey=yes
16 register: git_finished
</code> In the above lines we clone the git repository, where the application is hosted

<code>
18 - name: copy index.php
19 sudo: yes
20 copy: src=/opt/phpapp/index.php dest=/var/www/html/index.php mode=644
21 notify: Restart Apache
</code> In the above lines we copy the index.php files to the apache default directory, set permissions and restart apache.

&nbsp;

Typically the packer build which generates the VM image would be triggered automatically, however here lets see the result of running the packer build manually.

<img src="https://github.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/blob/master/images/packer-build1.png?raw=true" width="80%" height="auto" alt="environment variables set and packer build run" class="size-large" /> The setupenv.sh file sets the environment variables required by the packer file. After this the packer build command is fired.

<img src="https://raw.githubusercontent.com/maniSbindra/spinnaker-packer-ansible-php-azure-demo/master/images/packer-build2.png" width="80%" height="auto" alt="packer build command finished" class="size-large" /> packer build command finished

. After the build command finishes get the path of the vhd, and we also get the uri of the ARM template (<strong>TemplateUriReadOnlySas</strong>) which can used to provision VM based on the created VM image.

In the <a href="http://blogs.msdn.microsoft.com/manibindra/2016/12/26/how-to-continuously-deploy-web-application-to-azure-vm-scale-sets-using-vsts-and-packer/">next post</a> we look at using Visual Studio Team Services to automate creation of VM scalesets based on the VM image generated by packer.]]></content:encoded>
    </item>
    <item>
      <title>Noise Pollution Monitor (packaged as a docker container) using Lego mindstorms sensors, Brickpi and Raspberry Pi</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/noise-pollution-monitor-packaged-as-a-docker-container-using-lego-mindstorms-sensors-brickpi-and-raspberry-pi</link>
      <pubDate>Mon, 20 Jun 2016 08:39:12 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=355</guid>
      <description><![CDATA[Do you have a Lego Mindstorms NXT kit lying unused at home? You can combine a Raspberry Pi device,...]]></description>
      <content:encoded><![CDATA[Do you have a <strong>Lego</strong> <strong>Mindstorms</strong> NXT kit lying unused at home? You can combine a <strong>Raspberry Pi</strong> device, with a <strong>Brickpi</strong> to build your <strong>IOT solution</strong> using the awesome <strong>Lego Mindstorms</strong> <strong>sensors/motors</strong>. Here we will look at a <strong>Noise monitor</strong> (which has been packaged as a <strong>docker</strong> container) and built using the <strong>sound</strong> and <strong>LED color sensor</strong>.

Before going into the details of the solution I will try and answer a few questions :

<strong>Why a noise pollution monitor?</strong> Though there are several solutions which can be built using the <strong>Lego Mindstorms sensors and motors</strong>, I first decided to build this solution because, I am sure that if people realized how much <strong>unwanted noise</strong> they are adding to the environment by shouting, or pressing the car horn unnecessarily, they would change things for the better. As shown in the overview diagram whenever the sound intensity percentage crosses the configured threshold the green LED turns of and the <strong>red LED turns on</strong>.

<strong>Why Brickpi?</strong> Normally the Lego Minstorms sensors/motors are used with the <strong>Minstorms</strong> controller, however the Mindstorms controller has limited capability in terms of hardware (Memory, processor speed, no wifi to name a few). This is where <strong><a href="http://www.dexterindustries.com/BrickPi/">Brickpi</a></strong> comes in, it provides a similar interface to the <strong>Mindstorms</strong> controller for the <strong>sensors</strong> and <strong>motors</strong>, and it also interfaces with the <strong>raspberry pi</strong>, enabling us to utilize the awesome hardware and connectivity of the <strong>raspberry pi</strong>.
<p style="text-align: left"><strong>Why Docker?</strong> I wanted to make it seamless for anyone wanting to replicate this solution, and then tweak it as per their needs, and let’s face it once you start using docker, it is difficult to turn back, you want to use it for every solution. The <strong><a href="http://blog.hypriot.com/">hypriot</a></strong> image comes loaded with the docker engine, and is one of the easiest ways to get started with docker on the pi.
<br class="spacer_" /><br class="spacer_" /><strong>Overview :</strong>
<img class="" src="https://raw.githubusercontent.com/maniSbindra/docker-brickpi-raspberrypi-hypriot/master/images/overview.jpg" alt="" width="80%" height="auto" />
<strong>Noise Pollution Monitor</strong> (packaged as a <strong>docker</strong> container) using <strong>Lego mindstorms</strong> sensors, <strong>Brickpi</strong> and <strong>Raspberry Pi</strong></p>
<p style="text-align: left">Raspberry pi is loaded with the <a href="http://blog.hypriot.com/downloads/" target="_blank">Hypriot version 0.8.0 - Barbossa</a> image. Once the pi has booted up with this image, docker is available on the pi. All dependencies needed for the pi to control the Mindstorms sensors, and the Brick pi (including the Brickpi_Python library) are built into the docker container image, using the Dockerfile shown in the <a href="https://github.com/maniSbindra/docker-brickpi-raspberrypi-hypriot" target="_blank">project's github repository</a>.</p>
<p style="text-align: left">To start the monitor we can run the container as follows  :</p>
<p style="text-align: left"><code>docker run -e INTENSITY_THRESHOLD=40 -d --device /dev/ttyAMA0:/dev/ttyAMA0 --device /dev/mem:/dev/mem --privileged -ti maninderjit/pi-brickpi</code></p>
<p style="text-align: left">(Sound intensity threshold configured to 40% using -e switch of the docker run command above)</p>
For details of the python code and configuration details you can have a look at <strong><a href="https://github.com/maniSbindra/docker-brickpi-raspberrypi-hypriot" target="_blank">https://github.com/maniSbindra/docker-brickpi-raspberrypi-hypriot</a></strong>.

<br class="spacer_" />Thanks for reading my blog. I hope you liked it. Please feel free to write your comments and views about the same over here or at <a href="https://twitter.com/maniSbindra">@manisbindra</a>.]]></content:encoded>
    </item>
    <item>
      <title>How to configure your Drupal 8 ARM template deployment to Azure creating new MySQL Servers (Master and Slave with replication)</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/how-to-configure-your-drupal-8-arm-template-deployment-to-azure-creating-new-mysql-servers</link>
      <pubDate>Mon, 30 May 2016 17:00:12 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=325</guid>
      <description><![CDATA[This post discusses the parameter configurations needed when setting up a multi node Drupal...]]></description>
      <content:encoded><![CDATA[
This post discusses the parameter configurations needed when setting up a multi node <strong>Drupal</strong> deployment using the <a title="Drupal 8 VM scaleset (with GlusterFS and MySQL)" href="https://github.com/Azure/azure-quickstart-templates/tree/master/301-drupal8-vmss-glusterfs-mysql" target="_blank"><strong>Drupal</strong> <strong>8</strong> <strong>VM scaleset</strong> (with <strong>GlusterFS</strong> and <strong>new</strong> <strong>MySQL</strong> servers) <strong>ARM Template</strong>.</a>

To create <strong>MySql</strong> <strong>Master</strong> and <strong>Slave</strong> pair this template uses the <a href="https://github.com/Azure/azure-quickstart-templates/tree/master/mysql-replication"><strong>mysql-replication</strong></a> <strong>ARM template</strong> as a nested template.

<strong>Managing</strong> the created <strong>MySql</strong> Servers : The Readme.md file of the <a href="https://github.com/Azure/azure-quickstart-templates/tree/master/mysql-replication"><strong>mysql-replication</strong></a> template has instructions to do various things including connecting to the servers, failing over to the slave, backing up the database to azure blob storage etc.

<strong>Parameter values</strong> to be configured (sample values have been shown) :
<ul>
	<li>drupalVmSku: "Standard_D1_v2" (Size of the Drupal VMs)</li>
	<li>drupalUbuntuOSVersion: "14.04.4-LTS" (OS Version for the Drupal VMs)</li>
	<li>drupalAdminUser: "drupalAdmin" (Drupal Site Administrator)</li>
	<li>drupalAdminPassword: "drupalAdmin-123" (Password for Drupal Administrator)</li>
	<li>drupalVersion: "8.1.1" (The Drupal Version)</li>
	<li>vmssName: "dru25vmss" (Name of the VM Scaleset)</li>
	<li>instanceCount: "2" (Default and minimum number of Drupal VMs in the VM scaleset)</li>
	<li>maximumInstanceCount: "10" (Maximum Number of Drupal VMs in the scale set)</li>
	<li>adminUsername: "drupvmuser" (The ssh username for the drupal and gluster vms)</li>
	<li>adminPassword: "DrupVm-pass1234" (The ssh password for drupal and gluster vms)</li>
	<li>drupalInstallationDatabaseName: "drupaldb" (the drupal database name using which the drupal site will be installed)</li>
	<li><strong>createNewMySQLServer: "yes"</strong> (No is default, details of existing SQL Server need to be provided)</li>
	<li>existingMySqlFQDN: <strong>"anything"</strong> (FQDN of existing MySQL server). This can be set to any value. Will be ignored when creating new mysql server .</li>
	<li>existingMysqlUser: <strong>"anything"</strong>. When using the Mysql-Replication template the user name created will be <strong>"admin"</strong></li>
	<li>mysqlUserPassword: "Mysql-Pass1234" (<strong>The mysql admin users password will be set to this</strong>)</li>
	<li>glusterTemplateLocation: "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/gluster-file-system/" (Base location of ARM template used to create the Gluster cluster)</li>
	<li>templateLocation: "https://raw.githubusercontent.com/maniSbindra/azure-quickstart-templates/master/301-drupal8-vmss-glusterfs-mysql" (Base location of the the Drupal ARM template and scripts)</li>
	<li>storageAccountNamePrefix: "dru25stacc" (prefix for the VM storage accounts, which need to be unique)</li>
	<li>glusterVmSize: "Standard_D1_v2" (Size of the gluster VMs)</li>
	<li>glusterInstanceCount: "2" (Number of nodes in the gluster cluster)</li>
	<li>newMySqlDnsName: "mysqlserverdnsname" (The <strong>FQDN</strong> of the MySQL server will be <strong>dnsName.location.cloudapp.azure.com</strong>)</li>
	<li>newMySqlVmUserName: "mysqlVmUser" (user name used for ssh)</li>
	<li>newMySqlVmPassword: "MySQLVM-Pass1234" (password used for ssh)</li>
	<li>newMySqlVmSize: "Standard_D1_v2"</li>
	<li>dbCentosOSVersion: "6.6"</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>How to configure your Drupal 8 ARM template deployment to Azure using existing MySQL Server</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/how-to-configure-your-drupal-8-arm-template-deployment-to-azure-using-existing-mysql-server</link>
      <pubDate>Mon, 23 May 2016 15:01:37 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=315</guid>
      <description><![CDATA[This post discusses the parameter configurations needed when setting up a multi node Drupal...]]></description>
      <content:encoded><![CDATA[This post discusses the parameter configurations needed when setting up a multi node <strong>Drupal</strong> deployment using the <a title="Drupal 8 VM scaleset (with GlusterFS and MySQL)" href="https://github.com/Azure/azure-quickstart-templates/tree/master/301-drupal8-vmss-glusterfs-mysql" target="_blank"><strong>Drupal</strong> <strong>8 </strong><strong> VM scaleset</strong> (with <strong>GlusterFS</strong> and <strong>MySQL</strong>)</a> <strong>ARM Template</strong>.

<strong>Parameter values</strong> which need to be entered (sample values have been shown) :
<ul>
	<li>drupalVmSku: "Standard_D1_v2" (Size of the Drupal VMs)</li>
	<li>drupalUbuntuOSVersion: "14.04.4-LTS" (OS Version for the Drupal VMs)</li>
	<li>drupalAdminUser: "drupalAdmin" (Drupal Site Administrator)</li>
	<li>drupalAdminPassword: "drupalAdmin-123" (Password for Drupal Administrator)</li>
	<li>drupalVersion: "8.1.1" (The Drupal Version)</li>
	<li>vmssName: "dru25vmss" (Name of the VM Scaleset)</li>
	<li>instanceCount: "2" (Default and minimum number of Drupal VMs in the VM scaleset)</li>
	<li>maximumInstanceCount: "10" (Maximum Number of Drupal VMs in the scale set)</li>
	<li>adminUsername: "drupvmuser" (The ssh username for the drupal and gluster vms)</li>
	<li>adminPassword: "drupvmpass" (The ssh password for drupal and gluster vms)</li>
	<li>drupalInstallationDatabaseName: "drupaldb" (the drupal database name using which the drupal site will be installed)</li>
	<li>createNewMySQLServer: <strong>"no"</strong> (No is default, details of existing SQL Server need to be provided)</li>
	<li>existingMySqlFQDN: "host123.southcentralus.cloudapp.azure.com" (FQDN of existing MySQL server) . <strong>The MySQL Server needs to be accessible from the Drupal VMs.</strong></li>
	<li>existingMysqlUser: "admin" (the user name used to connect to the mysql server instance)</li>
	<li>mysqlUserPassword: "Mysql-Pass1234" (The password used to connect to the MySQL server instance)</li>
	<li>glusterTemplateLocation: "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/gluster-file-system/" (Base location of ARM template used to create the Gluster cluster)</li>
	<li>templateLocation: "https://raw.githubusercontent.com/maniSbindra/azure-quickstart-templates/master/301-drupal8-vmss-glusterfs-mysql" (Base location of the the Drupal ARM template and scripts)</li>
	<li>storageAccountNamePrefix: "dru25stacc" (prefix for the VM storage accounts, which need to be unique)</li>
	<li>glusterVmSize: "Standard_D1_v2" (Size of the gluster VMs)</li>
	<li>glusterInstanceCount: "2" (Number of nodes in the gluster cluster)</li>
</ul>
<strong>Parameter values which are needed only when setting up a new MySQL server and hence can be ignored :</strong>
<ul>
	<li>newMySqlDnsName: "NA"</li>
	<li>newMySqlVmUserName: "NA"</li>
	<li>newMySqlVmPassword: "NA"</li>
	<li>newMySqlVmSize: "NA"</li>
	<li>dbCentosOSVersion: "6.6"</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>How to move MySql database from AWS RDS to Azure ?</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/how-to-migrate-mysql-database-from-aws-rds-to-azure</link>
      <pubDate>Tue, 03 May 2016 20:48:57 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=275</guid>
      <description><![CDATA[There are several ways to backup mysql databases, as shown at Mysql Backup and Recovery. In this...]]></description>
      <content:encoded><![CDATA[There are several ways to <strong>backup</strong> <strong>mysql</strong> <strong>databases</strong>, as shown at <a href="https://dev.mysql.com/doc/refman/5.6/en/backup-and-recovery.html"><strong>Mysql</strong> <strong>Backup</strong> and Recovery</a>. In this <strong>post</strong> I have shown <strong>AWS</strong> <strong>RDS</strong> <strong>mysql</strong> backup using <strong>mysqldump</strong> utility, and <strong>restore</strong> to <strong>Azure</strong> using <strong>mysql</strong> command. This may not be the ideal way when you need to <strong>move</strong> very large databases.

<strong>Note! Please do have a look at the more recent documentation in this context at <a href="https://docs.microsoft.com/en-us/azure/mysql/concepts-migrate-import-export">https://docs.microsoft.com/en-us/azure/mysql/concepts-migrate-import-export</a></strong>

<a href="https://msdnshared.blob.core.windows.net/media/2016/05/Overview.jpg"><img class="alignnone size-large wp-image-296" src="https://msdnshared.blob.core.windows.net/media/2016/05/Overview1-1024x323.jpg" alt="Overview" width="80%" height="auto" /></a>
We need to first have machine where we can execute the mysqldump and mysql commands. If you already have such a machine you can directly start from step 2.
<ol>
	<li>Setting up <strong>migration</strong> <strong>script</strong> execution machine : I have used the <strong>Centos 6.7</strong> VM image from <strong>Azure</strong>, to create the script execution VM. This VM is needed to execute the backup and restore commands. Once the the VM has been created ssh on the vm and execute the following command to install the mysql client utilities:
<div style="background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em">sudo yum install mysql</div>
&nbsp;</li>
	<li><strong>Backing up AWS RDS MySql database to file</strong> : you will need the FQDN, database name, username and password of your AWS RDS mysql instance to execute the following command, which will create backup file for your database. Please make sure that the <strong>RDS MySql instance is accessible</strong> from the script execution vm (setting in AWS):
<div style="background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em">mysqldump -h rdsmysqlserverfqdn -P 3306 databasename &gt; dbbackupfile.sql -u dbusername -p</div>
You will be prompted to enter your RDS MySql password after you execute this command. After execution is complete you will see the backup file dbbackupfile.sql in your directory</li>
	<li><strong>Restoring database to</strong><strong>Azure</strong> : Azure has both PaaS (ClearDB) and IaaS option for MySql.
<ul>
	<li><strong>Restore to ClearDB (PaaS)</strong> : <a href="https://blogs.msdn.microsoft.com/cdndevs/2015/10/16/how-to-create-a-mysql-database-on-azure/">This </a>link shows how to create a <strong>ClearDB</strong> <strong>MySql</strong> instance. We need the ClearDB server name, database name, username and password to restore the database from backup. Once you have these details execute the following command :
<div style="background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em">mysql -h cleardb_server_name -P 3306 -u cleardb_username -p cleardb_databasename &lt; dbbackupfile.sql</div>
You will be prompted to enter your ClearDB password after you execute this command. After execution is complete you will see that the database has been restored</li>
	<li><strong>Restore to MySql deployed to VMs</strong>: One of the most popular MySQL Master-Slave setups can be achieved by deploying the <a href="https://github.com/Azure/azure-quickstart-templates/tree/master/mysql-replication"><strong>mysql-replication</strong></a> ARM template (by clicking on deploy to azure button). The Readme.md file of this template has instructions to do various things including backing up the database to azure blob storage. Once this template has been deployed we need to restore the backup using the following script:
<div style="background: #ffffff;overflow: auto;width: auto;border: solid gray;border-width: .1em .1em .1em .8em;padding: .2em .6em">mysql -h serverfqdn -P 3306 -u admin -p -D test &lt; dbbackupfile.sql</div>
You will be prompted to enter your admin password after you execute this command. After execution is complete you will see that the test database has been restored</li>
</ul>
<br class="spacer_" /><br class="spacer_" />Thanks for reading my blog. I hope you liked it. Please feel free to write your comments and views about the same over here or at <a href="https://twitter.com/maniSbindra">@manisbindra</a></li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>Custom VSTS / Slack integrations Part 2 ? Triggering VSTS builds from Slack</title>
      <link>https://docs.microsoft.com/archive/blogs/manibindra/custom-vsts-slack-integrations-part-2-triggering-vsts-builds-from-slack</link>
      <pubDate>Mon, 02 May 2016 15:19:39 GMT</pubDate>
      <dc:creator><![CDATA[Maninderjit Bindra]]></dc:creator>
      <guid
        isPermaLink="false">http://blogs.msdn.microsoft.com/manibindra/?p=265</guid>
      <description><![CDATA[Triggering VSTS builds from slack  
This is part 2 of the blog post Custom integration of VSTS and...]]></description>
      <content:encoded><![CDATA[<strong>Triggering VSTS builds from slack </strong> <br class="spacer_" /><br class="spacer_" />
This is part 2 of the blog post <a href="https://blogs.msdn.microsoft.com/manibindra/2016/01/14/visual-studio-slack-integration-part1/">Custom integration of VSTS and slack</a> . In this post we will look at how we can use VSTS - slack integration to trigger VSTS builds<br class="spacer_" /><br class="spacer_" />
The implementation details for this bot integration can be found at <a href="https://github.com/maniSbindra/devOpsBot">https://github.com/maniSbindra/devOpsBot</a> (Main application logic file is devBotModules/vstsBot.coffee). <br class="spacer_" /><br class="spacer_" /><a href="https://msdnshared.blob.core.windows.net/media/2016/05/DevOps-Bot.jpg"><img class="alignnone size-large wp-image-285" src="https://msdnshared.blob.core.windows.net/media/2016/05/DevOps-Bot-1024x297.jpg" alt="DevOps Bot" width="80%" height="auto" /></a>
The additional point with this integration as compared to the integration discussed in part 1, is that we need to validate whether the person sending the trigger build message in slack is authorized to trigger the VSTS build. <br class="spacer_" />The slack email id of the user sending the "trigger build" message is used in the example, and then this email id is passed to the external authorization service end point, to determine if the user can trigger the build, which in turn uses AD with custom attributes containing slack email id and slack user privileges. If the authorization is successful then the VSTS build is triggered using the REST endpoint.

<br class="spacer_" />
<strong>Please note </strong> this post was created prior to the Microsoft Bot framework being released, and the solution described uses pattern matching for intent detection . In case you want to see similar solution using <strong>botframework</strong> and <strong>Language Understanding and Intelligence Service</strong> (<strong>LUIS</strong>) for <strong>intent detection</strong> you can see <a href="https://blogs.msdn.microsoft.com/manibindra/2017/02/27/integrating-vsts-with-different-communication-channels-slack-skype-etc-using-botframework-and-luis/">https://blogs.msdn.microsoft.com/manibindra/2017/02/27/integrating-vsts-with-different-communication-channels-slack-skype-etc-using-botframework-and-luis/</a>
<br class="spacer_" />]]></content:encoded>
    </item>
  </channel>
</rss>