使用輸出公開資訊

您可以在建立部署作業時公開設定或範本的重要屬性,以供其他範本或使用者使用。例如,您可能會想要公開在範本中建立的資料庫的 IP 位址,以便使用者可以在設定自己的範本時輕鬆地參照該 IP。

您可以使用範本或設定中的「outputs」(輸出) 區段來定義使用者可以呼叫的鍵/值組合清單。您可以在輸出區段中定義任意鍵,並將鍵的值設為參考檔案範本屬性環境變數。使用者可以使用輸出來存取範本所建立資源的相關重要資訊。舉例來說,您可以宣告名為 databaseIP 的輸出,這項輸出會參照託管資料庫的執行個體 IP 位址,使用者則能在同一項部署作業的其他範本中參照該項輸出。

事前準備

範例

以下是含有輸出的範本範例:

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

輸出區段宣告了兩項屬性:databaseIpdatabasePortdatabaseIp 使用的參照會解析為主要執行個體資源的網路 IP 位址,databasePort 則是一個靜態值。在另一個範本中,您可以匯入 mongodb.jinja,將該範本當做類型,然後呼叫輸出。例如:

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)

宣告輸出

在與 resources: 區段相同的層級定義 outputs: 區段,即可在範本或設定中宣告輸出。範本或設定中的輸出鍵不得重複。

例如,範例 outputs: 區段可能如下所示:

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

以下是輸出在完整範本中的可能結果:

{#
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


輸出值可能是:

使用範本中的輸出

如要使用已在範本中定義的輸出,請匯入並使用含有該項輸出的範本來當做類型。舉例來說,如要使用在名為 template_with_outputs.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: 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)


如要呼叫輸出,請使用下列格式:

$(ref.RESOURCE.OUTPUT)
  • RESOURCE 是範本所建立資源的名稱,在上述範例中為 my-first-vm

  • OUTPUT 是在範本中宣告的輸出,在上述範例為 databaseIpdatabasePort。這與您用來宣告參照的語法相同。您也可以參照清單項目,例如 $ref.template.property[0]

Deployment Manager 會在您部署設定時將其展開,並將輸出的參照替換為輸出值。

說明結構定義中的輸出

對於隨附結構定義的範本,您可以進一步詳細說明輸出屬性。Deployment Manager 不會強制執行或驗證輸出區段中的任何資訊,但為了協助採用範本的使用者,使用此區段提供相關輸出的更多資訊可能會有所助益。

在結構定義檔案中,提供與範本中的輸出相符的輸出區段。例如:

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

使用者可以參考結構定義檔案,以便瞭解輸出的用法和類型。

查詢最終輸出值

部署使用輸出的範本之後,您可以查看部署作業的設定配置來瀏覽最終輸出值。最終輸出值由 finalValue 屬性指出。所有輸出值都會列入這個欄位,包括巢狀範本中的輸出值。例如:

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

避免循環相依性

建立範本時請務必小心,不要讓其中的兩個或多個資源依賴彼此的輸出。Deployment Manager 不會防止這種結構,但如果輸出造成循環相依性,部署作業將無法成功執行。例如,Deployment Manager 接受下列程式碼片段,但如果範本的內容造成循環相依性,部署作業將會失敗:

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

以下是會造成部署作業失敗的循環相依性範例,假設 frontend.jinja 和 backend.jinja 如下所示:

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)

請回想一下,這兩個資源都使用了對方資源中的 IP 輸出屬性:

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

但由於兩個屬性都依賴另一個資源的存在,從而產生了循環相依性,因此無法填入任一 IP 值。以下是完全展開的相同範本:

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 將會傳回錯誤:

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

但是,在下列情況中,此範本將可運作:

  1. frontend.jinja 建立了兩個虛擬機器執行個體 (vm-1 和 vm-2)。
  2. backend.jinja 建立了 vm-3 和 vm-4。
  3. vm-1 公開其外部 IP 做為輸出,而 vm-4 使用該輸出。
  4. vm-3 公開一個外部 IP 做為輸出,而 vm-2 使用該輸出。

後續步驟