출력을 사용하여 정보 노출

배포를 만들 때 구성, 다른 템플릿의 템플릿 또는 소비할 사용자의 키 속성을 노출하고자 할 수 있습니다. 예를 들어 사용자가 자신의 고유 템플릿을 구성할 때 IP를 쉽게 참조할 수 있도록 템플릿에 생성된 데이터베이스의 IP 주소를 노출해야 할 수 있습니다.

템플릿 또는 구성에 있는 출력 섹션을 사용하여 사용자가 호출할 수 있는 키/값 쌍 목록을 정의할 수 있습니다. 출력 섹션에서는 임의 키를 정의하고 키 값을 참조, 템플릿 속성 또는 환경 변수로 설정합니다. 사용자는 출력을 소비하여 템플릿으로 생성된 리소스에 대한 키 정보에 액세스할 수 있습니다. 예를 들어 데이터베이스를 호스팅하는 인스턴스의 IP 주소를 참조하는 databaseIP라는 출력을 선언할 수 있으며, 사용자는 동일한 배포의 다른 템플릿에서 이 출력을 참조할 수 있습니다.

시작하기 전에

다음은 출력이 포함된 예시 템플릿입니다.

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

출력 섹션에서는 databaseIpdatabasePort 등 속성 두 개를 선언합니다. 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)

출력 선언

outputs: 섹션을 resources: 섹션과 동일한 수준에서 정의하여 템플릿 또는 구성 중 하나에서 출력을 선언합니다. 출력 키는 템플릿 또는 구성 내에서 고유해야 합니다.

예를 들어 샘플 outputs: 섹션은 다음과 같을 수 있습니다.

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

전체 템플릿에서 출력은 다음과 같이 표시됩니다.



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

순환 종속성 방지

2개 이상의 리소스가 서로의 출력에 의존하는 경우에는 템플릿을 만들 때 주의해야 합니다. 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가 2개의 가상 머신 인스턴스인 vm-1 및 vm-2를 만듭니다.
  2. backend.jinja가 vm-3 및 vm-4를 만듭니다.
  3. vm-1이 해당 외부 IP를 출력으로 노출하고 vm-4가 이 출력을 사용합니다.
  4. vm-3가 외부 IP를 출력으로 노출하고 vm-2가 이 출력을 사용합니다.

다음 단계