Steve Spencer's Blog

Blogging on Azure Stuff

Error updating SSL certificates in Azure App Services

I was asked to update the SSL certificates on a website that was hosted in Azure Web Apps. No problem I thought.

Go to the Azure Portal,

Select the website you want to update.

When the blade appears scroll down the left panel and select SSL Certificates

image

image

 

remove the binding, by clicking … at the end of the binding row and select Delete

image

Now remove the certificate by clicking .. at the end of the certificate row and select Delete

This is where I got an error

image

It took a short while to resolve this.

I tried a few things like restarting the site & checking the staging slot, but I still got the error. Finally, I checked other sites in the same app service plan and I had the same certificate used for another Web App (both using the same domain url). Once I removed the binding from that site, I could delete the certificate and upload a new one. I had to then add the new bindings to both sites.

Migrating Azure WebJobs to Azure Service Fabric

As part of a proof of concept for Azure Service Fabric one of the challenges was to migrate backend services from a variety of different places. I had a number of services running as Azure Webjobs on the same platform as my web site. The WebJobs were hosted as triggered services meaning that they were using the WebJobs SDK and this has the advantage that the WebJob will run as a console application outside of the Azure Web site it is currently hosted in.

Azure Service Fabric has the capability to run any Windows application that can be run from a command line as a guest executable. This means that I could host my WebJob in Service Fabric as a guest executable.

Once I had Visual Studio setup with the Service Fabric SDK & Tools. It was relatively straight forward to add the WebJob.

As an example, my WebJob is triggered when a message is placed onto an Azure Storage Queue and it then passes the message into an Azure Service Bus Topic. The WebJob project was added to my Service Fabric application

clip_image001

To add this as a Guest Executable, right click on your service node in the Service Fabric application and select “New Service Fabric Service”

clip_image002

When the “New Service Fabric Service” dialog appears, select “Guest Executable”

clip_image004

Click Browse and select your WebJob executable folder. The WebJob executable should now appear in the Program drop down. Select this, change the service name and click OK.

This should add your WebJob as a guest executable to your application package root

clip_image005

Once deployed to a Service Fabric cluster, your WebJob should run as normal. If you leave the connection string settings the same as they are in the WebJob then your diagnostic traces will appear in the same blob container as they are now.

Changing Website Settings through the Azure Portal

When using configuration in Microsoft Azure websites, ensure that you put configuration that you are likely to change often in AppSettings. This allows you to make configuration changes in the Management portal of Azure rather than having to edit the web.config file directly. An example of where you might like to do this include settings that allow you to disable site features temporarily such as during an upgrade or routine maintenance.

App settings in the web config file are names/value pairs and are accessed as follows:

System.Configuration.ConfigurationManager.AppSettings["StevesSetting"]

Which can be seen in the web.config as follows:

<configuration>
  .
  <appSettings>
      <add key="StevesSetting" value="Webconfig setting" />
  </appSettings>
  .
</configuration>

In order to manage this configuration in the portal you need to navigate to your website and click the configure tab (in the old portal)

image

and scroll down to app settings, then add in the setting you wish to change

image

Or in the old portal navigate to the website and click settings then applications settings and scroll down to the app settings section

image

Setting Custom Domain for Traffic Manager and Azure Websites

Recently I’ve been looking at using traffic manager to front up websites hosted in Azure Websites. I needed to setup a custom domain name instead of using mydomain.trafficmanager.net.

In order to use Traffic Manager with an Azure website the website needs to be setup using a Standard Hosting Plan.

Each website you want to be included in the traffic manager routing will need to be added as an endpoint in the traffic manager portal.

Once you have this setup you will need to add the DNS CNAME record for your domain. This needs to be configured at your Domain provider. You set the CNAME to point to mydomain.trafficmanager.net

In order for the traffic to be routed to your Azure hosted website(s), each website setup as an endpoint in traffic manager will need to have your mapped domain e.g. www.mydomain.com  configured. This is done under settings->Custom Domains and SSL in the new portal and under the configure tab –> manage domains (or click the Manage Domains button)

If you don’t add this then you will see this 404 error page whenever you try to navigate to the site through the traffic manager custom domain name:

image

Azure Websites: Blocking access to the azurewebsites.net url

I’ve been setting up one of our services as the backend service for Azure API management. Part of this process we have mapped DNS to point to the service. As the service is hosted in Azure Websites there are now two urls that exist which can be used to access the service. I wanted to stop a user from accessing the site using the azurewebsites.net url and only access it via the mapped domain. This is easy to achieve and can be configured in the web.config file of the service.

In the <system.webServer> section add the following configuration

<rewrite>
    <rules>
        <rule name="Block traffic to the raw azurewebsites url"  patternSyntax="Wildcard" stopProcessing="true">
          <match url="*" />
          <conditions>
            <add input="{HTTP_HOST}" pattern="*azurewebsites.net*" />
          </conditions>
          <action type="CustomResponse" statusCode="403" statusReason="Forbidden"
          statusDescription="Site is not accessible" />
        </rule>
    </rules>
</rewrite>

Now if I try and access my site through the azurewebsites.net url, I get a 403 error, but accessing through the mapped domain is fine.

Azure Websites Slots and Configuration

One of the conundrums we have with deploying sites to test means that there is often a lot of configuration that is needed on a test site that is different to a live site. There is also the time and risk of deploying a new instance into the production sites once testing has completed.

Azure websites has introduced deployments slots which allows you to have multiple deployments and swap between them in a similar way you could do with the production and staging slots in cloud services. Websites has the added advantage that you can have more than two slots and you can call them whatever you want.

One approach we are looking at to ensure consistency with what is deployed is to configure up a number of slots on the website for a variety of uses e.g. Production, Staging, UAT. The issue with having multiple slots is that there are often sets of configurations that are required to ensure that each slot will work with the correct backend. By default all configuration stored in the appsettings in web.config will move with the slot. Details of the exact configuration settings that move with the deployment can be found here (http://azure.microsoft.com/en-gb/documentation/articles/web-sites-staged-publishing/)

For example, in my web.config file I have the following setting

<appSettings>

<add key="about" value="This is the web.config text" />

</appSettings>

This setting can be overridden in the Azure portal(s) and these by default will follow the deployment and not stay with the slot.

image

So in this example the "about" config will be set to "This is Now the Staging slot" and when the staging slot is swapped to be production, the new production configuration will also be "This is Now the Staging slot"

This is not necessarily what you want on production. Websites has a feature, that is currently unsupported by the management portal(s), which allows specific configuration items to become sticky i.e. they stay with the slot. There is a powershell cmdlet which allows individual appsettings to be marked as sticky and remain with the slot regardless of the deployment that is in the slot and they will also remain in the slot when the slots are swapped.

This can be set for both Appsettings and connection strings by running the following commands

Set-AzureWebsite -Name somesite -SlotStickyAppSettingNames @("about", "another_config_key")

Set-AzureWebsite -Name somesite -SlotStickyConnectionStringNames @("a_connection_string", "some_other_connectionstring")

After running the commands the example above will still have the configuration setting above, but once the deployment is swapped from the staging slot to production the configuration will remain on the staging slot.

This approach should now allow us to deploy to a UAT slot with UAT configuration and allow the customer to test, when they are happy we can move the same deployment that has just been tested to the staging slot with production configuration and be tested in isolation to live to ensure that it works. When you are happy that the staging slot is working this can then be swapped out to production.

For a more detailed introduction to slots and configuration see:

http://azure.microsoft.com/en-gb/documentation/articles/web-sites-staged-publishing/

http://blog.amitapple.com/post/2014/11/azure-websites-slots/#.VG22ik1yaAg

Moving an Azure Website to a separate set of Virtual Machines

When an Azure Website is created and is in production it will most likely be running in a Standard or Basic configuration. These are both sets of Virtual Machines and can be shared across your websites. In the old portal you could only scale the group of websites together but the new Azure Management portal now allows you to move your websites on to different virtual machines so that if one site is more heavily loaded than others it can be scaled out separately if required. The set of virtual machines is known as a Web Hosting Plan. If you want to move one or more of your websites to a different set of virtual machines then you will need to create a new web hosting plan for this.

In the new portal click on “Browse” in the left hand bar

image

This brings up the Browse Menu.

image

Select “Web hosting plans”

image

You can see that I only have 1 web hosting plan and it is currently hosting two websites. I would like to move them onto separate virtual machines so that I can scale them out independently.

To do this I need to navigate to the web site I wish to move.

image

The top menu needs to be expanded by clicking the 3 dots on the right of the menu bar. this then displays the web hosting plan button.

image

Clicking this displays the web hosting plan associated with this web site

image

Clicking on the new hosting plan option allows you to create a new plan

image

I’ve selected a standard small instance to host my website.

After clicking OK the new hosting plan will be created and the website moved to it. After a short while you should see that the hosting plan has changed in this website as well.

image

Note: you now have two hosting plans both of which will be a separate billing entity. I am also led to believe that if you move everything off of a hosting plan you will still be charged for it.Hosting plans can be deleted once all the websites have been moved off of it. This is done in the Web hosting plan page. right click on the plan you want to delete and select the Delete option

Creating a Simple Workflow with Azure Webjobs and Service Bus

With the announcement of an upgrade to the webjobs service in Microsoft Azure service bus triggers to Topics and Queues were added.

This got me thinking about how they could be used and there are a lot of scenarios where events need to trigger simple actions as well as running things off of a timer. Utilising Service Bus Topics along with a number of filtered subscriptions led me to create a simple workflow using Webjobs and Topics.

Setting up web jobs is fairly easy and the two links at the top of this article will give you a good start to this along with the 3 articles written by Mike Stall (about Blobs, Queues and Tables) (although the syntax has changed with the latest update, but its easy enough to work out the changes)

The first thing to note which I didn’t pick up on straight away was that you need to  make sure that you set up connection strings for the diagnostics to work. I did this in the Configure section of the web site where I was deploying the webjob. I also added it to my app.config file so that I could debug locally in Visual Studio

image

They all point to my Azure Storage account.

The way I set this up was to create a message class that contained the data that I wanted to send between states. This message class would be wrapped in a BrokeredMessage and I would use the properties to determine the state of the message. The message is then added to a Service Bus Topic. By setting properties on the message, I could create a number of subscriptions that had an SqlFilter applied which would allow the subscription to only contain messages of a specific type.

When coding this I created a basic console application and added the following code to the Main method: 

// now create the subscriptions for the states
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "start"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "start", 
                      new SqlFilter("State='WorkflowStart'"));
}
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "state1"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "state1", 
                      new SqlFilter("State='WorkflowState1'"));
}
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "state2"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "state2", 

                      new SqlFilter("State='WorkflowState2'"));
}

This allows me to create Topic triggers for the webjob for specific states as follows:

public static void SimpleWorkflowStart(
   [ServiceBusTrigger(TopicName, TopicName + "start")] BrokeredMessage message, TextWriter log)
{
      log.WriteLine("Workflow Started");
      .
      .
      .
 }

Two things to note with the method above. Firstly, the ServiceBusTrigger requires both the Topic name and the subscription name in order to receive the filtered list of messages. Secondly, by adding the TextWriter you can then send logging information to the dashboard, which is useful when trying to diagnose the webjobs when deployed to Azure.

I then setup a number of other methods for each subscription for each state. This allows me to perform whatever action I wanted to in each state. After carrying out the action I modified the message by changing the state property and then put it back onto the Topic. You can’t use the same brokered message so you either have to copy all the data out of the existing message and create a new one or you can use the Clone method on Brokered message (the easy option Smile).

// copied the old message
 BrokeredMessage newMessage = message.Clone();
// change the state
newMessage.Properties["State"] = "WorkflowState2";
TopicClient tc = TopicClient.CreateFromConnectionString(
               ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString, TopicName);
// delay sending the message a little
newMessage.ScheduledEnqueueTimeUtc = DateTime.Now.AddSeconds(10);
// send it
tc.Send(newMessage);

In my example I also added a delay to the Enqueue of the message so that I could see things progressing in order. The enqueue time of the message is the delay before the message appears in the subscription. This could be also be used as a delayed trigger if you needed something done after a specific time interval. I also achieve this by adding the data to a Azure SQL db and then using a scheduled webjob to check the db for expired jobs. I created a separate console application for this which looked for messages that were expired due to a specific start date being older than a certain time, sending an email using SendGrid and then marking the record as complete in the db.

Webjobs made the actions easy to do and with the addition of the service bus triggers allowed me to have a fairly simple code structure to carry our a sequence of simple action (which is often what we need to do) without a heavy overhead of a workflow engine. It also utilised a hosting environment that I was already using.