Generally applicable Ansible playbooks for administering a server network for Team Fortress 2.
Want to see what makes this better than the alternatives? Check out the Features.
Ansible requires Linux. If you're running Windows, you'll need to set up WSL. These playbooks only work with systemd-based hosts, which is the default for most Linux distributions.
Assuming you're using Ubuntu (WSL default), install Python, Ansible, and Docker using sudo apt install -y python3 ansible docker.io
NixOS users: a flake is provided for convenience, just run
nix develop
.
On all tf2
hosts (dedicated servers):
sudo apt install -y docker.io docker-compose-v2
- Install Docker and Docker-Compose.sudo useradd -UmG docker tf2server
- Create the tf2server
user with the docker
role.sudo loginctl enable-linger tf2server
- Enable systemd service lingering.On your metrics
host:
sudo apt install -y docker.io
- Install Docker.sudo useradd -UmG docker tf2server
- Create the tf2server
user with the docker
role.Of course, don't forget to put your SSH public key in /home/tf2server/.ssh/authorized_keys
.
There is a pre-commit hook that you should enable to ensure you don't commit any unencrypted secret:
ln .hooks/pre-commit .git/hooks/pre-commit
inventory.yml.sample
group_vars/tf2.yml.sample
group_vars/tf2.secret.yml.sample
host_vars/host.yml.sample
host_vars/host.secret.yml.sample
make sbpp-install
- Install SourceBans++ on your metrics
host. DB host:
db
DB user:sourcebans
DB name:sourcebans
Configure the rest to your liking.
make cycle
- Generate initial ssh keys for secure SB++ DB connection.
-- This directive also (re-)starts the SB++ network, so no need to run make sbpp
.make base
- Build the base Team Fortress 2 server Docker image on every tf2
host.make sm
- Distribute and build SourceMod.make srcds
- Build instance images.make deploy
- Start containers & setup crontab for the TF2 servers.make relay
- If configured & enabled, build the Discord -> Server relay/RCON bot on your metrics
host.make relay-deploy
- Deploy the bot on your metrics
host.
make all
or simplymake
is an alias formake sm srcds deploy relay relay-deploy
You can update your admins/reserved slots at any time withmake admins
make base
can take a long time!
This is because it's downloading the full TF2 server.
It is possible that Ansible will SILENTLY time out while waiting if it takes too long!
Watch for jackavery/base-tf2server
to show up in docker image ls
. If it's there, you can Ctrl+C Ansible.
Do not re-run sbpp-install
once you've installed SB++!
This is because it starts the container with intent to install SourceBans++.
This also means it will wipe your existing data, including user punishments and server configuration.
Because ansible-tf2network handles everything for you, you can look for cheap VPS Providers instead of managed hosting services. A lot of managed services will upcharge you for their ease of use; but, trying to do anything outside of the scope of what their management dashboard allows you to do is difficult. Going directly to a VPS provider and purchasing a box directly may be cheaper, and with ansible-tf2network, you can do more.
Using the discord_relay
plugin (depends on discord
plugin, uses a webhook in host_vars/{host}.secret.yml
) facilitates a Server to Discord relay, and correctly configuring your Discord bot (in group_vars/tf2.secret.yml
and host_vars/{host}.yml
) facilitates a Discord to Server relay between a specified Discord channel and Team Fortress 2 server. You can also allow specific Discord user IDs access to the /rcon
command, which allows remote control of the server network.
This playbook set comes with a robust and simple auto-update script that ensures your servers update as soon as a new version of Team Fortress 2 is available. This is done by rebuilding from scratch, instead of updating the existing image, so as to maintain image immutability. Servers are restarted once daily at a time set per-host as to prevent server clock errors. The relay plugin facilitates chat logs with user IDs for use by moderators for moderation decisions. This leads to a seamless 24/7 server experience with quality-of-life for your moderation team.
ansible-tf2network uses Ansible to provide a user-friendly and extensive configuration interface, and Docker to make your deploys consistent regardless of host. If you upgrade or move hosts, all you need to do is point your host record in inventory.yml
at the new IP.
Since the playbooks keep their activity contained within the tf2server
user folder with no actions performed as root, cleaning up a host after using ansible-tf2network can be done with these commands:
userdel -r tf2server
- Delete their userdocker stop [...]
- Stop the containers (do this for all servers)docker container prune
- Remove the containersdocker image prune -a
- Remove all unused Docker imagesansible-tf2network server configuration has 3 scopes: default, ruleset, and instance. Overriding configuration from outer scopes is possible within inner scopes, e.g., ruleset config overrides default config, and instance config overrides both.
Mapcycle configurations are separate from these scopes, and the mapcycle to be used is defined in the instance scope.
Default, ruleset, and mapcycle configuration is defined in group_vars/tf2.yml
, and instance config is defined per-host in host_vars
.
Some plugin configuration use Valve's KeyValues format (referred to in these playbooks as 'VDF'), and some use Valve's CFG format.
ansible-tf2network supports an unlimited amount of both formats by defining a default in the global scope (group_vars/tf2.yml
, default_cfgs
, default_vdfs
), which can be further tweaked in the ruleset and instance scopes. Note that a configuration must exist in the global scope in order for it to be included in the server.
KeyValues configurations can vary wildly, and as such, the entire configuration must be redefined in the inner scope. CFG overriding works as they usually contain all convars set by a plugin.
Only the secrets are encrypted! This makes it possible for users to view your server configuration if they're curious, as well as propose changes.