Creating an HTTP load-balanced logbook app

This advanced example demonstrates how to build a logbook app that uses node.js for its frontend and MySQL for its backend. The template also creates and connects an HTTP load balancer that load balances across two zones, and an autoscaler to automatically scale the app.

HTTP load-balanced deployment resources
HTTP load-balanced deployment resources (click to enlarge)

This example assumes you are familiar with Docker containers, as well as Compute Engine resources, particularly HTTP load balancing, autoscaling, managed instance groups, and instance templates.

For more introductory tutorials, refer to the Getting started guide or the Step-by-step guide.

Before you begin

Creating your templates

This example launches a deployment with several types of resources. To start, you will create reusable templates that define these resources separately. Later on, you will use these templates in your final configuration.

At the end of this example, you will have a deployment that contains these resources:

  • A single Compute Engine instance for the backend MySQL virtual machine.
  • An instance template that uses a Docker image.
  • Two autoscaled managed instance groups in two different zones, running the frontend node.js service.
  • Another two autoscaled managed instance group serving static data.
  • A health check and a HTTP load balancer to distributed traffic across the respective managed instance groups.

Creating the backend templates

The backend of this app is a single Compute Engine instance running a MySQL Docker container. Create a template that defines a Compute Engine instance that uses a container-optimized image. Name the file container_vm.[py|jinja]:

Jinja



{% from 'container_helper.jinja' import GenerateManifest %}
{% set COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' %}

resources:
- name: {{ env['name'] }}
  type: compute.v1.instance
  properties:
    zone: {{ properties['zone'] }}
    machineType: {{ COMPUTE_URL_BASE }}projects/{{ env['project'] }}/zones/{{ properties['zone'] }}/machineTypes/f1-micro
    metadata:
      items:
      - key: gce-container-declaration
        value: |
          {{ GenerateManifest(env['name'], properties['port'], properties['dockerImage'], properties['dockerEnv'])|indent(10) }}
    disks:
    - deviceName: boot
      type: PERSISTENT
      autoDelete: true
      boot: true
      initializeParams:
        diskName: {{ env['name'] }}-disk
        sourceImage: {{ COMPUTE_URL_BASE }}projects/cos-cloud/global/images/{{ properties['containerImage'] }}
    networkInterfaces:
    - accessConfigs:
      - name: external-nat
        type: ONE_TO_ONE_NAT
      network: {{ COMPUTE_URL_BASE }}projects/{{ env['project'] }}/global/networks/default
    serviceAccounts:
      - email: default
        scopes:
        - https://www.googleapis.com/auth/logging.write
        - https://www.googleapis.com/auth/monitoring.write

Python