terraform-azurerm-jmusicbot 2.0: Self-Updating, Always-On Cloud Solution for JMusicBot
From Manual Deployments to Cloud Automation: A Discord Music Bot Journey
About two years ago, YouTube cracked down on Groovy Bot and other popular music bots for Discord. This left many servers, including ours, without a reliable way to play music. That’s when I decided to set up our solution using Jagrosh’s Java-based JMusicBot.
The Beginning: Basic and Manual
I started with a simple plan: a basic Terraform module that set up a VM in Azure and installed JMusicBot. It worked, but it needed a lot of hands-on time. Every night, I’d open VSCode, type terraform apply
to start the music, and terraform destroy
when we were done. I kept this up for months.
Making It Cheaper
About a year later, I made some big improvements. By adding a javascript function app to the project which shuts down the VM when nobody is around, I cut down costs a lot. Before, it cost $15-$25 each month. Now, it was only $1-$10, sometimes even less than $3. This was great for saving money.
The Ongoing Problem
Even with these improvements, we still had one big issue. Updating JMusicBot was a pain. It took a lot of time and often left our Discord without music for a while. It was clear we needed to make this process smoother to keep the music playing non-stop.
The update procedure was tedious and grew annoying to me as I did it more and more.
- Open VSCode, manually update the
jar_path
variable invariables.tf
. - Download the new JMusicBot JAR file and place it in the module’s
jdiscordmusicbot
directory. - Push changes to main branch.
- Create a new module release.
- Update the config file to reference the latest version.
- Run
terraform init
andterraform apply
. - Wait and hope for the best π€£.
This process was not only cumbersome but also led to significant downtime. Our Discord server would go days, sometimes weeks, without music as I dreaded doing the damn update. I’d frequently receive inquiries about when we could play music again. Even after completing an update, a new version would often be released within days or weeks, restarting the cycle.
This vicious cycle resulted in fewer tunes for our Discord community, which sucked. The more updates to improve JMusicBot the more work I had to do. Constant manual updates and resulting downtime were becoming unsustainable.
Recognizing the need for a better solution, I realized that automating this process was crucial β not just for the sake of our Discord server’s music, but for my sanity as well π€£. This realization drove the development of the current version, aiming to eliminate these pain points and ensure continuous music availability for our Discord community.
Now that I have 2.0 up and running, I no longer need to manage updates to JMusicBot, and music is available for the Discord server 24/7. If you’re looking for a project to practice cloud platform engineering with VSCode, Azure, Terraform Cloud, and GitHub Actions, or if you need a 24/7, always-available cloud-based music solution for your Discord server, fork this configuration repository and follow the setup guide.
In the next sections, I’ll explain how I solved this problem and created a self-updating, always-on solution for our Discord music needs.
How it All Works: Overview of the Entire Solution
Hereβs a clear view of how everything works together to automate and manage JMusicBot on Azure via Terraform Cloud.
For complete setup instructions, refer to the configuration repo.
Components Overview
Component | Description |
---|---|
azure-jmusicbot-kv | Manages secrets using Azure Key Vault, storing the Discord bot token, VM SSH keys, and private SSH keys. |
azure-jmusicbot | Handles the primary deployment resources, pulling in secrets from azure-jmusicbot-kv , and managing Azure Function app variables. |
azure-jmusicbot-kv Terraform Cloud Workspace | Stores secrets needed for deployment. Uses Azure Key Vault to securely manage sensitive information. |
azure-jmusicbot Terraform Cloud Workspace | Manages the main deployment resources. Relies on secrets from azure-jmusicbot-kv and controls function app variables, including the custom script extension for the VM. |
Azure Resources | Includes Resource Group, VNet, Subnet, Public IP, NSG, NIC, VM, Storage Account, App Service Plan, Application Insights, and Azure Function. |
GitHub Actions | Automates updates and deployment processes: update-jar-and-release, Check for Module Update and TF Apply, and deploy-function. |
Configuration Repositories
- azure-jmusicbot-kv: Manages secrets using Azure Key Vault, storing the Discord bot token, VM SSH keys, and private SSH keys.
- azure-jmusicbot: Handles the primary deployment resources, pulling in secrets from
azure-jmusicbot-kv
, and managing Azure Function app variables.
Terraform Cloud Workspaces
- azure-jmusicbot-kv: Stores secrets needed for deployment. This workspace uses Azure Key Vault to securely manage sensitive information.
- azure-jmusicbot: Manages the main deployment resources. Relies on secrets from
azure-jmusicbot-kv
and controls function app variables, including the custom script extension for the VM.
Deployment Order:
- Deploy both workspaces through VS Code. First, deploy
azure-jmusicbot-kv
, followed byazure-jmusicbot
. - Set up a run trigger so that when the
azure-jmusicbot-kv
workspace completes its run, it triggers theazure-jmusicbot
workspace to run. This ensures an organized and automated workflow.
Azure Resources
- Resource Group: Contains all deployed resources.
- Virtual Network (VNet): Provides the network infrastructure.
- Subnet: Sub-network within the VNet.
- Public IP: Allows external access to the VM.
- Network Security Group (NSG): Controls inbound and outbound traffic.
- Network Interface (NIC): Connects the VM to the network.
- Virtual Machine (VM): Runs JMusicBot.
- Custom Script Extension: Taints and re-applies the VM to update JMusicBot to the latest version.
- Storage Account: Used by the Function App.
- App Service Plan: Hosts the Function App.
- Application Insights: Provides monitoring for the Function App.
- Azure Function (jdiscord-function): Manages the VM lifecycle based on Discord activity, including starting the VM when users join the music channel and stopping it when all users leave.
See my last blog post on this solution where I detail the function app and how it works. It has not changed much since 1.1.
GitHub Actions
The update-jar-and-release is a part of the module’s repository. You do not need to fork this repository. As such, you will not need to manage it. However, when you fork the configuration repo. You will have your own version of Check for Module Update and TF Apply and deploy-function workflows.
- update-jar-and-release: Checks daily for new JMusicBot releases, updates configuration files, commits changes, and creates a new release in the module repository.
- Check for Module Update and TF Apply: This can be triggered manually or on a schedule. Checks for updates to the
terraform-azurerm-jmusicbot
module runsterraform apply
if updates are detected, and taints the custom script extension to ensure the latest JMusicBot version is installed. Manages the VM and Function app state during the update process. - deploy-function: Deploys the Azure Function, sets up the Node.js environment, installs dependencies, and deploys the function to Azure.
Updating Secrets
To update the Discord bot token, use the Key Vaults workspace variables. To update the function app’s variables, use the primary workspace’s variables. Once a variable has been updated, you can manually trigger a run on the Key Vault workspace which will trigger the primary and process the variable update.
Note: If you update the function app’s variables and apply, you will need to restart the function app in the portal manually.
Initial Setup with set_workspace_variables.ps1
Use the set_workspace_variables.ps1
script to move variables from your local terraform.tfvars
file to the Terraform Cloud workspace. This script is useful for any Terraform project requiring local variables to be transferred to Terraform Cloud.
Future Plans
Future enhancements include tracking and replaying the top ten songs and users, and automating the rotation of the Discord bot token to handle token revocation issues smoothly.
Thanks for reading this far. I hope you found this project useful and/or educational. I found it to be both! If you have any issues with the module or the configuration repo please hit me up on here or via LinkedIn.
-Rudy
Relevant Links:
https://github.com/RCFromCLE/terraform-azurerm-jmusicbot
https://github.com/RCFromCLE/terraform-azurerm-jmusicbot-config
https://registry.terraform.io/modules/RCFromCLE/jmusicbot/azure/latest
https://jmusicbot.com/
https://github.com/jagrosh/MusicBot/releases