How to deploy on GCE

vm

Google Compute Engine is a popular subsidiary of Google that provides on-demand cloud computing platforms on a metered pay-as-you-go basis.

Google Cloud web console: console.cloud.google.com

Prerequisites

  • A physical or virtual machine running Ubuntu 24.04+

  • Juju 3.6+ installed via snap


Install the Google Cloud CLI

Install the Google Cloud CLI:

user@host:~$
sudo snap install google-cloud-cli --classic

Check the official the official Google Cloud documentation for other installation options.

To check it is correctly installed, run

user@host:~$
gcloud --version
Google Cloud SDK 474.0.0
...

Authenticate

Log in to Google Cloud:

user@host:~$
gcloud auth login

Create an service IAM account for Juju to operate GCE:

user@host:~$
gcloud iam service-accounts create juju-gce-account --display-name="Juju GCE service account"
Created service account [juju-gce-account].

Check your list of accounts:

user@host:~$
gcloud iam service-accounts list
DISPLAY NAME                   EMAIL                                                               DISABLED
...
Juju GCE service account       juju-gce-account@canonical-data-123456.iam.gserviceaccount.com      False
...

Create a private key:

user@host:~$
gcloud iam service-accounts keys create sa-private-key.json  --iam-account=juju-gce-account@canonical-data-123456.iam.gserviceaccount.com
created key [aaaaaaa....aaaaaaa] of type [json] as [sa-private-key.json] for [juju-gce-account@canonical-data-123456.iam.gserviceaccount.com]

Add a policy binding to the IAM policy of the project:

user@host:~$
gcloud projects add-iam-policy-binding canonical-data-123456 --role=roles/compute.admin --member serviceAccount:juju-gce-account@canonical-data-123456.iam.gserviceaccount.com

Bootstrap Juju controller on GCE

Due to a known Juju issue , move the newly exported Google Cloud JSON file into a snap-accessible folder:

user@host:~$
sudo mv sa-private-key.json /var/snap/juju/common/sa-private-key.json
user@host:~$
sudo chmod a+r /var/snap/juju/common/sa-private-key.json

Add GCE credentials to Juju:

user@host:~$
juju add-credential google
...
Enter credential name: juju-gce-account
...

Auth Types
  jsonfile
  oauth2

Select auth type [jsonfile]: jsonfile

Enter path to the .json file containing a service account key for your project
Path: /var/snap/juju/common/sa-private-key.json

Credential "juju-gce-account" added locally for cloud "google".

Bootstrap a Juju controller:

user@host:~$
juju bootstrap google gce
Creating Juju controller "gce" on google/us-east1
Looking for packaged Juju agent version 3.5.4 for amd64
Located Juju agent version 3.5.4-ubuntu-amd64 at https://streams.canonical.com/juju/tools/agent/3.5.4/juju-3.5.4-linux-amd64.tgz
Launching controller instance(s) on google/us-east1...
 - juju-33f662-0 (arch=amd64 mem=3.6G cores=4)
Installing Juju agent on bootstrap instance
Waiting for address
Attempting to connect to 35.231.246.157:22
Attempting to connect to 10.142.0.17:22
Connected to 35.231.246.157
Running machine configuration script...
Bootstrap agent now started
Contacting Juju controller at 35.231.246.157 to verify accessibility...

Bootstrap complete, controller "gce" is now available
Controller machines are in the "controller" model

Now you can run
	juju add-model <model-name>
to create a new model to deploy workloads.

See also: Juju | Google Cloud bootstrap options

You can check the instance availability in the web interface

Web interface: https://console.cloud.google.com/compute/instances

image|690x172

(Make sure to choose the right Google Cloud project!)

Access a test database (optional)

This section walks you through creating and accessing a test database in your newly configured cloud.

Create a Juju model:

user@host:~$
juju add-model <model-name>

The following command deploys PostgreSQL and the data-integrator charm to request a test database:

user@host:~$
juju deploy postgresql --channel 16/stable
user@host:~$
juju deploy data-integrator --config database-name=test-db
user@host:~$
juju integrate postgresql data-integrator

Once juju status shows the apps as active and idle, request the credentials for your newly bootstrapped PostgreSQL database:

user@host:~$
juju run data-integrator/leader get-credentials

Take note of the values for <username>, <password>, and <endpoint>.

At this point, you can access your cloud database using the internal IP address.

All further Juju applications will use the database through the internal network:

user@host:~$
psql postgresql://<username>:<password>@<endpoint>/test-db
psql (15.6 (Ubuntu 15.6-0ubuntu0.23.10.1), server 16.9 (Ubuntu 14.12-0ubuntu0.24.04.1))
Type "help" for help.

test-db=>

Expose database (optional)

To access the database from outside of the cloud, open the the cloud’s firewall using juju expose :

user@host:~$
juju expose postgresql

Once exposed, you can connect your database using the same credentials as above except the IP. This time, use the public IP assigned by the cloud provider to the PostgreSQL instance.

You can find it it with juju status:

user@host:~$
juju status postgresql
...
Unit           Workload  Agent  Machine  Public address  Ports     Message
postgresql/0*  active    idle   0        <public-ip>     5432/tcp  Primary
...
user@host:~$
psql postgresql://<username>:<password>@<public-ip>  :5432/test-db
psql (15.6 (Ubuntu 15.6-0ubuntu0.23.10.1), server 16.9 (Ubuntu 14.12-0ubuntu0.24.04.1))
Type "help" for help.

test-db=>

To close public access, run:

user@host:~$
juju unexpose postgresql

Clean up

Always clean cloud resources that are no longer necessary; they could be costly!

See all controllers in your machine with

user@host:~$
juju controllers
Controller         Model         User   Access     Cloud/Region                Models  Nodes    HA  Version
<controller-name>  <model-name>  admin  superuser  <cloud-name>/<region-name>  1       1      none  3.6.1

The following command will destroy the Juju controller and remove the cloud instance - meaning all your data will be permanently removed:

user@host:~$
juju destroy-controller <controller-name> --destroy-all-models --destroy-storage --force

Next, check and manually delete all unnecessary Google Cloud resources.

Run the following command to show the list of all your GCE instances:

user@host:~$
gcloud compute instances list
NAME           ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
juju-33f662-0  us-east1-b  n1-highcpu-4                10.142.0.17  35.231.246.157  RUNNING
juju-e2b96f-0  us-east1-b  n2d-highcpu-2               10.142.0.18  35.237.64.81    STOPPING
juju-e2b96f-1  us-east1-d  n2d-highcpu-2               10.142.0.19  34.73.238.173   STOPPING

List your Juju credentials:

user@host:~$
juju credentials
...
Client Credentials:
Cloud        Credentials
google       juju-gce-account
...

Remove Google Cloud credentials from Juju:

user@host:~$
juju remove-credential google juju-gce-account

Finally, remove Google Cloud JSON file user credentials to prevent any credential leakage:

user@host:~$
rm -f /var/snap/juju/common/sa-private-key.json