mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-08-03 21:52:29 +02:00
Infra and Deployment for ECS Fargate (#4449)
* Infra and Deployment for ECS Fargate --------- Co-authored-by: jpb80 <jordan.buttkevitz@gmail.com>
This commit is contained in:
68
deployment/aws_ecs_fargate/cloudformation/README.md
Normal file
68
deployment/aws_ecs_fargate/cloudformation/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Onyx AWS ECS Fargate CloudFormation Deployment
|
||||
|
||||
This directory contains CloudFormation templates and scripts to deploy Onyx on AWS ECS Fargate.
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration parameters are stored in a single JSON file: `onyx_config.json`. This file contains all the parameters needed for the different CloudFormation stacks.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"OnyxNamespace": "onyx",
|
||||
"Environment": "production",
|
||||
"EFSName": "onyx-efs",
|
||||
"AWSRegion": "us-east-2",
|
||||
"VpcID": "YOUR_VPC_ID",
|
||||
"SubnetIDs": "YOUR_SUBNET_ID1,YOUR_SUBNET_ID2",
|
||||
"DomainName": "YOUR_DOMAIN e.g ecs.onyx.app",
|
||||
"ValidationMethod": "DNS",
|
||||
"HostedZoneId": ""
|
||||
}
|
||||
```
|
||||
|
||||
### Required Parameters
|
||||
|
||||
- `Environment`: Used to prefix all stack names during deployment. This is required.
|
||||
- `OnyxNamespace`: Namespace for the Onyx deployment.
|
||||
- `EFSName`: Name for the Elastic File System.
|
||||
- `AWSRegion`: AWS region where resources will be deployed.
|
||||
- `VpcID`: ID of the VPC where Onyx will be deployed.
|
||||
- `SubnetIDs`: Comma-separated list of subnet IDs for deployment.
|
||||
- `DomainName`: Domain name for the Onyx deployment.
|
||||
- `ValidationMethod`: Method for domain validation (typically "DNS").
|
||||
- [optional] `HostedZoneId`: Route 53 hosted zone ID (only if using Route 53 for DNS).
|
||||
|
||||
The deployment script automatically extracts the needed parameters for each CloudFormation template based on the parameter names defined in the templates.
|
||||
|
||||
## Deployment Order
|
||||
|
||||
The deployment follows this order:
|
||||
|
||||
1. Infrastructure stacks:
|
||||
- EFS
|
||||
- Cluster
|
||||
- ACM
|
||||
|
||||
2. Service stacks:
|
||||
- Postgres
|
||||
- Redis
|
||||
- Vespa Engine
|
||||
- Model Server (Indexing)
|
||||
- Model Server (Inference)
|
||||
- Backend API Server
|
||||
- Backend Background Server
|
||||
- Web Server
|
||||
- Nginx
|
||||
|
||||
## Usage
|
||||
|
||||
To deploy:
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
To uninstall:
|
||||
```bash
|
||||
./uninstall.sh
|
||||
```
|
194
deployment/aws_ecs_fargate/cloudformation/deploy.sh
Executable file
194
deployment/aws_ecs_fargate/cloudformation/deploy.sh
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to remove comments from JSON and output valid JSON
|
||||
remove_comments() {
|
||||
sed 's/\/\/.*$//' "$1" | grep -v '^[[:space:]]*$'
|
||||
}
|
||||
|
||||
# Variables
|
||||
TEMPLATE_DIR="$(pwd)"
|
||||
SERVICE_DIR="$TEMPLATE_DIR/services"
|
||||
|
||||
# Unified config file
|
||||
CONFIG_FILE="onyx_config.jsonl"
|
||||
|
||||
# Try to get AWS_REGION from config, fallback to default if not found
|
||||
AWS_REGION_FROM_CONFIG=$(remove_comments "$CONFIG_FILE" | jq -r '.AWSRegion // empty')
|
||||
if [ -n "$AWS_REGION_FROM_CONFIG" ]; then
|
||||
AWS_REGION="$AWS_REGION_FROM_CONFIG"
|
||||
else
|
||||
AWS_REGION="${AWS_REGION:-us-east-2}"
|
||||
fi
|
||||
|
||||
# Get environment from config file
|
||||
ENVIRONMENT=$(remove_comments "$CONFIG_FILE" | jq -r '.Environment')
|
||||
if [ -z "$ENVIRONMENT" ] || [ "$ENVIRONMENT" == "null" ]; then
|
||||
echo "Missing Environment in $CONFIG_FILE. Please add the Environment field."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to get S3_BUCKET from config, fallback to default if not found
|
||||
S3_BUCKET_FROM_CONFIG=$(remove_comments "$CONFIG_FILE" | jq -r '.S3Bucket // empty')
|
||||
if [ -n "$S3_BUCKET_FROM_CONFIG" ]; then
|
||||
S3_BUCKET="$S3_BUCKET_FROM_CONFIG"
|
||||
else
|
||||
S3_BUCKET="${S3_BUCKET:-onyx-ecs-fargate-configs}"
|
||||
fi
|
||||
|
||||
INFRA_ORDER=(
|
||||
"onyx_efs_template.yaml"
|
||||
"onyx_cluster_template.yaml"
|
||||
"onyx_acm_template.yaml"
|
||||
)
|
||||
|
||||
# Deployment order for services
|
||||
SERVICE_ORDER=(
|
||||
"onyx_postgres_service_template.yaml"
|
||||
"onyx_redis_service_template.yaml"
|
||||
"onyx_vespaengine_service_template.yaml"
|
||||
"onyx_model_server_indexing_service_template.yaml"
|
||||
"onyx_model_server_inference_service_template.yaml"
|
||||
"onyx_backend_api_server_service_template.yaml"
|
||||
"onyx_backend_background_server_service_template.yaml"
|
||||
"onyx_web_server_service_template.yaml"
|
||||
"onyx_nginx_service_template.yaml"
|
||||
)
|
||||
|
||||
# Function to validate a CloudFormation template
|
||||
validate_template() {
|
||||
local template_file=$1
|
||||
echo "Validating template: $template_file..."
|
||||
aws cloudformation validate-template --template-body file://"$template_file" --region "$AWS_REGION" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Validation failed for $template_file. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
echo "Validation succeeded for $template_file."
|
||||
}
|
||||
|
||||
# Function to create CloudFormation parameters from JSON
|
||||
create_parameters_from_json() {
|
||||
local template_file=$1
|
||||
local temp_params_file="${template_file%.yaml}_parameters.json"
|
||||
|
||||
# Convert the config file contents to CloudFormation parameter format
|
||||
echo "[" > "$temp_params_file"
|
||||
|
||||
# Process all key-value pairs from the config file
|
||||
local first=true
|
||||
remove_comments "$CONFIG_FILE" | jq -r 'to_entries[] | select(.value != null and .value != "") | "\(.key)|\(.value)"' | while IFS='|' read -r key value; do
|
||||
if [ "$first" = true ]; then
|
||||
first=false
|
||||
else
|
||||
echo "," >> "$temp_params_file"
|
||||
fi
|
||||
echo " {\"ParameterKey\": \"$key\", \"ParameterValue\": \"$value\"}" >> "$temp_params_file"
|
||||
done
|
||||
|
||||
echo "]" >> "$temp_params_file"
|
||||
|
||||
# Debug output - display the created parameters file
|
||||
echo "Generated parameters file: $temp_params_file" >&2
|
||||
echo "Contents:" >&2
|
||||
cat "$temp_params_file" >&2
|
||||
|
||||
# Return just the filename
|
||||
echo "$temp_params_file"
|
||||
}
|
||||
|
||||
# Function to deploy a CloudFormation stack
|
||||
deploy_stack() {
|
||||
local stack_name=$1
|
||||
local template_file=$2
|
||||
|
||||
echo "Checking if stack $stack_name exists..."
|
||||
if aws cloudformation describe-stacks --stack-name "$stack_name" --region "$AWS_REGION" > /dev/null 2>&1; then
|
||||
echo "Stack $stack_name already exists. Skipping deployment."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Create temporary parameters file for this template
|
||||
local temp_params_file=$(create_parameters_from_json "$template_file")
|
||||
|
||||
# Special handling for SubnetIDs parameter if needed
|
||||
if grep -q "SubnetIDs" "$template_file"; then
|
||||
echo "Template uses SubnetIDs parameter, ensuring it's properly formatted..."
|
||||
# Make sure we're passing SubnetIDs as a comma-separated list
|
||||
local subnet_ids=$(remove_comments "$CONFIG_FILE" | jq -r '.SubnetIDs // empty')
|
||||
if [ -n "$subnet_ids" ]; then
|
||||
echo "Using SubnetIDs from config: $subnet_ids"
|
||||
else
|
||||
echo "Warning: SubnetIDs not found in config but template requires it."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Deploying stack: $stack_name with template: $template_file and generated config from: $CONFIG_FILE..."
|
||||
aws cloudformation deploy \
|
||||
--stack-name "$stack_name" \
|
||||
--template-file "$template_file" \
|
||||
--parameter-overrides file://"$temp_params_file" \
|
||||
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND \
|
||||
--region "$AWS_REGION" \
|
||||
--no-cli-auto-prompt > /dev/null
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Deployment failed for $stack_name. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up temporary parameter file
|
||||
rm "$temp_params_file"
|
||||
|
||||
echo "Stack deployed successfully: $stack_name."
|
||||
}
|
||||
|
||||
convert_underscores_to_hyphens() {
|
||||
local input_string="$1"
|
||||
local converted_string="${input_string//_/-}"
|
||||
echo "$converted_string"
|
||||
}
|
||||
|
||||
deploy_infra_stacks() {
|
||||
for template_name in "${INFRA_ORDER[@]}"; do
|
||||
# Skip ACM template if HostedZoneId is not set
|
||||
if [[ "$template_name" == "onyx_acm_template.yaml" ]]; then
|
||||
HOSTED_ZONE_ID=$(remove_comments "$CONFIG_FILE" | jq -r '.HostedZoneId')
|
||||
if [ -z "$HOSTED_ZONE_ID" ] || [ "$HOSTED_ZONE_ID" == "" ] || [ "$HOSTED_ZONE_ID" == "null" ]; then
|
||||
echo "Skipping ACM template deployment because HostedZoneId is not set in $CONFIG_FILE"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
template_file="$template_name"
|
||||
stack_name="$ENVIRONMENT-$(basename "$template_name" _template.yaml)"
|
||||
stack_name=$(convert_underscores_to_hyphens "$stack_name")
|
||||
|
||||
if [ -f "$template_file" ]; then
|
||||
validate_template "$template_file"
|
||||
deploy_stack "$stack_name" "$template_file"
|
||||
else
|
||||
echo "Warning: Template file $template_file not found. Skipping."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
deploy_services_stacks() {
|
||||
for template_name in "${SERVICE_ORDER[@]}"; do
|
||||
template_file="$SERVICE_DIR/$template_name"
|
||||
stack_name="$ENVIRONMENT-$(basename "$template_name" _template.yaml)"
|
||||
stack_name=$(convert_underscores_to_hyphens "$stack_name")
|
||||
|
||||
if [ -f "$template_file" ]; then
|
||||
validate_template "$template_file"
|
||||
deploy_stack "$stack_name" "$template_file"
|
||||
else
|
||||
echo "Warning: Template file $template_file not found. Skipping."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
echo "Starting deployment of Onyx to ECS Fargate Cluster..."
|
||||
deploy_infra_stacks
|
||||
deploy_services_stacks
|
||||
|
||||
echo "All templates validated and deployed successfully."
|
@@ -0,0 +1,31 @@
|
||||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Description: CloudFormation template to create an ACM Certificate.
|
||||
|
||||
Parameters:
|
||||
DomainName:
|
||||
Type: String
|
||||
Description: The primary domain name for the certificate (e.g., example.com).
|
||||
Default: example.com
|
||||
Environment:
|
||||
Type: String
|
||||
Default: production
|
||||
ValidationMethod:
|
||||
Type: String
|
||||
Default: DNS
|
||||
|
||||
Resources:
|
||||
Certificate:
|
||||
Type: AWS::CertificateManager::Certificate
|
||||
Properties:
|
||||
DomainName: !Ref DomainName
|
||||
ValidationMethod: !Ref ValidationMethod
|
||||
Tags:
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
|
||||
Outputs:
|
||||
OutputAcm:
|
||||
Description: ACM Cert Id
|
||||
Value: !Ref Certificate
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-OnyxCertificate
|
@@ -0,0 +1,156 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: The template used to create an ECS Cluster from the ECS Console.
|
||||
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
Description: The environment that is used in the name of the cluster as well.
|
||||
OnyxNamespace:
|
||||
Type: String
|
||||
Default: onyx
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
|
||||
Resources:
|
||||
ECSCluster:
|
||||
Type: AWS::ECS::Cluster
|
||||
Properties:
|
||||
ClusterName: !Sub ${Environment}-onyx-cluster
|
||||
CapacityProviders:
|
||||
- FARGATE
|
||||
- FARGATE_SPOT
|
||||
ClusterSettings:
|
||||
- Name: containerInsights
|
||||
Value: enhanced
|
||||
ServiceConnectDefaults:
|
||||
Namespace: !Sub ${Environment}-onyx-cluster
|
||||
Tags:
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
- Key: app
|
||||
Value: onyx
|
||||
|
||||
S3Bucket:
|
||||
Type: AWS::S3::Bucket
|
||||
Properties:
|
||||
BucketName: !Sub ${Environment}-onyx-ecs-fargate-configs
|
||||
AccessControl: Private
|
||||
BucketEncryption:
|
||||
ServerSideEncryptionConfiguration:
|
||||
- ServerSideEncryptionByDefault:
|
||||
SSEAlgorithm: AES256
|
||||
PublicAccessBlockConfiguration:
|
||||
BlockPublicAcls: true
|
||||
BlockPublicPolicy: true
|
||||
IgnorePublicAcls: true
|
||||
RestrictPublicBuckets: true
|
||||
|
||||
PrivateDnsNamespace:
|
||||
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
|
||||
Properties:
|
||||
Description: AWS Cloud Map private DNS namespace for resources for onyx website.
|
||||
Vpc: !Ref VpcID
|
||||
Name: !Ref OnyxNamespace
|
||||
Properties:
|
||||
DnsProperties:
|
||||
SOA:
|
||||
TTL: 50
|
||||
|
||||
ECSTaskRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: !Sub ${Environment}-OnyxEcsTaskRole
|
||||
AssumeRolePolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: ecs-tasks.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
Policies:
|
||||
- PolicyName: "EFSPolicy"
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Sid: "VisualEditor0"
|
||||
Effect: Allow
|
||||
Action:
|
||||
- "elasticfilesystem:*"
|
||||
Resource:
|
||||
- !Sub "arn:aws:elasticfilesystem:*:${AWS::AccountId}:access-point/*"
|
||||
- !Sub "arn:aws:elasticfilesystem:*:${AWS::AccountId}:file-system/*"
|
||||
- Sid: "VisualEditor1"
|
||||
Effect: Allow
|
||||
Action: "elasticfilesystem:*"
|
||||
Resource: "*"
|
||||
- PolicyName: "S3Policy"
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Sid: "VisualEditor0"
|
||||
Effect: Allow
|
||||
Action:
|
||||
- "s3:GetObject"
|
||||
- "s3:ListBucket"
|
||||
Resource:
|
||||
- !Sub "arn:aws:s3:::${Environment}-onyx-ecs-fargate-configs/*"
|
||||
- !Sub "arn:aws:s3:::${Environment}-onyx-ecs-fargate-configs"
|
||||
|
||||
ECSTaskExecutionRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: !Sub ${Environment}-OnyxECSTaskExecutionRole
|
||||
AssumeRolePolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: ecs-tasks.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
ManagedPolicyArns:
|
||||
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
|
||||
Policies:
|
||||
- PolicyName: "CloudWatchLogsPolicy"
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Sid: "VisualEditor0"
|
||||
Effect: Allow
|
||||
Action: "logs:CreateLogGroup"
|
||||
Resource: !Sub "arn:aws:logs:*:${AWS::AccountId}:log-group:*"
|
||||
- PolicyName: "SecretsManagerPolicy"
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${Environment}/postgres/user/password-*
|
||||
|
||||
Outputs:
|
||||
OutputEcsCluster:
|
||||
Description: Onyx ECS Cluster
|
||||
Value: !Ref ECSCluster
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-ECSClusterName
|
||||
OutputECSTaskRole:
|
||||
Description: Onyx ECS Task Role
|
||||
Value: !Ref ECSTaskRole
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-ECSTaskRole
|
||||
OutputECSTaskExecutionRole:
|
||||
Description: Onyx ECS TaskExecutionRole
|
||||
Value: !Ref ECSTaskExecutionRole
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-ECSTaskExecutionRole
|
||||
OutputOnyxNamespace:
|
||||
Description: Onyx CloudMap namespace ID for ECS service discvoery.
|
||||
Value: !Ref PrivateDnsNamespace
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-OnyxNamespace
|
||||
OutputOnyxNamespaceName:
|
||||
Description: Onyx CloudMap namespace domain name for ECS service discvoery.
|
||||
Value: !Ref OnyxNamespace
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-OnyxNamespaceName
|
16
deployment/aws_ecs_fargate/cloudformation/onyx_config.jsonl
Normal file
16
deployment/aws_ecs_fargate/cloudformation/onyx_config.jsonl
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
// Naming, likely doesn't need to be changed
|
||||
"OnyxNamespace": "onyx",
|
||||
"Environment": "production-1",
|
||||
"EFSName": "onyx-efs-1",
|
||||
|
||||
// Region and VPC Stuff
|
||||
"AWSRegion": "us-east-2",
|
||||
"VpcID": "vpc-08822ab4927074015",
|
||||
"SubnetIDs": "subnet-0c0c686bf71a9756e,subnet-0711d1a975b8a035c",
|
||||
|
||||
// Domain and ACM Stuff
|
||||
"DomainName": "ecs-chris.danswer.dev",
|
||||
"ValidationMethod": "DNS",
|
||||
"HostedZoneId": "" // Only specify if using Route 53 for DNS
|
||||
}
|
128
deployment/aws_ecs_fargate/cloudformation/onyx_efs_template.yaml
Normal file
128
deployment/aws_ecs_fargate/cloudformation/onyx_efs_template.yaml
Normal file
@@ -0,0 +1,128 @@
|
||||
Parameters:
|
||||
|
||||
EFSName:
|
||||
Type: String
|
||||
Default: onyx-efs
|
||||
Environment:
|
||||
Type: String
|
||||
Default: production
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-0f230ca52bb04c722
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
|
||||
Resources:
|
||||
|
||||
OnyxEfs:
|
||||
Type: AWS::EFS::FileSystem
|
||||
Properties:
|
||||
BackupPolicy:
|
||||
Status: ENABLED
|
||||
Encrypted: True
|
||||
PerformanceMode: generalPurpose
|
||||
FileSystemTags:
|
||||
- Key: Name
|
||||
Value: !Sub ${Environment}-${EFSName}-${AWS::Region}-${AWS::AccountId}
|
||||
FileSystemProtection:
|
||||
ReplicationOverwriteProtection: ENABLED
|
||||
ThroughputMode: elastic
|
||||
|
||||
VespaEngineTmpEfsAccessPoint:
|
||||
Type: AWS::EFS::AccessPoint
|
||||
Properties:
|
||||
AccessPointTags:
|
||||
- Key: Name
|
||||
Value: vespaengine-tmp
|
||||
FileSystemId: !Ref OnyxEfs
|
||||
RootDirectory:
|
||||
CreationInfo:
|
||||
OwnerGid: "1000"
|
||||
OwnerUid: "1000"
|
||||
Permissions: "0755"
|
||||
Path: /var/tmp
|
||||
|
||||
VespaEngineDataEfsAccessPoint:
|
||||
Type: AWS::EFS::AccessPoint
|
||||
Properties:
|
||||
AccessPointTags:
|
||||
- Key: Name
|
||||
Value: vespaengine-data
|
||||
FileSystemId: !Ref OnyxEfs
|
||||
RootDirectory:
|
||||
CreationInfo:
|
||||
OwnerGid: "1000"
|
||||
OwnerUid: "1000"
|
||||
Permissions: "0755"
|
||||
Path: /opt/vespa/var
|
||||
|
||||
PostgresDataEfsAccessPoint:
|
||||
Type: AWS::EFS::AccessPoint
|
||||
Properties:
|
||||
AccessPointTags:
|
||||
- Key: Name
|
||||
Value: postgres-data
|
||||
FileSystemId: !Ref OnyxEfs
|
||||
RootDirectory:
|
||||
CreationInfo:
|
||||
OwnerGid: "1000"
|
||||
OwnerUid: "1000"
|
||||
Permissions: "0755"
|
||||
Path: /var/lib/postgresql/data
|
||||
|
||||
EFSMountTarget1:
|
||||
DependsOn: OnyxEfs
|
||||
Type: AWS::EFS::MountTarget
|
||||
Properties:
|
||||
FileSystemId: !Ref OnyxEfs
|
||||
SubnetId: !Select [0, !Ref SubnetIDs]
|
||||
SecurityGroups:
|
||||
- !Ref EFSSecurityGroupMountTargets
|
||||
|
||||
EFSMountTarget2:
|
||||
DependsOn: OnyxEfs
|
||||
Type: AWS::EFS::MountTarget
|
||||
Properties:
|
||||
FileSystemId: !Ref OnyxEfs
|
||||
SubnetId: !Select [1, !Ref SubnetIDs]
|
||||
SecurityGroups:
|
||||
- !Ref EFSSecurityGroupMountTargets
|
||||
|
||||
EFSSecurityGroupMountTargets:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: Security Group for EFS Mount Targets
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
FromPort: 2049
|
||||
ToPort: 2049
|
||||
CidrIp: 0.0.0.0/0
|
||||
|
||||
Outputs:
|
||||
OutputOnyxEfsId:
|
||||
Description: Onyx Filesystem Id
|
||||
Value: !Ref OnyxEfs
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-OnyxEfsId
|
||||
OutputVespaEngineTmpEfsAccessPoint:
|
||||
Description: VespaEngine Tmp AP
|
||||
Value: !Ref VespaEngineTmpEfsAccessPoint
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-VespaEngineTmpEfsAccessPoint
|
||||
OutputVespaEngineDataEfsAccessPoint:
|
||||
Description: VespaEngine Data Ap
|
||||
Value: !Ref VespaEngineDataEfsAccessPoint
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-VespaEngineDataEfsAccessPoint
|
||||
OutputPostgresDataEfsAccessPoint:
|
||||
Description: Postgres Data AP
|
||||
Value: !Ref PostgresDataEfsAccessPoint
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-PostgresDataEfsAccessPoint
|
||||
OutputEFSSecurityGroupMountTargets:
|
||||
Description: EFS Security Group
|
||||
Value: !Ref EFSSecurityGroupMountTargets
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-EFSSecurityGroupMountTargets
|
@@ -0,0 +1,216 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Backend Api Server TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-backend-api-server
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "4096"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 8080
|
||||
ToPort: 8080
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 8080
|
||||
ToPort: 8080
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: onyx-backend
|
||||
Image: onyxdotapp/onyx-backend:latest
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
Command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- |
|
||||
alembic upgrade head && echo "Starting Onyx Api Server" && uvicorn onyx.main:app --host 0.0.0.0 --port 8080
|
||||
PortMappings:
|
||||
- Name: backend
|
||||
ContainerPort: 8080
|
||||
HostPort: 8080
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
Environment:
|
||||
- Name: REDIS_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-redis-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: MODEL_SERVER_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-model-server-inference-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: VESPA_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-vespaengine-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: POSTGRES_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-postgres-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: INDEXING_MODEL_SERVER_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-model-server-indexing-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: AUTH_TYPE
|
||||
Value: disabled
|
||||
Secrets:
|
||||
- Name: POSTGRES_PASSWORD
|
||||
ValueFrom: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${Environment}/postgres/user/password
|
||||
VolumesFrom: []
|
||||
SystemControls: []
|
||||
|
||||
ECSAutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
DependsOn: ECSService
|
||||
Properties:
|
||||
MaxCapacity: 5
|
||||
MinCapacity: 1
|
||||
ResourceId: !Sub
|
||||
- "service/${ImportedCluster}/${Environment}-${ServiceName}-service"
|
||||
- ImportedCluster: !ImportValue
|
||||
'Fn::Sub': "${Environment}-onyx-cluster-ECSClusterName"
|
||||
ServiceName: !Ref ServiceName
|
||||
Environment: !Ref Environment
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
ServiceNamespace: ecs
|
||||
|
||||
ECSAutoScalingPolicy:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-cpu-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 75
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageCPUUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
||||
|
||||
ECSAutoScalingPolicyMemory:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-mem-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 80
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageMemoryUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
@@ -0,0 +1,174 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Backend Background Server TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-backend-background-server
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "4096"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 8080
|
||||
ToPort: 8080
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 8080
|
||||
ToPort: 8080
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: onyx-backend-background
|
||||
Image: onyxdotapp/onyx-backend:latest
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
Command:
|
||||
- "/usr/bin/supervisord"
|
||||
- "-c"
|
||||
- "/etc/supervisor/conf.d/supervisord.conf"
|
||||
PortMappings:
|
||||
- Name: backend
|
||||
ContainerPort: 8080
|
||||
HostPort: 8080
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
Environment:
|
||||
- Name: REDIS_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-redis-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: MODEL_SERVER_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-model-server-inference-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: VESPA_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-vespaengine-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: POSTGRES_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-postgres-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: INDEXING_MODEL_SERVER_HOST
|
||||
Value: !Sub
|
||||
- "${Environment}-onyx-model-server-indexing-service.${ImportedNamespace}"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
- Name: AUTH_TYPE
|
||||
Value: disabled
|
||||
Secrets:
|
||||
- Name: POSTGRES_PASSWORD
|
||||
ValueFrom: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${Environment}/postgres/user/password
|
||||
VolumesFrom: []
|
||||
SystemControls: []
|
@@ -0,0 +1,163 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Model Server Indexing TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-model-server-indexing
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "4096"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 9000
|
||||
ToPort: 9000
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 9000
|
||||
ToPort: 9000
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: onyx-model-server-indexing
|
||||
Image: onyxdotapp/onyx-model-server:latest
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
Command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- >
|
||||
if [ "${DISABLE_MODEL_SERVER:-false}" = "True" ]; then echo 'Skipping service...';
|
||||
exit 0; else exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000; fi
|
||||
PortMappings:
|
||||
- Name: model-server
|
||||
ContainerPort: 9000
|
||||
HostPort: 9000
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
Environment:
|
||||
- Name: LOG_LEVEL
|
||||
Value: info
|
||||
- Name: INDEXING_ONLY
|
||||
Value: True
|
||||
- Name: VESPA_SEARCHER_THREADS
|
||||
Value: "1"
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume
|
||||
ContainerPath: /root/.cache/huggingface/
|
||||
ReadOnly: false
|
||||
VolumesFrom: []
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: "ecs"
|
||||
SystemControls: []
|
||||
Volumes:
|
||||
- Name: efs-volume
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: "/"
|
@@ -0,0 +1,200 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Model Server Inference TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-model-server-inference
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "4096"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 9000
|
||||
ToPort: 9000
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 9000
|
||||
ToPort: 9000
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: onyx-model-server-inference
|
||||
Image: onyxdotapp/onyx-model-server:latest
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
Command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- >
|
||||
if [ "${DISABLE_MODEL_SERVER:-false}" = "True" ]; then echo 'Skipping service...';
|
||||
exit 0; else exec uvicorn model_server.main:app --host 0.0.0.0 --port 9000; fi
|
||||
PortMappings:
|
||||
- Name: model-server
|
||||
ContainerPort: 9000
|
||||
HostPort: 9000
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
Environment:
|
||||
- Name: LOG_LEVEL
|
||||
Value: info
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume
|
||||
ContainerPath: /root/.cache/huggingface/
|
||||
ReadOnly: false
|
||||
VolumesFrom: []
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: "ecs"
|
||||
SystemControls: []
|
||||
Volumes:
|
||||
- Name: efs-volume
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: "/"
|
||||
|
||||
ECSAutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
DependsOn: ECSService
|
||||
Properties:
|
||||
MaxCapacity: 5
|
||||
MinCapacity: 1
|
||||
ResourceId: !Sub
|
||||
- "service/${ImportedCluster}/${Environment}-${ServiceName}-service"
|
||||
- ImportedCluster: !ImportValue
|
||||
'Fn::Sub': "${Environment}-onyx-cluster-ECSClusterName"
|
||||
ServiceName: !Ref ServiceName
|
||||
Environment: !Ref Environment
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
ServiceNamespace: ecs
|
||||
|
||||
ECSAutoScalingPolicy:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-cpu-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 75
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageCPUUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
||||
|
||||
ECSAutoScalingPolicyMemory:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-memory-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 80
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageMemoryUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
@@ -0,0 +1,288 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: "The template used to create an ECS Service from the ECS Console."
|
||||
|
||||
Parameters:
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
HostedZoneId:
|
||||
Type: String
|
||||
Default: ''
|
||||
DomainName:
|
||||
Type: String
|
||||
Default: demo.danswer.ai
|
||||
Environment:
|
||||
Type: String
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-nginx
|
||||
OnyxNamespace:
|
||||
Type: String
|
||||
Default: onyx
|
||||
OnyxBackendApiServiceName:
|
||||
Type: String
|
||||
Default: onyx-backend-api-server-service
|
||||
OnyxWebServerServiceName:
|
||||
Type: String
|
||||
Default: onyx-web-server-service
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "512"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "1024"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
GitHubConfigUrl:
|
||||
Type: String
|
||||
Default: "https://raw.githubusercontent.com/onyx-dot-app/onyx/main/deployment/data/nginx/app.conf.template.dev"
|
||||
Description: "URL to the nginx configuration file on GitHub"
|
||||
GitHubRunScriptUrl:
|
||||
Type: String
|
||||
Default: "https://raw.githubusercontent.com/onyx-dot-app/onyx/main/deployment/data/nginx/run-nginx.sh"
|
||||
Description: "URL to the nginx run script on GitHub"
|
||||
|
||||
Conditions:
|
||||
CreateRoute53: !Not
|
||||
- !Equals
|
||||
- !Ref HostedZoneId
|
||||
- ''
|
||||
|
||||
Resources:
|
||||
ECSService:
|
||||
Type: "AWS::ECS::Service"
|
||||
DependsOn: LoadBalancer
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: "FARGATE"
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}
|
||||
SchedulingStrategy: "REPLICA"
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: "ENABLED"
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: "ENABLED"
|
||||
SecurityGroups:
|
||||
- !Ref SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: "LATEST"
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: "ECS"
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt
|
||||
- "ServiceDiscoveryService"
|
||||
- "Arn"
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
LoadBalancers:
|
||||
- ContainerName: nginx
|
||||
ContainerPort: 80
|
||||
TargetGroupArn: !Ref TargetGroup
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
ContainerDefinitions:
|
||||
- Name: nginx
|
||||
Image: nginx:1.23.4-alpine
|
||||
Cpu: 0
|
||||
PortMappings:
|
||||
- Name: nginx-80-tcp
|
||||
ContainerPort: 80
|
||||
HostPort: 80
|
||||
Protocol: tcp
|
||||
Essential: true
|
||||
Command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- dos2unix /etc/nginx/conf.d/run-nginx.sh && /etc/nginx/conf.d/run-nginx.sh app.conf.template.dev
|
||||
Environment:
|
||||
- Name: EMAIL
|
||||
Value: ""
|
||||
- Name: DOMAIN
|
||||
Value: !Ref DomainName
|
||||
- Name: ONYX_BACKEND_API_HOST
|
||||
Value: !Sub ${Environment}-${OnyxBackendApiServiceName}.${OnyxNamespace}
|
||||
- Name: ONYX_WEB_SERVER_HOST
|
||||
Value: !Sub ${Environment}-${OnyxWebServerServiceName}.${OnyxNamespace}
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume
|
||||
ContainerPath: /etc/nginx/conf.d
|
||||
VolumesFrom: []
|
||||
DependsOn:
|
||||
- ContainerName: github-sync-container
|
||||
Condition: SUCCESS
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-OnyxNginxTaskDefinition
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: 25m
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
SystemControls: []
|
||||
- Name: github-sync-container
|
||||
Image: curlimages/curl:latest
|
||||
Cpu: 128
|
||||
MemoryReservation: 256
|
||||
PortMappings: []
|
||||
Essential: false
|
||||
Command:
|
||||
- sh
|
||||
- -c
|
||||
- !Sub |
|
||||
curl -L ${GitHubConfigUrl} -o /etc/nginx/conf.d/app.conf.template.dev &&
|
||||
curl -L ${GitHubRunScriptUrl} -o /etc/nginx/conf.d/run-nginx.sh &&
|
||||
chmod 644 /etc/nginx/conf.d/app.conf.template.dev &&
|
||||
chmod 755 /etc/nginx/conf.d/run-nginx.sh &&
|
||||
exit 0 || exit 1
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume
|
||||
ContainerPath: /etc/nginx/conf.d
|
||||
VolumesFrom: []
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-github-sync-configs-TaskDefinition
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: 25m
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
SystemControls: []
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
Volumes:
|
||||
- Name: efs-volume
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: /
|
||||
PlacementConstraints: []
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
EnableFaultInjection: false
|
||||
|
||||
SecurityGroup:
|
||||
Type: "AWS::EC2::SecurityGroup"
|
||||
Properties:
|
||||
GroupDescription: !Sub "Security group for ${ServiceName}"
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 80
|
||||
ToPort: 80
|
||||
IpProtocol: "tcp"
|
||||
CidrIp: "0.0.0.0/0"
|
||||
- FromPort: 80
|
||||
ToPort: 80
|
||||
IpProtocol: "tcp"
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Ref ServiceName
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
LoadBalancer:
|
||||
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
|
||||
DependsOn: SecurityGroup
|
||||
Properties:
|
||||
Type: application
|
||||
Scheme: internet-facing
|
||||
Subnets: !Ref SubnetIDs
|
||||
SecurityGroups:
|
||||
- !Ref SecurityGroup
|
||||
|
||||
LoadBalancerListener:
|
||||
Type: AWS::ElasticLoadBalancingV2::Listener
|
||||
Properties:
|
||||
LoadBalancerArn: !Ref LoadBalancer
|
||||
Port: 80
|
||||
Protocol: HTTP
|
||||
DefaultActions:
|
||||
- Type: forward
|
||||
TargetGroupArn: !Ref TargetGroup
|
||||
|
||||
TargetGroup:
|
||||
Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
||||
Properties:
|
||||
HealthCheckEnabled: True
|
||||
HealthCheckIntervalSeconds: 30
|
||||
HealthCheckPort: 80
|
||||
HealthCheckPath: /api/health
|
||||
HealthCheckProtocol: HTTP
|
||||
HealthCheckTimeoutSeconds: 20
|
||||
HealthyThresholdCount: 3
|
||||
Port: 80
|
||||
Protocol: HTTP
|
||||
ProtocolVersion: HTTP1
|
||||
VpcId: !Ref VpcID
|
||||
TargetType: ip
|
||||
|
||||
Route53Record:
|
||||
Type: AWS::Route53::RecordSet
|
||||
Condition: CreateRoute53
|
||||
Properties:
|
||||
HostedZoneId: !Ref HostedZoneId
|
||||
Name: !Ref DomainName
|
||||
Type: A
|
||||
AliasTarget:
|
||||
DNSName: !GetAtt LoadBalancer.DNSName
|
||||
HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID
|
||||
EvaluateTargetHealth: false
|
||||
|
||||
Outputs:
|
||||
ECSService:
|
||||
Description: "The created service."
|
||||
Value: !Ref "ECSService"
|
||||
ServiceDiscoveryService:
|
||||
Value: !Ref "ServiceDiscoveryService"
|
||||
OutputOnyxLoadBalancerDNSName:
|
||||
Description: LoadBalancer DNSName
|
||||
Value: !GetAtt LoadBalancer.DNSName
|
||||
Export:
|
||||
Name: !Sub ${AWS::StackName}-OnyxLoadBalancerDNSName
|
@@ -0,0 +1,177 @@
|
||||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
Default: production
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-postgres
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "1024"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: DISABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- !Ref SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 100
|
||||
MinimumHealthyPercent: 0
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 5432
|
||||
ToPort: 5432
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 5432
|
||||
ToPort: 5432
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
- FromPort: 2049
|
||||
ToPort: 2049
|
||||
IpProtocol: tcp
|
||||
SourceSecurityGroupId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-EFSSecurityGroupMountTargets"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
Volumes:
|
||||
- Name: efs-volume-data
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: "/"
|
||||
TransitEncryption: ENABLED
|
||||
AuthorizationConfig:
|
||||
AccessPointId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-PostgresDataEfsAccessPoint"
|
||||
ContainerDefinitions:
|
||||
- Name: !Ref ServiceName
|
||||
Image: postgres:15.2-alpine
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
StopTimeout: 30
|
||||
Command:
|
||||
- "-c"
|
||||
- "max_connections=250"
|
||||
PortMappings:
|
||||
- Name: postgres
|
||||
ContainerPort: 5432
|
||||
HostPort: 5432
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
Environment:
|
||||
- Name: POSTGRES_USER
|
||||
Value: postgres
|
||||
- Name: PGSSLMODE
|
||||
Value: require
|
||||
- Name: POSTGRES_DB
|
||||
Value: postgres
|
||||
Secrets:
|
||||
- Name: POSTGRES_PASSWORD
|
||||
ValueFrom: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:${Environment}/postgres/user/password
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume-data
|
||||
ContainerPath: /var/lib/postgresql/data
|
||||
ReadOnly: false
|
||||
- SourceVolume: efs-volume-data
|
||||
ContainerPath: /var/lib/postgresql
|
||||
ReadOnly: false
|
||||
User: "1000"
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: /ecs/OnyxPostgresTaskDefinition
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
@@ -0,0 +1,146 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Redis TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-redis
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "1024"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 6379
|
||||
ToPort: 6379
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 6379
|
||||
ToPort: 6379
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: redis
|
||||
Image: redis:7.4-alpine
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
Command:
|
||||
- "redis-server"
|
||||
- "--save"
|
||||
- "\"\""
|
||||
- "--appendonly"
|
||||
- "no"
|
||||
PortMappings:
|
||||
- Name: redis_port
|
||||
ContainerPort: 6379
|
||||
HostPort: 6379
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
Environment: []
|
||||
VolumesFrom: []
|
||||
SystemControls: []
|
@@ -0,0 +1,190 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Vespa Engine TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-vespaengine
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "4096"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "16384"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 19071
|
||||
ToPort: 19071
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 19071
|
||||
ToPort: 19071
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
- FromPort: 8081
|
||||
ToPort: 8081
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 8081
|
||||
ToPort: 8081
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
- FromPort: 2049
|
||||
ToPort: 2049
|
||||
IpProtocol: tcp
|
||||
SourceSecurityGroupId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-EFSSecurityGroupMountTargets"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: vespaengine
|
||||
Image: vespaengine/vespa:8.277.17
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
PortMappings:
|
||||
- Name: vespaengine_port
|
||||
ContainerPort: 19071
|
||||
HostPort: 19071
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
- Name: vespaengine_port2
|
||||
ContainerPort: 8081
|
||||
HostPort: 8081
|
||||
Protocol: tcp
|
||||
AppProtocol: http
|
||||
MountPoints:
|
||||
- SourceVolume: efs-volume-data
|
||||
ContainerPath: /opt/vespa/var
|
||||
ReadOnly: false
|
||||
- SourceVolume: efs-volume-tmp
|
||||
ContainerPath: /var/tmp
|
||||
ReadOnly: false
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: /ecs/OnyxVespaEngineTaskDefinition
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
User: "1000"
|
||||
Environment: []
|
||||
VolumesFrom: []
|
||||
SystemControls: []
|
||||
Volumes:
|
||||
- Name: efs-volume-tmp
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: "/"
|
||||
TransitEncryption: ENABLED
|
||||
AuthorizationConfig:
|
||||
AccessPointId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-VespaEngineTmpEfsAccessPoint"
|
||||
- Name: efs-volume-data
|
||||
EFSVolumeConfiguration:
|
||||
FilesystemId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-OnyxEfsId"
|
||||
RootDirectory: "/"
|
||||
TransitEncryption: ENABLED
|
||||
AuthorizationConfig:
|
||||
AccessPointId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-efs-VespaEngineDataEfsAccessPoint"
|
@@ -0,0 +1,190 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Description: CloudFormation template for Onyx Web Server TaskDefinition
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
SubnetIDs:
|
||||
Type: CommaDelimitedList
|
||||
Description: "Comma-delimited list of at least two subnet IDs in different Availability Zones"
|
||||
VpcID:
|
||||
Type: String
|
||||
Default: vpc-098cfa79d637dabff
|
||||
ServiceName:
|
||||
Type: String
|
||||
Default: onyx-web-server
|
||||
TaskCpu:
|
||||
Type: String
|
||||
Default: "1024"
|
||||
TaskMemory:
|
||||
Type: String
|
||||
Default: "2048"
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
|
||||
Resources:
|
||||
|
||||
ECSService:
|
||||
Type: AWS::ECS::Service
|
||||
Properties:
|
||||
Cluster:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSClusterName"
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${Environment}-${ServiceName}-service
|
||||
SchedulingStrategy: REPLICA
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
AvailabilityZoneRebalancing: ENABLED
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups:
|
||||
- Ref: SecurityGroup
|
||||
Subnets: !Ref SubnetIDs
|
||||
PlatformVersion: LATEST
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentCircuitBreaker:
|
||||
Enable: true
|
||||
Rollback: true
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
ServiceConnectConfiguration:
|
||||
Enabled: false
|
||||
ServiceRegistries:
|
||||
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
|
||||
Tags:
|
||||
- Key: app
|
||||
Value: onyx
|
||||
- Key: service
|
||||
Value: !Ref ServiceName
|
||||
- Key: env
|
||||
Value: !Ref Environment
|
||||
EnableECSManagedTags: true
|
||||
|
||||
SecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Sub Onyx SecurityGroup access to EFS mount and ${ServiceName}.
|
||||
GroupName: !Sub ${Environment}-ecs-${ServiceName}
|
||||
VpcId: !Ref VpcID
|
||||
SecurityGroupIngress:
|
||||
- FromPort: 3000
|
||||
ToPort: 3000
|
||||
IpProtocol: tcp
|
||||
CidrIp: 0.0.0.0/0
|
||||
- FromPort: 3000
|
||||
ToPort: 3000
|
||||
IpProtocol: tcp
|
||||
CidrIpv6: "::/0"
|
||||
|
||||
ServiceDiscoveryService:
|
||||
Type: "AWS::ServiceDiscovery::Service"
|
||||
Properties:
|
||||
Name: !Sub ${Environment}-${ServiceName}-service
|
||||
DnsConfig:
|
||||
DnsRecords:
|
||||
- Type: "A"
|
||||
TTL: 15
|
||||
NamespaceId:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespace"
|
||||
HealthCheckCustomConfig:
|
||||
FailureThreshold: 1
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${Environment}-${ServiceName}-TaskDefinition
|
||||
TaskRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskRole"
|
||||
ExecutionRoleArn:
|
||||
Fn::ImportValue:
|
||||
Fn::Sub: "${Environment}-onyx-cluster-ECSTaskExecutionRole"
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
Cpu: !Ref TaskCpu
|
||||
Memory: !Ref TaskMemory
|
||||
RuntimePlatform:
|
||||
CpuArchitecture: ARM64
|
||||
OperatingSystemFamily: LINUX
|
||||
ContainerDefinitions:
|
||||
- Name: onyx-webserver
|
||||
Image: onyxdotapp/onyx-web-server:latest
|
||||
Cpu: 0
|
||||
Essential: true
|
||||
PortMappings:
|
||||
- Name: webserver
|
||||
ContainerPort: 3000
|
||||
HostPort: 3000
|
||||
Protocol: tcp
|
||||
Environment:
|
||||
- Name: NEXT_PUBLIC_DISABLE_STREAMING
|
||||
Value: "false"
|
||||
- Name: NEXT_PUBLIC_NEW_CHAT_DIRECTS_TO_SAME_PERSONA
|
||||
Value: "false"
|
||||
- Name: INTERNAL_URL
|
||||
Value: !Sub
|
||||
- "http://${Environment}-onyx-backend-api-server-service.${ImportedNamespace}:8080"
|
||||
- ImportedNamespace: !ImportValue
|
||||
Fn::Sub: "${Environment}-onyx-cluster-OnyxNamespaceName"
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
Options:
|
||||
awslogs-group: !Sub /ecs/${Environment}-${ServiceName}
|
||||
mode: non-blocking
|
||||
awslogs-create-group: "true"
|
||||
max-buffer-size: "25m"
|
||||
awslogs-region: !Ref AWS::Region
|
||||
awslogs-stream-prefix: ecs
|
||||
User: "1000"
|
||||
VolumesFrom: []
|
||||
SystemControls: []
|
||||
|
||||
ECSAutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
DependsOn: ECSService
|
||||
Properties:
|
||||
MaxCapacity: 5
|
||||
MinCapacity: 1
|
||||
ResourceId: !Sub
|
||||
- "service/${ImportedCluster}/${Environment}-${ServiceName}-service"
|
||||
- ImportedCluster: !ImportValue
|
||||
'Fn::Sub': "${Environment}-onyx-cluster-ECSClusterName"
|
||||
ServiceName: !Ref ServiceName
|
||||
Environment: !Ref Environment
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
ServiceNamespace: ecs
|
||||
|
||||
ECSAutoScalingPolicy:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-cpu-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 75
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageCPUUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
||||
|
||||
ECSAutoScalingPolicyMemory:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Sub ${Environment}-${ServiceName}-service-memory-scaleout
|
||||
ScalingTargetId: !Ref ECSAutoScalingTarget
|
||||
PolicyType: TargetTrackingScaling
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
TargetValue: 80
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageMemoryUtilization
|
||||
ScaleOutCooldown: 60
|
||||
ScaleInCooldown: 60
|
76
deployment/aws_ecs_fargate/cloudformation/uninstall.sh
Executable file
76
deployment/aws_ecs_fargate/cloudformation/uninstall.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
AWS_REGION="${AWS_REGION:-us-west-1}"
|
||||
|
||||
# Reference to consolidated config
|
||||
CONFIG_FILE="onyx_config.json"
|
||||
|
||||
# Get environment from config file
|
||||
ENVIRONMENT=$(jq -r '.Environment' "$CONFIG_FILE")
|
||||
if [ -z "$ENVIRONMENT" ] || [ "$ENVIRONMENT" == "null" ]; then
|
||||
echo "Missing Environment in $CONFIG_FILE. Please add the Environment field."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to get S3_BUCKET from config, fallback to default if not found
|
||||
S3_BUCKET_FROM_CONFIG=$(jq -r '.S3Bucket // empty' "$CONFIG_FILE")
|
||||
if [ -n "$S3_BUCKET_FROM_CONFIG" ]; then
|
||||
S3_BUCKET="$S3_BUCKET_FROM_CONFIG"
|
||||
else
|
||||
S3_BUCKET="${S3_BUCKET:-onyx-ecs-fargate-configs}"
|
||||
fi
|
||||
|
||||
STACK_NAMES=(
|
||||
"${ENVIRONMENT}-onyx-nginx-service"
|
||||
"${ENVIRONMENT}-onyx-web-server-service"
|
||||
"${ENVIRONMENT}-onyx-backend-background-server-service"
|
||||
"${ENVIRONMENT}-onyx-backend-api-server-service"
|
||||
"${ENVIRONMENT}-onyx-model-server-inference-service"
|
||||
"${ENVIRONMENT}-onyx-model-server-indexing-service"
|
||||
"${ENVIRONMENT}-onyx-vespaengine-service"
|
||||
"${ENVIRONMENT}-onyx-redis-service"
|
||||
"${ENVIRONMENT}-onyx-postgres-service"
|
||||
"${ENVIRONMENT}-onyx-cluster"
|
||||
"${ENVIRONMENT}-onyx-acm"
|
||||
"${ENVIRONMENT}-onyx-efs"
|
||||
)
|
||||
|
||||
delete_stack() {
|
||||
local stack_name=$1
|
||||
|
||||
if [ "$stack_name" == "${ENVIRONMENT}-onyx-cluster" ]; then
|
||||
echo "Removing all objects and directories from the onyx config s3 bucket."
|
||||
aws s3 rm "s3://${ENVIRONMENT}-${S3_BUCKET}" --recursive
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
echo "Checking if stack $stack_name exists..."
|
||||
if aws cloudformation describe-stacks --stack-name "$stack_name" --region "$AWS_REGION" > /dev/null 2>&1; then
|
||||
echo "Deleting stack: $stack_name..."
|
||||
aws cloudformation delete-stack \
|
||||
--stack-name "$stack_name" \
|
||||
--region "$AWS_REGION"
|
||||
|
||||
echo "Waiting for stack $stack_name to be deleted..."
|
||||
aws cloudformation wait stack-delete-complete \
|
||||
--stack-name "$stack_name" \
|
||||
--region "$AWS_REGION"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Stack $stack_name deleted successfully."
|
||||
sleep 10
|
||||
else
|
||||
echo "Failed to delete stack $stack_name. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Stack $stack_name does not exist, skipping."
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
for stack_name in "${STACK_NAMES[@]}"; do
|
||||
delete_stack "$stack_name"
|
||||
done
|
||||
|
||||
echo "All stacks deleted successfully."
|
@@ -31,11 +31,11 @@ upstream api_server {
|
||||
|
||||
# for a TCP configuration
|
||||
# TODO: use gunicorn to manage multiple processes
|
||||
server api_server:8080 fail_timeout=0;
|
||||
server ${ONYX_BACKEND_API_HOST}:8080 fail_timeout=0;
|
||||
}
|
||||
|
||||
upstream web_server {
|
||||
server web_server:3000 fail_timeout=0;
|
||||
server ${ONYX_WEB_SERVER_HOST}:3000 fail_timeout=0;
|
||||
}
|
||||
|
||||
server {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Override log format to include request latency
|
||||
# Log format to include request latency
|
||||
log_format custom_main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
@@ -13,11 +13,11 @@ upstream api_server {
|
||||
|
||||
# for a TCP configuration
|
||||
# TODO: use gunicorn to manage multiple processes
|
||||
server api_server:8080 fail_timeout=0;
|
||||
server ${ONYX_BACKEND_API_HOST}:8080 fail_timeout=0;
|
||||
}
|
||||
|
||||
upstream web_server {
|
||||
server web_server:3000 fail_timeout=0;
|
||||
server ${ONYX_WEB_SERVER_HOST}:3000 fail_timeout=0;
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -66,5 +66,5 @@ server {
|
||||
proxy_redirect off;
|
||||
proxy_pass http://web_server;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,8 @@
|
||||
# fill in the template
|
||||
envsubst '$DOMAIN $SSL_CERT_FILE_NAME $SSL_CERT_KEY_FILE_NAME' < "/etc/nginx/conf.d/$1" > /etc/nginx/conf.d/app.conf
|
||||
ONYX_BACKEND_API_HOST="${ONYX_BACKEND_API_HOST:-api_server}"
|
||||
ONYX_WEB_SERVER_HOST="${ONYX_WEB_SERVER_HOST:-web_server}"
|
||||
|
||||
envsubst '$DOMAIN $SSL_CERT_FILE_NAME $SSL_CERT_KEY_FILE_NAME $ONYX_BACKEND_API_HOST $ONYX_WEB_SERVER_HOST' < "/etc/nginx/conf.d/$1" > /etc/nginx/conf.d/app.conf
|
||||
|
||||
# wait for the api_server to be ready
|
||||
echo "Waiting for API server to boot up; this may take a minute or two..."
|
||||
@@ -10,7 +13,7 @@ echo
|
||||
|
||||
while true; do
|
||||
# Use curl to send a request and capture the HTTP status code
|
||||
status_code=$(curl -o /dev/null -s -w "%{http_code}\n" "http://api_server:8080/health")
|
||||
status_code=$(curl -o /dev/null -s -w "%{http_code}\n" "http://${ONYX_BACKEND_API_HOST}:8080/health")
|
||||
|
||||
# Check if the status code is 200
|
||||
if [ "$status_code" -eq 200 ]; then
|
||||
|
Reference in New Issue
Block a user