Overview
Add a new torrust-tracker-deployer register command that serves as an alternative to the provision command for environments that already have existing infrastructure. Instead of provisioning new infrastructure, register allows users to provide the IP address of an existing instance.
This solves two critical needs:
- For End Users: Deploy on existing infrastructure (spare servers, unsupported cloud providers, custom setups)
- For E2E Testing: Replace the hacky
run_provision_simulation.rs workaround with a proper command for container-based tests
Key Insight
The create environment command creates the environment concept (SSH credentials, name, configuration) - not the actual infrastructure. The infrastructure is either:
- Provisioned via the
provision command (creates new VMs)
- Registered via the
register command (uses existing infrastructure)
Both paths lead to the same Provisioned state, and the only runtime output from provisioning stored is the instance IP (see src/domain/environment/runtime_outputs.rs). Therefore, register only needs the instance IP as input.
Workflow Comparison
Standard Workflow:
create environment → provision → configure → release → run
| |
[Created] [Provisioned]
↓
(continues...)
Register Workflow (Alternative to provision):
create environment → register → configure → release → run
| |
[Created] [Provisioned]
↓
(continues...)
Goals
Command Syntax
# Step 1: Create the environment (provides SSH credentials, name, etc.)
torrust-tracker-deployer create environment --env-file config.json
# Step 2: Register existing instance (provides only the instance IP)
torrust-tracker-deployer register <environment-name> --instance-ip <IP_ADDRESS>
Arguments
<environment-name> - Name of an existing environment in Created state
--instance-ip <IP_ADDRESS> - IP address of the existing instance (IPv4 or IPv6)
Example Usage
# First, create the environment with SSH credentials
torrust-tracker-deployer create environment --env-file prod-config.json
# Then, register the existing production server
torrust-tracker-deployer register production-tracker --instance-ip 192.168.1.100
# Continue with normal workflow
torrust-tracker-deployer configure production-tracker
torrust-tracker-deployer release production-tracker
torrust-tracker-deployer run production-tracker
Instance Requirements
The existing instance must meet these requirements (same as provisioned instances):
REQUIRED:
- Ubuntu 24.04 LTS
- SSH connectivity with credentials from
create environment
- Public SSH key installed for access
- Public IP address reachable from deployer
- Username with sudo access
- Cloud-init completion mark (see
templates/tofu/lxd/cloud-init.yml.tera)
Implementation Plan
Phase 1: Core Command Structure
- Register subcommand parsing
- Basic command handler skeleton
- Error types definition
Phase 2: Domain Logic
- State transition
Created → Provisioned
- Metadata handling (
"registered": "true")
- RuntimeOutputs update with instance IP
Phase 3: Infrastructure Integration
- SSH connectivity validation (minimal for v1)
- Environment repository save
Phase 4: E2E Test Migration
- Refactor
src/bin/e2e_config_tests.rs to use register command
- Remove
run_provision_simulation.rs hack
- Update
src/testing/e2e/tasks/container/mod.rs
Phase 5: Documentation
- User guide at
docs/user-guide/commands/register.md
- ADR at
docs/decisions/register-existing-instances.md
- Update
docs/console-commands.md
Acceptance Criteria
Related Documentation
Overview
Add a new
torrust-tracker-deployer registercommand that serves as an alternative to theprovisioncommand for environments that already have existing infrastructure. Instead of provisioning new infrastructure,registerallows users to provide the IP address of an existing instance.This solves two critical needs:
run_provision_simulation.rsworkaround with a proper command for container-based testsKey Insight
The
create environmentcommand creates the environment concept (SSH credentials, name, configuration) - not the actual infrastructure. The infrastructure is either:provisioncommand (creates new VMs)registercommand (uses existing infrastructure)Both paths lead to the same
Provisionedstate, and the only runtime output from provisioning stored is the instance IP (seesrc/domain/environment/runtime_outputs.rs). Therefore,registeronly needs the instance IP as input.Workflow Comparison
Goals
CreatedtoProvisionedstate by providing instance IPrun_provision_simulation.rshack in E2E tests with properregistercommandCommand Syntax
Arguments
<environment-name>- Name of an existing environment inCreatedstate--instance-ip <IP_ADDRESS>- IP address of the existing instance (IPv4 or IPv6)Example Usage
Instance Requirements
The existing instance must meet these requirements (same as provisioned instances):
REQUIRED:
create environmenttemplates/tofu/lxd/cloud-init.yml.tera)Implementation Plan
Phase 1: Core Command Structure
Phase 2: Domain Logic
Created→Provisioned"registered": "true")Phase 3: Infrastructure Integration
Phase 4: E2E Test Migration
src/bin/e2e_config_tests.rsto useregistercommandrun_provision_simulation.rshacksrc/testing/e2e/tasks/container/mod.rsPhase 5: Documentation
docs/user-guide/commands/register.mddocs/decisions/register-existing-instances.mddocs/console-commands.mdAcceptance Criteria
registercommand works with environment inCreatedstateProvisionedstateruntime_outputs.instance_ipset correctly"registered": "true"src/bin/e2e_config_tests.rsrefactored to use register commandrun_provision_simulation.rsremoved from codebaseRelated Documentation