-
-
Save adeel-shahzad/ac454d082b95d1467dbc618745692483 to your computer and use it in GitHub Desktop.
AWS Fargate cluster hosting Flowise exposed through ELB.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: "2010-09-09" | |
Description: This template creates resources for Flowise application | |
Parameters: | |
Stage: | |
Description: Prefix of resource names | |
Type: String | |
Default: flowise | |
Mappings: | |
SubnetConfig: | |
VPC: | |
CIDR: "10.0.0.0/16" | |
PublicOne: | |
CIDR: "10.0.0.0/24" | |
PublicTwo: | |
CIDR: "10.0.1.0/24" | |
PrivateOne: | |
CIDR: "10.0.2.0/24" | |
PrivateTwo: | |
CIDR: "10.0.3.0/24" | |
Resources: | |
#### | |
# VPC related resources | |
#### | |
VPC: | |
Type: AWS::EC2::VPC | |
Properties: | |
EnableDnsSupport: true | |
EnableDnsHostnames: true | |
CidrBlock: !FindInMap ["SubnetConfig", "VPC", "CIDR"] | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, vpc]] | |
PublicSubnetOne: | |
Type: AWS::EC2::Subnet | |
Properties: | |
AvailabilityZone: !Select | |
- 0 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
VpcId: !Ref "VPC" | |
CidrBlock: !FindInMap ["SubnetConfig", "PublicOne", "CIDR"] | |
MapPublicIpOnLaunch: true | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, public-subnet-one]] | |
PublicSubnetTwo: | |
Type: AWS::EC2::Subnet | |
Properties: | |
AvailabilityZone: !Select | |
- 1 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
VpcId: !Ref "VPC" | |
CidrBlock: !FindInMap ["SubnetConfig", "PublicTwo", "CIDR"] | |
MapPublicIpOnLaunch: true | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, public-subnet-two]] | |
PrivateSubnetOne: | |
Type: AWS::EC2::Subnet | |
Properties: | |
AvailabilityZone: !Select | |
- 0 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
VpcId: !Ref "VPC" | |
CidrBlock: !FindInMap ["SubnetConfig", "PrivateOne", "CIDR"] | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, private-subnet-one]] | |
PrivateSubnetTwo: | |
Type: AWS::EC2::Subnet | |
Properties: | |
AvailabilityZone: !Select | |
- 1 | |
- Fn::GetAZs: !Ref "AWS::Region" | |
VpcId: !Ref "VPC" | |
CidrBlock: !FindInMap ["SubnetConfig", "PrivateTwo", "CIDR"] | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, private-subnet-two]] | |
InternetGateway: | |
Type: AWS::EC2::InternetGateway | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, igw]] | |
GatewayAttachement: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Properties: | |
VpcId: !Ref "VPC" | |
InternetGatewayId: !Ref "InternetGateway" | |
PublicRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref "VPC" | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, public-rt]] | |
PublicRoute: | |
Type: AWS::EC2::Route | |
DependsOn: GatewayAttachement | |
Properties: | |
RouteTableId: !Ref "PublicRouteTable" | |
DestinationCidrBlock: "0.0.0.0/0" | |
GatewayId: !Ref "InternetGateway" | |
PublicSubnetOneRouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnetOne | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnetTwoRouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnetTwo | |
RouteTableId: !Ref PublicRouteTable | |
NatGatewayOneAttachment: | |
Type: AWS::EC2::EIP | |
DependsOn: GatewayAttachement | |
Properties: | |
Domain: vpc | |
NatGatewayTwoAttachment: | |
Type: AWS::EC2::EIP | |
DependsOn: GatewayAttachement | |
Properties: | |
Domain: vpc | |
NatGatewayOne: | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt NatGatewayOneAttachment.AllocationId | |
SubnetId: !Ref PublicSubnetOne | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, ngw-one]] | |
NatGatewayTwo: | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt NatGatewayTwoAttachment.AllocationId | |
SubnetId: !Ref PublicSubnetTwo | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, ngw-two]] | |
PrivateRouteTableOne: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref "VPC" | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, private-rt-one]] | |
PrivateRouteOne: | |
Type: AWS::EC2::Route | |
Properties: | |
RouteTableId: !Ref PrivateRouteTableOne | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref NatGatewayOne | |
PrivateRouteTableOneAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
RouteTableId: !Ref PrivateRouteTableOne | |
SubnetId: !Ref PrivateSubnetOne | |
PrivateRouteTableTwo: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref "VPC" | |
Tags: | |
- Key: Name | |
Value: !Join ["-", [!Ref Stage, private-rt-two]] | |
PrivateRouteTwo: | |
Type: AWS::EC2::Route | |
Properties: | |
RouteTableId: !Ref PrivateRouteTableTwo | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref NatGatewayTwo | |
PrivateRouteTableTwoAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
RouteTableId: !Ref PrivateRouteTableTwo | |
SubnetId: !Ref PrivateSubnetTwo | |
#### | |
# ALB related resources | |
#### | |
PublicLoadBalancerSG: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupName: !Join ["-", [!Ref Stage, public-lb-sg]] | |
GroupDescription: Access to the public facing load balancer | |
VpcId: !Ref "VPC" | |
SecurityGroupIngress: | |
- CidrIp: 0.0.0.0/0 | |
IpProtocol: -1 | |
PublicLoadBalancer: | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Properties: | |
Name: !Join ["-", [!Ref Stage, public-lb]] | |
Scheme: internet-facing | |
LoadBalancerAttributes: | |
- Key: idle_timeout.timeout_seconds | |
Value: "30" | |
Subnets: | |
- !Ref "PublicSubnetOne" | |
- !Ref "PublicSubnetTwo" | |
SecurityGroups: [!Ref "PublicLoadBalancerSG"] | |
# A dummy target group is used to setup the ALB to just drop traffic | |
# initially, before any real service target groups have been added. | |
DummyTargetGroupPublic: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
Properties: | |
Name: !Join ["-", [!Ref Stage, dummy-tg]] | |
HealthCheckIntervalSeconds: 6 | |
HealthCheckPath: / | |
HealthCheckProtocol: HTTP | |
HealthCheckTimeoutSeconds: 5 | |
HealthyThresholdCount: 2 | |
Port: 80 | |
Protocol: HTTP | |
UnhealthyThresholdCount: 2 | |
VpcId: !Ref "VPC" | |
PublicLoadBalancerListener: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
DependsOn: | |
- PublicLoadBalancer | |
Properties: | |
DefaultActions: | |
- TargetGroupArn: !Ref "DummyTargetGroupPublic" | |
Type: "forward" | |
LoadBalancerArn: !Ref "PublicLoadBalancer" | |
Port: 80 | |
Protocol: HTTP | |
#### | |
# ECS cluster related resources | |
#### | |
ECSCluster: | |
Type: AWS::ECS::Cluster | |
Properties: | |
ClusterName: !Join ["-", [!Ref Stage, ecs-cluster]] | |
ContainerSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupName: !Join ["-", [!Ref Stage, container-sg]] | |
GroupDescription: Access to the containers | |
VpcId: !Ref "VPC" | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: 0 | |
ToPort: 65535 | |
SourceSecurityGroupId: !Ref "PublicLoadBalancerSG" | |
#### | |
# EFS related resources | |
#### | |
EFSFileSystemSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupName: !Join ["-", [!Ref Stage, efs-sg]] | |
GroupDescription: Security group for EFS file system | |
VpcId: !Ref "VPC" | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: 2049 | |
ToPort: 2049 | |
SourceSecurityGroupId: !Ref ContainerSecurityGroup | |
EFSFileSystem: | |
Type: AWS::EFS::FileSystem | |
Properties: | |
Encrypted: true | |
PerformanceMode: generalPurpose | |
ThroughputMode: bursting | |
EFSMountTargetOne: | |
Type: AWS::EFS::MountTarget | |
Properties: | |
FileSystemId: !Ref EFSFileSystem | |
SubnetId: !Ref PrivateSubnetOne | |
SecurityGroups: | |
- !Ref EFSFileSystemSecurityGroup | |
EFSMountTargetTwo: | |
Type: AWS::EFS::MountTarget | |
Properties: | |
FileSystemId: !Ref EFSFileSystem | |
SubnetId: !Ref PrivateSubnetTwo | |
SecurityGroups: | |
- !Ref EFSFileSystemSecurityGroup | |
#### | |
# IAM roles related resources | |
#### | |
AutoScalingRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: ecs-tasks.amazonaws.com | |
Action: "sts:AssumeRole" | |
ManagedPolicyArns: | |
- "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole" | |
ECSRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: [ecs.amazonaws.com] | |
Action: ["sts:AssumeRole"] | |
Path: / | |
Policies: | |
- PolicyName: ecs-service | |
PolicyDocument: | |
Statement: | |
- Effect: Allow | |
Action: | |
- "ec2:AttachNetworkInterface" | |
- "ec2:CreateNetworkInterface" | |
- "ec2:CreateNetworkInterfacePermission" | |
- "ec2:DeleteNetworkInterface" | |
- "ec2:DeleteNetworkInterfacePermission" | |
- "ec2:Describe*" | |
- "ec2:DetachNetworkInterface" | |
- "elasticloadbalancing:DeregisterInstancesFromLoadBalancer" | |
- "elasticloadbalancing:DeregisterTargets" | |
- "elasticloadbalancing:Describe*" | |
- "elasticloadbalancing:RegisterInstancesWithLoadBalancer" | |
- "elasticloadbalancing:RegisterTargets" | |
Resource: "*" | |
ManagedPolicyArns: | |
- "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" | |
ECSTaskExecutionRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: [ecs-tasks.amazonaws.com] | |
Action: ["sts:AssumeRole"] | |
Path: / | |
Policies: | |
- PolicyName: AmazonECSTaskExecutionRolePolicy | |
PolicyDocument: | |
Statement: | |
- Effect: Allow | |
Action: | |
# Allow the ECS Tasks to download images from ECR | |
- "ecr:GetAuthorizationToken" | |
- "ecr:BatchCheckLayerAvailability" | |
- "ecr:GetDownloadUrlForLayer" | |
- "ecr:BatchGetImage" | |
# Allow the ECS tasks to upload logs to CloudWatch | |
- "logs:CreateLogStream" | |
- "logs:PutLogEvents" | |
Resource: "*" | |
- Effect: Allow | |
Action: | |
- elasticfilesystem:ClientMount | |
- elasticfilesystem:ClientWrite | |
- elasticfilesystem:DescribeMountTargets | |
- elasticfilesystem:DescribeFileSystems | |
Resource: !GetAtt EFSFileSystem.Arn | |
#### | |
# Flowise ECS service related resources | |
#### | |
ServiceFlowise: | |
Type: AWS::ECS::Service | |
DependsOn: | |
- PrivateRouteOne | |
- PrivateRouteTwo | |
- ListenerRuleFlowise | |
Properties: | |
Cluster: !Ref ECSCluster | |
TaskDefinition: !Ref TaskDefinitionFlowise | |
LaunchType: FARGATE | |
DesiredCount: 2 | |
NetworkConfiguration: | |
AwsvpcConfiguration: | |
AssignPublicIp: DISABLED | |
Subnets: | |
- !Ref PrivateSubnetOne | |
- !Ref PrivateSubnetTwo | |
SecurityGroups: | |
- !Ref ContainerSecurityGroup | |
LoadBalancers: | |
- ContainerName: "flowise-service" | |
ContainerPort: 3000 | |
TargetGroupArn: !Ref TargetGroupFlowise | |
TaskDefinitionFlowise: | |
Type: "AWS::ECS::TaskDefinition" | |
Properties: | |
ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn | |
RequiresCompatibilities: | |
- FARGATE | |
ContainerDefinitions: | |
- Name: "flowise-service" | |
Image: "flowiseai/flowise:latest" | |
Essential: true | |
PortMappings: | |
- ContainerPort: 3000 | |
Protocol: tcp | |
Environment: | |
- Name: Port | |
Value: "3000" | |
- Name: CORS_ORIGINS | |
Value: "" | |
- Name: IFRAME_ORIGINS | |
Value: "" | |
- Name: FLOWISE_USERNAME | |
Value: "" | |
- Name: FLOWISE_PASSWORD | |
Value: "" | |
- Name: FLOWISE_FILE_SIZE_LIMIT | |
Value: "" | |
- Name: DEBUG | |
Value: "" | |
- Name: DATABASE_PATH | |
Value: "/root/.flowise" | |
- Name: DATABASE_TYPE | |
Value: "" | |
- Name: DATABASE_PORT | |
Value: "" | |
- Name: DATABASE_HOST | |
Value: "" | |
- Name: DATABASE_NAME | |
Value: "" | |
- Name: DATABASE_USER | |
Value: "" | |
- Name: DATABASE_PASSWORD | |
Value: "" | |
- Name: DATABASE_SSL | |
Value: "" | |
- Name: DATABASE_SSL_KEY_BASE64 | |
Value: "" | |
- Name: APIKEY_PATH | |
Value: "/root/.flowise" | |
- Name: SECRETKEY_PATH | |
Value: "/root/.flowise" | |
- Name: FLOWISE_SECRETKEY_OVERWRITE | |
Value: "" | |
- Name: LOG_LEVEL | |
Value: "" | |
- Name: LOG_PATH | |
Value: "/root/.flowise/logs" | |
- Name: BLOB_STORAGE_PATH | |
Value: "/root/.flowise/storage" | |
- Name: DISABLE_FLOWISE_TELEMETRY | |
Value: "" | |
EntryPoint: | |
- /bin/sh | |
- -c | |
- "sleep 3; flowise start" | |
MountPoints: | |
- SourceVolume: efs-volume | |
ContainerPath: "/root/.flowise" | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-group: !Ref CloudWatchLogsGroupFlowise | |
awslogs-region: !Ref AWS::Region | |
awslogs-stream-prefix: !Ref Stage | |
NetworkMode: awsvpc | |
Memory: "512" | |
Cpu: "256" | |
Volumes: | |
- Name: efs-volume | |
EFSVolumeConfiguration: | |
FilesystemId: !Ref EFSFileSystem | |
RootDirectory: / | |
TransitEncryption: ENABLED | |
CloudWatchLogsGroupFlowise: | |
Type: AWS::Logs::LogGroup | |
Properties: | |
LogGroupName: !Ref AWS::StackName | |
RetentionInDays: 7 | |
TargetGroupFlowise: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
Properties: | |
VpcId: !Ref VPC | |
Port: 80 | |
Protocol: HTTP | |
Matcher: | |
HttpCode: 200-299 | |
HealthCheckIntervalSeconds: 10 | |
HealthCheckPath: / | |
HealthCheckProtocol: HTTP | |
HealthCheckTimeoutSeconds: 5 | |
HealthyThresholdCount: 2 | |
TargetType: ip | |
ListenerRuleFlowise: | |
Type: AWS::ElasticLoadBalancingV2::ListenerRule | |
Properties: | |
ListenerArn: !Ref PublicLoadBalancerListener | |
Priority: 1 | |
Conditions: | |
- Field: path-pattern | |
Values: | |
- /* | |
Actions: | |
- TargetGroupArn: !Ref TargetGroupFlowise | |
Type: forward | |
Outputs: | |
ExternalUrl: | |
Description: The url of Flowise application | |
Value: !Sub http://${PublicLoadBalancer.DNSName} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment