Flogo and Lambda

Serverless is all around us and perhaps the fastest growing market for compute. Flogo has first class support for AWS Lambda. So you can infinitely scale your ultralight functions and scale back to zero when not in use with AWS Lambda’s NoOps and seamless scaling capabilities.

We’ll guide you through the set of steps required to build the most basic of functions for deployment to AWS Lambda. The flow you’ll build will be the function you deploy.

Prerequisites

Before we get started there are a few prerequisites that we need to take into account:

  • You’ll need to have the Flogo CLI and at least Go 1.11 installed
  • If you want to deploy using the AWS cli you’ll need to install that too
  • You’ll obviously need an AWS account :)

Create the flogo.json

Flogo apps are constructed using a JSON file called flogo.json. You can create those files using the Flogo Web UI, or you can create them manually. You can copy the below content and paste it into a file called flogo.json. The Flogo app has a Lambda trigger which can be triggered by any event supported by AWS Lambda.

{
  "name": "myApp",
  "type": "flogo:app",
  "version": "0.0.1",
  "description": "",
  "appModel": "1.1.0",
  "imports": [
    "github.com/project-flogo/flow",
    "github.com/project-flogo/aws-contrib/trigger/lambda",
    "github.com/project-flogo/contrib/activity/actreturn",
    "github.com/project-flogo/contrib/activity/log",
    "github.com/project-flogo/contrib/function/string"
  ],
  "triggers": [
    {
      "id": "aws_lambda_trigger",
      "ref": "#lambda",
      "settings": null,
      "handlers": [
        {
          "settings": null,
          "actions": [
            {
              "ref": "#flow",
              "settings": {
                "flowURI": "res://flow:my_function"
              },
              "input": {
                "name": "=$.event.name"
              },
              "output": {
                "data": "=$.greeting",
                "status": 200
              }
            }
          ]
        }
      ]
    }
  ],
  "resources": [
    {
      "id": "flow:my_function",
      "data": {
        "name": "MyFunction",
        "metadata": {
          "input": [
            {
              "name": "name",
              "type": "string"
            }
          ],
          "output": [
            {
              "name": "greeting",
              "type": "any"
            }
          ]
        },
        "tasks": [
          {
            "id": "log_2",
            "name": "Log",
            "description": "Logs a message",
            "activity": {
              "ref": "#log",
              "input": {
                "addDetails": false,
                "message": "=string.concat(\"Hello \", $flow.name)"
              }
            }
          },
          {
            "id": "actreturn_3",
            "name": "Return",
            "description": "Return Activity",
            "activity": {
              "ref": "#actreturn",
              "settings": {
                "mappings": {
                  "greeting": {
                    "mapping": {
                      "Hello": "=$flow.name"
                    }
                  }
                }
              }
            }
          }
        ],
        "links": [
          {
            "from": "log_2",
            "to": "actreturn_3"
          }
        ]
      }
    }
  ]
}

Create an app

To create the source code simply execute

flogo create -f flogo.json myapp

This tells the flogo cli to take the flogo.json file and create the source for the app in a folder called myapp. It will also download a few Go packages that the app will need.

Build

The next step is to build the executable and for that we need to be in the directory myapp. To build a flogo app from the source that you can run on AWS Lambda we’ll need to execute the command

flogo build -e --shim aws_lambda_trigger

. This command tells the flogo cli to build the app as an embedded application (the -e option) and with a target shim (the –shim option which uses the trigger id). The AWS Lambda trigger leverages a makefile to kick off the build process, which simply builds your Flogo application using the Lambda trigger shim and zips the binary for deployment to AWS Lambda.

Once this command finishes successfully the zip file (handler.zip) will be located in your app src directory (for example /path/to/app/lambda/src/lambda/handler.zip).

Deploy

There are several ways to deploy to AWS Lambda. A non-exhaustive list is:

  • Uploading the code
  • Using SAM templates
  • Using Serverless Framework
  • Using the AWS CLI

In this scenario we’ll look at numbers 1 and 4

Uploading the code

From the Lambda console you can easily create a new function. As you do that set the runtime to Go 1.x, upload the zip file and set the handler to handler.

Using the AWS CLI

To deploy your app using the AWS CLI go to the directory where the zip was created and from there execute the command

aws lambda create-function --function-name tutorial --runtime go1.x --role arn:aws:iam::<account>:role/<role name> --handler handler --zip-file "fileb://handler.zip"

This will create a new function in Lambda called tutorial, which uses the Go runtime. The –role arn:aws:iam:::role/ is the full ARN of the IAM role used to deploy this function. If all went well you’ll see a JSON response like this:

{
    "TracingConfig": {
        "Mode": "PassThrough"
    },
    "CodeSha256": "KzHoXLnTXi9uMugXAOLrMHq6qJ6RimzYdNfrWXIxwLw=",
    "FunctionName": "tutorial",
    "CodeSize": 4026592,
    "RevisionId": "94b184e5-74e3-4881-abf5-debad47541b5",
    "MemorySize": 128,
    "FunctionArn": "arn:aws:lambda:<region>:<account>:function:tutorial",
    "Version": "$LATEST",
    "Role": "arn:aws:iam::<account>:role/<role>",
    "Timeout": 3,
    "LastModified": "2018-05-12T19:30:41.116+0000",
    "Handler": "handler",
    "Runtime": "go1.x",
    "Description": ""
}

Testing 1… 2… 3…

The only thing left is to test your function. To do that log into AWS and select “Lambda”, you’ll be presented with all the functions you’ve deployed so far and one of them will be called tutorial. Click on that, and you’ll see the overview of your function, including a large button that says “Test”. Click “Test” to configure a new test event. The input for the test event should be

{
  "name": "World"
}

You can replace “world” with any name or message you want

From there, click “Test” and the execution logs will display the result

{
  "Hello": "World"
}

And the log output

START RequestId: 2f4086f8-5721-4bf4-b0b7-94cb9d52c709 Version: $LATEST
2019/05/13 13:13:37 Received request: 2f4086f8-5721-4bf4-b0b7-94cb9d52c709
2019/05/13 13:13:37 Payload Type: unknown
2019/05/13 13:13:37 Payload: 'map[name:Matt]'
END RequestId: 2f4086f8-5721-4bf4-b0b7-94cb9d52c709
REPORT RequestId: 2f4086f8-5721-4bf4-b0b7-94cb9d52c709	Duration: 0.76 ms	Billed Duration: 100 ms 	Memory Size: 512 MB	Max Memory Used: 30 MB

As you’re glancing over the results, also look at the Duration and Max Memory Used. Isn’t that one of the smallest functions you’ve seen?!