Google Cloud Platform

This document describes the process for creating and managing a customer private cloud on the Google Cloud Platform (GCP).

Service Account

Telestream Cloud uses a GCP service account to create and manage a customer private cloud. A service account is identified by an email address of the form:

[email protected]

where project-id identifies the Telestream Cloud GCP project and service-account-name identifies the private cloud management account (the service account address will provided on request).

Create the IAM Roles

Using the GCP console, the command line interface (CLI) or Terraform scripts the customer creates Identify and Access Management (IAM) roles to delegate specific permissions to the Telestream Cloud service account.

There are three roles that need to be created by the customer:

bootstrap

The bootstrap roles allows the Telestream Cloud service account to create a private cloud within the customer GCP project. This role requires the following permissions:

compute.firewalls.create
compute.firewalls.get
compute.networks.create
compute.networks.get
compute.networks.list
compute.networks.updatePolicy
compute.subnetworks.create
compute.subnetworks.get

Note that the customer should remove this role from the service account once the private cloud has been created. Alternatively Telestream can provide a Terraform script that the customer can use to create a private cloud in their account.

autoscaling

The autoscaling role allows the Telestream Cloud service account to create and delete compute instances within the private cloud. This role requires the following permissions:

compute.disks.create
compute.disks.setLabels
compute.instances.create
compute.instances.delete
compute.instances.get
compute.instances.list
compute.instances.setMetadata
compute.instances.setServiceAccount
compute.instances.setTags
compute.subnetworks.use
compute.subnetworks.useExternalIp

instance

The instance role allows a compute instance to create additional block storage if required by a specific job. The role is assigned to the instance by autoscaler. This role requires the following permissions:

compute.disks.create
compute.disks.delete
compute.disks.get
compute.disks.list
compute.disks.setLabels
compute.disks.use
compute.instances.attachDisk
compute.instances.detachDisk
compute.instances.get
compute.regions.list
compute.zones.list
iam.serviceAccounts.actAs

Terraform

The main.tf script defines the bootstrap, autoscaling and instance service account names:

variable project {
  type = string
}

locals {
  telestream_autoscaling_service_account = "telestream-autoscaling@telestream-cloud-services.iam.gserviceaccount.com"
  telestream_bootstrap_service_account = "telestream-bootstrap@telestream-cloud-services.iam.gserviceaccount.com"
  instance_service_account = "telestream-instance"
}

provider "google" {
  project = var.project
}

bootstrap

The bootstrap.tf script creates the bootstrap role and user:

resource "google_project_iam_custom_role" "bootstrap-role" {
  role_id = "telestream_bootstrap"
  title = "Telestream Bootstrap"

  permissions = [
    "compute.firewalls.create",
    "compute.firewalls.get",
    "compute.networks.create",
    "compute.networks.get",
    "compute.networks.list",
    "compute.networks.updatePolicy",
    "compute.subnetworks.create",
    "compute.subnetworks.get",
  ]
}


output "bootstrap-role" {
  value = google_project_iam_custom_role.bootstrap-role.id
}

resource "google_project_iam_member" "bootstrap-user" {
  project = var.project
  role = google_project_iam_custom_role.bootstrap-role.id
  member = "serviceAccount:${local.telestream_bootstrap_service_account}"
}

output "bootstrap-user" {
  value = google_project_iam_member.bootstrap-user.id
}

autoscaling

The autoscaling.tf script creates the autoscaling role and user:

resource "google_project_iam_custom_role" "autoscaling-role" {
  role_id = "telestream_autoscaling"
  title = "Telestream Autoscaling"

  permissions = [
    "compute.disks.create",
    "compute.disks.setLabels",

    "compute.instances.create",
    "compute.instances.delete",
    "compute.instances.list",
    "compute.instances.get",
    "compute.instances.setMetadata",
    "compute.instances.setServiceAccount",
    "compute.instances.setTags",

    "compute.subnetworks.use",
    "compute.subnetworks.useExternalIp",
  ]

}

output "autoscaling-role" {
  value = google_project_iam_custom_role.autoscaling-role.id
}

resource "google_project_iam_member" "autoscaling-user" {
  project = var.project
  role = google_project_iam_custom_role.autoscaling-role.id
  member = "serviceAccount:${local.telestream_autoscaling_service_account}"

}

output "autoscaling-user" {
  value = google_project_iam_member.autoscaling-user.id
}

instance

The instance.tf script creates the instance role and service account:

resource "google_project_iam_custom_role" "instance-role" {
  role_id = "telestream_instance"
  title = "Telestream Instance"

  permissions = [
    "compute.disks.create",
    "compute.disks.delete",
    "compute.disks.get",
    "compute.disks.list",
    "compute.disks.setLabels",
    "compute.disks.use",

    "compute.instances.attachDisk",
    "compute.instances.detachDisk",
    "compute.instances.get",

    "compute.regions.list",

    "compute.zones.list",

    "iam.serviceAccounts.actAs",
  ]
}


output "instance-role" {
  value = google_project_iam_custom_role.instance-role.id
}

# Create instance role
resource "google_service_account" "instance-service-account" {
  project = var.project
  account_id = local.instance_service_account
}

output "instance-service-account" {
  value = google_service_account.instance-service-account.email
}

# Set permissions for instance service account, otherwise it will have no permissions
resource "google_project_iam_binding" "project" {
  project = var.project
  role = google_project_iam_custom_role.instance-role.id

  members = [
    "serviceAccount:${google_service_account.instance-service-account.email}"
  ]
}

# Allow autoscaling user to use instance role
resource "google_service_account_iam_binding" "instance-binding" {
  service_account_id = google_service_account.instance-service-account.name
  role = google_project_iam_custom_role.instance-role.id

  members = [
    google_project_iam_member.autoscaling-user.member,
  ]
}