Skip to content

Latest commit

 

History

History
333 lines (224 loc) · 36.8 KB

File metadata and controls

333 lines (224 loc) · 36.8 KB

Design Decisions

High-level design considerations

A Seqera Platform deployment has two separate phases:

  1. Initial stand-up
    Infrastructure is provisioned, the first set of containers are downloaded, and Seqera Platform-specific configuration files are created.

  2. Upgrade & maintenance
    Includes downloading new containers and/or modifying Seqera Platform configuration files.
    Depending on the initial stand-up decisions, new infrastructure may also be provisioned (e.g. switching from the containerized database to an RDS instance).

Regardless of phase, a system administrator must consider two themes as they do their work:

  1. How to provide necessary values (sensitive and non-sensitive) in configuration files.
  2. Executing the commands necessary to install packages, pull containers, and run programs.

With these phases and themes in mind, the following was considered when designing the tool:

  1. Security
    Sensitive values like passwords should be stored in a secure store rather than being written into configuration files as plain text.

  2. Repeatability
    Provided the same input values, the outputs generated by the solution should be consistent.

  3. Operational resilience
    Individuals change roles / leave organizations and workstations can fail. The solution should not be dependent on a single vulnerable asset.

  4. Visibility
    The solution should ensure the entire end-to-end process can be determined by a reader with access to these project files.

  5. Flexibility
    Clients have a wide range of environment configuration and deployment needs. The solution should avoid implementating a one-size-fits-all approach wherever possible.

  6. Speed & efficiency
    Slow deployment cycles increase the likelihood that a user will deviate from established deployment processes. The solution should minimize execution time to ensure best practices are followed.

  7. Familiarity
    Users have a varying range of familiarity with cloud infrastructure and are not guaranteed to have any experience with Terraform. The solution should use familiar patterns wherever possible, even if this means deviating from Terraform community best practices.

General design decisions

In response to the outlined design considerations, the following design decisions were made:

  1. Structure project and name files for the benefit of non-Terraform experts
    This project does not follow standard Terraform file naming conventions nor implement extensive hierarchical modularization. Priority was given to make this as easy as possible for non-Terraform experts (a majority of our anticipated users). As a result, cascading inputs/outputs were minimized as much as possible and the .tf files were named in a way to model the DAG execution flow to facilitate troubleshooting.

  2. Store sensitive values in AWS Systems Manager Parameter Store (SSM).
    Use a world-class secret store to protect values at rest and only retrieve the values at runtime using a native integration supplied by the Micronaut framework (upon which Seqera Platform is built).

  3. Store sensitive values in omnibus starter entries.
    Each SSM-based configuration value must have its own unique prefix. To minimimize the operational burden, clients will create a small number of complex SSM entries ahead of tool invocation. The tool extracts these entries into their own specific prefixes. TODO_ADD_LINK_TO_TEMPLATE.

  4. Do not supply default values for Terraform variables.
    Terraform variables can be given a default value as they are defined. Despite this behaviour being considered a best pratice by the Terraform community, we respectfully disagree as this spreads values across two different files (variables.tf and terraform.tfvars), and makes the values of some variables implicit while others must be defined explicitly. The solution requires all values to be defined explicitly within the terraform.tfvars file.

  5. Favour templatefiles over in-resource definitions.
    Terraform prefers to have practitioners define content within a resource (example: IAM Policy) which it transforms to JSON at runtime. In our opinion, this is sub-optimal because (1) it makes resource definitions bigger and (2) it makes it harder to compare JSON objects in the AWS console to the source files in the Terraform project. As a result, this solution uses discrete JSON and YML template files instead.

  6. Regenerate assets on every terraform apply.
    To minimize the risk of drift, the solution will regenerate secrets and Seqera Platform configuration files every time. This ensures that any change made to the starting omnibus secret objects and/or terraform.tfvars file are guaranteed to be applied to the resulting Seqera Platform instance.

  7. Regenerate files via null_resource instead of local_file.
    This project uses local-exec provisioners with null_resources to generate files. Our preference would have been to use the more targeted local_file resource (example), but local_file resources don't regenerate consistently.

  8. Do not optimize Terraform state management Terraform offers a wide variety of backend options. These implementations can get quite complex and are beyond the scope of this solution. We default to local state storage by default. Clients are free to implement a more robust state management solution without their own project effort.

  9. Minimize reliance on third-party tooling where possible Supply-chain attacks are growing in popularity and scope. The best way to minimize risk is to reduce reliance on third-party software packages and favour standard libraries or native tooling wherever possible. There is a balance to be struck, however. Using AWS-supported Terraform modules can significantly reduce the number of resources that the project needs to generate/maintain. As a result, we use third-party packages issued by trusted upstream sources and try to minimize reliance on less well-known Github projects (even if this means the resulting code is less elegant).

Notable design decisions

In addition to the general design decisions noted above, there are a few decisions which must be called out specifically due to their influence on the project.

  1. The solution should create infrastructure, conduct VM configuration, and generate application configuration.
    Seqera Platform needs all three of these to run successfully. Whereas a Kubernetes deployment is more cleanly split between Terraform (infrastructure) and Helm (application configuration), a VM-based Docker-Compose solution isn't as easy. To provide clients with a true end-to-end experience, we need to blur the lines of segregated responsibly.

  2. Conduct VM configuration via Ansible rather than Packer.
    Hashicorp advises against using provisioners except as a last resort, and has a specific section regarding configuration management via Packer. This project uses Ansible instead of Packer.

    While Packer is a great tool, its inclusion would add a tool dependency and introduce delays into the first-time provisioning process (waiting for the image to generate so it can be referenced by the AWS EC2 instance resource). Changes to system packages would force AMI regeneration and would not remove the need for Ansible since it is used to execute further application configuration steps on the instance.

  3. Use bespoke Bash commands via local-exec to copy and run commands on the remote VM.

    Earlier versions of this tool used native Terraform provisioners like file and remote-exec to cleanly copy local files to the remote instance and execute commands. These features rely on the establishment of a connection to the target instance.

    Our clients have consistently said that they want to run their Seqera Platform instance in a private subnet and minimize public access to their VPC. AWS's Instance Connect Endpoint service offers a way to connect to a private subnet-based machine directly, but relies upon the ability to specify ProxyCommand arguments to establish a tunnel.

    The Terraform connection object does not appear to support ProxyCommand arguments, which negates the viability of these provisioners for this common use case. The Terraform community is actively discussing adding enhancements for the SSM tunnel, but this is currently only available as an unofficial module (terraform-ssh-tunnel). As a result, despite the known risks and general preference, bespoke logic is used execute interaction with the remote host.

  4. Use AWS Instance Connect Endpoint as the default method to connect to a private VM.

    AWS's Instance Connect Endpoint is an elegant way to shield the Seqera Platform VM instance from direct public access while still allowing administrators to reach it via SSH when necessary (even across the public internet). The security gains heavily outweigh the additional complexity needed to implement the solution, and thus has been implemented as the default approach.

    EICE is not a perfect solution, however. There is a limit of one endpoint per VPC (which can only connect to a single subnet) and access must be limited if deploying into an existing VPC with heavily managed routing infrastructure (split-tunnels, Palo Alto firewalls, etc). In such cases, where a VPN connection is already present, the EICE solution can be discarded and the private IP of the VM be used to connect directly.

  5. A single NAT will serve private subnets if a new VPC with private subnets is created. The VMs in private subnets must be able to egress to the public internet to accomplish their operational duties. As a result, a newly-generated VPC must have NAT infrastructure in place to support this egress. To minimize ongoing operational charges to our clients, the VPC module is configured by default to use a single NAT instance to support all private subnets within the VPC. Should this decision not meet a client's needs, they can modify the VPC module directly.

  6. Support DNS flexibility.
    DNS has proven to be surprisingly diverse in our client sites thus far, and it is not guaranteed that the installer will have the authority or access required to automatically generate the A record needed to direct traffic to a target load balancer or VM instance. As a result, the installer has been built to:

    • Use an existing public Route53 hosted zone in the same account
    • Use an existing or create a new private hosted zone in Route53 (same account)
    • Or entirely forego DNS record generation and only use a local hosts file entry in the event that a record must be created in an external system.
  7. Platform instance must be contacted via DNS name Due to modified redirection logic introduced in 23.3, DNS names should be used to contact the Platform instance rather than the VM IP. This is possible due to the range of DNS options the installer supports.

  8. Public VMs will be assigned an Elastic IP This provides better stability (especially if using a DNS solution not accessible to the installer) for a minor ongoing cost. In the event that the VM hosting the Seqera Platform is stopped and restarted, it will keep the same public IP, thereby avoiding the need to update any external systems.

  9. Solution will not manage database backups.
    There is too much variability in client operational procedures to implement a one-size-fits-all solution for database backup. This is left to each client to implement in a manner appropriate to their business needs.

  10. Solution is HIGHLY opinionated re: your Data Studio implementation. The Data Studio feature made available in v24.1 requires nested subdomains to function. While the feature itself supports the data studio URL being several layers below your Tower domain, this results in more complex configurations of your DNS and related TLS certificates.

    As a result, this tool has a highly opinionated implementation of the Data Studio feature, which is not adjustable without directly modifying non-terraform.tfvars settings.

    1. The Subdomain is one layer below your Tower URL.
    2. The Subdomain is called connect. (example: https://connnect.mytower.com).
  11. Solution is explicit with Data Studios versioning. The solution explicitly pins to the major and minor versions for the connect-client (e.g., 1.83.0-0.7.1 and 1.83.0-0.8.0). This allows for easier tracing and troubleshooting in the event of any errors. Anyone that wishes to use a sliding patch can switch to using the connect-client v0.7 ("0.7") to retrieve latest patch.

    The solution explicity lists a single entry for each client (rstudio, vscode, xpra, jupyter) that pertain to a specific container version. However, multiple container versions of the same client can be used with the example below

    The example demonstrates adding 2 entries for different versions of rstudio. NOTE: the qualifier values are required to be unique and MUST use hyphens (-), NOT underscores (_).:

    data_studio_options = {
        vscode-1-83-0-0-8-0 = {
            qualifier = "VSCODE-1-83-0-0-8-0"
            icon      = "vscode"
            tool      = "vscode"
            status    = "deprecated"
            container = "public.cr.seqera.io/platform/data-studio-vscode:1.83.0-0.8.0"
        },
        vscode-1-101-2-0-8-5 = {
            qualifier = "VSCODE-1-101-2-0-8-5"
            icon      = "vscode"
            tool      = "vscode"
            status    = "recommended"
            container = "public.cr.seqera.io/platform/data-studio-vscode:1.101.2-0.8.5"
        },
    }
    
  12. Replace home-grown parser with better 3rd-party alternative (affects Releases > 1.5.0)

    Aspects of this solution rely on transforming the HCL contained in terraform.tfvars into a Python library (i.e. database connection string generation, tfvars validation). Releases <= 1.5.0 all rely on a crude parser created by gwright99. This approach was taken to avoid introducing a 3rd-party binary dependency in our clients' environments.

    The Add Wave Lite enhancement work has introduced more complex objects which the parser simply cannot handle. Rather than spend significant staff time to rewrite the crude solution, we have opted instead to introduce a third party dependency in the form of tmccombs/hcl2json. Furthermore, rather than require our implementors to install Golang on their machines, we've opted to access the binary via supplied container (original source: https://hub.docker.com/r/tmccombs/hcl2json).

    We recognize the effect of this decision on the existing security posture, and have thus taken the following actions to mitigate risks:

    1. Seqera Security personnel conducted an analysis of the open-source project.
    2. We have vendored our own copy of the image (with source Dockerfile included in the project).
    3. When calling the container as part of the deployment process, the following precautions are in place:
      1. Use of a non-root UID.
      2. Volume bind-mounting only the terraform.tfvars file required as input.
      3. Complete removal of access to any networking capability.
      4. Container stdout is captured and written to file by our own code rather than allowing the container to do so.

    Addendum — Phases 1+2 of #352 (linux/amd64 and linux/arm64): the vendored container is now treated as a delivery vehicle for the Go binary rather than a runtime parser. The extract_hcl2json Makefile recipe pulls the binary out of the container once (at the start of any make verify / make run_tests_* invocation) and places it at /tmp/cx-installer/hcl2json. scripts/installer/utils/extractors.py:hcl_to_json execs that binary directly on supported hosts, eliminating ~1-2 s of per-call Docker startup. Phase 2 extends the supported set to aarch64/arm64 Linux by republishing the vendored image as a multi-arch manifest (mirror of upstream tmccombs/hcl2json via docker buildx imagetools create); the --platform linux/amd64 flag was also dropped from the docker run fallback so the daemon can pick the host-matching architecture natively. Unsupported hosts (Darwin until Phase 3) keep the per-call docker run flow described above; the security precautions listed in point 3 still apply to that fallback path. Phases 1+2 also make tests/unit/ runnable in sandboxes that block runtime Docker, provided the binary was extracted outside the sandbox first (or /tmp/cx-installer/ is mounted into it — the path is project-namespaced precisely so bwrap-style jails can expose it without giving the sandbox a view of the host's full /tmp).

  13. Wave-Lite .sql file generation

    Prior to the introduction of the Wave-Lite feature (Release > 1.5.0), application configuration files were defined as .tpl files and processed / interpolated by Terrafrom templatefile functions at deployment time. Unfortunately, the Wave-Lite deployment relies on postgres as a backend; postgres is insistent on single-quotes in various SQL statements; and terraform templatefile functions detest single quotes.

    The result is a mess: appeasing one tool enrages the other. As a result, the creation of .sql files for Wave-Lite behaves differently than the generation of other config files. For Wave-Lite files:

    • The source file is does not have a .tpl extension.
    • The source file is written in proper psql.
    • The source file contains string-based text placeholders.
    • The text placeholders are processed in 010_prepare_config_files.tf by:
      1. Copying the source file to the target folder.
      2. Running targeted sed commands to replace the placeholder with configured SSM Secret.

    As noted in the various config files, this is definitely a hacky solution but it allows the application to deploy and provide some degree of legibility and consistency. Suggestions for improvement are welcome but - in the meantime - we'll stick with this pattern.

  14. Wave-Lite Multiple Replicas & Reverse-Proxy

    The Wave-Lite augmentation flow is a single-threaded blocking function. To reduce bottlenecks, the Wave Lite container has been designed to run with multiple replicas (default 2).

    Running multiple container copies, however, created networking challenges:

    - The containers could not all share the same host port as this caused errors when the _nth_ container tried to bind an already-bound port.
    - Host ports could be dynamically assigned to each replica but this would require upstream work to modify how the ALB target groups send Wave-related traffic to the EC2 instance.
    - We could use a "poor man's K8s Service" and introduce a reverse proxy container into the deployment which would accept all Wave-related traffic and then round-robin the calls to the downstream containers.
    

    The decision was made to implement the reverse proxy solution. We introduced an brand new instance rather than repurposing the existing proxy using for private certs. This was done to minimize the mixing of concerns and simplify implementation. We may choose to rationalize this deployment in a future release (TBD).

  15. Subdomain routing favoured over path-based routing

    Seqera Platform v25.2.0 introduces path-based routing for Studios instances. This exists as a workaround for sites who are unable to use the default *.YOUR_PLATFORM_DOMAIN DNS sub-domanin approach.

    Path-based routing has limitations, however, (TODO: Add link to official docs outlining) so the project favours use of the subdomains by default.

  16. Private Certificate support overhaul

    As of <TODO: RELEASE TIED TO v25.2.0>, private certificate support has been overhauled.

    The original solution used a convoluted mix of files added to the project, Bash, and Ansible to generate necessary files and updated configurations. This has been shifted left as much as possible into the build-time Terraform templatefile mechanism. The change was mostly beneficial in that it reduced complexity and brittle Ansible runtime execution, restricted unnecessary re-execution, and better aligned the paths required for net-new private CA creation vs. using certificates form preexisting CAs.

    Unfortunately, the change also highlighted a potential maintenance / security vulnerability: what do do about sensitive key files stored within the git project?

    - Keys must be available in the event of loss / new administrators.
    - Keys cant be checked into git due to their sensitivity, but can't be on .gitignore since this doesn't solve the distribution problem.
    

    Two solutions were mooted:

    1. Use SSM

      • PROs:
        • We already use this mechanism for other secrets and it's easily adopted.
      • CONS:
        • The idea of properly pasting .crt/.key data into the JSON fills me with dread.
        • Distribution not simple; must download string from SSM then convert into properly formatted file. Likely painful.
        • Different flow nuances for a newly-created cert vs pre-existing.
    2. Use S3 Bucket

      • PROs:
        • Well-understood pattern.
        • File(ish) storage.
        • Easy to implement
        • Minimal deltas between new cert creation and use of pre-existing.
        • Works well in context of wider Seqera ecosystem (Nextflow pipelines, Studios, etc.)
      • CONs:
        • Introduces a 3rd pillar to state storage (git + SSM + S3)
        • Minor AWS IAM permissions creep

    DECISION:

    • Make generation of certificate a one-time non-automated step.
    • Regardless of how cert generated, administrator manually loads cert & key (new or existing) into S3 Bucket.
    • If private cert necessary, Ansible pulls target files onto EC2 and makes availabe to trust store and reverseproxy.
  17. Introduction of use_mock flag into resources related to Database & Redis

    A var.use_mocks check has been introduced to database and Redis related resources in 003_database.tf.

    (TODO: Release version) release shipped with the first phase of a testing framework. This feature conducts a series of quick local checks to ensure the veracity of core connection details and configuration files. While we favour terraform plan as much as possible, the generation of configuration files requires a terraform apply motion.

    Using terraform apply -target=... reduces scope and improves speed but, unfortunately, module.connection_strings is central to all the tests and it in turn relies upon the provision of RDS and Elasticache resources for deployments that follow best practices guidelines. As a result, a testing loop that must actually deploy these resources takes up to 20 minutes to complete.

    By adding a ... && !var.use_mocks to the count of the affected resources, I can descope these resources from the minimal footprint deployment, thereby vastly speeding up (and thereby encouraging the on-going use of) testing. The downside of this approach, however, is that there is an ongoing intermingling of concerns between logic meant to deploy resources for real, versus logic focused on testing. I cannot think of a better way to balance speed with rigour at the moment so this will be the go-forward approach until a better technique presents itself.

  18. SSH access requires a dedicated NLB alongside the existing ALB

    The Studios SSH feature allows users to open an SSH connection directly into a running Studio session which requires the connect-proxy container port 2222 to be exposed.

    An existing ALB solution cannot serve this need as ALBs operate at Layer 7 (HTTP/HTTPS) but Layer 4 TCP connections like SSH are not supported. To fill the gap, a Network Load Balancer (NLB) is the chosen infrastructure solution: it operates at Layer 4 and passes TCP connections through to the connect-proxy container.

    The implementation handles both deployment topologies:

    • With a load balancer (flag_create_load_balancer = true): A dedicated NLB is provisioned solely for SSH traffic on port 2222, and a Route53 A record (connect-ssh.<tower_server_url>) is pointed at it as an alias.
    • Without a load balancer (flag_create_load_balancer = false): No NLB is created. The Route53 A record points directly to the EC2 instance IP, and a security group rule allows inbound TCP 2222 from the configured ingress CIDRs directly to the host.

    The following are design choices baked into the implementation. They are not configurable without modifying files outside of terraform.tfvars. If any of these do not fit your environment, SSH for Studios is not supported for your deployment without custom work.

    • Port 2222 is hardcoded and not configurable. If your network blocks port 2222 or you need a different port for any reason, this feature will not work for your deployment without custom changes outside of terraform.tfvars.
    • The SSH subdomain is always connect-ssh.<tower_server_url>. This is derived automatically and follows the same one-level convention as the Studios connect proxy (connect.<tower_server_url>). It is not user-configurable.
    • An NLB is provisioned as a second load balancer when flag_create_load_balancer = true. It runs continuously once provisioned and incurs additional AWS cost. There is no option to share it with the ALB.
    • The NLB uses the same subnets as the ALB (subnet_ids_alb). The NLB needs to be reachable from wherever users connect to Platform, so it belongs in the same network.
    • Route53 DNS must be managed within the same AWS account. If DNS is managed externally, the connect-ssh.* A record must be created manually before SSH connections will resolve correctly.
  19. Auto-skip adapters in tests/conftest.py

    Two pytest-collection adapters layer environment-aware skips on top of the existing marker filters defined in tests/pytest.ini:

    • No Docker socket → skip @pytest.mark.testcontainer. Detection checks DOCKER_HOST=unix://... (verifies the actual socket path exists, since the env var may point outside a sandbox mount), other DOCKER_HOST schemes (trust user intent), or falls back to /var/run/docker.sock.
    • variables.tf unchanged on this branch → skip @pytest.mark.variable_validation. "Changed" is the union of committed-on-branch (vs origin/master / origin/main / master / main), staged, and unstaged. If no base ref can be resolved, no skip is applied — uncertainty fails open.

    Both adapters defer to positive -m selection: invoking make run_tests_variables_only or make run_tests_containers_only bypasses the heuristic so explicit recipes always behave as the operator expects.

  20. Some Connect proxy environment variables are intentionally omitted from the installer

    The installer exposes only the Connect proxy variables that have practical value for standard deployments. The remaining variables documented in the connect environment variables reference are omitted for the reasons described below.

    Variable Default Reason omitted
    CONNECT_LISTENER_PORT 7777 Compiled-in default in the Connect server. No value in rendering it explicitly for standard deployments. Only relevant if port conflicts exist.
    CONNECT_TUNNEL_PORT 7070 Same as above.
    CONNECT_STORAGE_ROOT /data Built-in Caddyfile default ({$CONNECT_STORAGE_ROOT:/data}). Only relevant if a custom volume mount path is required.
    CONNECT_HOST_DOMAIN "" The installer auto-derives and wires the Connect subdomain (connect.<tower_server_url>). No known standard deployment scenario requires this override.
    CONNECT_CLIENT_NAME tower-connect-proxy-client The default is the only correct value for a Seqera Platform Studios deployment. Changing it would break the OIDC registration flow with Platform.
    CONNECT_GRANT_TYPE authorization_code Same as above — changing this would break the OIDC auth flow.
    CONNECT_REDIS_PREFIX connect:session The default is appropriate for all deployments. An override is only needed when running multiple Connect proxy instances against the same Redis database, which is beyond the scope of this installer.
    CONNECT_REDIS_TLS_ENABLE false Redis TLS support is not yet implemented in the installer (redis_security_mode_inferred = "insecure" in the connection strings module). Exposing Connect TLS vars while Platform has no Redis TLS support would create an inconsistent configuration.
    CONNECT_REDIS_TLS_SKIP_VERIFY false Dependent on CONNECT_REDIS_TLS_ENABLE — omitted for the same reason.
    CONNECT_REDIS_TLS_KEY_FILE "" Dependent on CONNECT_REDIS_TLS_ENABLE — omitted for the same reason.
    CONNECT_REDIS_TLS_CERT_FILE "" Dependent on CONNECT_REDIS_TLS_ENABLE — omitted for the same reason.
    CONNECT_REDIS_USER "" The installer has no Redis authentication mechanism. Platform connects to Redis without credentials (TOWER_REDIS_URL carries no auth). Since Connect shares the same Redis instance, Redis AUTH is equally inapplicable.
    CONNECT_REDIS_PASSWORD "" Same as above.
    CONNECT_SSH_KEY_VALUE_BASE64 "" Base64-encoded alternative to the file-mounted SSH host key. The installer mounts the key as a file via CONNECT_SSH_KEY_PATH=/data/ssh-host-key, which is the correct default for all standard deployments. The base64 option exists for environments where file mounting is not possible — an edge case beyond the scope of this installer.
    CONNECT_SSH_MAX_CONNECTIONS 2000 SSH tuning variable. Built-in default is appropriate for the vast majority of deployments. Only relevant under unusually high SSH load.
    CONNECT_SSH_MAX_CONN_CHANNELS 30 Same as above.
    CONNECT_SSH_HANDSHAKE_TIMEOUT 1m Same as above.

    Deployers who need to override any of these values can do so by adding them directly to data-studios.env on the target instance after deployment. If you need assistance configuring any of these variables, reach out to Seqera and we can discuss your requirements. Full variable reference: connect environment variables.

  21. Some Studios platform environment variables are intentionally omitted from the installer

    The installer exposes only the Studios platform variables that have practical value for standard deployments. The remaining variables documented in the configuration overview are omitted for the reasons described below.

    Variable Default Reason omitted
    TOWER_DATA_STUDIO_LIST_MAX_ALLOWED 100 Pagination tuning. 100 concurrent Studios per page is sufficient for all standard deployments. Only relevant at very high Studio volume.
    TOWER_DATA_STUDIO_FEATURE_MANIFEST_URL Platform default Internal manifest URL for Studio template version compatibility. Platform provides its own default — a custom URL would only be provided by Seqera directly.
    TOWER_STUDIO_METRICS_RETENTION_DAYS 90 Metrics storage tuning. 90 days is appropriate for all deployments. Only relevant if storage constraints require shorter retention.
    TOWER_DATA_STUDIO_WAVE_CUSTOM_IMAGE_NAME_STRATEGY tagPrefix Advanced Wave image naming convention. The default tagPrefix is the only strategy used in standard Studio image builds. Changing this requires corresponding changes to the Wave build pipeline.
    TOWER_DATA_STUDIO_WAVE_STATUS_CHECK_INITIAL_DELAY 5s Timing tuning for Wave build status polling. Default is appropriate for all deployments.
    TOWER_DATA_STUDIO_WAVE_STATUS_CHECK_RATE 30s Timing tuning for Wave build status polling. Default is appropriate for all deployments.
    TOWER_DATA_STUDIO_CONNECT_IFRAME_ALLOWED_WORKSPACES "" (all workspaces) Workspace-scoped iframe embedding control. The vast majority of deployments have no iframe embedding requirement — including this variable would prompt an unnecessary decision for every deployer. Teams who need to restrict iframe access can add it directly to tower.env after deployment.
    TOWER_SSH_KEYS_SUPPORTED_TYPES ssh-rsa,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521 The default covers all commonly used modern SSH key types and is hardcoded in the template. FIPS-constrained deployments requiring algorithm restriction are better served by editing tower.env post-deployment — introducing this as an installer variable would require validation logic and a migration path on every algorithm list change, for a use case that affects a very small subset of deployers.

    Deployers who need to override any of these values can do so by adding them directly to tower.env on the target instance after deployment. If you need assistance configuring any of these variables, reach out to Seqera and we can discuss your requirements. Full variable reference: configuration overview.

  22. Data Lineage SQS queue creation is Platform's responsibility, not the installer's

    Seqera Platform v26.1.0+ has built-in support for creating the SQS queue (and the paired S3 bucket + bucket-notification routing) required by the Data Lineage feature. Platform creates these per-workspace under the seqera-lineage-* resource-name prefix at the moment a workspace enables lineage via its UI.

    Rather than replicate that functionality, the installer's role for lineage is intentionally scoped to granting the EC2 instance role the IAM permissions Platform needs to do the queue/bucket creation itself. The installer attaches a policy (${global_prefix}_policy_lineage) authorising the relevant S3 + SQS actions on seqera-lineage-* ARNs only — see assets/src/aws/iam_role_policy_lineage.json.tpl.

    Consequences of this division of labour:

    • The installer does not provision an SQS queue, S3 bucket, or bucket-notification rule for lineage. Those resources don't appear in terraform plan and aren't part of terraform destroy.
    • Queue/bucket lifecycle (creation, configuration, deletion) is owned entirely by Platform. Deployers cannot pre-create or pin specific ARNs from the installer side.
    • If Platform's resource-naming convention or auto-provisioning behaviour changes in a future release, the only file that needs to update is the IAM policy template — not the installer's resource graph.