Skip to content

Commit

Permalink
docs(samples): Adding samples for instance from template creation (#159)
Browse files Browse the repository at this point in the history
* docs(samples): Adding samples for instance from template creation
  • Loading branch information
m-strzelczyk authored Nov 24, 2021
1 parent ac2cbda commit 143b02d
Show file tree
Hide file tree
Showing 2 changed files with 233 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START compute_instances_create_from_template]
# [START compute_instances_create_from_template_with_overrides]
from google.cloud import compute_v1
# [END compute_instances_create_from_template_with_overrides]


def create_instance_from_template(
project_id: str, zone: str, instance_name: str, instance_template_url: str
) -> compute_v1.Instance:
"""
Creates a Compute Engine VM instance from an instance template.
Args:
project_id: ID or number of the project you want to use.
zone: Name of the zone you want to check, for example: us-west3-b
instance_name: Name of the new instance.
instance_template_url: URL of the instance template used for creating the new instance.
It can be a full or partial URL.
Examples:
- https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
- projects/project/global/instanceTemplates/example-instance-template
- global/instanceTemplates/example-instance-template
Returns:
Instance object.
"""
operation_client = compute_v1.ZoneOperationsClient()
instance_client = compute_v1.InstancesClient()

instance_insert_request = compute_v1.InsertInstanceRequest()
instance_insert_request.project = project_id
instance_insert_request.zone = zone
instance_insert_request.source_instance_template = instance_template_url
instance_insert_request.instance_resource.name = instance_name

op = instance_client.insert(instance_insert_request)
operation_client.wait(project=project_id, zone=zone, operation=op.name)

return instance_client.get(project=project_id, zone=zone, instance=instance_name)


# [END compute_instances_create_from_template]


# [START compute_instances_create_from_template_with_overrides]
def create_instance_from_template_with_overrides(
project_id: str,
zone: str,
instance_name: str,
instance_template_name: str,
machine_type: str,
new_disk_source_image: str,
) -> compute_v1.Instance:
"""
Creates a Compute Engine VM instance from an instance template, changing the machine type and
adding a new disk created from a source image.
Args:
project_id: ID or number of the project you want to use.
zone: Name of the zone you want to check, for example: us-west3-b
instance_name: Name of the new instance.
instance_template_name: Name of the instance template used for creating the new instance.
machine_type: Machine type you want to set in following format:
"zones/{zone}/machineTypes/{type_name}". For example:
- "zones/europe-west3-c/machineTypes/f1-micro"
- You can find the list of available machine types using:
https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list
newDiskSourceImage: Path the the disk image you want to use for your new
disk. This can be one of the public images
(like "projects/debian-cloud/global/images/family/debian-10")
or a private image you have access to.
For a list of available public images, see the documentation:
http://cloud.google.com/compute/docs/images
Returns:
Instance object.
"""
operation_client = compute_v1.ZoneOperationsClient()
instance_client = compute_v1.InstancesClient()
instance_template_client = compute_v1.InstanceTemplatesClient()

# Retrieve an instance template by name.
instance_template = instance_template_client.get(
project=project_id, instance_template=instance_template_name
)

# Adjust diskType field of the instance template to use the URL formatting required by instances.insert.diskType
# For instance template, there is only a name, not URL.
for disk in instance_template.properties.disks:
if disk.initialize_params.disk_type:
disk.initialize_params.disk_type = (
f"zones/{zone}/diskTypes/{disk.initialize_params.disk_type}"
)

instance = compute_v1.Instance()
instance.name = instance_name
instance.machine_type = machine_type
instance.disks = instance_template.properties.disks

new_disk = compute_v1.AttachedDisk()
new_disk.initialize_params.disk_size_gb = 50
new_disk.initialize_params.source_image = new_disk_source_image
new_disk.auto_delete = True
new_disk.boot = False
new_disk.type_ = compute_v1.AttachedDisk.Type.PERSISTENT

instance.disks.append(new_disk)

instance_insert_request = compute_v1.InsertInstanceRequest()
instance_insert_request.project = project_id
instance_insert_request.zone = zone
instance_insert_request.instance_resource = instance
instance_insert_request.source_instance_template = instance_template.self_link

op = instance_client.insert(instance_insert_request)
operation_client.wait(project=project_id, zone=zone, operation=op.name)

return instance_client.get(project=project_id, zone=zone, instance=instance_name)


# [END compute_instances_create_from_template_with_overrides]
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import uuid

import google.auth
from google.cloud import compute_v1
import pytest

from quickstart import delete_instance
from sample_instance_from_template import (
create_instance_from_template,
create_instance_from_template_with_overrides,
)


PROJECT = google.auth.default()[1]
INSTANCE_ZONE = "us-central1-b"


@pytest.fixture
def instance_template():
disk = compute_v1.AttachedDisk()
initialize_params = compute_v1.AttachedDiskInitializeParams()
initialize_params.source_image = (
"projects/debian-cloud/global/images/family/debian-11"
)
initialize_params.disk_size_gb = 25
disk.initialize_params = initialize_params
disk.auto_delete = True
disk.boot = True

network_interface = compute_v1.NetworkInterface()
network_interface.name = "global/networks/default"

template = compute_v1.InstanceTemplate()
template.name = "test-template-" + uuid.uuid4().hex[:10]
template.properties.disks = [disk]
template.properties.machine_type = "e2-standard-4"
template.properties.network_interfaces = [network_interface]

template_client = compute_v1.InstanceTemplatesClient()
operation_client = compute_v1.GlobalOperationsClient()
op = template_client.insert(project=PROJECT, instance_template_resource=template)
operation_client.wait(project=PROJECT, operation=op.name)

template = template_client.get(project=PROJECT, instance_template=template.name)

yield template

op = template_client.delete(project=PROJECT, instance_template=template.name)
operation_client.wait(project=PROJECT, operation=op.name)


@pytest.fixture()
def autodelete_instance_name():
instance_name = "test-instance-" + uuid.uuid4().hex[:10]
yield instance_name
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)


def test_create_instance_from_template(instance_template, autodelete_instance_name):
instance = create_instance_from_template(
PROJECT, INSTANCE_ZONE, autodelete_instance_name, instance_template.self_link
)

assert instance.name == autodelete_instance_name
assert instance.zone.endswith(INSTANCE_ZONE)


def test_create_instance_from_template_override(
instance_template, autodelete_instance_name
):
image_client = compute_v1.ImagesClient()

image = image_client.get_from_family(project="centos-cloud", family="centos-8")
instance = create_instance_from_template_with_overrides(
PROJECT,
INSTANCE_ZONE,
autodelete_instance_name,
instance_template.name,
f"zones/{INSTANCE_ZONE}/machineTypes/n2-standard-2",
image.self_link,
)

assert instance.name == autodelete_instance_name
assert instance.machine_type.endswith("n2-standard-2")
assert len(instance.disks) == 2

0 comments on commit 143b02d

Please sign in to comment.