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.
- Follow the Ansible installation instructions.
-
Clone the Paroli Ansible deployment repository with Git:
git clone https://gitlab.com/action-lab-aus/phoneconferencing/freeswitch-deployment.git
-
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.
-
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 keyansible_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 togateway
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 loginpassword
The password for the trunk's logincaller_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.