Skip to main content
Version: 23.2

CloudFormation deployment (deprecated)

!!! danger "Deprecated" This deployment option is deprecated, and will be removed in the future. We strongly recommend against using this option unless you are sufficiently experienced with CloudFormation to customize this template for your own infrastructure.

Tower can be deployed via AWS CloudFormation, using the included configuration.

This guide assumes that all prerequisites have been met.

Setup ECS cluster

  1. Navigate to the ECS console in AWS.

  2. Select Create cluster.

  3. Select Amazon ECS -> Clusters -> EC2 Linux + Networking.

ECS Cluster Configuration

  • Name: nf-tower

Instance Configuration

  • Provisioning Model: On-demand
  • EC2 instance type: c4.2xlarge
  • Number of instances: 1
  • EC2 AMI id: Amazon Linux 2
  • Root EBS Volume Size (GiB): none
  • Key pair: none

Networking Configuration

  • Create new VPC

Container instance IAM role

  • Create new role (if ecsInstance role doesn't exist)

Obtain Instance ServerURL

  • Record the Public IP of the instance in the ECS cluster e.g. 3.122.246.202

Deploy Tower

Click to view aws-ecs-cloudformation.json
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Nextflow Tower ECS template",
"Parameters": {
"ClusterName": {
"Type": "String",
"Description": "ECS cluster name"
},
"TowerSmtpHost": {
"Type": "String",
"Description": "SMTP server hostname"
},
"TowerSmtpPort": {
"Type": "String",
"Description": "SMTP server port"
},
"TowerSmtpUser": {
"Type": "String",
"Description": "SMTP server username",
"NoEcho": "true"
},
"TowerSmtpPassword": {
"Type": "String",
"Description": "SMTP server password",
"NoEcho": "true"
},
"TowerContactEmail": {
"Type": "String",
"Description": "Email for login emails"
},
"TowerServerUrl": {
"Type": "String",
"Description": "IP address of container instance"
},
"TowerJwtSecret": {
"Type": "String",
"Description": ">256 bit random string",
"NoEcho": "true"
},
"TowerCryptoSecretkey": {
"Type": "String",
"Description": ">256 bit random string",
"NoEcho": "true"
},
"TowerLicense": {
"Type": "String",
"Description": "The Tower License",
"NoEcho": "true"
},
"TowerDbUrl": {
"Type": "String",
"Description": "MySQL DB connection URL"
},
"TowerDbUser": {
"Type": "String",
"Description": "MySQL DB username"
},
"TowerDbPassword": {
"Type": "String",
"Description": "MySQL DB password",
"NoEcho": "true"
}
},
"Resources" : {
"TowerTask": {
"Type": "AWS::ECS::TaskDefinition",
"Properties": {
"NetworkMode": "bridge",
"ContainerDefinitions": [
{
"Name": "redis",
"Image": "cr.seqera.io/public/redis:5.0.8",
"Memory": 2000,
"Cpu": 0,
"PortMappings": [{
"ContainerPort": 6379,
"HostPort": 6379
}],
"Command": ["--appendonly yes"]
},
{
"Name": "cron",
"Image": "cr.seqera.io/private/nf-tower-enterprise/backend:v23.1.3",
"Memory": 2000,
"Cpu": 0,
"Links": [
"redis"
],
"DependsOn": [
{
"ContainerName": "redis",
"Condition": "START"
}
],
"WorkingDirectory": "/work",
"EntryPoint": [ "/bin/sh" ],
"Command": [ "-c", "/migrate-db.sh; /tower.sh" ],
"Environment": [
{
"Name": "TOWER_CONTACT_EMAIL",
"Value": {
"Ref": "TowerContactEmail"
}
},
{
"Name": "TOWER_SMTP_HOST",
"Value": {
"Ref": "TowerSmtpHost"
}
},
{
"Name": "TOWER_SMTP_PORT",
"Value": {
"Ref": "TowerSmtpPort"
}
},
{
"Name": "TOWER_SMTP_USER",
"Value": {
"Ref": "TowerSmtpUser"
}
},
{
"Name": "TOWER_SMTP_PASSWORD",
"Value": {
"Ref": "TowerSmtpPassword"
}
},
{
"Name": "TOWER_DB_URL",
"Value": {
"Ref": "TowerDbUrl"
}
},
{
"Name": "TOWER_DB_DRIVER",
"Value": "org.mariadb.jdbc.Driver"
},
{
"Name": "TOWER_DB_DIALECT",
"Value": "io.seqera.util.MySQL55DialectCollateBin"
},
{
"Name": "TOWER_DB_USER",
"Value": {
"Ref": "TowerDbUser"
}
},
{
"Name": "TOWER_DB_PASSWORD",
"Value": {
"Ref": "TowerDbPassword"
}
},
{
"Name": "TOWER_SERVER_URL",
"Value": {
"Ref": "TowerServerUrl"
}
},
{
"Name": "MICRONAUT_ENVIRONMENTS",
"Value": "prod,redis,cron"
},
{
"Name": "TOWER_ENABLE_PLATFORMS",
"Value": "awsbatch-platform,azbatch-platform,gls-platform,slurm-platform"
},
{
"Name": "TOWER_JWT_SECRET",
"Value": {
"Ref": "TowerJwtSecret"
}
},
{
"Name": "TOWER_CRYPTO_SECRETKEY",
"Value": {
"Ref": "TowerCryptoSecretkey"
}
},
{
"Name": "TOWER_LICENSE",
"Value": {
"Ref": "TowerLicense"
}
},
{
"Name": "FLYWAY_LOCATIONS",
"Value": "classpath:db-schema/mysql"
}
]
},
{
"Name": "frontend",
"Image": "cr.seqera.io/private/nf-tower-enterprise/frontend:v23.1.3",
"Memory": 2000,
"Cpu": 0,
"Essential": false,
"PortMappings": [{
"ContainerPort": 80,
"HostPort": 80
}],
"Links": [
"backend"
],
"DependsOn": [
{
"ContainerName": "backend",
"Condition": "START"
}
]
},
{
"Name": "backend",
"Hostname": "backend",
"Memory": 2000,
"Cpu": 0,
"Image": "cr.seqera.io/private/nf-tower-enterprise/backend:v23.1.3",
"PortMappings": [{
"ContainerPort": 8080,
"HostPort": 8080
}],
"Essential": false,
"Links": [
"redis",
"cron"
],
"WorkingDirectory": "/work",
"DependsOn": [
{
"ContainerName": "cron",
"Condition": "START"
},
{
"ContainerName": "redis",
"Condition": "START"
}
],
"Environment": [
{
"Name": "TOWER_CONTACT_EMAIL",
"Value": {
"Ref": "TowerContactEmail"
}
},
{
"Name": "TOWER_SMTP_HOST",
"Value": {
"Ref": "TowerSmtpHost"
}
},
{
"Name": "TOWER_SMTP_PORT",
"Value": {
"Ref": "TowerSmtpPort"
}
},
{
"Name": "TOWER_SMTP_USER",
"Value": {
"Ref": "TowerSmtpUser"
}
},
{
"Name": "TOWER_SMTP_PASSWORD",
"Value": {
"Ref": "TowerSmtpPassword"
}
},
{
"Name": "TOWER_DB_URL",
"Value": {
"Ref": "TowerDbUrl"
}
},
{
"Name": "TOWER_DB_DRIVER",
"Value": "org.mariadb.jdbc.Driver"
},
{
"Name": "TOWER_DB_DIALECT",
"Value": "io.seqera.util.MySQL55DialectCollateBin"
},
{
"Name": "TOWER_DB_USER",
"Value": {
"Ref": "TowerDbUser"
}
},
{
"Name": "TOWER_DB_PASSWORD",
"Value": {
"Ref": "TowerDbPassword"
}
},
{
"Name": "TOWER_SERVER_URL",
"Value": {
"Ref": "TowerServerUrl"
}
},
{
"Name": "MICRONAUT_ENVIRONMENTS",
"Value": "prod,redis,ha"
},
{
"Name": "TOWER_ENABLE_PLATFORMS",
"Value": "awsbatch-platform,azbatch-platform,gls-platform,slurm-platform"
},
{
"Name": "TOWER_JWT_SECRET",
"Value": {
"Ref": "TowerJwtSecret"
}
},
{
"Name": "TOWER_CRYPTO_SECRETKEY",
"Value": {
"Ref": "TowerCryptoSecretkey"
}
},
{
"Name": "TOWER_LICENSE",
"Value": {
"Ref": "TowerLicense"
}
},
{
"Name": "FLYWAY_LOCATIONS",
"Value": "classpath:db-schema/mysql"
}
],
"EntryPoint": [ "/bin/sh" ],
"Command": [ "-c", "/tower.sh" ]
}]
}
},
"TowerService": {
"Type" : "AWS::ECS::Service",
"Properties" : {
"Cluster": {
"Ref": "ClusterName"
},
"DesiredCount" : 1,
"ServiceName" : "TowerService",
"TaskDefinition": {
"Ref": "TowerTask"
},
"LaunchType": "EC2"
}
}
}
}
Click to view params.json.template
[
{
"ParameterKey": "ClusterName",
"ParameterValue": ""
},
{
"ParameterKey": "TowerSmtpUser",
"ParameterValue": ""
},
{
"ParameterKey": "TowerSmtpPassword",
"ParameterValue": ""
},
{
"ParameterKey": "TowerContactEmail",
"ParameterValue": ""
},
{
"ParameterKey": "TowerServerUrl",
"ParameterValue": ""
},
{
"ParameterKey": "TowerJwtSecret",
"ParameterValue": ""
},
{
"ParameterKey": "TowerCryptoSecretkey",
"ParameterValue": ""
},
{
"ParameterKey": "TowerLicense",
"ParameterValue": ""
},
{
"ParameterKey": "TowerDbUrl",
"ParameterValue": "tower"
},
{
"ParameterKey": "TowerDbUser",
"ParameterValue": "tower"
},
{
"ParameterKey": "TowerDbPassword",
"ParameterValue": "tower"
},
{
"ParameterKey": "TowerSmtpHost",
"ParameterValue": "email-smtp.eu-west-1.amazonaws.com"
},
{
"ParameterKey": "TowerSmtpPort",
"ParameterValue": "587"
},
]
  1. Download aws-ecs-cloudformation.json and params.json.template.

  2. Rename params.template.json to params.json and configure for your environment.

    For more information on configuration, visit the Configuration section.

  3. Deploy the Tower stack to your ECS cluster:

    aws cloudformation create-stack \
    --stack-name Tower \
    --template-body file://aws-ecs-cloudformation.json \
    --parameters file://params.json

    You can delete the stack at any time, to uninstall Tower or update any parameters:

    aws cloudformation delete-stack \
    --stack-name Tower