Protecting Azure Logic Apps Using Azure API Management
In this blog post, we are going to explore two complementary Azure Services: Azure Logic Apps and Azure API Management. When used together, they allow developers to build secure and scalable solutions, without writing a lot of code.
For those of you who are new to these technologies, Azure Logic Apps is an Integration Platform as a Service (iPaaS) that allows organizations to build workflow and connectivity solutions in the cloud. Azure Logic App solutions can be authored using a modern web browser or Visual Studio. Logic Apps can also connect to many popular SaaS applications, on-premises Line of Business (LOB) systems and custom APIs. Azure API Management is a solution for managing APIs by providing security, productivity, monitoring and developer engagement capabilities. Azure API Management can manage APIs that reside on-premises, third party APIs, and first party custom APIs.
Why should I used these two Azure Services together?
You certainly do not need to introduce API Management in front of Azure Logic Apps, but there are several reasons why you may want to, including:
1. Abstract your back-end implementation from consuming clients
When you are providing a service, the consuming client really does not need to know where your backend endpoint is or what the underlying implementation is. By introducing API Management, you have agility in your backend and can make changes without impacting your client.
A common feature of many API Management platforms, including Azure API Management, is the ability to cache responses to common requests. For example, if you have an application that fetches common (static) data, like company master data, why would you want to fetch this same dataset on every request? These redundant calls become very expensive when you bridge a mobile application with an on-premises Line of Business (Lob) system. You can typically save a couple hundred milliseconds to a few seconds by caching this type of information and increasing end user satisfaction. API Management can protect your backend systems from being hit too hard by consuming clients. For example, if you have a “freemium” service tier that allows consumers to make 100 transactions per minute, you can easily enforce this using API Management. This ensures your backend systems have system resources available to handle requests from your “platinum” customers.
When you expose a Logic App with an HTTP endpoint, a SAS token is included in the URL that gets exposed. This token acts as credentials for a calling application. However, this is not enough for some organizations. Using Azure API Management allows an organization to layer additional security on top of existing solutions. These additional layers may include OAuth 2.0, Azure Active Directory, connecting to a virtual network, Mutual Certificate authentication and Basic authentication.
Azure API Management provides policies that allow for small, but powerful, changes to what the API will be called. Policies may include changing payload formats (XML, JSON), CORS, string manipulation, checking or modifying HTTP headers, setting HTTP status codes, retries and logging to an Event Hub, for example.
While the telemetry for Azure Logic Apps is quite good, there are some advantages to using Azure API Management’s out of box telemetry. It’ll give you some region-specific information, performance, consuming client and blocked requests, to name a few.
6. API Orchestration
Azure Logic Apps are able to consume API Apps, that allow for connectivity to Microsoft first party systems, third party SaaS systems and your own custom APIs that can be hosted on-premises or in the cloud. Since most of these connectors are Restful APIs, API Management can call these directly. However, by doing so, you may be unnecessarily passing complexity down to your calling application and leaving them to deal with flow control, security, error handling and compensation. We will discover why this concept is very important in the following section.
The solution that we will be reviewing today is a client application, that needs to be able to create a ticket in an IT Service Management application. For our example, we will be connecting to ServiceNow, a popular SaaS-based service, used by more than 1800 companies, through a custom API App. The purpose of this API App, or connector, is to facilitate the connectivity between Azure Logic Apps and ServiceNow. The custom connector wraps ServiceNow Restful operations and have been decorated with Swagger so that it can be plugged into Azure Logic Apps quickly and easily.
As part of the custom connector, different resources and operations have been exposed, including the ability to access AssignmentGroups, Incidents and Users.
A challenge that developers will encounter is that all the operations are exposed at a very granular level. ServiceNow has done this to allow for the most flexibility for customers. But the problem is, that in order to create a ServiceNow Incident Ticket, one must also include required reference data, including a sysid for the group that the ticket should be assigned to and the sysid for the user that is logging the ticket.
In theory, we can protect the custom connector with API Management and pass the very granular API operations down to the client application. This would then create additional complexity for the client application, which is never a good practice. Instead, we can use Azure Logic Apps to perform some API Orchestration. We can wire up these additional calls to get the User and AssignmentGroup details inside a Logic App.
API App Connectivity
With our custom ServiceNow connector published to Azure, we need to ensure that it is accessible to Azure Logic Apps. In order to achieve this we need to enable CORS so that our Swagger metadata can be retrieved by Logic Apps. To keep things simple for this post, we will enable all Allowed Origins by providing a value of * within the CORS configuration of our custom ServiceNow API App. For a production application, you will want to be more specific about the origins that you allow.
We also need to provide the URL for our Swagger API definition. By providing this value, Logic Apps can understand what are the required inputs and expected outputs are when calling our ServiceNow API App operations.
Note: This URL can be retrieved from your API App’s Swagger launch page. See the Swagger image in the Solution Overview section of this document as an example.
With both CORS and our API definition set, we should be able to see our API App in our Logic Apps design canvas as shown below.
When we select our custom API App, we should see all of the exposed operations that are available to us. If this list will not load, there is an issue with CORS or our API definition.
Logic Apps Configuration
The following image illustrates the design of our Logic App.
The steps involved in processing inbound HTTP requests are:
1. We will expose a Request trigger that will accept a JSON message body. This JSON message body represents what our incoming payload should look like. In this particular instance, the JSON message instance was modeled using http://jsonschema.net/.
Note: When we save the Request configuration, a URL will be exposed that represents the location of our endpoint. We can copy the URL by clicking on the copy icon. We will use this URL later to test our service before wiring up Azure API Management.
2. Next, we need to retrieve the User and Assignment Group’s details in order to retrieve the sysid for each entity. In order to obtain this information, we need to pass in data from our request message into these Get operations.
3. By getting the required sysids, we can now execute Post operation that allows us to create a ticket. The remaining information comes from the original request message that was sent to the Logic App.
4. Lastly, we will construct a response message and return it to the caller. Since it was a Post and we did create a resource, we will return an HTTP Status code of 201 and include information from our ServiceNow calls including the Ticket Number.
5. Before wiring up Azure API Management, let’s perform a simple test using PostMan to ensure our Logic App is working as expected. The following image illustrates our request message, including our required message payload. Once called, we can see our response, including our newly created Ticket Number.
Azure API Management Configuration
Note: As of this writing, the following Azure API Management configuration is in public preview. This new capability is found in the new Azure portal. For the purpose of this blog post, I will be using my own developer instance of Azure API Management.
The API Management configuration was established using the following steps.
1. Within my API Management instance, a blade will appear that includes a link for APIs – PREVIEW. Once I click on this, I will be navigated over to the new API Management experience.
2. Within the new API canvas, there are several new ways to add an API including Logic Apps. In order to protect our recently-developed Logic App we can simply click on that icon.
3. Next, we need to select the Logic App that we would like to import. For this scenario we will select LA-ServiceNow-CreateTicket.
4. We now need to add some additional information such as a Description, API URL suffix, and our Base URL will be exposed. Clicking on Create will take us back to the Design surface. 5. Within the Design surface, we now have a visual representation of our API, including our Logic App Backend. If you look closely you can also see the current context is set for All operations. This allows us to make policy changes at a “global” level instead of at the operation level.
6. In order to explore our specific operation, we can click on Post manual run and we will then see our specific operation is in context. We can then click on the dropdown and take a look at the Form-based editor.
7. Within the Form-based editor, for the Frontend, we can change some of the settings to be more contextual including our Display name and Description. While in this section, we also have the ability to define any URL Template parameters, Query parameters, Headers and Request/Response content types, schemas and status codes
8. With our Ticket – Create operation in context, we can now check out the Form-based editor for the Inbound processing stage.
9. This is where this new integration between Azure API Management and Azure Logic Apps gets interesting. When we went through the import process, API Management was able to auto-configure some of the necessary information like what our Backend URL-Rewrite needs to be, including the SAS token that we discovered when the URL was created in step 1 of the Logic Apps Configuration. In the previous version of the API Management service, we had to perform all of this configuration manually.
10. When Azure Logic Apps receives a JSON message, it is dependent upon a Content-Type in order to infer the correct message structure. To ensure this content is always JSON, let’s add a header to this specific operation and include a value of application/json.
11. If we want, we can override the message body that will be sent over to our Azure Logic App on the Set body tab, but it is not required for this step. This information is just provided for awareness.
12. Next, we can check out our Backend configuration by clicking on the Form-based editor in that stage.
13. We will discover that an Azure resource has been set to Logic App, which should not be a surprise based upon our import action performed in step 2 of this section.
Note: This feature aligns with the Why is this important section of this document. Using API Management we can abstract the backend without the consuming client being impacted. Using this screen we can swap out our Logic App for another resource such as an HTTP endpoint, if we really wanted to, without impacting our consumer.
14. Lastly, we can check out the Outbound processing stage settings by clicking on Form-based editor.
15. Within this section, we can set any Outbound Headers or Body. For the purpose of this blog post, it is not required but has been included for awareness.
If you are familiar with Azure API Management, you have likely used the Developer Portal to test your APIs. It is also a good resource for providing access to developers who will be consuming your API in order to get started. The Developer Portal still exists and can be accessed using the following link.
However, it is not the only way you, as an admin, can test your API. There is now a Test tab in the design surface. When we click on this link, we are navigated to a test harness where we can try out our API.
Within this view, we will have our required Headers populated. We can also provide a Request body (bonus marks if you have already included a sample body in your configuration) and click the Send button to submit your request.
After we have submitted a request, a HTTP response will be displayed that includes our Ticket Number from ServiceNow.
For more detailed information, we can click on the Trace link where detailed diagnostic information is included.
The level of detail within this blog post only scratches the surface of what is possible when these two services are put together. One area which we did not get into was all of the available policies that are out of the box with Azure API Management. Within this latest instance of Azure API Management, we still have a code view where we can quickly configure XML policies. Using these policies we can add functionality for security, load and rate limiting, flow control, whitelisting or blacklisting IP ranges, model custom flow control, add additional logging to Event Hubs, convert JSON <-> XML and enable caching.
Another common request that I have heard, and agree with, is for the ability to restrict where your Logic App is being called from. For example, if someone has your Logic App endpoint and SAS key, they can call it from anywhere and by-pass Azure API Management which defeats the purpose of using Azure API Management.
Well, this is no longer a concern. Recently, the Logic Apps team has provided Access control configuration that allows you to restrict IPv4 or IPv6 ranges.
Azure API Management will provide you with a static IP address for the lifetime of the tenant when you are using either the Standard or Premium tiers. There are a few exceptions, which are described in the following post.
In this post, we explored how Azure API Management can protect Azure Logic Apps that have been exposed by an HTTP endpoint. We also discussed some of the benefits that Azure API Management and Azure Logic Apps can provide developers by giving Service Abstraction, Performance, Security, Agility, Monitoring and API Orchestration capabilities. Even more, we saw the new Azure API Management design canvas, explored some API Management policies and demonstrated how we can restrict access to our Azure Logic App.
Kent Weare is a senior enterprise architect at TransAlta, a multi-national power generation and energy trading company. His expertise includes BizTalk, logic apps, API management and service bus technologies. In addition to his enterprise architect responsibilities, he writes for InfoQ.com on matters relating to cloud computing. Kent holds a master’s degree in Information Management from Arizona State University and a computer science degree from the University of Regina.