Creating Azure Logic Apps from R using httr

May 2019 · 3 minute read

Logic Apps is a serverless framework in Azure quite similar to IFTTT (if this, then that) and Zapier that allows you to connect different services and create workflows.

You can define different types of triggers based on:

to start workflows.

Logic Apps can be created using a visual interface in the Azure Portal, but also programmatically using the Azure REST api. In this post I want to show you how we can create Logic Apps in Azure directly from R.

Getting Started

To create or update Logic Apps, we will use the following REST call template:

# Line breaks for legibility only
PUT subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/
providers/Microsoft.Logic/workflows/<workflowName>
?api-version=2016-06-01  HTTP/1.1
Authorization: Bearer <bearer-token>
Content-Type: application/json
Host: management.azure.com

{
  <body>
}

But before we can start, we need to create a resource group in Azure for our Logic App.

We will use httr to send the PUT request to create the resource group, but first we need to acquire an access token (Note: make sure you have httpuv installed as well):

library(httr)

app_name = "azure_mgmt"

# client_id of Azure CLI so we do not need to register an app
client_id = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"    

# we have no client secret, we do everything interactively
client_secret = NULL

# Your tenant_id/directory_id -> azure portal/azure active directory/Properties/directory id
tenant_id = "441ec6d2-e277-43f8-b599-8dc54649d5c8"

# azure subscription -> azure portal/subscriptions
subscription = "a946be7b-3533-413d-9366-91e10c0b209b" 

# name of the logic app workflow in azure
workflow_name = "serverless_testworkflow"     

# endpoint we need to request permission to
resource_uri = "https://management.core.windows.net/"

# Endpoints are of the form: 
# https://login.windows.net/<tenant-id>/oauth2/<authorize | token>
azure_endpoint = oauth_endpoint(authorize = glue::glue("https://login.windows.net/{tenant_id}/oauth2/authorize"),
                                access = glue::glue("https://login.windows.net/{tenant_id}/oauth2/token"))

logic_app = oauth_app(
  appname = app_name,
  key = client_id,
  secret = client_secret
)

token <- oauth2.0_token(azure_endpoint, logic_app,
  user_params = list(resource = resource_uri),
  use_oob = FALSE
)

We can now create our resource group like so:

resource_group = "serverless"                         # Resource group we are going to use
url = glue::glue("https://management.azure.com/subscriptions/{subscription}/resourcegroups/{resource_group}?api-version=2018-05-01")

body = paste0('
  {
  "location": "westeurope"
}'
)

PUT(url = url,
    add_headers(.headers = c(
                "Authorization" = paste0("Bearer ", token$credentials$access_token)
                ,"Content-Type" = "application/json")
    ),
    body = body,
    encode = "json"
    )

Now, let’s try to stitch together our REST call to create a simple Logic App.

We will setup a super simple logic app with an http trigger that returns a “Hello world!”:

{
    "properties": {
        "definition": {
            "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
            "actions": {
                "Response": {
                    "inputs": {
                        "body": {
                            "response": "Hello world!"
                        },
                        "statusCode": 200
                    },
                    "kind": "Http",
                    "runAfter": {},
                    "type": "Response"
                }
            },
            "contentVersion": "1.0.0.0",
            "outputs": {},
            "parameters": {},
            "triggers": {
                "manual": {
                    "inputs": {
                        "schema": {}
                    },
                    "kind": "Http",
                    "type": "Request"
                }
            }
        }
    },
        "location": "westeurope"
}

Let’s build the query to submit the request:

url = glue::glue("https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/Microsoft.Logic/workflows/{workflow_name}?api-version=2016-06-01")

body = readLines(con = "../../data/logic_app.json")


PUT(url = url, 
    add_headers(.headers = c(
                "Authorization" = paste0("Bearer ", token$credentials$access_token)
                ,"Content-Type" = "application/json")
    ),
    body = body,
    encode = "json"
    )

And we are done:) If you go to your resource group in the Azure portal, you should see the logic app we defined above.