Skip to content

Deploying Paroli's FreeSWITCH Server

Note: Make sure you have completed the prerequisite steps before continuing

Installing and Configuring Ansible

Ansible is an automation tool for infrastructure provisioning and configuration. It is typically run from a developer's local machine, targetting a remote server. Without using Ansible, installing and configuring a Paroli server can easily take a full day, and mistakes are easy to make. Ansible makes the process much less painful. Through Ansible's 'playbooks', we are able to create sets of instructions that will be enacted upon our Debian server to install packages, clone repositories, start processes, and create, edit or delete particular files.

If you are using a Windows machine, I recommend running Ansible from WSL, using a Linux distro like Ubuntu. Follow these steps to get started. If you're not already, you should also be using the official Terminal app.

  1. Follow the Ansible installation instructions.
  2. Clone the Paroli Ansible deployment repository with Git:

    git clone https://gitlab.com/action-lab-aus/phoneconferencing/freeswitch-deployment.git
    
  3. In order to configure the remote Paroli app properly, the Ansible playbook needs to have details of your Firebase project. This is done through two files. Make sure not to commit the contents of these files into Git.

    • /staging/firebase_config.json

    The contents for this file can be found on the Firebase console. Open your project, and click the settings icon on the left, next to 'Project Overview', and click 'Project Settings'. Under the 'General' tab, scroll down to 'Your apps'. If nothing is there, click 'Add app', then choose to create a web app. Once an app is in place, select the 'Config' radio button and copy the value of the 'firebaseConfig' json object into the file (see the file's current contents as an example).

    • /staging/firebase_service_acc_private_key.json

    This file is also created through the Firebase console. Go to 'Project Settings' again, and then go to the 'Service accounts' tab. Click 'Generate new private key', and copy the contents of the generated file into firebase_service_acc_private_key.json.

  4. The playbook also needs some details about the server and your SIP trunk(s). This is done through the inventory file. Make sure not to commit the contents of this file into Git. The inventory is in a YAML format. Here's a brief explanation of the contents of the file, and what you need to change:

    • hosts This is an array of the servers you wish to deploy to.
    • 000.00.00.00 Change this to your server's address (e.g. ec2-blah-blah.compute.amazonaws.com)
    • ansible_ssh_private_key_file The relative path of your ssh key
    • ansible_ssh_user The user Ansible will log in with. AWS uses 'admin'
    • debian_sc The version of Debian installed on the server (e.g. 'bullseye')
    • domain_name Your server's (sub)domain (e.g. freeswitch.mydomain.com)
    • domain_registered_email Your email address. Reminders for SSL certificates will be sent here.
    • fs_password Used to secure your FreeSWITCH instance from use by third parties (important!)
    • fs_user_password A password for web-based caller accounts (less important)
    • languages An object which defines the languages your Paroli instance will use. It has two properties: 'default', which is the language that will be used if the user's country's language is not supported; and 'supported', which is an array of all languages your instance can support. Be aware that you need audio recordings for each of these languages (see here).
    • signalwire_token Your signalwire token, acquired earlier.
    • trunks An array of the trunks this server can connect to
    • gateway A name for this trunk, unique on this server (e.g. 'twilio')
    • proxy The proxy address for this trunk (e.g. mytrunk.pstn.twilio.com)
    • updated Milliseconds since epoch that you last edited the details of this trunk (e.g. 1677553180947). This is used to check if any details in the database set during runtime should be overwritten if you redeploy.
    • username The username for the trunk's login
    • password The password for the trunk's login
    • caller_number The phone number for this trunk, including country code (e.g. '+44123456789')
    • caller_name The caller ID for this number (e.g. 'Paroli')
    • capacity How many simultaneous callers this trunk can support (e.g. 50)
    • codes_cost_per_min A dictionary. Keys are country dial codes, and the values are cost per minute per person in USD when dialing that country (e.g. "+44" : 0.06)
    • handle_all_countries Boolean value. If true, the trunk can handle calls from all countries. If not, it will only handle calls from the codes_cost_per_min dictionary.
    • addresses Array of IP addresses that the trunk may use.

How to use the Ansible playbooks

Once you have set up the above config files, there are several commands available. On your local machine, you can run the entire setup process on the remote server with this command:

    ansible-playbook  mainplaybook.yml

You can choose to only run specific parts of the setup process through the use of tags. The available tags are listed below. As an example, if you want to update the server to use the latest code from the Paroli repository but not go through the rest of the installation process, you can run the following:

    ansible-playbook mainplaybook.yml --tags "paroli"

Similarly, you can choose to skip specific parts of the installation by using tags. For example, to re-run setup without refreshing the SSL certificates needlessly, you can run:

    ansible-playbook mainplaybook.yml --skip-tags "letsencrypt"

Multiple tags can be used at once by seperating them with a comma. E.g. "paroli,ufw"

What do the playbooks do?

The deployment project consists of seven playbooks. Six are located in the './playbooks' folder, and are each dedicated to setting up a particular aspect of the server. The main playbook in located in the project root, and initiates the others.

mainplaybook.yml Tags: paroli

This is the hub of the deployment project. It installs and updates necessary apt packages and clones/updates the Paroli server repository. It will then run all of the following playbooks (unless you specify tags):

./playbooks/nodeplays.yml Tags: node

Installs Node.js if it is missing.

./playbooks/freeswitchplays.yml Tags: freeswitch

Downloads and compiles FreeSWITCH, and installs its audio files, its necessary additional components, and configures it with the necessary languages, security settings and specified SIP trunks.

./playbooks/paroliplays.yml Tags: paroli

Configures the FreeSWITCH installation and sets up the Firebase connection using the files downlaoded from the Paroli repository and the details from the Ansible inventory file.

./playbooks/letsencryptplays.yml Tags: letsencrypt

Generates and installs SSL certificates for the server, using the domain and email address specified in the inventory file. You should run this again when you receive reminder emails from letsencrypt about the certificate expiring.

./playbooks/firewallplays.yml Tags: ufw

Configures the server's firewall with UFW, making it so only ports needed for WebRTC, SSH, and connections to the SIP trunks can get through.

./playbooks/pm2plays.yml Tags: pm2,paroli

Installs and configures PM2 so that Paroli will launch at boot. Note that this step will cause an error the first time you run it which is safe to ignore.

Next: Deploy the Firebase Functions