<a id="cloud-gce"></a>

# Google GCE

In Juju, [Google GCE](https://cloud.google.com/compute/docs) is a [machine cloud](https://documentation.ubuntu.com/juju/4.0/reference/cloud.md#machine-cloud) and works as described below.

#### NOTE
This reference assumes basic familiarity with Juju. If you are new to Juju, start with the [Tutorial](https://documentation.ubuntu.com/juju/4.0/tutorial.md#tutorial), then use this page together with the generic materials it links to and/or consult the [example workflows](#gce-appendix-example-workflows).

<a id="gce-requirements"></a>

## Requirements

Juju needs Service Account Key Admin, Compute Instance Admin, and Compute Security Admin to create and manage the GCE resources used during cloud registration and bootstrap.

See more: [Google | Compute Engine IAM roles and permissions](https://cloud.google.com/compute/docs/access/iam)

<a id="gce-cloud-concepts"></a>

## Concepts

The following table shows how GCE abstractions map to Juju concepts:

| GCE                                                                                  | Juju                                                                                              |
|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| [Project](https://cloud.google.com/resource-manager/docs/creating-managing-projects) | Administrative boundary for [models](https://documentation.ubuntu.com/juju/4.0/reference/model.md#model) (roughly) |
| [Compute Engine instance](https://cloud.google.com/compute/docs/instances)           | [machine](https://documentation.ubuntu.com/juju/4.0/reference/machine.md#machine)                                    |
| Process on a VM                                                                      | [unit](https://documentation.ubuntu.com/juju/4.0/reference/unit.md#unit)                                          |
| Managed set of workload instances                                                    | [application](https://documentation.ubuntu.com/juju/4.0/reference/application.md#application)                            |
| [Persistent Disk](https://cloud.google.com/compute/docs/disks)                       | [storage](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage)                                    |
| [VPC/subnet](https://cloud.google.com/vpc/docs)                                      | Network spaces and placement targets (roughly)                                                    |

<a id="gce-cloud"></a>

## The cloud

See also: [Cloud](https://documentation.ubuntu.com/juju/4.0/reference/cloud.md#cloud), [Juju | Manage clouds](https://documentation.ubuntu.com/juju/4.0/howto/manage-clouds.md#manage-clouds), [Terraform Provider for Juju | Manage clouds](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-clouds/#manage-clouds)

As for all machine clouds, the cloud is registered in Juju via a cloud definition, stored in `clouds.yaml` on the client (on Linux: `~/.local/share/juju/clouds.yaml`) and following this schema:

```yaml
clouds:
  <cloud-name>:  # Predefined name
    type: gce
    auth-types:
      - <auth-type>                # See Authentication types below
    regions:
      <region-name>:               # e.g. us-central1
        endpoint: <endpoint>       # Region-specific GCE API endpoint
    config:                        # Optional: model config defaults
      <config-key>: <value>        # See Configuration keys below
```

<a id="gce-credential"></a>

## Credentials

See also: [Credential](https://documentation.ubuntu.com/juju/4.0/reference/credential.md#credential), [Juju | Manage credentials](https://documentation.ubuntu.com/juju/4.0/howto/manage-credentials.md#manage-credentials), [Terraform Provider for Juju | Manage credentials](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-credentials/#manage-credentials)

As for all machine clouds, credentials are stored in `credentials.yaml` on the client and follow this schema:

```yaml
credentials:
  google                         # Predefined cloud name for GCE
    <credential-name>:             # User-defined credential name
      auth-type: <auth-type>       # oauth2 | jsonfile | service-account (see Authentication types below)
      <attribute>: <value>         # Auth-type-specific attributes (see below)
```

<a id="gce-credential-authentication-types"></a>

### Authentication types

Google GCE supports the following authentication types:

<a id="gce-credential-oauth2"></a>

#### `oauth2`

Attributes:

- `client-id`: Client ID (required).
- `client-email`: Client e-mail address (required).
- `private-key`: Client secret (required).
- `project-id`: Project ID (required).

<a id="gce-credential-jsonfile"></a>

#### `jsonfile`

Attributes:

- `file`: Path to the `.json` file containing a service account key for your project (required).

**Auto-detection:** If `GOOGLE_APPLICATION_CREDENTIALS` is set to a valid file path, `juju autoload-credentials` detects this credential type automatically. If `CLOUDSDK_COMPUTE_REGION` is also set, it becomes the default region for the detected credential.

See more: [Authenticate with a credential and a service account](#gce-appendix-workflow-2)

<a id="gce-credential-service-account"></a>

#### `service-account`

**Requirements:**

- Juju 3.6+
- A service account with sufficient privileges:
  - `https://www.googleapis.com/auth/compute`
  - `https://www.googleapis.com/auth/devstorage.full_control`
- The `add-credential` steps must be run from a jump host running in Google Cloud to reach the cloud metadata endpoint.

See more: [Authenticate with a service account (recommended)](#gce-appendix-workflow-1)

<a id="gce-controller"></a>

## Controllers

See also: [Controller](https://documentation.ubuntu.com/juju/4.0/reference/controller.md#controller), [Juju | Manage controllers](https://documentation.ubuntu.com/juju/4.0/howto/manage-controllers.md#manage-controllers), [Terraform Provider for Juju | Manage controllers](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-controllers/#manage-controllers)

<a id="gce-controller-bootstrap-behavior"></a>

### Bootstrap behavior

Creates a controller instance on GCE in a single API request. Juju creates the required GCE resources directly – no templates.

<a id="gce-controller-resources-created-at-bootstrap"></a>

### Resources created at bootstrap

The controller runs on a GCE instance provisioned using the same mechanisms as workload machines – see [Resources created per machine](#gce-machine-resources-created-per-machine) for the full per-machine resource model. Controller-specific differences are noted below.

**Compute**

- **Compute instance**: Ubuntu LTS instance. Machine type selected based on hardware constraints (default `n1-standard-1`). Instance creation includes boot disk inline.
- **Service account** (optional): Attached if credential type is `service-account` or `instance-role` constraint specified. Scopes: `compute`, `devstorage.full_control`. Enables metadata service credentials.
- **Instance metadata**: Tagged with `juju-controller-uuid`, `juju-is-controller: true`, and bootstrap metadata.
- **Instance tags**: `juju-<model-uuid>` (for firewall targeting), hostname.

**Networking**

- **Network interface**: Primary interface in specified VPC/subnet or default network. Private IP auto-assigned from subnet CIDR. External NAT with public IP if `allocate-public-ip=true` (default).
- **Firewall rule**: Global VPC firewall rule `juju-<model-uuid>` targeting instances tagged `juju-<model-uuid>`. Created with no initial rules; rules are added dynamically via `open-ports`.

**Storage**

- **Boot disk**: Persistent disk, device name auto-assigned. Default 10 GiB minimum (expanded if constraint/image requires). Type `pd-standard` (default) or `pd-ssd`. Auto-deleted when instance terminates.

<a id="gce-model"></a>

## Models

See also: [Model](https://documentation.ubuntu.com/juju/4.0/reference/model.md#model), [Juju | Manage models](https://documentation.ubuntu.com/juju/4.0/howto/manage-models.md#manage-models), [Terraform Provider for Juju | Manage models](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-models/#manage-models)

<a id="gce-model-configuration-keys"></a>

### Configuration keys

Google GCE supports the following [cloud-specific model configuration keys](https://documentation.ubuntu.com/juju/4.0/reference/configuration/list-of-model-configuration-keys.md#model-config-cloud-specific-key):

**Networking**

<a id="gce-model-vpc-id"></a>
- **`vpc-id`**: Use a specific VPC network. When not specified, Juju requires a default VPC to be available for the account. Example: `vpc-a1b2c3d4`. Type: `string`. Default: `""`. Immutable.

<a id="gce-model-vpc-id-force"></a>
- **`vpc-id-force`**: Force Juju to use the GCE VPC ID specified with `vpc-id`, when it fails the minimum validation criteria. Type: `bool`. Default: `false`. Immutable.

**Storage**

<a id="gce-model-base-image-path"></a>
- **`base-image-path`**: Base path to look for machine disk images. Type: `string`. Default: none.

<a id="gce-machine"></a>

## Machines

See also: [Machine](https://documentation.ubuntu.com/juju/4.0/reference/machine.md#machine), [Juju | Manage machines](https://documentation.ubuntu.com/juju/4.0/howto/manage-machines.md#manage-machines), [Terraform Provider for Juju | Manage machines](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-machines/#manage-machines)

<a id="gce-machine-constraints"></a>

### Constraints

Google GCE supports the following [constraints](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint):

#### NOTE
The constraints `instance-type` and `[cores, cpu-power, mem]` are mutually exclusive.

**Compute**

- [arch](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-arch)
- [container](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-container)
- [cores](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-cores)
- [cpu-power](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-cpu-power)
- [image-id](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-image-id). Starting with Juju 3.6.28. Valid values: A GCE image ID.
- [instance-role](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-instance-role). Valid values: A service account email.
- [instance-type](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-instance-type). Valid values: Any GCE machine type. Default: `n1-standard-1`.
- [mem](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-mem)

**Networking**

- [allocate-public-ip](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-allocate-public-ip)
- [spaces](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-spaces)
- [zones](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-zones)

**Storage**

- [root-disk](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-root-disk)
- [root-disk-source](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-root-disk-source)

<a id="gce-machine-placement-directives"></a>

### Placement directives

Google GCE supports the following [placement directives](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive):

- [<machine>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-machine)
- [subnet=<subnet>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-subnet): Matches subnet by name or CIDR range.
- [zone=<zone>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-zone)

<a id="gce-machine-resources-created-per-machine"></a>

### Resources created per machine

Applies to all machines, including controller machines. Controller-specific defaults are documented in [Resources created at bootstrap](#gce-controller-resources-created-at-bootstrap).

**Compute**

- **Compute instance**: Instance with name `<model-uuid><machine-id>`. Machine type selected based on constraints. Status sequence: `PROVISIONING` → `STAGING` → `RUNNING`.
- **Service account** (optional): Attached if `instance-role` constraint specified. Enables metadata service credentials.
- **Instance metadata**: Bootstrap metadata, controller UUID, and model UUID.
- **Instance tags**: `juju-<model-uuid>`, hostname (for firewall targeting).

**Networking**

- **Network interface**: Primary interface in VPC/subnet. Private IP auto-assigned. External NAT with public IP if `allocate-public-ip=true`.

**Storage**

- **Boot disk**: Persistent disk attached inline. Size: max(10 GiB, constraint, image minimum). Type: `pd-standard` (default) or `pd-ssd` via `root-disk-source` constraint. Auto-deleted when instance terminates.
- **Additional persistent disks** (optional): Created when storage specified via storage constraints. Must reside in same zone as instance.
- **Disk labels**: `juju-model`, `juju-controller` (set via upgrade step).

<a id="gce-machine-networking-behavior"></a>

### Networking behavior

- **VPC requirements**: If you use a VPC, Juju validates the configuration before bootstrap. A valid VPC must have: at least one subnet with status `READY`, OR `AutoCreateSubnetworks=true` enabled; SSH access enabled (firewall rule for port 22).
- **VPC/subnet selection**: Uses VPC configured via `vpc-id` model config or default network (`global/networks/default`). Subnet selection driven by `zone` or `subnet` placement directives. Random selection from available subnets in region. Space constraints filter to valid subnets.
- **Public IP handling**: Assigned via external NAT (`ONE_TO_ONE_NAT`) if `allocate-public-ip=true` (default). Ephemeral public IP auto-assigned by GCE.
- **Firewall rules**: Environment-level rule (`juju-<model-uuid>`) allows traffic between instances with same tag. Per-machine rules target instance by hostname tag. User-defined port rules via `open-ports` create additional firewall rules.
- **Address resolution**: Returns private address (cloud-local scope, from subnet CIDR) and public address (if NAT configured).

<a id="gce-machine-storage-behavior"></a>

### Storage behavior

See also: [gce](#storage-provider-gce) for the GCE storage provider configuration options.

- **Boot disk**: Persistent disk, type `pd-standard` by default. Configurable via `root-disk-source` constraint (specify a storage pool with `disk-type`).
- **Additional disks**: Must reside in the same availability zone as the instance.
- **Auto-deletion**: Boot disks are auto-deleted when the instance terminates.

<a id="gce-storage"></a>

## Storage

See also: [Storage](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage), [Juju | Manage storage](https://documentation.ubuntu.com/juju/4.0/howto/manage-storage.md#manage-storage)

<a id="gce-storage-providers"></a>

### Storage providers

In addition to generic storage providers, Google GCE provides the following [cloud-specific storage providers](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage-provider-cloud-specific):

<a id="storage-provider-gce"></a>

#### `gce`

**Type:** GCE persistent disks

**Configuration options:**

- `disk-type`: Disk type. Valid values: `pd-standard` (default), `pd-ssd`, `pd-balanced`, `pd-extreme`, `hyperdisk-balanced`, `hyperdisk-balanced-high-availability`, `hyperdisk-extreme`, `hyperdisk-ml`, `hyperdisk-throughput`.

<a id="gce-appendix-example-workflows"></a>

## Appendix: Example workflows

<a id="gce-appendix-workflow-1"></a>

### Authenticate with a service account (recommended)

**Requirements:**

- Juju 3.6+
- A service account with sufficient privileges (see `service-account` authentication type above).
- The `add-credential` steps must be run from a jump host in Google Cloud to reach the metadata endpoint.

**Steps:**

1. Run `juju add-credential google`; choose `service-account`; supply the service account email.
2. Bootstrap as usual.

#### TIP
With this workflow you avoid storing credential secrets in either your Juju client or controller. The user running `add-credential`/`bootstrap` doesn’t need credential secrets.

#### TIP
To configure workload machines to use a different (less privileged) service account, use the `instance-role` constraint. This can be set on the model to apply to all (non-controller) machines.

<a id="gce-appendix-workflow-2"></a>

### Authenticate with a credential and a service account

**Requirements:**

- Juju 3.6+
- A service account with sufficient privileges (see `service-account` authentication type above).

**Steps:**

1. Bootstrap with the arg `--bootstrap-constraints="instance-role=<your-service-account-email>"`.
2. The controller machines will be created and attached to that service account.
3. To use the project’s default service account, set `instance-role=auto` instead.

#### TIP
To configure workload machines to use a different (less privileged) service account, use the `instance-role` constraint. This can be set on the model to apply to all (non-controller) machines.
