Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 009_define_file_templates.tf
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ locals {
tower_db_dns = module.connection_strings.tower_db_dns,
flag_enable_groundswell = var.flag_enable_groundswell,
flag_enable_data_studio = var.flag_enable_data_studio,
flag_use_wave = var.flag_use_wave,
flag_use_wave_lite = var.flag_use_wave_lite,
wave_lite_db_dns = module.connection_strings.wave_lite_db_dns,
}
Expand Down
13 changes: 11 additions & 2 deletions 010_prepare_config_files.tf
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ resource "null_resource" "generate_independent_config_files" {
# Update seqerakit prerun script to pull private cert
# https://help.tower.nf/23.2/enterprise/configuration/ssl_tls/
# Note: This approach works for most clients but there can be occasional problems due to chains.

# Update assets dependent
if [[ "${var.flag_use_private_cacert}" == "true" ]]; then

{
Expand All @@ -77,6 +75,17 @@ resource "null_resource" "generate_independent_config_files" {

fi

if [[ "${var.flag_use_private_cacert}" == "true" ]]; then

cat > ${path.module}/assets/target/docker_compose/import-cert.sh << 'EOF'
#!/bin/sh
keytool -import -trustcacerts -cacerts -storepass changeit -noprompt -alias seqera-rootca -file /tmp/rootCA.crt >/dev/null 2>&1 || true
exec /bin/sh "$@"
EOF
chmod +x ${path.module}/assets/target/docker_compose/import-cert.sh

fi

# THIS IS A TOTAL HACK (Wave-Lite)
# Using this technique so postgres can get config files with single quotes only.
# Terraform templatefile (.tpl) abandoned and we use real SQL with placeholders-to-be-replaced-by-sed
Expand Down
3 changes: 2 additions & 1 deletion assets/src/ansible/02_update_file_configurations.yml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@

# Grab leaf cert and stash in target/ folder
cd /home/ec2-user/target/customcerts
aws s3 cp ${private_cacert_bucket_prefix}/${tower_base_url}.crt ${tower_base_url}.crt
aws s3 cp ${private_cacert_bucket_prefix}/${tower_base_url}.crt ${tower_base_url}.crt
aws s3 cp ${private_cacert_bucket_prefix}/${tower_base_url}.key ${tower_base_url}.key
aws s3 cp ${private_cacert_bucket_prefix}/rootCA.crt rootCA.crt
%{ endif ~}

%{ if flag_enable_data_studio ~}
Expand Down
29 changes: 29 additions & 0 deletions assets/src/docker_compose/docker-compose.yml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,20 @@ services:
cron:
image: cr.seqera.io/private/nf-tower-enterprise/backend:${docker_version}
command: -c "/tower.sh"
%{ if flag_use_private_cacert == true ~}
entrypoint: ["/bin/sh", "/tmp/import-cert.sh"]
%{ endif ~}
networks:
- frontend
- backend
volumes:
- $HOME/target/tower_config/tower.yml:/tower.yml
%{ if flag_enable_data_studio == true ~}
- $HOME/target/tower_config/data-studios-rsa.pem:/data-studios-rsa.pem
%{ endif ~}
%{ if flag_use_private_cacert == true ~}
- $HOME/target/customcerts/rootCA.crt:/tmp/rootCA.crt
- $HOME/target/docker_compose/import-cert.sh:/tmp/import-cert.sh
%{ endif ~}
env_file:
# Seqera environment variables — see https://docs.seqera.io/platform/latest/enterprise/configuration/overview for details
Expand All @@ -121,13 +128,20 @@ services:
%{ else ~}
command: -c "/migrate-db.sh; /tower.sh"
%{ endif }
%{ if flag_use_private_cacert == true ~}
entrypoint: ["/bin/sh", "/tmp/import-cert.sh"]
%{ endif ~}
networks:
- frontend
- backend
volumes:
- $HOME/target/tower_config/tower.yml:/tower.yml
%{ if flag_enable_data_studio == true ~}
- $HOME/target/tower_config/data-studios-rsa.pem:/data-studios-rsa.pem
%{ endif ~}
%{ if flag_use_private_cacert == true ~}
- $HOME/target/customcerts/rootCA.crt:/tmp/rootCA.crt
- $HOME/target/docker_compose/import-cert.sh:/tmp/import-cert.sh
%{ endif ~}
env_file:
# Seqera environment variables — see https://docs.seqera.io/platform/latest/enterprise/configuration/overview for details
Expand Down Expand Up @@ -155,6 +169,9 @@ services:
%{ else ~}
command: -c "/tower.sh"
%{ endif }
%{ if flag_use_private_cacert == true ~}
entrypoint: ["/bin/sh", "/tmp/import-cert.sh"]
%{ endif ~}
networks:
- frontend
- backend
Expand All @@ -164,6 +181,10 @@ services:
- $HOME/target/tower_config/tower.yml:/tower.yml
%{ if flag_enable_data_studio == true ~}
- $HOME/target/tower_config/data-studios-rsa.pem:/data-studios-rsa.pem
%{ endif ~}
%{ if flag_use_private_cacert == true ~}
- $HOME/target/customcerts/rootCA.crt:/tmp/rootCA.crt
- $HOME/target/docker_compose/import-cert.sh:/tmp/import-cert.sh
%{ endif ~}
env_file:
- $HOME/target/tower_config/tower.env
Expand Down Expand Up @@ -286,8 +307,16 @@ services:
# - 9099:9090
expose:
- 9090
%{ if flag_use_private_cacert == true ~}
entrypoint: ["/bin/sh", "/tmp/import-cert.sh"]
command: ["/launch.sh"]
%{ endif ~}
volumes:
- $HOME/target/wave_lite_config/wave-lite.yml:/work/config.yml
%{ if flag_use_private_cacert == true ~}
- $HOME/target/customcerts/rootCA.crt:/tmp/rootCA.crt
- $HOME/target/docker_compose/import-cert.sh:/tmp/import-cert.sh
%{ endif ~}
#env_file:
# - wave-lite.env
environment:
Expand Down
14 changes: 14 additions & 0 deletions documentation/design_decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,17 @@ In addition to the general design decisions noted above, there are a few decisio
- **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.

18. **rootCA.crt is mounted into backend and cron containers whenever `flag_use_private_cacert = true`**

When a private/self-signed certificate is in use, the rootCA is unconditionally volume-mounted into the `backend` and `cron` containers and imported into their JVM trust stores at startup via the `import-cert.sh` entrypoint wrapper. This applies regardless of whether Wave is enabled.

Per [Seqera documentation](https://docs.seqera.io/platform-enterprise/enterprise/configuration/ssl_tls#configure-seqera-to-trust-your-private-certificate):

> "If you secure related infrastructure (such as private Git repositories) with certificates issued by a private Certificate Authority (CA), you may need to configure Seqera to trust those certificates."

The JVM inside each container maintains its own trust store, independent of the host OS. Even if the host OS trusts the private CA (via `update-ca-trust`), Java processes in the containers will still reject TLS connections to any service using that CA unless the rootCA is explicitly imported into the container JVM's cacerts.

Mounting the rootCA into backend/cron whenever a private cert is in use is the safe, forward-compatible default — it covers the case where Wave is later enabled, or where other private-CA-secured infrastructure is being called from within the Platform JVM. The marginal cost (a volume mount + a single `keytool` call at container start) is negligible.

When `flag_use_wave_lite = true`, the rootCA is additionally mounted into the `wave-lite` container for the same reason.
20 changes: 18 additions & 2 deletions documentation/setup/optional_private_certificates.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,24 @@ When using private certificates with Studios, you must create custom container i
- **Custom Image Configuration:** After creating your custom image, you'll need to configure Studios to use it. See the [Seqera Platform Enterprise documentation on custom containers](https://docs.seqera.io/platform-enterprise/25.1/studios/custom-envs#custom-containers) for detailed instructions.
- **Multiple Image Types:** You may need to create custom images for different Studios environments (e.g., Jupyter, RStudio, VSCode) if you use multiple types.

### Other Compute Assets
- TODO: Bake cert into Nextflow worker nodes using Wave-Lite.
### Wave Lite: Custom AMI for Nextflow Compute Workers

When using Wave Lite (`flag_use_wave_lite = true`) with a private certificate, Nextflow compute workers on AWS Batch must pull Wave-augmented container images from your self-hosted Wave Lite server. Because Wave Lite is served over your private certificate, Docker on the compute worker must trust your root CA at the OS level — this cannot be handled by an entrypoint wrapper (which only affects JVM trust stores inside containers).

The solution is to bake your `rootCA.crt` into the host OS trust store of a custom AMI and configure your Compute Environments to use that AMI.

**Steps:**

1. Start from the AWS-managed Amazon Linux 2 AMI (or whichever base AMI you normally use for Batch).
2. Copy `rootCA.crt` onto the instance and add it to the OS trust store:
```bash
sudo cp rootCA.crt /etc/pki/ca-trust/source/anchors/rootCA.crt
sudo update-ca-trust
```
3. Create an AMI from the instance.
4. Set the AMI ID in each Compute Environment that will run Wave Lite workloads.

**AMI creation method:** Any approach that produces an AMI with the rootCA baked in is valid. [Packer](https://developer.hashicorp.com/packer) is a commonly used option for automating this, but launching an EC2 instance manually, running the above commands, and creating an AMI via the console or CLI works equally well.


## Runtime
Expand Down
Loading
Loading