Deploying a Flogo App on AWS EKS

Procedure

  1. Create a new EKS cluster using the following command:
    eksctl create cluster <cluster name>

    For example:

    eksctl create cluster flogoDemo
    Note: By default, the kubeconfig configuration file is created at the default kubeconfig path (.kube/config) in your home directory or merged with an existing kubeconfig at that location.
  2. Set up the OIDC ID provider (IdP) in AWS. This enables the IAM role for service accounts on EKS cluster:
    eksctl utils associate-iam-oidc-provider --name <cluster name> --approve

    For example:

    eksctl utils associate-iam-oidc-provider --name flogoDemo --approve
  3. Create a new policy which allows you to access to AWS Marketplace Metering.
    The JSON policy looks as follows:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "aws-marketplace:RegisterUsage"
                ],
                "Effect": "Allow",
                "Resource": "*"
            }
        ]
    }
  4. Add this policy to the role created in step # 1.
  5. Create a Kubernetes service account, set up the IAM role that defines access to the targeted services (such as AWS Marketplace Metering), specify the IAM trust policy that allows the specified Kubernetes service account to assume the IAM role:
    eksctl create iamserviceaccount --name
    <Name of service account> --namespace default --cluster <cluster
    name> --attach-policy-arn <Policy ARN> --approve

    Where:

    <Name of service account> is the identity of your app towards the Kubernetes API server. The pod that hosts your app uses this service account.

    <Policy ARN> is the policy created in step # 3.

    For example:

    eksctl create iamserviceaccount --name my-serviceaccount --namespace default --cluster flogoDemo --attach-policy-arn arn:aws:iam::338799163723:policy/marketPlaceRegisterUsage --approve
  6. Set up a pod:
    1. Set up a pod to use the service account created in the previous step. Add the details to a pod spec, for example, pod-definition-sample.yaml:
      kind: Pod
      apiVersion: v1
      metadata:
        name: sample-pod
      spec:
        containers:
          - image: <Flogo application image from ECR>
            name: sample-pod
            stdin: true
            tty: true
        serviceAccountName: <Name of service account>

      Where <Flogo application image from ECR> is the URI of the image pushed to the AWS ECR Repository or the name of the image from the public Docker hub repository.

    2. Create the pod and deploy the app:
      kubectl apply -f pod-definition-sample.yaml

      A pod is created.

      The kubectl get pods command returns the following:
      NAME         READY   STATUS    RESTARTS   AGE
      sample-pod   1/1     Running   0          7s

      The kubectl logs <pod name> command returns the following logs (as an example):

      ######################## Starting Flogo Application #######################
      TIBCO Flogo® Runtime - 2.7.0 (Powered by Project Flogo™ - v0.9.3)
      TIBCO Flogo® connector for General -  1.1.0.251
      2019-09-15T06:59:52.007Z INFO [flogo] - AWS region environment variable not present, obtaining via ec2 instance metadata.
      2019-09-15T06:59:53.288Z INFO [flogo] - Product usage is registered with AWS metering service.
      2019-09-15T06:59:53.288Z INFO [flogo] - Standard TIBCO connectors used in the app - 1
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           Starting TIBCO Flogo® Runtime
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      2019-09-15T06:59:53.289Z WARN [flogo] - unable to create child logger named: ReceiveHTTPMessage - unable to create child logger
      2019-09-15T06:59:53.289Z INFO [general-trigger-rest] - Name: ReceiveHTTPMessage, Port: 9999
      2019-09-15T06:59:53.289Z INFO [general-trigger-rest] - ReceiveHTTPMessage: Registered handler [Method: GET, Path: /books]
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Starting app [ fe-270-payg-rest ] with version [ 1.1.0 ]
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Engine Starting...
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Starting Services...
      2019-09-15T06:59:53.289Z INFO [flogo] - ActionRunner Service: Started
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Started Services
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Starting Application...
      2019-09-15T06:59:53.289Z INFO [flogo] - Starting Triggers...
      2019-09-15T06:59:53.289Z INFO [general-trigger-rest] - Starting ReceiveHTTPMessage...
      2019-09-15T06:59:53.289Z INFO [general-trigger-rest] - Started ReceiveHTTPMessage
      2019-09-15T06:59:53.289Z INFO [flogo] - Trigger [ ReceiveHTTPMessage ]: Started
      2019-09-15T06:59:53.289Z INFO [flogo] - Triggers Started
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Application Started
      2019-09-15T06:59:53.289Z INFO [flogo.engine] - Engine Started
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           Runtime started in 1.767401ms
      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      2019-09-15T06:59:53.290Z INFO [flogo] - Management Service started successfully on Port[7777]
  7. If you want to deploy a Flogo App with a REST endpoint:
    1. Create a Service in Kubernetes using a YAML file. For example, service-definition-sample.yaml:
      apiVersion: v1
      kind: Service
      metadata:
        name: flogo-rest
        labels:
          app: flogo-rest
      spec:
        type: LoadBalancer 
        ports:
        - port: 9999
          targetPort: 9999
          name: app
        selector:
          app: flogo-rest
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: flogo-rest
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: flogo-rest
        template:
          metadata:
            name: flogo-rest
            labels:
              app: flogo-rest
          spec:
            containers:
              - name: flogo-rest
                image: <Flogo application image from ECR>
                imagePullPolicy: Always
                ports:
                  - containerPort: 9999
            serviceAccountName: <Name of service account>
    2. Create a service using the following command:
      kubectl apply -f service-definition-sample.yaml
    3. You can get service information, such as External-IP/PORT, using the following command:
      kubectl get svc <name of service>
      For example, the command returns:
    4. Access the REST endpoint of the Flogo app as follows:
      http://<EXTERNAL-IP>:PORT/<Resource name defined in Flogo app>

      For example:

      http://a8674b572d7a811e99b4206034ad335a-1518682477.eu-west-1.elb.amazonaws.com:9999/books
  8. (Optional) Deploy the Kubernetes Web UI (Dashboard) to your EKS cluster. For more information, refer to https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html.
  9. To clean up all the Kubernetes resources (such deployments, pods, replica sets, services, secrets, and so on), run the following command:
    kubectl delete all --all