CosmosDB – Build 2017 Recap Vienna

AzureCosmosDBViennaSpeakerAuf der Veranstaltung //BUILD on Tour gestern bei Microsoft Österreich durfte ich einen Vortrag zum Thema “CosmosDB” halten.

Die Slides zu meinem CosmosDB Vortrag könnt ihr hier herunterladen. Auf GitHub findet ihr meinen Source Code zum CosmosDB Vortrag und hier das Azure CosmosDB Graph Explorer Beispiel.

Hier auch die Gremlin Queries für das Beispiel aus The Hobbit.

Aja, nachdem es für einige Verwirrung gesorgt hat. In CosmosDB gibt es nur Request Units (RU) pro Sekunde/Minute und keine Orks Smile. Obwohl es hätte was.

Bester Sager eines Teilnehmers in dem Vortrag zu den UWP Apps: “Helene Fischer? Naja ohne Ton gehts” *haha*

Viel Spaß

AndiP

Global Azure Bootcamp 2017 Nachlese

 

Wissensturm in Linz 2017 (c) by Andreas PollakWie jedes Jahr fand auch heuer das Global Azure Bootcamp  für Österreich im Linzer Wissensturm statt. Wie immer , dank Rainer Stropek und Karin Huber, ausgezeichnet organisiert und mit spannenden Vorträgen versehen.

Diesmal durfte ich gleich zwei Vorträge zu den Themen “Azure API Management” und “Azure DocumentDB” beisteuern.

Speaker Foto (c) by Rainer StropekUnterhalb findet ihr die Verweise zu den Vortragsslides. Dort könnt ihr auch die Codebeispiele von GitHub herunterladen.

 

Slidedecks & Source

Viel Spaß und bis demnächst

AndiP

Direct Methods and MQTT Box in action

This is to anyone who wants to connect MQTT-Box to Azure IOT-Hub. In my last post I was changing the Microsoft.Azure.Devices.Client implementation to enable Direct Methods. In this article I am showing how to setup MQTT-Box to be able to receive Direct Messages there.

First and foremost you need to create a new IoT-Hub instance with “DeviceManagmentPreview” enabled. If you struggle with this have a look at this post.  To create the shared access signatures we use Device Explorer which you can get here. After you have set up IOT-Hub and downloaded MQTT-Box and Device Explorer start up those tools.

Copy the connection string from the IOT-Hub SAS-policy “iothubowner” to the connection info in Device Explorer:

image

Switch to Management-Tab and click “Create…” to create a new Device. Lets name it “myDeviceId”. Leave the suggested keys and click “Create”.   Click button “SAS Token…”. Select your device, set the time to live (TTL) to 1 and click “Generate”.

image

Copy the value of the SharedAccessSignature (everything after “SharedAccessSignature=”). The result should look like this

SharedAccessSignature sr=<yourIOTHubName>.azure-devices.net%2Fdevices%2F<yourDeviceId>&sig=<signature>&se=<se>

Then start MQTT-Box and create a new MQTT Client

image

Copy the SAS into the password field. Set the following fields and settings:

MQTT Client Name = Something
MQTT Client Id = <your Device ID>
Append timestamp to MQTT client Id? = NO
Protocol = mqtts / tsl
Host = <yourIOTHubName>.azuredevices.net:8883
UserName = <yourIOTHubName>.azure-devices.net/<your Device ID>/DeviceClientType=azure-iot-device%2F1.1.0-dtpreview&api-version=2016-09-30-preview

Click “Save” – You should get a green “Connected”-Button

image

Finally to receive the messages set the “Topic to subscribe” in the yellow box to:

  • $iothub/methods/POST/#

Then hit the “Subscribe”-Button. Now you need to start the node sample from this article to send a direct message to your device on your IOT-Hub. As a result you will receive the message in you MQTT-Box.
image

Of course, since we do not reply here the node client writes out a timeout error after a while. If you want however to send a successful response have a look at the “Topics to publish” section in MQTT Box

Prepare the “Topic to publish”: $iothub/methods/res/200/?$rid=
Payload Type: Strings /JSON / XML /Characters
Payload: “Hello”

Now use the node client to send a direct message again. Have a look at the results in the orange box and quickly copy the number after “$rid=”. After the second call it should be “2”. In the image above it is “1”.

Add this RID-Number to your Topic to publish. In this case: $iothub/methods/res/200/?$rid=2

Hit “Publish”. The message should pop up below:
image

In your node window you will get the result:
image

Enjoy
AndiP

Enable IOT Hub DeviceManagement Preview

imageI do not know if it is just my portal which is missing the “Enable Device Management PREVIEW” – Checkbox when creating a new IOT-Hub. It is still described in the article “Tutorial: Get started with device management” from Juan Perez .

You still can create it with an ARM Template by setting the “Feature”-Field to “DeviceManagement”.

I have written an ARM Template for an IOT-Hub with Device Management which you can download here. Be aware though, that this only works in certain regions like NorthEurope (but now WestEurope).

Enjoy
AndiP

Direct Methods with IOTHub in C#

There is a new preview in town. With this you can invoke a direct method on a device. Currently only MQTT devices are supported in this scenario. There is a nice article with some NodeJS samples. When Roman Kiss posted on the Azure Forum that he would like to write his simulated device in C# I thought this might be an nice opportunity to figure out why this does not work.

Well the answer is pretty simple: It is not yet implemented in the C# SDK.

But being me I decided to make the “impossible” possible (for the fun sake of it). First I did pull the complete preview of the Azure IOT Sdks  from github. Then I spend some time in figuring out what the NodeJS implementation does. I love debugging JavaScript *sigh*.

And then I quickly modded (aka hacked) the Microsoft.Azure.Devices.Client (Be aware that this is not an optimal solution Smile). These are the changes I made:

Microsoft.Azure.Devices.Client – MqttIotHubAdapter

sealed class MqttIotHubAdapter : ChannelHandlerAdapter
...
const string TelemetryTopicFormat = "devices/{0}/messages/events/";
// ADDED =>
const string MethodTopicFilterFormat = "$iothub/methods/POST/#";
const string MethodTopicFormat = "$iothub/methods/res/{0}/?$rid={1}";

Microsoft.Azure.Devices.Client – MqttIotHubAdapter – Connect Function

This was the most difficult to find out, because I did not expect this “hack”. Expect the unexpectable!
async void Connect(IChannelHandlerContext context)
{
...
var connectPacket = new ConnectPacket
{
ClientId = this.deviceId,
HasUsername = true,
// CHANGED => You need to add this weird suffix to make it work!
Username = this.iotHubHostName + "/" + this.deviceId + "/DeviceClientType=azure-iot-device%2F1.1.0-dtpreview&api-version=2016-09-30-preview",
HasPassword = !string.IsNullOrEmpty(this.password),

Microsoft.Azure.Devices.Client – MqttIotHubAdapter – SubscribeAsync Function
Here I added the method topic subscription!

async Task SubscribeAsync(IChannelHandlerContext context)
{
if (this.IsInState(StateFlags.Receiving) || this.IsInState(StateFlags.Subscribing))
{
return;
}

this.stateFlags |= StateFlags.Subscribing;

this.subscribeCompletion = new TaskCompletionSource();
string topicFilter = CommandTopicFilterFormat.FormatInvariant(this.deviceId);
var subscribePacket = new SubscribePacket(Util.GetNextPacketId(), new SubscriptionRequest(topicFilter, this.mqttTransportSettings.ReceivingQoS));
System.Diagnostics.Debug.WriteLine($"Topic filter: {topicFilter}");
await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);
await this.subscribeCompletion.Task;

// ADDED => WE are using the const I decleared earlier to construct the topicFilter
this.subscribeCompletion = new TaskCompletionSource();
topicFilter = MethodTopicFilterFormat.FormatInvariant(this.deviceId);
System.Diagnostics.Debug.WriteLine($"Topic filter: {topicFilter}");
subscribePacket = new SubscribePacket(Util.GetNextPacketId(), new SubscriptionRequest(topicFilter, this.mqttTransportSettings.ReceivingQoS/*QualityOfService.AtMostOnce*/));
await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);
await this.subscribeCompletion.Task;
// <= ADDED

}
Microsoft.Azure.Devices.Client – MqttIotHubAdapter –SendMessageAsync Function
Since we do want to acknowledge the arrival of the method we need to modify this too:
async Task SendMessageAsync(IChannelHandlerContext context, Message message)
{
// CHANGED => For our publish message we need to send to a different topic
string topicName = null;
if (message.Properties.ContainsKey("methodName"))
topicName = string.Format(MethodTopicFormat, message.Properties["status"], message.Properties["requestID"]);
else
topicName = string.Format(TelemetryTopicFormat, this.deviceId);
// <= CHANGED

PublishPacket packet = await Util.ComposePublishPacketAsync(context, message, this.mqttTransportSettings.PublishToServerQoS, topicName);
...
Microsoft.Azure.Devices.Client – MqttTransportHandler – ReceiveAsync Function
Since we do not get a lockToken with the Methodcall, we should not enqueue the Null in our completionQueue
public override async Task<Message> ReceiveAsync(TimeSpan timeout)
{
...
Message message;
lock (this.syncRoot)
{
this.messageQueue.TryDequeue(out message);
message.LockToken = message.LockToken;
// Changed line below to exclude LockTokens that are null #HACK better check if it is a Method message
if ((message.LockToken != null)&&(this.qos == QualityOfService.AtLeastOnce) )
{
this.completionQueue.Enqueue(message.LockToken);
}
...
Microsoft.Azure.Devices.Client – Util– ComposePublishPacketAsync
A little change here to prevent that this method “destroys” our carefully constructed topic name earlier.
public static async Task<PublishPacket> ComposePublishPacketAsync(IChannelHandlerContext context, Message message, QualityOfService qos, string topicName)
{
var packet = new PublishPacket(qos, false, false);

// MODIFIED ==>
if (message.Properties.ContainsKey("methodName"))
packet.TopicName = topicName; // Make sure to keep our Topic Name
else
packet.TopicName = PopulateMessagePropertiesFromMessage(topicName, message);
// <== MODIFIED
...

Microsoft.Azure.Devices.Client – Util– PopulateMessagePropertiesFromPacket
And finally we need to populate our method Messages with properties like our requestID, methodName,…
public static void PopulateMessagePropertiesFromPacket(Message message, PublishPacket publish)
{
message.LockToken = publish.QualityOfService == QualityOfService.AtLeastOnce ? publish.PacketId.ToString() : null;

// MODIFIED ==>
Dictionary<string, string> properties = null;
if (publish.TopicName.StartsWith("$iothub/methods"))
{
var segments = publish.TopicName.Split('/');
properties = UrlEncodedDictionarySerializer.Deserialize(segments[4].Replace("?$rid", "requestID"), 0);
properties.Add("methodName", segments[3]);
properties.Add("verb", segments[2]);
}
else
properties = UrlEncodedDictionarySerializer.Deserialize(publish.TopicName, publish.TopicName.NthIndexOf('/', 0, 4) + 1);
// <== MODIFIED

foreach (KeyValuePair<string, string> property in properties)
{
...

Building the simulated device with the modded Microsoft.Azure.Devices.Client SDK
Just create a new Console application and reference the modded SDK
 
using Microsoft.Azure.Devices.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace DeviceClientCS
{
class Program
{
private static async void ReceiveCloudToDeviceMessageAsync(DeviceClient client,
string theDeviceID)
{
Console.WriteLine($"Receiving messages from Cloud for device {theDeviceID}");
while (true)
{
Message receivedMessage = await client.ReceiveAsync();
if (receivedMessage == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Received method ({receivedMessage.Properties["methodName"]}): {Encoding.ASCII.GetString(receivedMessage.GetBytes())} for device {theDeviceID} - Verb: {receivedMessage.Properties["verb"]}");
Console.ResetColor();

// ACKNOWLEDGE the method call
byte[] msg = Encoding.ASCII.GetBytes("Input was written to log.");
Message respondMethodMessage = new Message();
foreach (KeyValuePair<string, string> kv in receivedMessage.Properties)
respondMethodMessage.Properties.Add(kv.Key, kv.Value);
respondMethodMessage.Properties.Add("status", "200");
await client.SendEventAsync(respondMethodMessage);
}
}


static void Main(string[] args)
{
string deviceID= "myDeviceId";
string connectionString = "<Your device connection string goes here>";

DeviceClient client = DeviceClient.CreateFromConnectionString(connectionString, deviceID, TransportType.Mqtt);
ReceiveCloudToDeviceMessageAsync(client, deviceID);
Console.ReadLine();
}
}
}
 
And here is a final screen shot of my results:
Result
Cheers
AndiP

 
 
 
 

Ubuntu with Visual Studio Code ARM Template

 

Setup the new cross-platform ASP.NET Core with Visual Studio Code on a Linux machine quickly? It’s a bit tedious to do all the required installation bits, not to mention to figure out the little issues.

DeployToAzure

imageUsing our new ARM-Template you can setup such Box on Microsoft Azure with a single click on the Deploy-Button (if you have an Azure Account already, if not get one here)! 

Then fill the parameters with values

  • Credentials
  • DNS-Name
  • Run full Ubuntu-Desktop? (installation will take much longer, but you can play Mahjong)
  • Resource-Group Name

and click “Create”.

The ARM Template installs:

  • Docker (from Docker Extension)
  • Ubuntu Desktop with XRDP and xfce4 (Full or Minimal)
  • Visual Studio Code
  • .NET Core SDK
  • NodeJS and NPM v6
  • Yeoman with ASP.NET Generator
  • C# Extension for Visual Studio Code in Visual Studio Code

RDPLoginLater use Remote Desktop Connection to connect to your machine! Computer:<DNS-Name>.<Location of Resource Group>.cloudapp.azure.com. Enter your credentials in the xrdp login dialog. Make sure “sesman-Xvnc” is selected!

 

VSCodeMenuYou find Visual Studio Code under Development. Or you can start it from the shell with “code .”. You also may use Yeoman with the preinstalled ASP.NET Generator.

Read more about the ASP.NET Generator at the blog of Scott Hanselman.

Enjoy playing with .NET Core and Visual Studio Code running in Windows Azure

YOGeneratorAndiP

API Management on Global Azure Bootcamp 2016

I recently had the opportunity to give an introduction into API Management at the Global Azure Bootcamp 2016 in Linz. You can find the pickings of that event here (german only). I decided to publish my slides about API Management but also some information about the demo environment I used.

Ok this turned out to be more a blog post about how to authenticate Web Apps with Web API Apps Smile

First and foremost, to play around with Azure API Management you need a Microsoft Azure Subscription, which you can get here.

My demo environment looked like this:

  • 1 developer instance of API Management managed through the classic azure portal.
  • 1 azure resource group where I run a free  App Service Plan managed through the new azure portal with
  • 3 Azure API Apps (CalcGAB2016, CalcEnterprise, CalcEnterpriseClient)
  • 1 azure active directory instance managed through the classic azure portal.

If you plan to create API Apps yourself I recommend to use the template “Azure API APP” in ASP.NET applications. This will come preconfigured with the Swashbuckle packages which allow to create an OPEN API SPECIFICATION (formerly known as swagger) document straight from your code. You can read more here about how to customize the swashbuckle  generated api definitions.

Now to my sample code. Since there is plenty of documentation on how to use API-Management (you can find an incomplete but helpful list in the last slide of my presentation). My JWT-Token demo is based on the presentation from Darren Miller (see time – 7:30).

Therefore will focus instead on some specifics in the AAD Integration of the API app “CalcEnterprise” and the web app “CalcEnterpriseClient” which I have secured with AAD.

Securing Azure Web/API Apps

I love the idea that you can move out the authentication of your application and instead just configure it on the portal. Like a former colleague of me said: You do not want a web developer to write your authentication code Smile. Instead you just write the application with “No Authentication” selected and configure the access in the new management portal:

image

Depending on the authentication you selected your ClaimsPrincipal.Current object will hold all claims provided by the authority that authenticated your visitors. Aside of that you receive the complete token and some other information about the authentication in the headers that Azure provides:

X-MS-CLIENT-PRINCIPAL-NAME=f.e. email
X-MS-CLIENT-PRINCIPAL-ID=f.e. a GUID like in AAD
X-MS-CLIENT-PRINCIPAL-IDP=Identity Provider (AAD => aad)
X-MS-TOKEN-AAD-ID-TOKEN=in AAD the JWT Token with additional claims, that you also can find in ClaimsPrincipal.Current.Claims if you happen to run the application in ASP.NET

Step 1 Configure your AAD & securing your Web APP/API

After you have created a new AAD instance like <yourChoosenName>.onmicrosoft.com you can define an AAD application which your application will be using. Under Applications Tab

  • Add new application “Add an application that my organization is developing”
  • Name it and select “Web Application and/or WEB API”
  • Provide the sign-in url which will be the URL to your website like: https://&lt;yourapp>.azurewebsites.net
  • Provide an unique ID which can be any unique URI, but for multitenant applications use the base tenant uri in combination like so: https://<yourTenantName>.onmicrosoft.com/<your unique name of the app>

After you have created the application you will find also populated the REPLY URL which is important as the JWT Token will be sent only to this URL by the identity provider! To configure Authentication/Authorization for your Web APP/API:

  • copy Client ID of your AAD Application
  • Open “View Endpoints” (button on the bottom of the screen) – Copy the URL of the Federation Metadata Document
    Open the Federation Metadata Document URL in a browser
    In the XML find the element “Entity” and copy the content of the  attribute “entityID” which contains the link to the Issuer (Issuer  URL)

You will need these two values to configure Authentication/Authorization in your WebAPP/API like so:

image

Step 2 Applying this concept to my Sample Code

I figured out that I could create at least 2 different scenarios with my two Web APP/APIs:

  • Assign Client and API to a single AAD applications
  • Assign Client and API into separate AAD applications

With the first option I can easily authenticate my call into the API from my Client with the same identity that authenticated on the client (Implemented in the HomeController “Index_SameAAD”):image

With the second option I can my Client App as Service Principal to authenticate to my API, which hides the original identity for the API.
(Implemented in the HomeController “Index”):

image

But I also can re-authenticate the identity on the API to see the original identity. I found this excellent article of Vittorio Bertocci on using ADAL’s AquireTokenByAuthorizationCode to call a Web API from a Web APP which showed me the way how to implement this.(Implemented in the HomeController “Index_OtherAAD”):

image

Step 3 – Clone the source

Feel free to clone my source code from my github repository and play with it.

You need to replace following placeholders with actual values and deploy & configure your apps to Azure of course.

  • ”<your API MGMT API key>”
  • <yourAPIMInstanceName>
  • <yourcalcEnterpriseAPIwebsitesUrl>
  • <yourAPIMInstanceName>
  • <CalcEnterpriseClient AAD CLientID>
  • <CalcEnterpriseClient AAD App Secret/Key>
  • <CalcEnterpriseAPI AAD CLientID>
  • <yourTenantName>

First restore all packages – For some reasons I had issues in the Calc-Project with not loading the correct DLL for System.Web.Http and others (funny enough it shows errors in Visual Studio 2015 but still compiles fine *lol*). Closing the Solutions and opening the Project-File instead fixes this.

Clone the Source
Download Slides

Enjoy a nice day – AndiP

Connect ZyWALL 35 with Azure VPN site to site

Some time ago I got an “old” ZyWALL 35 from an ex colleague and I always wanted to configure a site-to-site connection  to Azure. Although Microsoft only provides automatic scripts for the more advanced professional enterprise VPN gateways you can configure the device (if it is capable of VPN) yourself. This however can have some caveats like different expected key sizes, where you need to work around.

Hopefully this helps others with a ZyWALL35 to configure site-2-site connection and also those who also happen to have a different device.

I divided the article into the following sections:

  1. Setting up the virtual network environment in Azure
  2. Set Shared Key Length in Azure VNET to 31
  3. Configuring the ZyWALL35

May you succeed Smile.  Cheers AndiP!

1. Setting up the virtual network environment in Azure

My small private local network is operating in the following address range: 10.0.0.0/24 (10.0.0.0 – 10.0.0.255). I do want to have my Azure machines operate in the local VNET in the address range 10.0.1.0/24. So first of all we will create a virtual network in Azure for that purpose. Log into the Azure Management Portal. With the “+ NEW” button in the lower left corner we create a new virtual network.

image

image

image

Then hit the “Create”-Button. After Azure has created the virtual network we are presented with the Dashboard of our new virtual network. From there we add more Subnet’s.

image

Here we add another subnet (Do not forget to save the changes with the SAVE button!). I left some address range empty because this will be required by the Gateway-Subnet for the VPN Site-to-Site connection. Unfortunately you cannot add the Gateway-Subnet here in the new portal.

Name Address Space CIDR Block
Subnet-2 10.0.1.0/24 10.0.1.32/27

Now we need to configure our site to site connection by clicking into the VPN connection section. Inside the VPN Connection settings we select “Site-to-site” and give the local site a name (in our case “SpectoLogicLocalVPN”). As VPN gateway IP address we provide the public facing IP address of our ZyWALL 35 behind the internet modem. Finally we provide the address ranges of our local network we would like to connect. Due to a bug in the new Azure Portal you need to checkCreate gateway immediately”*.

It is also important to set the optional gateway configuration (see images below). Set the routing type to “Static”!

*Otherwise you will get the error “Deployment Failed”. The reason might be that you are not able to create the required Subnet-Gateway in the SubNet section. Once you created a site-to-site connection and remove it again you cannot remove the new created “Gateway Subnet” in the subnets, even though you would not require it any longer (another bug).

image    image

image

We can now see the new automatically added subnet “GatewaySubNet”:
image

Creating the gateway will take some time. (UP to 25 minutes)!

Once the gateway is created we will see the result here. The public gateway IP-Address will be needed later when we configuring our ZyWALL35 device!
image

2. Set Shared Key Length in Azure VNET to 31

Azure  uses SharedKeys that are bigger than the ZyWALL 35 supports. So we have to set the key size in Azure manually via PowerShell Script to change it to a smaller value. In our case “31”!

As David pointed out in the comment section there is now an easier way to achieve this.

We also need to switch to the old Azure Portal as the new portal does not allow the shared key management. Navigate to your VNET and you will find the “Manage Key”-Button in the Dashboard of the VNET:
image

Unfortunately the key is 32 characters long:
image

While we are at it. Although we gave meaningful names in our new Azure Portal the names of the local VPN Network and the Azure Network are completely differing from what we originally entered. I assume that this is because of the new “Resource Group” management. It makes things a bit more complex as we need the “real” names for our powershell script.

The VNETName can be found either in the new portal here Surprised smile:
image
or in the old portal here:
image

The local network name can be found in the new portal here Surprised smile Surprised smile Surprised smile:
image
or in the old portal here:
image

Now, after we somehow managed to find out the real names we can use them in our script below. Make sure you have imported the Azure publishing settings file and that you have imported the certificate either to your personal or local machine store. If not you need to know the Thumbprint of the certificate and assign it to the variable $mgmtCertThumb. If the certificate can be found in the store the script will locate it for you:

# Sets a vpn key with a smaller keylength
# © by Andreas Pollak / SpectoLogic

$subID = (Get-AzureSubscription -Current).SubscriptionId
$VNetName = „Group SpectoLogic_Resources SpectoLogicVPN
$VNetNameLocal = „9A10F5F7_SpectoLogicLocalVPN
$uri = „
https://management.core.windows.net/“+$subID+“/services/networking/“+$VNetName+“/gateway/connection/“+$VNetNameLocal+“/sharedkey“
$body = ‚<?xml version=“1.0″ encoding=“utf-8″?><ResetSharedKey xmlns=“
http://schemas.microsoft.com/windowsazure“><KeyLength>31</KeyLength></ResetSharedKey>‘;

#Identify Management Certificate Thumbprint
$mgmtCertThumb = $null

$mgmtCertCandidateCount = (Get-ChildItem -path cert:\CurrentUser\My\ | Where-Object {$_.FriendlyName -like ((Get-AzureSubscription -Current).SubscriptionName + ‚*‘)}).Count
if ($mgmtCertCandidateCount -ne 1)
{
$mgmtCertCandidateCount = (Get-ChildItem -path cert:\LocalMachine\My\ | Where-Object {$_.FriendlyName -like ((Get-AzureSubscription -Current).SubscriptionName + ‚*‘)}).Count
if ($mgmtCertCandidateCount -eq 1)
{
$mgmtCertThumb = (Get-ChildItem -path cert:\LocalMachine\My\ | Where-Object {$_.FriendlyName -like ((Get-AzureSubscription -Current).SubscriptionName + ‚*‘)} | Select-Object -First 1).Thumbprint
}
else
{
echo „Could not locate the certificate thumbprint of the corresponding azure
management certificate!“
echo „Please make sure to install the azure management certificate in the ‚personal‘
folder “
echo „of either the ‚local machine‘ or ‚current user‘ certificate store on your
machine! “
echo „The friendly name of the certificate must start with the SubscriptionName to be
automatically detected! “
}
}
else
{
$mgmtCertThumb = (Get-ChildItem -path cert:\CurrentUser\My\ | Where-Object {$_.FriendlyName -like ((Get-AzureSubscription -Current).SubscriptionName + ‚*‘)} | Select-Object -First 1).Thumbprint
}

$headerDate = ‚2012-03-01‘
$headers = @{„x-ms-version“=“$headerDate“}

Invoke-RestMethod -Uri $uri -Method Put -Body $body -Headers $headers -CertificateThumbprint $mgmtCertThumb

After running the script we can now acquire our key and store it for later when we configure our ZyWALL35. It should be 31 characters long now. ATTENTION: DO NOT RECREATE THE KEY. Otherwise it will be 32 characters long again. Use the script again to regenerate the key!

3. Configuring the ZyWALL35

Finally we get to configure our ZyWALL35. First we download a script as text file where we can read the basic configuration settings like HASH, Encryption Algorithms,…

image

We log on to the ZyWALL35 Configuration Website and select VPN from the “Security”-Menu.

image image

Configure the Global Settings as shown in this screen shot:
image

Select the tab “VPN Rules (IKE)”.  Add a new gateway policy by clicking on the “add new gateway policy” button (image).

In the section “Property” we name our local VPN Gateway Policy “SpectoLogicVPNGWPolicy”. Also make sure NAT Traversal is checked!

In the section “Gateway Policy Information” we need to provide our local public IP address as well as the public Azure VPN Gateway address. So under “My ZyWALL” we provide our local public IP address:
image

Under “Primary Remote Gateway” we provide the public Azure Gateway IP-Address. In our home scenario we leave IPSec High Availability unchecked.
image

Since I have not set up any PKI Infrastructure I go for the simple “Pre-Shared-Key” Authentication. Note that the ZyWALL 35 only supports Pre-Shared-Keys that are 31 characters long. This conflicts with Azure, per default not allowing smaller key sizes. See section “Set Shared Key Length in Azure VNET to 31 “ above on how to change that.
image

We leave the extended authentication settings untouched (uncheck “Enable Extended Authentication”)  and configure the IKE Proposal.
image

Finally we hit apply. Back in the “VPN Rules (IKE)”-Tab  we select “Add Network Policy”:
image

We name the VPN Network Policy “SpectoLogic VPN Net Policy” and set it to active (check that checkbox!). Also check “Nailed-up”!
image

The linked Gateway Policy should already appear populated:
image

In the section “Local Network” we select “Subnet Address” from the “Address Type” dropdown and we provide the starting IP address in our local network and define the subnet mask for the range.
image

Now we also need to configure our remote network under the “Remote Network” section. Again we select “Subnet Address” from the “Address Type” dropdown and provide starting IP address and subnet mask:
image

For the IPSec Proposal select the same values we already used for the VPN Gateway Policy (Exception: PFS set to NONE!):
image

So we end up with:
image

To Connect / Disconnect the VPN in the new portal click on the following elements:
image
You also can pin the last element to your dashboard by right clicking on the name of the VNET in the middle section:
image

Finally we can enjoy our site-2-site connection (New Portal / Old Portal):

imageimage