您可以在建立部署作業時公開設定或範本的重要屬性,以供其他範本或使用者使用。例如,您可能會想要公開在範本中建立的資料庫的 IP 位址,以便使用者可以在設定自己的範本時輕鬆地參照該 IP。
您可以使用範本或設定中的「outputs」(輸出) 區段來定義使用者可以呼叫的鍵/值組合清單。您可以在輸出區段中定義任意鍵,並將鍵的值設為參考檔案、範本屬性或環境變數。使用者可以使用輸出來存取範本所建立資源的相關重要資訊。舉例來說,您可以宣告名為 databaseIP
的輸出,這項輸出會參照託管資料庫的執行個體 IP 位址,使用者則能在同一項部署作業的其他範本中參照該項輸出。
事前準備
- 如要使用本指南提供的指令列範例,請安裝 `gcloud` 指令列工具。
- 如要使用本指南提供的 API 範例,請設定 API 存取權。
- 瞭解如何建立基本設定。
範例
以下是含有輸出的範本範例:
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
輸出區段宣告了兩項屬性:databaseIp
和 databasePort
。databaseIp
使用的參照會解析為主要執行個體資源的網路 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
以下是輸出在完整範本中的可能結果:
輸出值可能是:
使用範本中的輸出
如要使用已在範本中定義的輸出,請匯入並使用含有該項輸出的範本來當做類型。舉例來說,如要使用在名為 template_with_outputs.jinja
的範本中定義的輸出,您必須將其匯入並用於建立資源:
如要呼叫輸出,請使用下列格式:
$(ref.RESOURCE.OUTPUT)
RESOURCE
是範本所建立資源的名稱,在上述範例中為my-first-vm
。OUTPUT
是在範本中宣告的輸出,在上述範例為databaseIp
和databasePort
。這與您用來宣告參照的語法相同。您也可以參照清單項目,例如$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.'>]>
但是,在下列情況中,此範本將可運作:
- frontend.jinja 建立了兩個虛擬機器執行個體 (vm-1 和 vm-2)。
- backend.jinja 建立了 vm-3 和 vm-4。
- vm-1 公開其外部 IP 做為輸出,而 vm-4 使用該輸出。
- vm-3 公開一個外部 IP 做為輸出,而 vm-2 使用該輸出。