One-click deployment of EMQX MQTT Broker on GCP using Terraform

introduction

MQTT is a lightweight messaging protocol for IoT applications to communicate between devices. As a mainstream open source MQTT Broker, EMQX can provide highly scalable, reliable and secure MQTT messaging services.

With Terraform, a widely used infrastructure-as-code (IaC) tool, you can easily and automatically deploy EMQX MQTT Broker on GCP, thereby simplifying and standardizing the setup and management of MQTT infrastructure.

This article will guide you how to set up GCP projects, create service accounts, and write Terraform configuration files to easily deploy EMQX MQTT Broker.

Preparation

Before you begin, prepare the following:

  • Sign up for a Google Cloud Platform account
  • Install the Google Cloud SDK on your local machine
  • Install Terraform on your local machine
  • Basic understanding of GCP, Terraform and MQTT

Configure the GCP environment

Follow the steps below to configure your GCP environment:

  1. Create a new GCP project or use an existing project (Project).
  2. Enable the required API (Compute Engine API) for your project.
  3. Create a service account for Terraform with the required permissions. The Compute Engine Admin role is recommended.
  4. Download the JSON key file.

Deploy EMQX on GCP using Terraform

Configure Terraform

Configure the GCP Provider in your Terraform code and use the service account key file for authentication.

provider "google" {
  credentials = file("<PATH-TO-KEY-FILE>")
  project     = "<PROJECT-ID>"
  region     = "<REGION>"
  zone       = "<ZONE>"
}

configure network

This step requires an understanding of three basic terms related to GCP: project, VPC, and subnet. The definitions of these terms are as follows:

  • A project is the top-level organizational unit in GCP and contains all resources.
  • A VPC is a private network defined within a GCP project that allows you to create and manage IP addresses, subnets, and route tables.
  • Subnets are a way of dividing a VPC network into smaller, more manageable sections. They can assign IP addresses to specific resources and define different network segments.

The relationship between them can be illustrated by the following figure:

Projects, VPCs, and Subnets (Subnets)

Create a VPC network

We need to create a VPC network to provide connectivity for your network-related resources, including:

  • Compute Engine VM instance
  • Container Engine container
  • App Engine Flex Services
  • Other web-related resources
resource "google_compute_network" "vnet" {
  project                 = "<PROJECT>"
  name                    = "<NAME>"
  auto_create_subnetworks = false
}

Create subnets in VPC

Each VPC network is divided into several subnets, here we create a subnet.

resource "google_compute_subnetwork" "sn" {
  name          = "<NAME>"
  ip_cidr_range = cidrsubnet(var.address_space, 8, 1)

  region  = var.region
  network = google_compute_network.vnet.id
}

Create firewall rules

Each network has its own firewall that controls access between instances and between instances and the outside world. All traffic to the instance, including traffic from other instances, is blocked by the firewall unless firewall rules are created to allow access to the instance.

"ports" defines some MQTT-related ports, such as "1883", "8883", "8083", "8084".

resource "google_compute_firewall" "fw" {
  name          = "<NAME>"
  network       = google_compute_network.vnet.name
  source_ranges = ["0.0.0.0/0"]

  allow {
    protocol = "icmp"
  }

  allow {
    protocol = "tcp"
    ports    = "<PORTS>"
  }
}

Configure EMQX cluster

Create a virtual machine instance for each EMQX node

Virtual machine instances can be used to deploy applications, run services, or perform computing tasks.

In the example below, we create a google_compute_instance resource called example-instance and specify the name, machine_type, boot_disk, network_interface properties.

resource "google_compute_instance" "example" {
  name         = "example-instance"
  machine_type = "n1-standard-1"

  boot_disk {
    initialize_params {
      image = ""ubuntu-os-cloud/ubuntu-2004-lts""
    }
  }

  network_interface {
    network = google_compute_network.example.name
    subnetwork = google_compute_subnetwork.example.name
    access_config {
      // Ephemeral external IP
    }
  }
}

Start the EMQX node

After creating a virtual machine instance, each EMQX node needs to be initialized. First, you must initialize and copy init.sh to each node. Then download the EMQX package and execute the copied init.sh on each node . Finally, start EMQX respectively.

resource "null_resource" "init" {
  depends_on = [google_compute_instance.example]

  count = "<INSTANCE-COUNT>"
  connection {
    type        = "ssh"
    host        = "<HOST-LIST>"
    user        = "ubuntu"
    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"
    ]
  }
}

Add EMQX nodes to the cluster

Randomly select a node in the EMQX cluster, and then add other nodes to this node one by one.

resource "null_resource" "emqx_cluster" {
  depends_on = [null_resource.init]

  count = "<INSTANCE-COUNT>-1"

  connection {
    type        = "ssh"
    host        = <OTHERS>[count.index % <OTHERS>]
    user        = "ubuntu"
    private_key = "<YOUR-PRIVATE-KEY>"
  }

  provisioner "remote-exec" {
    inline = [
      "/home/ubuntu/emqx/bin/emqx_ctl cluster join emqx@${local.another_emqx}"
    ]
  }
}

Configure load balancing

Configure load balancing

In the example above:

  1. Created a google_compute_http_health_check resource for configuring health checks.
  2. A google_compute_target_pool resource is created, which references the instance group and health check.
  3. Created a google_compute_forwarding_rule resource that sets forwarding rules to route inbound traffic on port 1883 to the target pool.
  4. You can also add more google_compute_forwarding_rules for other ports ("8883", "8083", "8084", "18083").
resource "google_compute_http_health_check" "example" {
  name               = "example-health-check"
  check_interval_sec = 30
  timeout_sec        = 5
  port         = 8081
  request_path = "/status"
}

resource "google_compute_target_pool" "example" {
  name = "example-target-pool"

  instances = [
    google_compute_instance_group.example.self_link
  ]

  health_checks = [
    google_compute_http_health_check.example.name
  ]
}

resource "google_compute_forwarding_rule" "example-1883" {
  name       = "example-forwarding-rule"
  target     = google_compute_target_pool.example.self_link
  port_range = "1883"
  ip_protocol = "TCP"
}

resource "google_compute_forwarding_rule" "example-8883" {
  ...
}

Initialize and apply Terraform

terraform init
terraform plan
terraform apply

When applied successfully, the following will be output:

Outputs:
loadbalancer_ip = ${loadbalancer_ip}
tls_ca = <sensitive>
tls_cert = <sensitive>
tls_key = <sensitive>

You can now access different services through the corresponding ports.

Dashboard: ${loadbalancer_ip}:18083
MQTT: ${loadbalancer_ip}:1883
MQTTS: ${loadbalancer_ip}:8883
WS: ${loadbalancer_public_ip}:8083
WSS: ${loadbalancer_public_ip}:8084

epilogue

Using Terraform to deploy EMQX on GCP allows you to easily manage IoT infrastructure and focus on creating IoT applications. Following the guidelines in this article, you can quickly build an MQTT Broker with strong scalability and high reliability on GCP to provide support for your IoT projects.

Copyright statement: This article is original by EMQ, please indicate the source for reprinting.

Original link: https://www.emqx.com/zh/blog/one-click-deploying-emqx-mqtt-broker-on-gcp-using-terraform

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4174826/blog/10024054