Expón información mediante resultados

Cuando creas una implementación, es posible que quieras indicar propiedades clave de las configuraciones o plantillas para que las usen otros usuarios o plantillas. Por ejemplo, podrías exponer la dirección IP de una base de datos creada en la plantilla para que los usuarios puedan hacer referencia a la IP fácilmente cuando configuren sus plantillas.

Puedes usar la sección de resultados en tu plantilla o configuración para definir una lista de pares clave-valor que los usuarios pueden llamar. En la sección de resultados, debes definir las claves arbitrarias y establecer el valor como una referencia, una propiedad de plantilla, o una variable de entorno. Los usuarios pueden usar los resultados para acceder a información clave de los recursos creados por la plantilla. Por ejemplo, puedes declarar un resultado llamado databaseIP que hace referencia a la dirección IP de una instancia que aloja una base de datos. Además, los usuarios podrán hacer referencia a ese resultado en otras plantillas de la misma implementación.

Antes de comenzar

Ejemplo

Esta es una plantilla de ejemplo con resultados:

mongodb.jinja
{% set MASTER = env["name"] + "-" + env["deployment"] + "-mongodb" %}
resources:
- name: {{ MASTER }}
  type: instance
  ...
outputs:
- name: databaseIp
  value: $(ref.{{ MASTER }}.network[0].ip)  # Treated as a string during expansion
- name: databasePort
  value: 88

La sección de resultados declara dos propiedades: databaseIp y databasePort. databaseIp usa una referencia que resuelve la dirección IP de la red del recurso principal, mientras que databasePort es un valor estático. En otra plantilla, puedes importar mongodb.jinja, usar la plantilla como un tipo y llamar a los resultados. Por ejemplo:

imports:
- path: example/path/to/mongodb.jinja
  name: mongodb.jinja

resources:
- name: my_mongo
  type: mongodb.jinja
  properties:
    size: 100

- name: my_instance
  type: compute.v1.instance
  properties:
    
    databaseIp: $(ref.my_mongo.databaseIp)
    databasePort: $(ref.my_mongo.databasePort)

Declara un resultado

Define una sección outputs: en el mismo nivel que la sección resources: para declarar un resultado en una plantilla o una configuración. Las claves de resultado deben ser únicas en la plantilla o configuración:

Por ejemplo, una sección de muestra outputs: podría tener el aspecto siguiente:

...
outputs:
- name: databaseIp
  value: $(ref.my-first-vm.networkInterfaces[0].accessConfigs[0].natIP)
- name: machineType
  value: {{ properties['machineType'] }}
- name: databasePort
  value: 88

Así se verían los resultados en una plantilla completa:

{#
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: my-first-vm
  type: compute.v1.instance
  properties:
    zone: us-central1-a
    machineType: zones/us-central1-a/machineTypes/{{ properties['machineType'] }}
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: projects/debian-cloud/global/images/family/debian-11
    networkInterfaces:
    - network: global/networks/default
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT

# Declare outputs here
outputs:
- name: databaseIp
  value: $(ref.my-first-vm.networkInterfaces[0].accessConfigs[0].natIP)
- name: machineType
  value: {{ properties['machineType'] }}
- name: databasePort
  value: 88


Los valores de resultados pueden ser los siguientes:

Usa resultados de plantillas

Para usar un resultado definido en una plantilla, debes importar y usar la plantilla con el resultado como un tipo. Por ejemplo, si quieres usar resultados definidos en una plantilla llamada template_with_outputs.jinja, deben importarse y usarse para crear un recurso:

# 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: template_with_outputs.jinja
  name: template.jinja

resources:
- name: my-first-vm
  type: template.jinja
  properties:
    machineType: n1-standard-1

outputs:
- name: databaseIp
  value: $(ref.my-first-vm.databaseIp)
- name: machineType
  value: $(ref.my-first-vm.machineType)
- name: databasePort
  value: $(ref.my-first-vm.databasePort)


Para llamar a un resultado, usa el formato siguiente:

$(ref.RESOURCE.OUTPUT)
  • RESOURCE es el nombre del recurso creado por la plantilla. En el ejemplo anterior, sería my-first-vm.

  • OUTPUT es el resultado declarado en la plantilla. En el ejemplo anterior, sería databaseIp y databasePort. Es la misma sintaxis que usas para declarar referencias. También puedes hacer referencia a elementos de la lista, por ejemplo: $ref.template.property[0].

Cuando implementes la configuración, Deployment Manager la expande y reemplaza las referencias a los resultados con los valores de estos.

Describe los resultados en esquemas

En las plantillas que tienen esquemas complementarios, puedes describir las propiedades de los resultados en más detalle. Deployment Manager no aplica ni valida la información de la sección de resultados, pero puede ser muy útil usar esta sección para brindar más información sobre los resultados relevantes, lo que beneficiará a los usuarios que usen tus plantillas.

En el archivo de esquema, proporciona la sección de resultados que coincida con el resultado de tu plantilla. Por ejemplo:

...
outputs:
  databaseIp:
    description: Reference to ip address of your new cluster
    type: string
  databasePort:
    description: Port to talk on
    type: integer

Los usuarios pueden hacer referencia al archivo de esquema a fin de comprender el uso y tipo de tus resultados.

Busca los valores finales de los resultados

Después de que implementes las plantillas en las que se usan estos resultados, revisa el diseño de la configuración para ver los valores finales de los resultados de la implementación. Los valores finales de salida se indican con la propiedad finalValue. Este campo incluye todos los valores de resultados, incluidos los de plantillas anidadas. Por ejemplo:

layout: |
  resources:
  - name: vm_template
    outputs:
    - finalValue: 104.197.69.69
      name: databaseIp
      value: $(ref.vm-test.networkInterfaces[0].accessConfigs[0].natIP)
    properties:
      zone: us-central1-a
    resources:
    - name: datadisk-example-instance
      type: compute.v1.disk
    - name: vm-test
      type: compute.v1.instance
    type: vm_template.jinja
name: manifest-1455057116997

Evita las dependencias circulares

Ten cuidado cuando crees plantillas en las que dos o más recursos se basan en resultados de la otra plantilla. Deployment Manager no omite esta estructura, pero si los resultados causan una dependencia circular, la implementación no tendrá éxito. Por ejemplo, Deployment Manager acepta el fragmento siguiente, pero si los contenidos de las plantillas generan una dependencia circular, la implementación fallará:

resources:
- name: frontend
  type: frontend.jinja
  properties:
    ip: $(ref.backend.ip)
- name: backend
  type: backend.jinja
  properties:
    ip: $(ref.frontend.ip)

Como ejemplo de una dependencia circular en la que falla la implementación, puedes suponer que tanto frontend.jinja como backend.jinja se ven así:

resources:
- name: {{ env['name'] }}
  type: compute.v1.instance
  properties:
    zone: us-central1-f
    ...
    networkInterfaces:
    - network: global/networks/default
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT
    metadata:
      items:
      - key: startup-script
        value: |
          #!/bin/bash
          export IP={{ properties["ip"] }}
      ...

outputs:
- name: ip
  value: $(ref.{{ env['name'] }}.networkInterfaces[0].accessConfigs[0].natIP)

Recuerda que ambos recursos usan la propiedad del resultado de IP del recurso contrario:

resources:
- name: frontend
  type: frontend.jinja
  properties:
    ip: $(ref.backend.ip)
- name: backend
  type: backend.jinja
  properties:
    ip: $(ref.frontend.ip)

Sin embargo, no se puede propagar ninguno de los valores IP porque ambas propiedades se basan en la existencia del otro recurso, lo que crea una dependencia circular. Esta es la misma plantilla expandida en su totalidad:

resources:
- name: frontend
  type: compute.v1.instance
  properties:
    zone: us-central1-f
    ...
    networkInterfaces:
    - network: global/networks/default
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT
    metadata:
      items:
      - key: startup-script
        value: |
          #!/bin/bash
          export IP=$(ref.backend.networkInterfaces[0].accessConfigs[0].natIP)
- name: backend
  type: compute.v1.instance
  properties:
    zone: us-central1-f
    ...
    networkInterfaces:
    - network: global/networks/default
      accessConfigs:
      - name: External NAT
        type: ONE_TO_ONE_NAT
    metadata:
      items:
      - key: startup-script
        value: |
          #!/bin/bash
          export IP=$(ref.frontend.networkInterfaces[0].accessConfigs[0].natIP)

Deployment Manager muestra un error si intentas ejecutar la configuración:

 code: u'CONDITION_NOT_MET'
 message: u'A dependency cycle was found amongst backend, frontend.'>]>

Sin embargo, la plantilla funcionaría en los siguientes casos:

  1. frontend.jinja creó dos instancias de máquina virtual: vm-1 y vm-2.
  2. backend.jinja creó vm-3 y vm-4.
  3. vm-1 expuso su IP externa como un resultado y vm-4 usó ese resultado.
  4. vm-3 expuso una IP externa como un resultado y vm-2 usó ese resultado.

¿Qué sigue?