创建部署时,您可能希望公开自己配置或模板的关键属性以供其他模板或用户使用。例如,您可能希望公开在模板中创建的数据库的 IP 地址,以便用户在配置自己的模板时可以轻松引用 IP。
您可以使用模板或配置中的输出部分来定义用户可以调用的键/值对列表。在 outputs 部分中,您可以定义任意键并将键的值设置为引用、模板属性或环境变量。用户可以使用输出来访问模板所创建资源的关键信息。例如,您可以声明一个名为 databaseIP
的输出,该输出引用托管数据库的实例的 IP 地址,用户可以在同一部署的其他模板中引用该输出。
准备工作
- 如果要使用本指南中的命令行示例,请安装 “gcloud” 命令行工具。
- 如果希望使用本指南中的 API 示例,请设置 API 访问权限。
- 了解如何创建基本配置。
示例
这是一个含 outputs 的示例模板:
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
outputs 部分声明了两个属性: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 使用。