Skip to content

Commit

Permalink
feat: add aws-ts-localai-flowise example (pulumi#1602)
Browse files Browse the repository at this point in the history
  • Loading branch information
dirien committed Feb 28, 2024
1 parent 9f097a6 commit ae6a0c4
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 0 deletions.
3 changes: 3 additions & 0 deletions aws-ts-localai-flowise/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/bin/
/node_modules/
/workshop/
17 changes: 17 additions & 0 deletions aws-ts-localai-flowise/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: localai-flowise-example
runtime: nodejs
description: A TypeScript program to deploy a Kubernetes cluster on AWS

config:
aws:region: eu-central-1
desiredClusterSize: "3"
eksNodeInstanceType: m4.4xlarge
maxClusterSize: "6"
minClusterSize: "3"
vpcNetworkCidr: 10.0.0.0/24
publicSubnetCIDRs:
- "10.0.0.0/27"
- "10.0.0.32/27"
availabilityZones:
- eu-central-1a
- eu-central-1b
51 changes: 51 additions & 0 deletions aws-ts-localai-flowise/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Example Code to deploy LocalAI, Flowise, and Pulumi on AWS EKS

## Prerequisites

- [Pulumi CLI](https://www.pulumi.com/docs/install/)
- [Node.js](https://nodejs.org/en/download/)
- [AWS Account](https://aws.amazon.com)

## How to deploy?

> If you run Pulumi for the first time, you will be asked to log in. Follow the instructions on the screen to
> login. You may need to create an account first, don't worry it is free.
### Step 1 - Clone the repository

```shell
git clone https://github.com/pulumi/examples.git
cd examples/aws-ts-localai-flowise
```

### Step 2 - Install the dependencies

```shell
pulumi install
```

### Step 3 - Login to AWS

```shell
aws configure
```

### Step 4 - Deploy the infrastructure

```shell
pulumi up
```

### Step 5 - Port forward the Flowise UI

To retrieve the kubeconfig file, you can use the following command:

```shell
pulumi stack output kubeconfig --show-secrets > kubeconfig.yaml
```

As the program does not deploy a LoadBalancer, you need to port forward the UI to your local machine:

```shell
kubectl port-forward svc/flowise-ui 3000:3000
```
229 changes: 229 additions & 0 deletions aws-ts-localai-flowise/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
// Copyright 2016-2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as aws from "@pulumi/aws";
import * as eks from "@pulumi/eks";
import * as k8s from "@pulumi/kubernetes";
import * as pulumi from "@pulumi/pulumi";

// Grab some values from the Pulumi configuration (or use default values)
const config = new pulumi.Config();
const minClusterSize = config.getNumber("minClusterSize") || 3;
const maxClusterSize = config.getNumber("maxClusterSize") || 6;
const desiredClusterSize = config.getNumber("desiredClusterSize") || 3;
const eksNodeInstanceType = config.get("eksNodeInstanceType") || "t3.medium";
const vpcNetworkCidr = config.get("vpcNetworkCidr") || "10.0.0.0/16";

const publicSubnetCIDRs: pulumi.Input<string>[] = config.requireObject("publicSubnetCIDRs") || [
"10.0.0.0/27",
"10.0.0.32/27",
];


const availabilityZones: pulumi.Input<string>[] = config.requireObject("availabilityZones") || [
"eu-central-1a",
"eu-central-1b",
];

// Create a new VPC
const eksVpc = new aws.ec2.Vpc("eks-vpc", {
enableDnsHostnames: true,
cidrBlock: vpcNetworkCidr,
});

// Create an Internet Gateway and Route Table for the public subnets
const eksInternetGateway = new aws.ec2.InternetGateway("eks-igw", {
vpcId: eksVpc.id,
});

const eksRouteTable = new aws.ec2.RouteTable("eks-rt", {
vpcId: eksVpc.id,
routes: [{
cidrBlock: "0.0.0.0/0",
gatewayId: eksInternetGateway.id,
}],
});

const publicSubnetIDs: pulumi.Input<string>[] = [];

// Create the public subnets and route table associations
for (let i = 0; i < availabilityZones.length; i++) {
const publicSubnet = new aws.ec2.Subnet(`eks-public-subnet-${i}`, {
vpcId: eksVpc.id,
mapPublicIpOnLaunch: false,
assignIpv6AddressOnCreation: false,
cidrBlock: publicSubnetCIDRs[i],
availabilityZone: availabilityZones[i],
tags: {
Name: `eks-public-subnet-${i}`,
},
});

publicSubnetIDs.push(publicSubnet.id);

const routeTableAssociation = new aws.ec2.RouteTableAssociation(`eks-rt-association-${i}`, {
subnetId: publicSubnet.id,
routeTableId: eksRouteTable.id,
});
}


// Create the EKS cluster
const cluster = new eks.Cluster("eks-cluster", {
vpcId: eksVpc.id,
privateSubnetIds: publicSubnetIDs,
instanceType: eksNodeInstanceType,
desiredCapacity: desiredClusterSize,
minSize: minClusterSize,
maxSize: maxClusterSize,
endpointPrivateAccess: false,
endpointPublicAccess: true,
createOidcProvider: true,
nodeRootVolumeSize: 150,
});

// Export some values for use elsewhere
export const kubeconfig = pulumi.secret(cluster.kubeconfig);

const provider = new k8s.Provider("k8s", {
kubeconfig: cluster.kubeconfigJson,
enableServerSideApply: true,
});


// @ts-ignore
const assumeEBSRolePolicy = pulumi.all([cluster.core.oidcProvider.arn, cluster.core.oidcProvider.url])
.apply(([arn, url]) =>
aws.iam.getPolicyDocumentOutput({
statements: [{
effect: "Allow",
actions: ["sts:AssumeRoleWithWebIdentity"],
principals: [
{
type: "Federated",
identifiers: [
arn,
],
},
],
conditions: [
{
test: "StringEquals",
variable: `${url.replace("https://", "")}:sub`,
values: ["system:serviceaccount:kube-system:ebs-csi-controller-sa"],
},
{
test: "StringEquals",
variable: `${url.replace("https://", "")}:aud`,
values: ["sts.amazonaws.com"],
},
],
}],
}),
);

const ebsRole = new aws.iam.Role("eks-ebsi-role", {
assumeRolePolicy: assumeEBSRolePolicy.json,
});

const rolePolicyAttachment = new aws.iam.RolePolicyAttachment("eks-ebs-role-policy", {
role: ebsRole,
policyArn: "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy",
});


const awsEBSCSIDriver = new k8s.helm.v3.Release("aws-ebs-csi-driver", {
chart: "aws-ebs-csi-driver",
version: "2.27.0",
namespace: "kube-system",
repositoryOpts: {
repo: "https://kubernetes-sigs.github.io/aws-ebs-csi-driver",
},
values: {
controller: {
serviceAccount: {
annotations: {
"eks.amazonaws.com/role-arn": ebsRole.arn,
},
},
},
},
}, {
provider: provider,
});


const localai = new k8s.helm.v3.Release("local-ai", {
chart: "local-ai",
version: "3.2.0",
repositoryOpts: {
repo: "https://go-skynet.github.io/helm-charts",
},
forceUpdate: true,
namespace: "local-ai",
createNamespace: true,
values: {
deployment: {
image: {
repository: "quay.io/go-skynet/local-ai",
tag: "latest",
},
env: {
debug: "true",
context_size: 512,
modelsPath: "/models",
},
}, resources: {
requests: {
cpu: "8",
memory: "32Gi",
},
},
models: {
list: [
{
url: "https://gpt4all.io/models/ggml-gpt4all-j.bin",
name: "ggml-gpt4all-j",
},
],
},
persistence: {
models: {
size: "50Gi",
storageClass: "gp2",
accessModes: "ReadWriteOnce",
},
output: {
size: "10Gi",
storageClass: "gp2",
accessModes: "ReadWriteOnce",

},
},
},
}, {
provider: provider,
});

const flowise = new k8s.helm.v3.Release("flowise", {
chart: "flowise",
version: "2.5.0",
repositoryOpts: {
repo: "https://cowboysysop.github.io/charts/",
},
namespace: "flowise",
createNamespace: true,
}, {
provider: provider,
});
15 changes: 15 additions & 0 deletions aws-ts-localai-flowise/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "civo-navigate",
"devDependencies": {
"@types/node": "^18"
},
"dependencies": {
"typescript": "^4.0.0",
"@pulumi/pulumi": "^3.0.0",
"@pulumi/eks": "^v2.0.0",
"@pulumi/aws": "^6.22.2",
"@pulumi/docker": "^4.5.1",
"@pulumi/kubernetes": "^4.7.1",
"@pinecone-database/pulumi": "^0.4.0"
}
}
18 changes: 18 additions & 0 deletions aws-ts-localai-flowise/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}

0 comments on commit ae6a0c4

Please sign in to comment.