Creating a Template

You can create a deployment using a configuration at any time, but as you create more complex configurations, you should create and use templates for more flexible and robust configurations.

A template is a separate file from your configuration that defines a set of resources. You import a template into your configuration and Deployment Manager expands the template and inlines the contents during deployment, leaving a cleaner, simpler configuration file. After it has been imported, you can use a template in the same way you use a resource type.

A template can use other templates and Deployment Manager recursively expands templates when they are used in a configuration, so that the final result after templates have been expanded would be as if you had written the configuration without templates. For example, a configuration with templates could look like this:

imports:
- path: vm-template.jinja

resources:
- name: vm-instance
  type: vm-template.jinja

After Deployment Manager expands the templates, the full configuration looks like this, without additional work on your part:

resources:
- name: vm-instance
  type: compute.v1.instance
  properties:
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/family/debian-9
    machineType: https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-f/machineTypes/f1-micro
    networkInterfaces:
    - network: $(ref.a-new-network.selfLink)
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT
    zone: us-central1-f

Next, you will take the configuration you created in step two, Create a Configuration, and create a template from the contents. Then, import and use the template in your configuration to create a new deployment.

At the end, your new deployment contains the same resources as your first deployment but the configuration file will be much simpler.

Writing Jinja2 or Python templates

You can write templates in your choice of Python 2.7 or Jinja2. Python templates are more powerful for complex deployments, and more flexible when your deployments to get more complex over time. If you are familiar with Python, we recommend using Python for your templates.

You can also use the Jinja2 templating language for your templates. With Jinja2, you can write your templates in YAML, and use features such as control structures and expressions to customize the templates.

If you aren't familiar with Python or want to write simple templates without using Python, use Jinja2. The rest of this guide includes examples in both Jinja and Python.

Python templates

If you choose to write templates in Python, your templates must meet these requirements:

  • The template must be written in Python 2.7

  • The template must define a method called GenerateConfig() or generate_config(). If you use both method names in the same template, the generate_config() method will take precedence.

  • The method must return a Python dictionary.

Other than that, it is up to you to generate the contents of your template. For examples of the methods you can use to write a Python template, see Creating a Basic Template.

Create your first template

Make a copy of the resources definition you created in step four, Using References, into a new file called vm-template.[jinja|py]. Choose the appropriate file extension based on whether you want to use Jinja or Python templates. Remember to replace [MY_PROJECT] with your own project ID:

Jinja

{#
Copyright 2016 Google Inc. All rights reserved.
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.
#}

resources:
- name: the-first-vm
  type: compute.v1.instance
  properties:
    zone: us-central1-f
    machineType: https://www.googleapis.com/compute/v1/projects/[MY_PROJECT]/zones/us-central1-f/machineTypes/f1-micro
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/family/debian-9
    networkInterfaces:
    - network: $(ref.a-new-network.selfLink)
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

"""Creates the virtual machine."""

COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/'


def GenerateConfig(unused_context):
  """Creates the first virtual machine."""

  resources = [{
      'name': 'the-first-vm',
      'type': 'compute.v1.instance',
      'properties': {
          'zone': 'us-central1-f',
          'machineType': ''.join([COMPUTE_URL_BASE, 'projects/[MY_PROJECT]',
                                  '/zones/us-central1-f/',
                                  'machineTypes/f1-micro']),
          'disks': [{
              'deviceName': 'boot',
              'type': 'PERSISTENT',
              'boot': True,
              'autoDelete': True,
              'initializeParams': {
                  'sourceImage': ''.join([COMPUTE_URL_BASE, 'projects/',
                                          'debian-cloud/global/',
                                          'images/family/debian-9'])
              }
          }],
          'networkInterfaces': [{
              'network': '$(ref.a-new-network.selfLink)',
              'accessConfigs': [{
                  'name': 'External NAT',
                  'type': 'ONE_TO_ONE_NAT'
              }]
          }]
      }
  }]
  return {'resources': resources}

Create a second template

Create a file named vm-template-2.[jinja|py] and add the following contents. Remember to replace [MY_PROJECT] with your own project ID:

Jinja

{#
Copyright 2016 Google Inc. All rights reserved.
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.
#}

resources:
- name: the-second-vm
  type: compute.v1.instance
  properties:
    zone: us-central1-f
    machineType: https://www.googleapis.com/compute/v1/projects/[MY_PROJECT]/zones/us-central1-f/machineTypes/g1-small
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/family/debian-9
    networkInterfaces:
    - network: $(ref.a-new-network.selfLink)
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

"""Creates the virtual machine."""

COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/'


def GenerateConfig(unused_context):
  """Creates the second virtual machine."""

  resources = [{
      'name': 'the-second-vm',
      'type': 'compute.v1.instance',
      'properties': {
          'zone': 'us-central1-f',
          'machineType': ''.join([COMPUTE_URL_BASE, 'projects/[MY_PROJECT]',
                                  '/zones/us-central1-f/',
                                  'machineTypes/g1-small']),
          'disks': [{
              'deviceName': 'boot',
              'type': 'PERSISTENT',
              'boot': True,
              'autoDelete': True,
              'initializeParams': {
                  'sourceImage': ''.join([COMPUTE_URL_BASE, 'projects/',
                                          'debian-cloud/global',
                                          '/images/family/debian-9'])
              }
          }],
          'networkInterfaces': [{
              'network': '$(ref.a-new-network.selfLink)',
              'accessConfigs': [{
                  'name': 'External NAT',
                  'type': 'ONE_TO_ONE_NAT'
              }]
          }]
      }
  }]
  return {'resources': resources}

Import your templates

Go back to your configuration, two-vms.yaml. At the top of the file, import your template by adding the imports string, followed by the relative path to the template file. Then, replace the properties of your resources with the name of the templates.

Jinja

# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

imports:
- path: vm-template.jinja
- path: vm-template-2.jinja

resources:
- name: vm-1
  type: vm-template.jinja
- name: vm-2
  type: vm-template-2.jinja
- name: a-new-network
  type: compute.v1.network
  properties:
    routingConfig:
      routingMode: REGIONAL
    autoCreateSubnetworks: true

Python

# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

imports:
- path: vm-template.py
- path: vm-template-2.py

resources:
- name: vm-1
  type: vm-template.py
- name: vm-2
  type: vm-template-2.py
- name: a-new-network
  type: compute.v1.network
  properties:
    routingConfig:
      routingMode: REGIONAL
    autoCreateSubnetworks: true

Resource names

When you use a template, your resource names are defined using the name field provided in the template, not the name in the configuration file.

For example, in this case, the virtual machine instances are created using the names in the templates you created, “the-first-vm” and “the-second-vm.” The values “vm-1” and "vm-2," defined in the configuration, are used to name an instantiation of the template, but are not resource names, unless you decide to use environment variables to set both names to be the same.

Save your configuration and deploy it!

gcloud deployment-manager deployments create deployment-with-templates --config two-vms.yaml

View your deployment

gcloud deployment-manager deployments describe deployment-with-templates

Also, you can use the deployment’s manifest to see the original configuration with the templates and the expanded configuration which includes the contents of the templates. Remember, to get a manifest, take the manifest-TIMESTAMP value from the output above, and provide it in the following command:

gcloud deployment-manager manifests describe manifest-TIMESTAMP --deployment deployment-with-templates

Great, you created a deployment using a template! Next, see how to create configurations with templates that call other templates.

Delete Your Deployment

Compute Engine resources incur charges, so you should delete this deployment, as it is no longer necessary for future steps. Deleting this deployment deletes all the resources in this deployment as well. If you leave the deployment around, you will run into conflicts with future examples.

To delete this deployment:

gcloud deployment-manager deployments delete deployment-with-templates

Next: Using Multiple Templates

Related topics

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Cloud Deployment Manager Documentation