We are running Logic Apps in Docker containers in our Kubernetes environment (using the NodeJS version, doing development in VS Code), and it works great; has full access to your on-premise resources, if you have an on-premise Kubernetes environment this is a no-cost (or minimal) approach to deploying your Logic Apps.
I created the following shell script that I use inside the Docker container to inspect the worfklow runs/logs (generates a menu based system using Linux "dialog" and JQ for JSON formatting/parsing). This is the one thing that I was struggling with was inspecting the logs of the runs when they failed, and this 100% solves it as you can use it in a console window in the Kubernetes Dashboards in your browser:
#!/bin/bash
# while-menu-dialog: a menu driven system information program
DIALOG_CANCEL=1
DIALOG_ESC=255
HEIGHT=0
WIDTH=0
POD_NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
APICODE=$(curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" "https://kubernetes.default:443/api/v1/namespaces/$POD_NAMESPACE/$AzureWebJobsKubernetesSecretName" | jq -cr .data.\"host.master\" | base64 --decode)
WORKFLOWS=($(curl -s "http://localhost/runtime/webhooks/workflow/api/management/workflows?code=$APICODE" | jq -r '.[]|.name'))
workflowRunActionMenu() {
clear
ACTION_PROPERTIES=$(curl -s "http://localhost/runtime/webhooks/workflow/api/management/workflows/$1/runs/$2/actions/$3?code=$APICODE")
ACTION_INPUTURL=$(echo "$ACTION_PROPERTIES" | jq -r .properties.inputsLink.uri | sed 's/https:\/\/localhost\:443/http:\/\/localhost/')
ACTION_OUTPUTURL=$(echo "$ACTION_PROPERTIES" | jq -r .properties.outputsLink.uri | sed 's/https:\/\/localhost\:443/http:\/\/localhost/')
ACTION_MENU_ITEMS=("P" "Properties")
ACTION_COUNT=1
if [ "$ACTION_INPUTURL" != "null" ]; then
ACTION_MENU_ITEMS+=("I" "Action_Input")
ACTION_COUNT=$(($ACTION_COUNT+1))
fi
if [ "$ACTION_OUTPUTURL" != "null" ]; then
ACTION_MENU_ITEMS+=("O" "Action_Output")
ACTION_COUNT=$(($ACTION_COUNT+1))
fi
while true; do
exec 3>&1
ACTION_MENU_ID=$(dialog --backtitle "Logic App Workflow Log Viewer" --menu "Actions ($2)" $HEIGHT $WIDTH $ACTION_COUNT ${ACTION_MENU_ITEMS[@]} 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL | $DIALOG_ESC)
clear
return
;;
esac
case $ACTION_MENU_ID in
P)
echo "$ACTION_PROPERTIES" | jq -C . | less -R
;;
I)
curl -s $ACTION_INPUTURL | jq -C . | less -R
;;
O)
curl -s $ACTION_OUTPUTURL | jq -C . | less -R
;;
esac
done
}
workflowRunActionsMenu() {
clear
RUN_ACTIONS=($(curl -s "http://localhost/runtime/webhooks/workflow/api/management/workflows/$1/runs/$2/actions?code=$APICODE" | jq -r '.value|sort_by(.properties.startTime)|map(.name,"\(.properties.startTime),(\(.properties.status))")|.[]'))
while true; do
exec 3>&1
ACTION_NAME=$(dialog --backtitle "Logic App Workflow Log Viewer" --menu "Actions ($2)" $HEIGHT $WIDTH $(((${#RUN_ACTIONS[@]} + 1) / 2)) ${RUN_ACTIONS[@]} 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL | $DIALOG_ESC)
clear
return
;;
esac
workflowRunActionMenu $1 $2 $ACTION_NAME
done
}
workflowRunMenu() {
clear
RUN_MENU_OPTIONS=("P" "Properties/JSON")
WFPROPERTIES=$(curl -s "http://localhost/runtime/webhooks/workflow/api/management/workflows/$1/runs/$2?code=$APICODE")
WFINPUTURL=$(echo "$WFPROPERTIES" | jq -r .properties.trigger.inputsLink.uri | sed 's/https:\/\/localhost\:443/http:\/\/localhost/')
WFOUTPUTURL=$(echo "$WFPROPERTIES" | jq -r .properties.trigger.outputsLink.uri | sed 's/https:\/\/localhost\:443/http:\/\/localhost/')
WFRESPONSEURL=$(echo "$WFPROPERTIES" | jq -r .properties.response.outputsLink.uri | sed 's/https:\/\/localhost\:443/http:\/\/localhost/')
WFCOUNT=2
if [ "$WFINPUTURL" != "null" ]; then
RUN_MENU_OPTIONS+=("I" "Trigger_Input")
WFCOUNT=$(($WFCOUNT+1))
fi
if [ "$WFOUTPUTURL" != "null" ]; then
RUN_MENU_OPTIONS+=("O" "Trigger_Output")
WFCOUNT=$(($WFCOUNT+1))
fi
if [ "$WFRESPONSEURL" != "null" ]; then
RUN_MENU_OPTIONS+=("R" "Response")
WFCOUNT=$(($WFCOUNT+1))
fi
RUN_MENU_OPTIONS+=("A" "Actions")
while true; do
exec 3>&1
RUN_MENU_ACTION=$(dialog --backtitle "Logic App Workflow Log Viewer" --menu "Run $2" $HEIGHT $WIDTH $WFCOUNT ${RUN_MENU_OPTIONS[@]} 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL | $DIALOG_ESC)
clear
return
;;
esac
case $RUN_MENU_ACTION in
P)
echo "$WFPROPERTIES" | jq -C . | less -R
;;
I)
curl -s $WFINPUTURL | jq -C . | less -R
;;
O)
curl -s $WFOUTPUTURL | jq -C . | less -R
;;
R)
curl -s $WFRESPONSEURL | jq -C . | less -R
;;
A)
workflowRunActionsMenu $1 $2
;;
esac
done
}
workflowMenu() {
clear
WORKFLOW_RUNS=($(curl -s "http://localhost/runtime/webhooks/workflow/api/management/workflows/${WORKFLOWS[($1 - 1)]}/runs?code=$APICODE" | jq -r '.value|map(.name,"\(.properties.startTime),(\(.properties.status))")|.[]'))
while true; do
exec 3>&1
RUNID=$(dialog --backtitle "Logic App Workflow Log Viewer" --menu "${WORKFLOWS[($1 - 1)]}" $HEIGHT $WIDTH $(((${#WORKFLOW_RUNS[@]} + 1) / 2)) ${WORKFLOW_RUNS[@]} 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL | $DIALOG_ESC)
clear
return
;;
esac
workflowRunMenu ${WORKFLOWS[($1 - 1)]} $RUNID
done
}
while true; do
exec 3>&1
selection=$(dialog --cancel-label "Exit" --backtitle "Logic App Workflow Log Viewer" --menu "Workflows" $HEIGHT $WIDTH ${#WORKFLOWS[@]} $( (for ((i = 0; i < ${#WORKFLOWS[@]}; i++)); do echo -n "$(($i + 1)) ${WORKFLOWS[$i]} "; done)) 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL)
clear
echo "Program terminated."
exit
;;
$DIALOG_ESC)
clear
echo "Program aborted." >&2
exit 1
;;
esac
workflowMenu $selection
done