A modern Perl console application for deploying Torrust Tracker to cloud providers using OpenTofu/Terraform and cloud-init for VM configuration.
This project uses cloud-init for VM configuration instead of building golden images with tools like Packer. While golden images could speed up provisioning by pre-installing the torrust user, Docker, and other basic setup, we chose cloud-init because:
- Cross-cloud compatibility: No way to generate a single base image that works across multiple
cloud providers - Deployment frequency: Since deployment is typically done once, the extra time for cloud-init
configuration is acceptable - Simplicity: Eliminates the complexity of managing and maintaining custom images across
different providers - Transparency: All VM configuration is visible in the cloud-init templates
This project requires Perl v5.38 or higher. We chose v5.38 specifically because:
- Modern Perl features: Enables
strict
andwarnings
by default without explicituse
statements - GitHub Actions compatibility: v5.38 is the default Perl version in Ubuntu 24.04 LTS
(GitHub Actions runners) - No additional CI setup: Avoids the overhead of installing newer Perl versions in CI, which
can be slow - Modern enough: Provides all the modern Perl features we need for this application
You can check your Perl version with:
perl -v
If you need to install a newer Perl version, consider using perlbrew for
local development.
First, install system dependencies:
# On Ubuntu/Debian:
sudo apt install libssh2-1-dev ansible
Install cpanminus:
curl -L https://cpanmin.us | perl - --sudo App::cpanminus
Install local::lib:
cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
Install Carmel dependency manager:
cpanm Carmel
Set up the environment (add carmel to PATH and set PERL5LIB):
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
export PATH="$HOME/perl5/bin:$PATH"
Note: You need to run the eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
command in each new
terminal session, or add it to your shell profile (.bashrc
, .zshrc
, etc.).
Then install project dependencies:
carmel install
Run the application:
carmel exec -- ./bin/torrust-deploy help
Provision a Torrust Tracker virtual machine using OpenTofu with libvirt provider:
carmel exec -- ./bin/torrust-deploy provision
This command will:
- Copy OpenTofu configuration templates from
templates/tofu/
directory - Initialize OpenTofu if needed
- Create a minimal Ubuntu 22.04 LTS VM with hardcoded configuration
- Wait for cloud-init completion via SSH monitoring
- Verify SSH key authentication and system readiness
- Run post-provision verification using Ansible (experimental)
- Display final system summary
Before using the provision command, ensure you have:
-
OpenTofu installed (Download from opentofu.org)
-
Ansible installed for post-provision verification and configuration:
# On Ubuntu/Debian: sudo apt install ansible # Verify installation: ansible --version
-
libvirt/KVM installed and running:
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils sudo systemctl enable libvirtd sudo systemctl start libvirtd sudo usermod -aG libvirt $USER
-
SSH development libraries for Net::SSH2 Perl module:
sudo apt install libssh2-1-dev
-
Default libvirt storage pool configured:
virsh pool-list --all # If 'default' pool doesn't exist, create it: sudo virsh pool-define-as default dir - - - - "/var/lib/libvirt/images" sudo virsh pool-build default sudo virsh pool-start default sudo virsh pool-autostart default
The VM is created with:
- OS: Ubuntu 22.04 LTS (Cloud Image)
- CPU: 2 vCPUs
- Memory: 2GB RAM
- Disk: 10GB
- Network: NAT with DHCP (192.168.122.0/24)
- User:
torrust
(with sudo access) - SSH: Enabled (requires SSH key configuration in cloud-init.yml)
After provisioning, you can find the VM IP with:
cd build/tofu && tofu output
The project includes two types of tests:
Run unit tests that don't require virtualization:
./script/test unit
These tests can run in CI environments and test individual components in isolation.
Run integration tests that require multiple components to work together:
./script/test integration
It does not require any special setup and can be run on any machine with the necessary dependencies installed.
Run tests that require Docker:
./script/test container
Run end-to-end tests that require local virtualization support:
./script/test e2e
Requirements for E2E tests:
- Local machine with KVM/libvirt support
- OpenTofu installed
- Ansible installed
- Required system tools:
qemu-system-x86_64
,sshpass
- SSH development libraries:
libssh2-1-dev
- Cannot run in CI environments
Run both unit and E2E tests:
./script/test-all
E2E tests will be automatically skipped in CI environments or when virtualization tools are not available.