Skip to content

Commit a788051

Browse files
authored
feat: add automatic deployments of support bot infra (#1272)
Signed-off-by: drptbl <jakub.mucha@icloud.com>
1 parent 095454c commit a788051

File tree

8 files changed

+1500
-471
lines changed

8 files changed

+1500
-471
lines changed

pnpm-lock.yaml

Lines changed: 1332 additions & 470 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ packages:
44
- "examples/*"
55
- "release"
66
- "docs"
7-
- "support-bot"
7+
- "support-bot/*"

support-bot/infra/Pulumi.dev.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
encryptionsalt: v1:sWT/mMw+Vh8=:v1:E7nHaX+HYvauMdyx:m7XabdAaqeh1RpCULGOaGlkCX/s9ZA==
2+
config:
3+
gcp:project: synpress
4+
gcp:zone: us-central1-b
5+
gcp:region: us-central1

support-bot/infra/Pulumi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: support-bot
2+
description: Support Bot infrastructure for GCP deployment
3+
runtime:
4+
name: nodejs
5+
options:
6+
packagemanager: pnpm

support-bot/infra/index.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import * as gcp from '@pulumi/gcp'
2+
import * as pulumi from '@pulumi/pulumi'
3+
4+
// Get GCP configuration
5+
const gcpConfig = new pulumi.Config('gcp')
6+
const projectId = gcpConfig.require('project')
7+
const zone = gcpConfig.require('zone')
8+
const region = gcpConfig.require('region')
9+
10+
// Create a new network
11+
const network = new gcp.compute.Network('synpress-support-bot-network', {
12+
autoCreateSubnetworks: true
13+
})
14+
15+
// Create a firewall rule to allow incoming traffic
16+
const firewall = new gcp.compute.Firewall('synpress-support-bot-firewall', {
17+
network: network.name,
18+
allows: [
19+
{
20+
protocol: 'tcp',
21+
ports: ['22']
22+
}
23+
],
24+
sourceRanges: ['0.0.0.0/0'],
25+
targetTags: ['synpress-support-bot']
26+
})
27+
28+
// Create a service account for the VM
29+
const serviceAccount = new gcp.serviceaccount.Account('synpress-support-bot-sa', {
30+
accountId: 'synpress-support-bot-sa',
31+
displayName: 'Synpress Support Bot Service Account'
32+
})
33+
34+
// Add necessary IAM roles to the service account
35+
const roles = [
36+
'roles/logging.logWriter',
37+
'roles/monitoring.metricWriter',
38+
'roles/monitoring.viewer',
39+
'roles/stackdriver.resourceMetadata.writer'
40+
]
41+
42+
roles.forEach((role, i) => {
43+
new gcp.projects.IAMBinding(`synpress-support-bot-iam-binding-${i}`, {
44+
project: projectId,
45+
role: role,
46+
members: [pulumi.interpolate`serviceAccount:${serviceAccount.email}`]
47+
})
48+
})
49+
50+
const instanceStartupScript = pulumi.interpolate`#!/bin/bash
51+
set -e # Exit on error
52+
set -x # Print commands for debugging
53+
54+
echo "Starting installation process..."
55+
# Install Node.js and npm
56+
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
57+
apt-get install -y nodejs
58+
59+
# Install pnpm
60+
npm install -g pnpm
61+
62+
# Create app directory
63+
mkdir -p /opt/support-bot
64+
cd /opt/support-bot
65+
66+
# Clone repo
67+
git clone https://github.com/Synthetixio/synpress.git
68+
cd synpress
69+
git checkout dev
70+
71+
# Install dependencies and start the bot
72+
pnpm install
73+
cd support-bot
74+
pnpm build
75+
pnpm start
76+
`
77+
78+
// Create a VM instance
79+
const instance = new gcp.compute.Instance('synpress-support-bot-instance', {
80+
machineType: 'e2-micro',
81+
zone: zone,
82+
bootDisk: {
83+
initializeParams: {
84+
image: 'ubuntu-os-cloud/ubuntu-2004-lts',
85+
size: 10,
86+
type: 'pd-ssd', // Use SSD
87+
labels: {
88+
environment: 'production',
89+
managed_by: 'pulumi',
90+
application: 'synpress-support-bot'
91+
}
92+
},
93+
autoDelete: true,
94+
deviceName: 'synpress-support-bot-boot-disk'
95+
},
96+
networkInterfaces: [
97+
{
98+
network: network.name
99+
}
100+
],
101+
serviceAccount: {
102+
email: serviceAccount.email,
103+
scopes: ['https://www.googleapis.com/auth/cloud-platform']
104+
},
105+
metadataStartupScript: instanceStartupScript,
106+
labels: {
107+
environment: 'production',
108+
managed_by: 'pulumi',
109+
application: 'synpress-support-bot'
110+
},
111+
tags: ['synpress-support-bot']
112+
})
113+
114+
// Create a Cloud Storage bucket for bot data and logs
115+
const bucket = new gcp.storage.Bucket('synpress-support-bot-bucket', {
116+
location: region,
117+
uniformBucketLevelAccess: true
118+
})
119+
120+
// Grant the service account access to the bucket
121+
const bucketIAM = new gcp.storage.BucketIAMMember('synpress-support-bot-bucket-iam', {
122+
bucket: bucket.name,
123+
role: 'roles/storage.objectViewer',
124+
member: pulumi.interpolate`serviceAccount:${serviceAccount.email}`
125+
})

support-bot/infra/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "support-bot-infra",
3+
"private": true,
4+
"main": "index.ts",
5+
"dependencies": {
6+
"@pulumi/gcp": "8.19.1",
7+
"@pulumi/pulumi": "3.150.0"
8+
},
9+
"devDependencies": {
10+
"@types/node": "22.13.4",
11+
"typescript": "5.7.3"
12+
}
13+
}

support-bot/infra/tsconfig.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"outDir": "bin",
5+
"target": "es2016",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"sourceMap": true,
9+
"experimentalDecorators": true,
10+
"pretty": true,
11+
"noFallthroughCasesInSwitch": true,
12+
"noImplicitReturns": true,
13+
"forceConsistentCasingInFileNames": true,
14+
"esModuleInterop": true
15+
},
16+
"files": ["index.ts"]
17+
}

support-bot/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "@synpress/support-bot",
33
"version": "0.1.0",
4+
"private": true,
45
"description": "Discord support bot using Gemini AI for Synpress",
56
"type": "module",
67
"main": "dist/index.js",

0 commit comments

Comments
 (0)