DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Terraform Best Practices: The 20 Practices You Should Adopt
  • Keep Your Application Secrets Secret
  • Auto-Scaling a Spring Boot Native App With Nomad
  • Build Sustainable Applications Using Azure Services

Trending

  • Best Plugins For JetBrains IDEs
  • Deploy a Session Recording Solution Using Ansible and Audit Your Bastion Host
  • Send Your Logs to Loki
  • 5 Web3 Trends to Follow in 2023
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. One-Click Deploying EMQX MQTT Broker on Azure Using Terraform

One-Click Deploying EMQX MQTT Broker on Azure Using Terraform

A step-by-step guide on how to set up an Azure project, create a service principal, and write a Terraform configuration file to deploy EMQX MQTT Broker.

Weihong Zhang user avatar by
Weihong Zhang
·
Sep. 05, 23 · Tutorial
Like (1)
Save
Tweet
Share
4.21K Views

Join the DZone community and get the full member experience.

Join For Free

MQTT is a lightweight messaging protocol used in the Internet of Things (IoT) to enable communication between devices. As a popular open-source MQTT broker, EMQX provides high scalability, reliability, and security for MQTT messaging.

By using Terraform, a widespread Infrastructure as Code (IaC) tool, you can automate the deployment of EMQX MQTT Broker on Azure, making it easy to set up and manage your MQTT infrastructure.

This blog will provide a step-by-step guide on how to set up an Azure project, create a service principal, and write a Terraform configuration file to deploy EMQX MQTT Broker.

Prerequisites

Before you start, prepare the following:

  • An Azure account.
  • The Azure CLI is installed on your local machine.
  • Terraform installed on your local machine.
  • A basic understanding of Azure, Terraform, and MQTT.

Set Up the Azure Environment

  1. Install the Azure CLI by following the instructions here.
  2. Run az login and follow the prompts to authenticate with your Azure account.
  3. Run az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/YOUR_SUBSCRIPTION_ID" to create a new service principal with the "Contributor" role.
  4. Note down the appId, password, and tenant values from the output. You'll need them for the Terraform configuration.

Deploy EMQX on Azure Using Terraform

Configure Terraform

Configure the Azure provider in your Terraform code.

 
terraform {
  required_version = ">=1.2"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.11.0, <4.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "3.3.2"
    }
  }
}

Create Resource Group

Resource groups in Azure are logical containers for resources deployed within an Azure subscription.

 
resource "azurerm_resource_group" "example" {
  name     = "example-resource-group"
  location = "East US"
}

Configure Network

Create a Network Security Group

The Network Security Group(NSG) is used to apply security rules to network traffic, allowing or denying traffic based on the direction (inbound or outbound), protocol, source, and destination.

The example allows inbound TCP traffic to port 1883(MQTT).

 
resource "azurerm_network_security_group" "example" {
  name                = "example-security-group"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  security_rule {
    name                       = "mqtt"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "1883"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

Create a VPC Network

A virtual network is a logically isolated section of the Azure cloud where you can launch Azure resources. It allows for private communication between resources and helps to structure your cloud infrastructure.

In the following example, the VPC address space is set to 10.0.0.0/16:

 
resource "azurerm_virtual_network" "example" {
  name                = "example-virtual-network"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  address_space       = ["10.0.0.0/16"]
}

Create a Subnet

A subnet is a range of IP addresses within a virtual network (VNet) that helps organize and isolate resources in a cloud infrastructure.

In the following example, the address space for the subnet is set to 10.0.1.0/24:

 
resource "azurerm_subnet" "exmaple" {
  name                 = "example-subenet"
  resource_group_name  = azurerm_resource_group.exmaple.name
  virtual_network_name = azurerm_virtual_network.exmaple.name
  address_prefixes     = ["10.0.1.0/24"]
}

Create a Network Interface

A network interface (NIC) is the interconnection between a virtual machine (VM) and the virtual network (VNet).

We assigned the subnet_id to the one we created inside the azurerm_network_interface blocks.

 
resource "azurerm_network_interface" "exmaple" {
  name                = "exmaple-network-interface"
  location            = azurerm_resource_group.exmaple.location
  resource_group_name = azurerm_resource_group.exmaple.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.exmaple.id
    private_ip_address_allocation = "Dynamic"
  }
}

Configure EMQX Cluster

Provide a VM Instance for Each EMQX Node

The resource azurerm_linux_virtual_machine simplifies provisioning a Linux VM in Azure by handling various aspects like OS image, networking, storage, and compute resources.

We assigned the resource_group_name and network_interface_ids with the ones we created inside the azurerm_linux_virtual_machine blocks.

 
resource "azurerm_linux_virtual_machine" "exmaple" {
  name                            = "exmaple-virtual-machine"
  resource_group_name             = azurerm_resource_group.exmaple.name
  location                        = azurerm_resource_group.exmaple.location
  size                            = "<YOUR-VM-SIZE>"
  admin_username                  = "azureuser"
  network_interface_ids           = [azurerm_network_interface.exmaple.id]

  admin_ssh_key {
    ...
  }

  os_disk {
    ...
  }

  source_image_reference {
    ...
  }
}

Initiate EMQX Nodes and Create a Cluster

Initialize each EMQX node after the VM instance is created. First, you must initialize and copy the init.sh to each none. Then download the EMQX package and execute the init.sh you’ve copied at each node. Finally, start EMQX separately.

 
resource "null_resource" "emqx" {
  depends_on = [azurerm_linux_virtual_machine.vm]

  count = "<INSTANCE-COUNT>"
  connection {
    type        = "ssh"
    host        = "<HOST-LIST>"
    user        = "azureuser"
    private_key = "<YOUR-PRIVATE-KEY>"
  }

  # config init script
  provisioner "file" {
    content = templatefile("${path.module}/scripts/init.sh", { local_ip = <PRIVATE-IPS>[count.index],
      emqx_lic = <EMQX-LICENSE>, emqx_ca = <EMQX-CA> emqx_cert = <EMQX-CERT>, emqx_key = <PRIVATE-KEY> })
    destination = "/tmp/init.sh"
  }

  # download EMQX package
  provisioner "remote-exec" {
    inline = [
      "curl -L --max-redirs -1 -o /tmp/emqx.zip <EMQX-PACKAGE-URL>"
    ]
  }

  # init system
  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/init.sh",
      "/tmp/init.sh",
      "sudo mv /tmp/emqx <HOME>",
    ]
  }

  # start EMQX 
  provisioner "remote-exec" {
    inline = [
      "sudo <HOME>/bin/emqx start"
    ]
  }
}

In the init.sh, we configure a fixed node list to discover and create clusters automatically:

 
cluster.discovery = static
cluster.static.seeds = emqx1@127.0.0.1,emqx2@127.0.0.1

Configure Load Balancer

To create a Load Balancer with Terraform on Azure, you'll need to use multiple resources: azurerm_lb, azurerm_lb_backend_address_pool, azurerm_lb_probe, azurerm_lb_rule, and azurerm_lb_nat_rule (if needed). This example demonstrates how to create a simple Azure Load Balancer with a backend address pool, health probe, and load balancing rule.

In this example, we create:

  • An azurerm_public_ip resource to associate with the Load Balancer.
  • An azurerm_lb resource to define the Load Balancer with the frontend IP configuration.
  • An azurerm_lb_backend_address_pool resource to define the backend pool for the Load Balancer.
  • An azurerm_lb_probe resource to define the health probe for the Load Balancer.
  • An azurerm_lb_rule resource to define the Load Balancing rule
 
resource "azurerm_public_ip" "example" {
  name                = "example-public-ip"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  allocation_method   = "Static"
}

resource "azurerm_lb" "exmaple" {
  name                = "exmaple-lb"
  location            = azurerm_resource_group.exmaple.location
  resource_group_name = azurerm_resource_group.exmaple.name

  frontend_ip_configuration {
    name                 = "example-frontend-ip"
    public_ip_address_id = azurerm_public_ip.example.id
  }
}

resource "azurerm_lb_backend_address_pool" "exmaple" {
  name                = "example-backend-address-pool"
  loadbalancer_id     = azurerm_lb.exmaple.id
}

resource "azurerm_lb_probe" "exmaple" {
  name                = "example-health-probe"
  loadbalancer_id     = azurerm_lb.exmaple.id
  port                = 1883
  protocol            = "Tcp"
  interval_in_seconds = 5
  number_of_probes    = 2
}

resource "azurerm_lb_rule" "exmaple" {
  name                           = "example-lb-rule"
  loadbalancer_id                = azurerm_lb.exmaple.id
  protocol                       = "Tcp"
  frontend_port                  = 1883
  backend_port                   = 1883
  frontend_ip_configuration_name = "example-frontend-ip"
  backend_address_pool_id        = azurerm_lb_backend_address_pool.exmaple.id
  probe_id                       = azurerm_lb_probe.exmaple.id
}


Conclusion

Deploying EMQX on Azure using Terraform streamlines the management of your IoT infrastructure, allowing you to focus on building applications that leverage the power of connected devices. Following the steps outlined in this blog post, you can easily set up a scalable and reliable MQTT broker on Azure to support your IoT projects.

Command-line interface MQTT Network interface Transmission Control Protocol azure Terraform (software)

Published at DZone with permission of Weihong Zhang. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Terraform Best Practices: The 20 Practices You Should Adopt
  • Keep Your Application Secrets Secret
  • Auto-Scaling a Spring Boot Native App With Nomad
  • Build Sustainable Applications Using Azure Services

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: