Using Multiple Templates

Next, create a template that imports another template. In this example, you further deconstruct the configuration you originally created (two-vms.yaml) and create a template for a network and a template for a firewall rule to allow incoming traffic on port 80.

Then, you will move the whole deployment into a single combined template; at the end of this page, your configuration only needs to call a single template to create a deployment with all of these resources.

Create a template for a network

Create a new template file named network-template.[jinja|py] with the following network definition:

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: a-new-network
  type: compute.v1.network
  properties:
    IPv4Range: 10.0.0.1/16

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 network."""


def GenerateConfig(unused_context):
  """Creates the network."""

  resources = [{
      'name': 'a-new-network',
      'type': 'compute.v1.network',
      'properties': {
          'IPv4Range': '10.0.0.1/16'
      }
  }]
  return {'resources': resources}

Create a template for a firewall

Create a template for a new firewall rule that allows TCP traffic from port 80. Call the file firewall-template.[jinja|py]:

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: a-firewall-rule
  type: compute.v1.firewall
  properties:
    network: $(ref.a-new-network.selfLink)
    sourceRanges: ["0.0.0.0/0"]
    allowed:
    - IPProtocol: TCP
      ports: ["80"]

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 firewall."""


def GenerateConfig(unused_context):
  """Creates the firewall."""

  resources = [{
      'name': 'a-firewall-rule',
      'type': 'compute.v1.firewall',
      'properties': {
          'network': '$(ref.a-new-network.selfLink)',
          'sourceRanges': ['0.0.0.0/0'],
          'allowed': [{
              'IPProtocol': 'TCP',
              'ports': [80]
          }]
      }
  }]
  return {'resources': resources}

Notice that a template can use references as well; as long as the final configuration contains a network named a-new-network, the references are valid.

Create a template that uses the network, firewall, and virtual machine templates

Create a file named compute-engine-template.[jinja|py]. Add the following to the file (note that the resource names are arbitrary because Deployment Manager names the resources based on the names in the base 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.
#}

resources:
- name: vm-1
  type: vm-template.jinja
- name: vm-2
  type: vm-template-2.jinja
- name: network-1
  type: network-template.jinja
- name: firewall-1
  type: firewall-template.jinja

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 Compute Engine."""


def GenerateConfig(unused_context):
  """Creates the Compute Engine with network and firewall."""

  resources = [{
      'name': 'vm-1',
      'type': 'vm-template.py'
  }, {
      'name': 'vm-2',
      'type': 'vm-template-2.py'
  }, {
      'name': 'network-1',
      'type': 'network-template.py'
  }, {
      'name': 'firewall-1',
      'type': 'firewall-template.py'
  }]
  return {'resources': resources}

Create the configuration

Create a configuration that uses the templates you just create. Create a file named config-with-many-templates.yaml and add the following content to the configuration:

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
- path: network-template.jinja
- path: firewall-template.jinja
- path: compute-engine-template.jinja

resources:
- name: compute-engine-setup
  type: compute-engine-template.jinja

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
- path: network-template.py
- path: firewall-template.py
- path: compute-engine-template.py

resources:
- name: compute-engine-setup
  type: compute-engine-template.py

Notice that even though the configuration didn’t directly call the other templates, you must still import them along with the compute-engine-template.jinja file. This is because the compute-engine-template.jinja file depends on the rest of the templates to be valid.

Also, it’s not used here, but you can name your imports with an optional name field, which is applied as the name of the template and used as the resource type in the rest of the file. The name field is useful when you have a template that is stored in a different directory than the current file and you don’t want to have to include the fully-qualified file path as the template name. For example:

imports:
- path: a/path/to/templates/vm-template.jinja
  name: a-vm-template.jinja

This allows you to use a-vm-template.jinja as the type, rather than the full path:

resources:
- name: this-is-just-an-example
  type: a-vm-template.jinja

Save your configuration and deploy it

gcloud deployment-manager deployments create deployment-with-many-templates \
  --config config-with-many-templates.yaml

See your deployment

gcloud deployment-manager deployments describe deployment-with-many-templates

You can also list your resources through the Compute Engine API to confirm the resources exist:

To get information about the instances:

gcloud compute instances list # List instances
gcloud compute instances describe the-first-vm

To get information about the network:

gcloud compute networks list # List networks
gcloud compute networks describe a-new-network

To get information about the firewall rule:

gcloud compute firewall-rules list # List firewall rules

Next, lets replace some of the more rigid parts of the templates with custom template and environment variables.

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-many-templates

Next: Using Template and Environment Variables

Related topics

Was this page helpful? Let us know how we did:

Send feedback about...

Cloud Deployment Manager Documentation