Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
33
activepieces-fork/deploy/pulumi/.gitignore
vendored
Normal file
33
activepieces-fork/deploy/pulumi/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/.pulumi/
|
||||
/.vscode/
|
||||
/.vs/
|
||||
bin/
|
||||
build/
|
||||
node_modules/
|
||||
*.pyc
|
||||
.Python
|
||||
venv/
|
||||
include/
|
||||
lib/
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
# https://www.pulumi.com/blog/iac-recommended-practices-developer-stacks-git-branches/#using-developer-stacks
|
||||
# Pulumi.*.yaml
|
||||
# Pulumi.*dev*.yaml
|
||||
.idea/
|
||||
.ionide/
|
||||
*.iml
|
||||
key.rsa*
|
||||
obj/
|
||||
vendor
|
||||
Gopkg.lock
|
||||
**/.DS_Store
|
||||
|
||||
**/ci-scripts
|
||||
|
||||
# Java app
|
||||
.gradle/
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
target/
|
||||
22
activepieces-fork/deploy/pulumi/Pulumi.activepieces-dev.yaml
Normal file
22
activepieces-fork/deploy/pulumi/Pulumi.activepieces-dev.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
encryptionsalt: v1:wHCVNl3bj/g=:v1:mxogi9ZeBjIcxNZC:q+bjpLv9rnJnu8qq7xwKGLd/GAZOqA==
|
||||
config:
|
||||
activepieces:environment: "dev"
|
||||
activepieces:apEncryptionKey:
|
||||
activepieces:apJwtSecret:
|
||||
activepieces:deployLocalBuild: "false"
|
||||
activepieces:repoName:
|
||||
activepieces:containerCpu: "256"
|
||||
activepieces:containerMemory: "512"
|
||||
activepieces:containerInstances: "1"
|
||||
activepieces:usePostgres: "false"
|
||||
activepieces:dbInstanceClass: "db.t3.small"
|
||||
activepieces:dbUsername: "postgres"
|
||||
activepieces:dbIsPublic: "false"
|
||||
activepieces:dbPassword:
|
||||
secure: v1:MXNSOcqZCp10X2PX:mU2iTrcETjdisk8FkD5yHLJYUxRei/9l
|
||||
activepieces:addIpToPostgresSecurityGroup:
|
||||
activepieces:useRedis: "false"
|
||||
activepieces:redisNodeType: "cache.t3.small"
|
||||
activepieces:domain:
|
||||
activepieces:subDomain:
|
||||
aws:region: "us-east-1"
|
||||
@@ -0,0 +1,19 @@
|
||||
encryptionsalt: v1:icXg2cmIvSc=:v1:y8+4YhdMCPPDY26J:5cNYmimH353n8sjUDDc6srvcPgb+8Q==
|
||||
config:
|
||||
activepieces:environment: "prod"
|
||||
activepieces:apEncryptionKey:
|
||||
activepieces:apJwtSecret:
|
||||
activepieces:deployLocalBuild: "true"
|
||||
activepieces:repoName: "activepieces-prod-repo"
|
||||
activepieces:containerCpu: "512"
|
||||
activepieces:containerMemory: "1024"
|
||||
activepieces:containerInstances: "1"
|
||||
activepieces:usePostgres: "true"
|
||||
activepieces:dbInstanceClass: "db.t3.small"
|
||||
activepieces:dbIsPublic: "false"
|
||||
activepieces:dbPassword:
|
||||
secure: v1:MXNSOcqZCp10X2PX:mU2iTrcETjdisk8FkD5yHLJYUxRei/9l
|
||||
activepieces:dbUsername: "postgres"
|
||||
activepieces:useRedis: "true"
|
||||
activepieces:redisNodeType: "cache.t3.small"
|
||||
aws:region: "us-east-1"
|
||||
56
activepieces-fork/deploy/pulumi/Pulumi.yaml
Normal file
56
activepieces-fork/deploy/pulumi/Pulumi.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
runtime: nodejs
|
||||
name: activepieces
|
||||
description: A Pulumi template to deploy Activepieces in a development or production configuration.
|
||||
stack: activepieces-dev
|
||||
template:
|
||||
description: Deploy Activepieces into into an ECS Fargate instance & optionally add Postgres, Redis and a DNS registration with SSL.
|
||||
config:
|
||||
aws:region:
|
||||
description: The AWS region to deploy into
|
||||
default: us-west-2
|
||||
environment:
|
||||
description: Environment
|
||||
default: prod
|
||||
containerCpu:
|
||||
description: The amount of CPU to allocate for the container
|
||||
default: 256
|
||||
containerMemory:
|
||||
description: The amount of memory to allocate for the container
|
||||
default: 512
|
||||
containerInstances:
|
||||
description: Number of running containers behind load balancer
|
||||
default: 1
|
||||
usePostgres:
|
||||
description: Add Postgres for storage or use SQLite3 locally
|
||||
default: true
|
||||
dbIsPublic:
|
||||
description: Should Db be publicly reachable. Ignored if usePostgres is false.
|
||||
default: false
|
||||
dbUsername:
|
||||
description: Default username for the Postgres. Ignored if usePostgres is false
|
||||
default: postgres
|
||||
dbPassword:
|
||||
description: Defaults to "postgres". Ignored if usePostgres is false
|
||||
default: postgres
|
||||
secret: true
|
||||
dbInstanceClass:
|
||||
description: The size of the RDS instance
|
||||
default: db.t3.micro
|
||||
useRedis:
|
||||
description: Use a single node Redis cluster or in-memory
|
||||
default: true
|
||||
redisNodeType:
|
||||
description: Node type for the Redis 7 cluster
|
||||
default: cache.t3.micro
|
||||
domain:
|
||||
description: Optional - E.g. "yourdomain.com". Hosted zone must already exist in Route 53. Creates SSL cert
|
||||
subDomain:
|
||||
description: Optional - E.g. "activepieces". "domain" must be set
|
||||
addIpToPostgresSecurityGroup:
|
||||
description: Optional - An IP address to add to the allowed inbound traffic for the Postgres
|
||||
apEncryptionKey:
|
||||
description: Optional - Run 'openssl rand -hex 16' locally to generate or leave blank to auto-generate
|
||||
secret: true
|
||||
apJwtSecret:
|
||||
description: Optional - Run 'openssl rand -hex 32' locally to generate or leave blank to auto-generate
|
||||
secret: true
|
||||
3
activepieces-fork/deploy/pulumi/README.md
Normal file
3
activepieces-fork/deploy/pulumi/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Getting Started
|
||||
|
||||
See instruction on https://www.activepieces.com/docs/install/options/aws
|
||||
16
activepieces-fork/deploy/pulumi/autotag.ts
Normal file
16
activepieces-fork/deploy/pulumi/autotag.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { isTaggable } from "./taggable";
|
||||
|
||||
/**
|
||||
* registerAutoTags registers a global stack transformation that merges a set
|
||||
* of tags with whatever was also explicitly added to the resource definition.
|
||||
*/
|
||||
export function registerAutoTags(autoTags: Record<string, string>): void {
|
||||
pulumi.runtime.registerStackTransformation((args) => {
|
||||
if (isTaggable(args.type)) {
|
||||
args.props["tags"] = { ...args.props["tags"], ...autoTags };
|
||||
return { props: args.props, opts: args.opts };
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
466
activepieces-fork/deploy/pulumi/index.ts
Normal file
466
activepieces-fork/deploy/pulumi/index.ts
Normal file
@@ -0,0 +1,466 @@
|
||||
import * as aws from "@pulumi/aws";
|
||||
import * as docker from "@pulumi/docker";
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as awsx from "@pulumi/awsx";
|
||||
import { ApplicationLoadBalancer } from "@pulumi/awsx/lb/applicationLoadBalancer";
|
||||
import { registerAutoTags } from './autotag';
|
||||
import * as child_process from "child_process";
|
||||
|
||||
const stack = pulumi.getStack();
|
||||
const config = new pulumi.Config();
|
||||
|
||||
const apEncryptionKey = config.getSecret("apEncryptionKey")?.apply(secretValue => {
|
||||
return secretValue || child_process.execSync("openssl rand -hex 16").toString().trim();
|
||||
});
|
||||
const apJwtSecret = config.getSecret("apJwtSecret")?.apply(secretValue => {
|
||||
return secretValue || child_process.execSync("openssl rand -hex 32").toString().trim();
|
||||
});
|
||||
const containerCpu = config.requireNumber("containerCpu");
|
||||
const containerMemory = config.requireNumber("containerMemory");
|
||||
const containerInstances = config.requireNumber("containerInstances");
|
||||
const addIpToPostgresSecurityGroup = config.get("addIpToPostgresSecurityGroup");
|
||||
const domain = config.get("domain");
|
||||
const subDomain = config.get("subDomain");
|
||||
const usePostgres = config.requireBoolean("usePostgres");
|
||||
const useRedis = config.requireBoolean("useRedis");
|
||||
const redisNodeType = config.require("redisNodeType");
|
||||
const dbIsPublic = config.getBoolean("dbIsPublic");
|
||||
const dbUsername = config.get("dbUsername");
|
||||
const dbPassword = config.getSecret("dbPassword");
|
||||
const dbInstanceClass = config.require("dbInstanceClass");
|
||||
|
||||
// Add tags for every resource that allows them, with the following properties.
|
||||
// Useful to know who or what created the resource/service
|
||||
registerAutoTags({
|
||||
"pulumi:Project": pulumi.getProject(),
|
||||
"pulumi:Stack": pulumi.getStack(),
|
||||
"Created by": config.get("author") || child_process.execSync("pulumi whoami").toString().trim().replace('\\', '/')
|
||||
});
|
||||
|
||||
let imageName;
|
||||
|
||||
// Check if we're deploying a local build or direct from Docker Hub
|
||||
if (config.getBoolean("deployLocalBuild")) {
|
||||
|
||||
const repoName = config.require("repoName");
|
||||
|
||||
const repo = new aws.ecr.Repository(repoName, {
|
||||
name: repoName // https://www.pulumi.com/docs/intro/concepts/resources/names/#autonaming
|
||||
}); // Create a private ECR repository
|
||||
|
||||
const repoUrl = pulumi.interpolate`${repo.repositoryUrl}`; // Get registry info (creds and endpoint)
|
||||
const name = pulumi.interpolate`${repoUrl}:latest`;
|
||||
|
||||
// Get the repository credentials we use to push the image to the repository
|
||||
const repoCreds = repo.registryId.apply(async (registryId) => {
|
||||
const credentials = await aws.ecr.getCredentials({
|
||||
registryId: registryId,
|
||||
});
|
||||
const decodedCredentials = Buffer.from(credentials.authorizationToken, "base64").toString();
|
||||
const [username, password] = decodedCredentials.split(":");
|
||||
return {
|
||||
server: credentials.proxyEndpoint,
|
||||
username,
|
||||
password
|
||||
};
|
||||
});
|
||||
|
||||
// Build and publish the container image.
|
||||
const image = new docker.Image(stack, {
|
||||
build: {
|
||||
context: `../../`,
|
||||
dockerfile: `../../Dockerfile`,
|
||||
builderVersion: "BuilderBuildKit",
|
||||
args: {
|
||||
"BUILDKIT_INLINE_CACHE": "1"
|
||||
},
|
||||
},
|
||||
skipPush: pulumi.runtime.isDryRun(),
|
||||
imageName: name,
|
||||
registry: repoCreds
|
||||
});
|
||||
|
||||
imageName = image.imageName;
|
||||
|
||||
pulumi.log.info(`Finished pushing image to ECR`, image);
|
||||
} else {
|
||||
imageName = process.env.IMAGE_NAME || config.get("imageName") || "activepieces/activepieces:latest";
|
||||
}
|
||||
|
||||
const containerEnvironmentVars: awsx.types.input.ecs.TaskDefinitionKeyValuePairArgs[] = [];
|
||||
|
||||
// Allocate a new VPC with the default settings:
|
||||
const vpc = new awsx.ec2.Vpc(`${stack}-vpc`, {
|
||||
numberOfAvailabilityZones: 2,
|
||||
natGateways: {
|
||||
strategy: "Single"
|
||||
},
|
||||
tags: {
|
||||
// For some reason, this is how you name a VPC with AWS:
|
||||
// https://github.com/pulumi/pulumi-terraform/issues/38#issue-262186406
|
||||
Name: `${stack}-vpc`
|
||||
},
|
||||
enableDnsHostnames: true,
|
||||
enableDnsSupport: true
|
||||
});
|
||||
|
||||
const albSecGroup = new aws.ec2.SecurityGroup(`${stack}-alb-sg`, {
|
||||
name: `${stack}-alb-sg`,
|
||||
vpcId: vpc.vpcId,
|
||||
ingress: [{ // Allow only http & https traffic
|
||||
protocol: "tcp",
|
||||
fromPort: 443,
|
||||
toPort: 443,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
},
|
||||
{
|
||||
protocol: "tcp",
|
||||
fromPort: 80,
|
||||
toPort: 80,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
}],
|
||||
egress: [{
|
||||
protocol: "-1",
|
||||
fromPort: 0,
|
||||
toPort: 0,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
}]
|
||||
})
|
||||
|
||||
const fargateSecGroup = new aws.ec2.SecurityGroup(`${stack}-fargate-sg`, {
|
||||
name: `${stack}-fargate-sg`,
|
||||
vpcId: vpc.vpcId,
|
||||
ingress: [
|
||||
{
|
||||
protocol: "tcp",
|
||||
fromPort: 80,
|
||||
toPort: 80,
|
||||
securityGroups: [albSecGroup.id]
|
||||
}
|
||||
],
|
||||
egress: [ // allow all outbound traffic
|
||||
{
|
||||
protocol: "-1",
|
||||
fromPort: 0,
|
||||
toPort: 0,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (usePostgres) {
|
||||
const rdsSecurityGroupArgs: aws.ec2.SecurityGroupArgs = {
|
||||
name: `${stack}-db-sg`,
|
||||
vpcId: vpc.vpcId,
|
||||
ingress: [{
|
||||
protocol: "tcp",
|
||||
fromPort: 5432,
|
||||
toPort: 5432,
|
||||
securityGroups: [fargateSecGroup.id] // The id of the Fargate security group
|
||||
}],
|
||||
egress: [ // allow all outbound traffic
|
||||
{
|
||||
protocol: "-1",
|
||||
fromPort: 0,
|
||||
toPort: 0,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Optionally add the current outgoing public IP address to the CIDR block
|
||||
// so that they can connect directly to the Db during development
|
||||
if (addIpToPostgresSecurityGroup) {
|
||||
|
||||
// @ts-ignore
|
||||
rdsSecurityGroupArgs.ingress.push({
|
||||
protocol: "tcp",
|
||||
fromPort: 5432,
|
||||
toPort: 5432,
|
||||
cidrBlocks: [`${addIpToPostgresSecurityGroup}/32`],
|
||||
description: `Public IP for local connection`
|
||||
});
|
||||
}
|
||||
|
||||
const rdsSecurityGroup = new aws.ec2.SecurityGroup(`${stack}-db-sg`, rdsSecurityGroupArgs);
|
||||
|
||||
const rdsSubnets = new aws.rds.SubnetGroup(`${stack}-db-subnet-group`, {
|
||||
name: `${stack}-db-subnet-group`,
|
||||
subnetIds: dbIsPublic ? vpc.publicSubnetIds : vpc.privateSubnetIds
|
||||
});
|
||||
|
||||
const db = new aws.rds.Instance(stack, {
|
||||
allocatedStorage: 10,
|
||||
engine: "postgres",
|
||||
engineVersion: "14.9",
|
||||
identifier: stack, // In RDS
|
||||
dbName: "postgres", // When connected to the DB host
|
||||
instanceClass: dbInstanceClass,
|
||||
port: 5432,
|
||||
publiclyAccessible: dbIsPublic,
|
||||
skipFinalSnapshot: true,
|
||||
storageType: "gp2",
|
||||
username: dbUsername,
|
||||
password: dbPassword,
|
||||
dbSubnetGroupName: rdsSubnets.id,
|
||||
vpcSecurityGroupIds: [rdsSecurityGroup.id],
|
||||
backupRetentionPeriod: 0,
|
||||
applyImmediately: true,
|
||||
allowMajorVersionUpgrade: true,
|
||||
autoMinorVersionUpgrade: true
|
||||
}, {
|
||||
protect: dbIsPublic === false,
|
||||
deleteBeforeReplace: true
|
||||
});
|
||||
|
||||
containerEnvironmentVars.push(
|
||||
{
|
||||
name: "AP_POSTGRES_DATABASE",
|
||||
value: db.dbName
|
||||
},
|
||||
{
|
||||
name: "AP_POSTGRES_HOST",
|
||||
value: db.address
|
||||
},
|
||||
{
|
||||
name: "AP_POSTGRES_PORT",
|
||||
value: pulumi.interpolate`${db.port}`
|
||||
},
|
||||
{
|
||||
name: "AP_POSTGRES_USERNAME",
|
||||
value: db.username
|
||||
},
|
||||
{
|
||||
name: "AP_POSTGRES_PASSWORD",
|
||||
value: config.requireSecret("dbPassword")
|
||||
},
|
||||
{
|
||||
name: "AP_POSTGRES_USE_SSL",
|
||||
value: "false"
|
||||
});
|
||||
|
||||
} else {
|
||||
containerEnvironmentVars.push(
|
||||
{
|
||||
name: "AP_DB_TYPE",
|
||||
value: "SQLITE3"
|
||||
});
|
||||
}
|
||||
|
||||
if (useRedis) {
|
||||
|
||||
const redisCluster = new aws.elasticache.Cluster(`${stack}-redis-cluster`, {
|
||||
clusterId: `${stack}-redis-cluster`,
|
||||
engine: "redis",
|
||||
engineVersion: '7.0',
|
||||
nodeType: redisNodeType,
|
||||
numCacheNodes: 1,
|
||||
parameterGroupName: "default.redis7",
|
||||
port: 6379,
|
||||
subnetGroupName: new aws.elasticache.SubnetGroup(`${stack}-redis-subnet-group`, {
|
||||
name: `${stack}-redis-subnet-group`,
|
||||
subnetIds: vpc.privateSubnetIds
|
||||
}).id,
|
||||
securityGroupIds: [
|
||||
new aws.ec2.SecurityGroup(`${stack}-redis-sg`, {
|
||||
name: `${stack}-redis-sg`,
|
||||
vpcId: vpc.vpcId,
|
||||
ingress: [{
|
||||
protocol: "tcp",
|
||||
fromPort: 6379, // The standard port for Redis
|
||||
toPort: 6379,
|
||||
securityGroups: [fargateSecGroup.id]
|
||||
}],
|
||||
egress: [{
|
||||
protocol: "-1",
|
||||
fromPort: 0,
|
||||
toPort: 0,
|
||||
cidrBlocks: ["0.0.0.0/0"]
|
||||
}]
|
||||
}).id
|
||||
]
|
||||
});
|
||||
|
||||
const redisUrl = pulumi.interpolate`${redisCluster.cacheNodes[0].address}:${redisCluster.cacheNodes[0].port}`;
|
||||
containerEnvironmentVars.push(
|
||||
{
|
||||
name: "AP_REDIS_URL",
|
||||
value: redisUrl
|
||||
});
|
||||
|
||||
} else {
|
||||
containerEnvironmentVars.push(
|
||||
{
|
||||
name: "AP_QUEUE_MODE",
|
||||
value: "MEMORY"
|
||||
});
|
||||
}
|
||||
|
||||
let alb: ApplicationLoadBalancer;
|
||||
// Export the URL so we can easily access it.
|
||||
let frontendUrl;
|
||||
|
||||
if (subDomain && domain) {
|
||||
const fullDomain = `${subDomain}.${domain}`;
|
||||
|
||||
const exampleCertificate = new aws.acm.Certificate(`${stack}-cert`, {
|
||||
domainName: fullDomain,
|
||||
validationMethod: "DNS",
|
||||
});
|
||||
|
||||
const hostedZoneId = aws.route53.getZone({ name: domain }, { async: true }).then(zone => zone.zoneId);
|
||||
|
||||
// DNS records to verify SSL Certificate
|
||||
const certificateValidationDomain = new aws.route53.Record(`${fullDomain}-validation`, {
|
||||
name: exampleCertificate.domainValidationOptions[0].resourceRecordName,
|
||||
zoneId: hostedZoneId,
|
||||
type: exampleCertificate.domainValidationOptions[0].resourceRecordType,
|
||||
records: [exampleCertificate.domainValidationOptions[0].resourceRecordValue],
|
||||
ttl: 600,
|
||||
});
|
||||
|
||||
const certificateValidation = new aws.acm.CertificateValidation(`${fullDomain}-cert-validation`, {
|
||||
certificateArn: exampleCertificate.arn,
|
||||
validationRecordFqdns: [certificateValidationDomain.fqdn],
|
||||
});
|
||||
|
||||
// Creates an ALB associated with our custom VPC.
|
||||
alb = new awsx.lb.ApplicationLoadBalancer(`${stack}-alb`, {
|
||||
securityGroups: [albSecGroup.id],
|
||||
name: `${stack}-alb`,
|
||||
subnetIds: vpc.publicSubnetIds,
|
||||
listeners: [{
|
||||
port: 80, // port on the docker container
|
||||
protocol: "HTTP",
|
||||
defaultActions: [{
|
||||
type: "redirect",
|
||||
redirect: {
|
||||
protocol: "HTTPS",
|
||||
port: "443",
|
||||
statusCode: "HTTP_301",
|
||||
},
|
||||
}]
|
||||
},
|
||||
{
|
||||
protocol: "HTTPS",
|
||||
port: 443,
|
||||
certificateArn: certificateValidation.certificateArn
|
||||
}],
|
||||
defaultTargetGroup: {
|
||||
name: `${stack}-alb-tg`,
|
||||
port: 80 // port on the docker container ,
|
||||
}
|
||||
});
|
||||
|
||||
// Create a DNS record for the load balancer
|
||||
const albDomain = new aws.route53.Record(fullDomain, {
|
||||
name: fullDomain,
|
||||
zoneId: hostedZoneId,
|
||||
type: "CNAME",
|
||||
records: [alb.loadBalancer.dnsName],
|
||||
ttl: 600,
|
||||
});
|
||||
|
||||
frontendUrl = pulumi.interpolate`https://${subDomain}.${domain}`;
|
||||
|
||||
} else {
|
||||
|
||||
// Creates an ALB associated with our custom VPC.
|
||||
alb = new awsx.lb.ApplicationLoadBalancer(`${stack}-alb`, {
|
||||
securityGroups: [albSecGroup.id],
|
||||
name: `${stack}-alb`,
|
||||
subnetIds: vpc.publicSubnetIds,
|
||||
listeners: [{
|
||||
port: 80, // exposed port from the docker file
|
||||
protocol: "HTTP"
|
||||
}],
|
||||
defaultTargetGroup: {
|
||||
name: `${stack}-alb-tg`,
|
||||
port: 80, // port on the docker container
|
||||
protocol: "HTTP"
|
||||
}
|
||||
});
|
||||
|
||||
frontendUrl = pulumi.interpolate`http://${alb.loadBalancer.dnsName}`;
|
||||
}
|
||||
|
||||
const environmentVariables = [
|
||||
...containerEnvironmentVars,
|
||||
{
|
||||
name: "AP_ENGINE_EXECUTABLE_PATH",
|
||||
value: "dist/packages/engine/main.js"
|
||||
},
|
||||
{
|
||||
name: "AP_ENCRYPTION_KEY",
|
||||
value: apEncryptionKey
|
||||
},
|
||||
{
|
||||
name: "AP_JWT_SECRET",
|
||||
value: apJwtSecret
|
||||
},
|
||||
{
|
||||
name: "AP_ENVIRONMENT",
|
||||
value: "prod"
|
||||
},
|
||||
{
|
||||
name: "AP_FRONTEND_URL",
|
||||
value: frontendUrl
|
||||
},
|
||||
{
|
||||
name: "AP_TRIGGER_DEFAULT_POLL_INTERVAL",
|
||||
value: "5"
|
||||
},
|
||||
{
|
||||
name: "AP_EXECUTION_MODE",
|
||||
value: "UNSANDBOXED"
|
||||
},
|
||||
{
|
||||
name: "AP_REDIS_USE_SSL",
|
||||
value: "false"
|
||||
},
|
||||
{
|
||||
name: "AP_SANDBOX_RUN_TIME_SECONDS",
|
||||
value: "600"
|
||||
},
|
||||
{
|
||||
name: "AP_TELEMETRY_ENABLED",
|
||||
value: "true"
|
||||
},
|
||||
{
|
||||
name: "AP_TEMPLATES_SOURCE_URL",
|
||||
value: "https://cloud.activepieces.com/api/v1/templates"
|
||||
}
|
||||
];
|
||||
|
||||
const fargateService = new awsx.ecs.FargateService(`${stack}-fg`, {
|
||||
name: `${stack}-fg`,
|
||||
cluster: (new aws.ecs.Cluster(`${stack}-cluster`, {
|
||||
name: `${stack}-cluster`
|
||||
})).arn,
|
||||
networkConfiguration: {
|
||||
subnets: vpc.publicSubnetIds,
|
||||
securityGroups: [fargateSecGroup.id],
|
||||
assignPublicIp: true
|
||||
},
|
||||
desiredCount: containerInstances,
|
||||
taskDefinitionArgs: {
|
||||
family: `${stack}-fg-task-definition`,
|
||||
container: {
|
||||
name: "activepieces",
|
||||
image: imageName,
|
||||
cpu: containerCpu,
|
||||
memory: containerMemory,
|
||||
portMappings: [{
|
||||
targetGroup: alb.defaultTargetGroup,
|
||||
}],
|
||||
environment: environmentVariables
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pulumi.log.info("Finished running Pulumi");
|
||||
|
||||
export const _ = {
|
||||
activePiecesUrl: frontendUrl,
|
||||
activepiecesEnv: environmentVariables
|
||||
};
|
||||
13
activepieces-fork/deploy/pulumi/package.json
Normal file
13
activepieces-fork/deploy/pulumi/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "pulumi",
|
||||
"main": "index.ts",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pulumi/pulumi": "^3.0.0",
|
||||
"@pulumi/aws": "^6.0.0",
|
||||
"@pulumi/awsx": "^2.20.0",
|
||||
"@pulumi/docker": "^4.4.0"
|
||||
}
|
||||
}
|
||||
237
activepieces-fork/deploy/pulumi/taggable.ts
Normal file
237
activepieces-fork/deploy/pulumi/taggable.ts
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* isTaggable returns true if the given resource type is an AWS resource that supports tags.
|
||||
*/
|
||||
export function isTaggable(t: string): boolean {
|
||||
return (taggableResourceTypes.indexOf(t) !== -1);
|
||||
}
|
||||
|
||||
// taggableResourceTypes is a list of known AWS type tokens that are taggable.
|
||||
const taggableResourceTypes = [
|
||||
"aws:accessanalyzer/analyzer:Analyzer",
|
||||
"aws:acm/certificate:Certificate",
|
||||
"aws:acmpca/certificateAuthority:CertificateAuthority",
|
||||
"aws:alb/loadBalancer:LoadBalancer",
|
||||
"aws:alb/targetGroup:TargetGroup",
|
||||
"aws:apigateway/apiKey:ApiKey",
|
||||
"aws:apigateway/clientCertificate:ClientCertificate",
|
||||
"aws:apigateway/domainName:DomainName",
|
||||
"aws:apigateway/restApi:RestApi",
|
||||
"aws:apigateway/stage:Stage",
|
||||
"aws:apigateway/usagePlan:UsagePlan",
|
||||
"aws:apigateway/vpcLink:VpcLink",
|
||||
"aws:applicationloadbalancing/loadBalancer:LoadBalancer",
|
||||
"aws:applicationloadbalancing/targetGroup:TargetGroup",
|
||||
"aws:appmesh/mesh:Mesh",
|
||||
"aws:appmesh/route:Route",
|
||||
"aws:appmesh/virtualNode:VirtualNode",
|
||||
"aws:appmesh/virtualRouter:VirtualRouter",
|
||||
"aws:appmesh/virtualService:VirtualService",
|
||||
"aws:appsync/graphQLApi:GraphQLApi",
|
||||
"aws:athena/workgroup:Workgroup",
|
||||
"aws:autoscaling/group:Group",
|
||||
"aws:backup/plan:Plan",
|
||||
"aws:backup/vault:Vault",
|
||||
"aws:cfg/aggregateAuthorization:AggregateAuthorization",
|
||||
"aws:cfg/configurationAggregator:ConfigurationAggregator",
|
||||
"aws:cfg/rule:Rule",
|
||||
"aws:cloudformation/stack:Stack",
|
||||
"aws:cloudformation/stackSet:StackSet",
|
||||
"aws:cloudfront/distribution:Distribution",
|
||||
"aws:cloudhsmv2/cluster:Cluster",
|
||||
"aws:cloudtrail/trail:Trail",
|
||||
"aws:cloudwatch/eventRule:EventRule",
|
||||
"aws:cloudwatch/logGroup:LogGroup",
|
||||
"aws:cloudwatch/metricAlarm:MetricAlarm",
|
||||
"aws:codebuild/project:Project",
|
||||
"aws:codecommit/repository:Repository",
|
||||
"aws:codepipeline/pipeline:Pipeline",
|
||||
"aws:codepipeline/webhook:Webhook",
|
||||
"aws:codestarnotifications/notificationRule:NotificationRule",
|
||||
"aws:cognito/identityPool:IdentityPool",
|
||||
"aws:cognito/userPool:UserPool",
|
||||
"aws:datapipeline/pipeline:Pipeline",
|
||||
"aws:datasync/agent:Agent",
|
||||
"aws:datasync/efsLocation:EfsLocation",
|
||||
"aws:datasync/locationSmb:LocationSmb",
|
||||
"aws:datasync/nfsLocation:NfsLocation",
|
||||
"aws:datasync/s3Location:S3Location",
|
||||
"aws:datasync/task:Task",
|
||||
"aws:dax/cluster:Cluster",
|
||||
"aws:directconnect/connection:Connection",
|
||||
"aws:directconnect/hostedPrivateVirtualInterfaceAccepter:HostedPrivateVirtualInterfaceAccepter",
|
||||
"aws:directconnect/hostedPublicVirtualInterfaceAccepter:HostedPublicVirtualInterfaceAccepter",
|
||||
"aws:directconnect/hostedTransitVirtualInterfaceAcceptor:HostedTransitVirtualInterfaceAcceptor",
|
||||
"aws:directconnect/linkAggregationGroup:LinkAggregationGroup",
|
||||
"aws:directconnect/privateVirtualInterface:PrivateVirtualInterface",
|
||||
"aws:directconnect/publicVirtualInterface:PublicVirtualInterface",
|
||||
"aws:directconnect/transitVirtualInterface:TransitVirtualInterface",
|
||||
"aws:directoryservice/directory:Directory",
|
||||
"aws:dlm/lifecyclePolicy:LifecyclePolicy",
|
||||
"aws:dms/endpoint:Endpoint",
|
||||
"aws:dms/replicationInstance:ReplicationInstance",
|
||||
"aws:dms/replicationSubnetGroup:ReplicationSubnetGroup",
|
||||
"aws:dms/replicationTask:ReplicationTask",
|
||||
"aws:docdb/cluster:Cluster",
|
||||
"aws:docdb/clusterInstance:ClusterInstance",
|
||||
"aws:docdb/clusterParameterGroup:ClusterParameterGroup",
|
||||
"aws:docdb/subnetGroup:SubnetGroup",
|
||||
"aws:dynamodb/table:Table",
|
||||
"aws:ebs/snapshot:Snapshot",
|
||||
"aws:ebs/snapshotCopy:SnapshotCopy",
|
||||
"aws:ebs/volume:Volume",
|
||||
"aws:ec2/ami:Ami",
|
||||
"aws:ec2/amiCopy:AmiCopy",
|
||||
"aws:ec2/amiFromInstance:AmiFromInstance",
|
||||
"aws:ec2/capacityReservation:CapacityReservation",
|
||||
"aws:ec2/customerGateway:CustomerGateway",
|
||||
"aws:ec2/defaultNetworkAcl:DefaultNetworkAcl",
|
||||
"aws:ec2/defaultRouteTable:DefaultRouteTable",
|
||||
"aws:ec2/defaultSecurityGroup:DefaultSecurityGroup",
|
||||
"aws:ec2/defaultSubnet:DefaultSubnet",
|
||||
"aws:ec2/defaultVpc:DefaultVpc",
|
||||
"aws:ec2/defaultVpcDhcpOptions:DefaultVpcDhcpOptions",
|
||||
"aws:ec2/eip:Eip",
|
||||
"aws:ec2/fleet:Fleet",
|
||||
"aws:ec2/instance:Instance",
|
||||
"aws:ec2/internetGateway:InternetGateway",
|
||||
"aws:ec2/keyPair:KeyPair",
|
||||
"aws:ec2/launchTemplate:LaunchTemplate",
|
||||
"aws:ec2/natGateway:NatGateway",
|
||||
"aws:ec2/networkAcl:NetworkAcl",
|
||||
"aws:ec2/networkInterface:NetworkInterface",
|
||||
"aws:ec2/placementGroup:PlacementGroup",
|
||||
"aws:ec2/routeTable:RouteTable",
|
||||
"aws:ec2/securityGroup:SecurityGroup",
|
||||
"aws:ec2/spotInstanceRequest:SpotInstanceRequest",
|
||||
"aws:ec2/subnet:Subnet",
|
||||
"aws:ec2/vpc:Vpc",
|
||||
"aws:ec2/vpcDhcpOptions:VpcDhcpOptions",
|
||||
"aws:ec2/vpcEndpoint:VpcEndpoint",
|
||||
"aws:ec2/vpcEndpointService:VpcEndpointService",
|
||||
"aws:ec2/vpcPeeringConnection:VpcPeeringConnection",
|
||||
"aws:ec2/vpcPeeringConnectionAccepter:VpcPeeringConnectionAccepter",
|
||||
"aws:ec2/vpnConnection:VpnConnection",
|
||||
"aws:ec2/vpnGateway:VpnGateway",
|
||||
"aws:ec2clientvpn/endpoint:Endpoint",
|
||||
"aws:ec2transitgateway/routeTable:RouteTable",
|
||||
"aws:ec2transitgateway/transitGateway:TransitGateway",
|
||||
"aws:ec2transitgateway/vpcAttachment:VpcAttachment",
|
||||
"aws:ec2transitgateway/vpcAttachmentAccepter:VpcAttachmentAccepter",
|
||||
"aws:ecr/repository:Repository",
|
||||
"aws:ecs/capacityProvider:CapacityProvider",
|
||||
"aws:ecs/cluster:Cluster",
|
||||
"aws:ecs/service:Service",
|
||||
"aws:ecs/taskDefinition:TaskDefinition",
|
||||
"aws:efs/fileSystem:FileSystem",
|
||||
"aws:eks/cluster:Cluster",
|
||||
"aws:eks/fargateProfile:FargateProfile",
|
||||
"aws:eks/nodeGroup:NodeGroup",
|
||||
"aws:elasticache/cluster:Cluster",
|
||||
"aws:elasticache/replicationGroup:ReplicationGroup",
|
||||
"aws:elasticbeanstalk/application:Application",
|
||||
"aws:elasticbeanstalk/applicationVersion:ApplicationVersion",
|
||||
"aws:elasticbeanstalk/environment:Environment",
|
||||
"aws:elasticloadbalancing/loadBalancer:LoadBalancer",
|
||||
"aws:elasticloadbalancingv2/loadBalancer:LoadBalancer",
|
||||
"aws:elasticloadbalancingv2/targetGroup:TargetGroup",
|
||||
"aws:elasticsearch/domain:Domain",
|
||||
"aws:elb/loadBalancer:LoadBalancer",
|
||||
"aws:emr/cluster:Cluster",
|
||||
"aws:fsx/lustreFileSystem:LustreFileSystem",
|
||||
"aws:fsx/windowsFileSystem:WindowsFileSystem",
|
||||
"aws:gamelift/alias:Alias",
|
||||
"aws:gamelift/build:Build",
|
||||
"aws:gamelift/fleet:Fleet",
|
||||
"aws:gamelift/gameSessionQueue:GameSessionQueue",
|
||||
"aws:glacier/vault:Vault",
|
||||
"aws:glue/crawler:Crawler",
|
||||
"aws:glue/job:Job",
|
||||
"aws:glue/trigger:Trigger",
|
||||
"aws:iam/role:Role",
|
||||
"aws:iam/user:User",
|
||||
"aws:inspector/resourceGroup:ResourceGroup",
|
||||
"aws:kinesis/analyticsApplication:AnalyticsApplication",
|
||||
"aws:kinesis/firehoseDeliveryStream:FirehoseDeliveryStream",
|
||||
"aws:kinesis/stream:Stream",
|
||||
"aws:kms/externalKey:ExternalKey",
|
||||
"aws:kms/key:Key",
|
||||
"aws:lambda/function:Function",
|
||||
"aws:lb/loadBalancer:LoadBalancer",
|
||||
"aws:lb/targetGroup:TargetGroup",
|
||||
"aws:licensemanager/licenseConfiguration:LicenseConfiguration",
|
||||
"aws:lightsail/instance:Instance",
|
||||
"aws:mediaconvert/queue:Queue",
|
||||
"aws:mediapackage/channel:Channel",
|
||||
"aws:mediastore/container:Container",
|
||||
"aws:mq/broker:Broker",
|
||||
"aws:mq/configuration:Configuration",
|
||||
"aws:msk/cluster:Cluster",
|
||||
"aws:neptune/cluster:Cluster",
|
||||
"aws:neptune/clusterInstance:ClusterInstance",
|
||||
"aws:neptune/clusterParameterGroup:ClusterParameterGroup",
|
||||
"aws:neptune/eventSubscription:EventSubscription",
|
||||
"aws:neptune/parameterGroup:ParameterGroup",
|
||||
"aws:neptune/subnetGroup:SubnetGroup",
|
||||
"aws:opsworks/stack:Stack",
|
||||
"aws:organizations/account:Account",
|
||||
"aws:pinpoint/app:App",
|
||||
"aws:qldb/ledger:Ledger",
|
||||
"aws:ram/resourceShare:ResourceShare",
|
||||
"aws:rds/cluster:Cluster",
|
||||
"aws:rds/clusterEndpoint:ClusterEndpoint",
|
||||
"aws:rds/clusterInstance:ClusterInstance",
|
||||
"aws:rds/clusterParameterGroup:ClusterParameterGroup",
|
||||
"aws:rds/clusterSnapshot:ClusterSnapshot",
|
||||
"aws:rds/eventSubscription:EventSubscription",
|
||||
"aws:rds/instance:Instance",
|
||||
"aws:rds/optionGroup:OptionGroup",
|
||||
"aws:rds/parameterGroup:ParameterGroup",
|
||||
"aws:rds/securityGroup:SecurityGroup",
|
||||
"aws:rds/snapshot:Snapshot",
|
||||
"aws:rds/subnetGroup:SubnetGroup",
|
||||
"aws:redshift/cluster:Cluster",
|
||||
"aws:redshift/eventSubscription:EventSubscription",
|
||||
"aws:redshift/parameterGroup:ParameterGroup",
|
||||
"aws:redshift/snapshotCopyGrant:SnapshotCopyGrant",
|
||||
"aws:redshift/snapshotSchedule:SnapshotSchedule",
|
||||
"aws:redshift/subnetGroup:SubnetGroup",
|
||||
"aws:resourcegroups/group:Group",
|
||||
"aws:route53/healthCheck:HealthCheck",
|
||||
"aws:route53/resolverEndpoint:ResolverEndpoint",
|
||||
"aws:route53/resolverRule:ResolverRule",
|
||||
"aws:route53/zone:Zone",
|
||||
"aws:s3/bucket:Bucket",
|
||||
"aws:s3/bucketObject:BucketObject",
|
||||
"aws:sagemaker/endpoint:Endpoint",
|
||||
"aws:sagemaker/endpointConfiguration:EndpointConfiguration",
|
||||
"aws:sagemaker/model:Model",
|
||||
"aws:sagemaker/notebookInstance:NotebookInstance",
|
||||
"aws:secretsmanager/secret:Secret",
|
||||
"aws:servicecatalog/portfolio:Portfolio",
|
||||
"aws:sfn/activity:Activity",
|
||||
"aws:sfn/stateMachine:StateMachine",
|
||||
"aws:sns/topic:Topic",
|
||||
"aws:sqs/queue:Queue",
|
||||
"aws:ssm/activation:Activation",
|
||||
"aws:ssm/document:Document",
|
||||
"aws:ssm/maintenanceWindow:MaintenanceWindow",
|
||||
"aws:ssm/parameter:Parameter",
|
||||
"aws:ssm/patchBaseline:PatchBaseline",
|
||||
"aws:storagegateway/cachesIscsiVolume:CachesIscsiVolume",
|
||||
"aws:storagegateway/gateway:Gateway",
|
||||
"aws:storagegateway/nfsFileShare:NfsFileShare",
|
||||
"aws:storagegateway/smbFileShare:SmbFileShare",
|
||||
"aws:swf/domain:Domain",
|
||||
"aws:transfer/server:Server",
|
||||
"aws:transfer/user:User",
|
||||
"aws:waf/rateBasedRule:RateBasedRule",
|
||||
"aws:waf/rule:Rule",
|
||||
"aws:waf/ruleGroup:RuleGroup",
|
||||
"aws:waf/webAcl:WebAcl",
|
||||
"aws:wafregional/rateBasedRule:RateBasedRule",
|
||||
"aws:wafregional/rule:Rule",
|
||||
"aws:wafregional/ruleGroup:RuleGroup",
|
||||
"aws:wafregional/webAcl:WebAcl",
|
||||
"aws:workspaces/directory:Directory",
|
||||
"aws:workspaces/ipGroup:IpGroup",
|
||||
];
|
||||
20
activepieces-fork/deploy/pulumi/tsconfig.json
Normal file
20
activepieces-fork/deploy/pulumi/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"outDir": "bin",
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"pretty": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": false,
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"index.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user