Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
HOT: Heat Orchestration Template の書き方
2015-12-24
1
基本
2
HOTとは?
 Heatで利用するシステム構成をデータ構造(YAML)で記述したファ
イルを指す。
 Heat が定めるデータ構造
 YAML形式で記述
 作成するリソース、設定するパラメータなどのシステム構造を定義する。
 多段ネス...
Heatを使うための条件
 イメージ
 cloud-init
 インストールされていなくてもHeatは利用できますが、利用可能であればより
高度な設定が可能です。
 heat-cfntools
 インストールされていなくてもHeatは...
HOTの基本
 OpenStack上で行える操作がほぼ全て行えます。
 例)
 仮想サーバーの作成
 キーペアの作成
 仮想ネットワーク、サブネットの作成
 仮想ルーターの作成、ネットワークとの接続
 Floating IPの作成...
テンプレートに記述できるリソース
 heat resource-type-list コマンドで一覧を確認できます。
 利用できるリソースはHeatのバージョンに依存します。
 またHeatのバージョンによって同じリソースでも仕様が異なって...
テンプレートのバージョン
 Heatはバージョンごとサポートされるリソースと、DSL内関数の機能が異
なっています。
 基本的に新しいHeatは過去のテンプレートバージョンをサポートしています。
 テンプレートの先頭にどのバージョンを利用...
シンプルなテンプレート
 以下は1台のインスタンスを作成するテンプレートです。
 nova boot コマンドと同じようなパラメータを与えています。
 テンプレートはYAMLのデータ構造でシステム全体の構造を定義するのが役割です。
 シ...
スタック
 スタックとはテンプレートから作成されたシステム全体を表すリ
ソースです。
 Heatはこのスタックを操作対象にするテンプレートを記述可能です。
9
heat_template_version: 2015-
04-30
resou...
スタックの状態
 作成されたスタックは状態を持ちます。
 管理するリソースの状態、操作の状況によってスタックは様々
な状態へ変化します。
 以下は状態の一例です。
10
init_in_progress
init_complete
ini...
スタックの状態の基本
 HeatはOpenStackの各APIサーバーと通信してリソースの状
態を取得します。
 つまり、実体のリソースの本当の状態をHeatは知ることはでき
ません。
 例)
 インスタンスをHeatのテンプレートで作...
HOTの構造
 先にシンプルなテンプレート例を紹介しましたが、実際のテン
プレートはもっと多くの情報を含んでいます。
 ここではトップレベルの構造を紹介します。現在のテンプレート
は5つのセクションをテンプレート内に持ちます。
 heat...
テンプレート例
 以下は仮想ルーター、仮想ネットワークを作成・接続し、論理ポートを作
成した後で、インスタンスを一台起動して、Floating IPを与える例です。
13
parameters:
image:
type: string
lab...
Parameters セクション
 定義したパラメーターの値はテンプレート内から get_param
関数で参照可能です。
 パラメーターにはデフォルト値を設定することが可能。
 デフォルト値は、スタック作成時に上書き可能。
14
par...
Resources セクション
 作成するリソースを記述していく。
 リソースは作成する単位ごとに1つのタイプを持つ。
 get_resource, get_attr 関数で他のリソースの値を参照可能。
15
resources:
wai...
Outputs セクション
 作成したスタックの情報を外部に出力する。
 他のプログラムとの連携や、別のテンプレートで仕様する。
16
outputs:
instance_name:
description: Name of the ins...
リソースの依存関係
 Resourcesセクションでは get_resource, get_attr で他のリソースを参照した場合に、Heat側で自動で依存関係が設定されます。
 リソース作成時に、 depend_on パラメーターを与える...
リソースの依存関係
 右下図の依存関係が自動で設定される。
18
private_subnet:
type: OS::Neutron::Subnet
properties:
network_id: { get_resource: privat...
リソースの依存関係
 作成された依存関係
19
OS::Heat::WaitCondition
OS::Heat::WaitConditionHandle
OS::Nova::Server
OS::Neutron::Port
OS::Neut...
発展
20
特殊なリソース
 HOTで記述するリソースは基本的にOpenStackが持つリソー
スが対象になります。
 インスタンス、ネットワーク、ボリューム等々・・・
 しかし、システム構成を記述する場合には、単純にリソースを
配置していくだけでは...
 続く
22
Upcoming SlideShare
Loading in …5
×

Hot の書き方(Template Version 2015-04-30) 前編

14,665 views

Published on

Heat

Published in: Technology

Hot の書き方(Template Version 2015-04-30) 前編

  1. 1. HOT: Heat Orchestration Template の書き方 2015-12-24 1
  2. 2. 基本 2
  3. 3. HOTとは?  Heatで利用するシステム構成をデータ構造(YAML)で記述したファ イルを指す。  Heat が定めるデータ構造  YAML形式で記述  作成するリソース、設定するパラメータなどのシステム構造を定義する。  多段ネスト可能  リソース間の依存関係を定義  暗黙の依存関係  明示的な依存関係  定義された依存関係に基づいてリソースの作成順序が決まる  依存関係がないものは平行で作成される  作成された全てのリソースは「状態」を持つ  Heatが検知する状態  ユーザーが外部から与える状態 3
  4. 4. Heatを使うための条件  イメージ  cloud-init  インストールされていなくてもHeatは利用できますが、利用可能であればより 高度な設定が可能です。  heat-cfntools  インストールされていなくてもHeatは利用できますが、利用可能であればより 高度な設定が可能です。  userdata で 連携を行うため cloud-init が導入されていることが前提です。  ネットワーク  Heat管理下で作成するインスタンスは外部ネットワーク(Heatのエン ドポイント)へ接続できる事が推奨  閉じたネットワークでも利用可能だが、一部の機能が制限される。  これは状態の通知がエンドポイント経由で行われるため。 4
  5. 5. HOTの基本  OpenStack上で行える操作がほぼ全て行えます。  例)  仮想サーバーの作成  キーペアの作成  仮想ネットワーク、サブネットの作成  仮想ルーターの作成、ネットワークとの接続  Floating IPの作成、割当て  論理ポートの作成  セキュリティグループの作成  仮想ボリュームの作成、アタッチ  「リソース」をYAMLで記述することで作成できます。  このYAMLファイルを「テンプレート」と呼びます。 5 resources: server1: type: OS::Nova::Server properties: name: "Heat_Deployed_Server" image: { get_param: ImageID } flavor: "m1.small" key_name: "temp-key-001" networks: - network: { get_param: NetID } web_server_security_group: type: OS::Neutron::SecurityGroup properties: name: web_server_security_group rules: - protocol: icmp - protocol: tcp port_range_min: 22 port_range_max: 22 - protocol: tcp port_range_min: 443 port_range_max: 443 - protocol: tcp port_range_min: 80 port_range_max: 80 private_subnet: type: OS::Neutron::Subnet properties: network_id: { get_resource: private_network } cidr: 10.10.20.0/24 dns_nameservers: - 8.8.8.8 - 8.8.4.4 セキュリティグループの作成 仮想サーバーの作成 サブネットの作成
  6. 6. テンプレートに記述できるリソース  heat resource-type-list コマンドで一覧を確認できます。  利用できるリソースはHeatのバージョンに依存します。  またHeatのバージョンによって同じリソースでも仕様が異なっている場合があります。  例)  パラメータのバリデーション方法など。  これにより、前のバージョンでは動いていたのに、新しいバージョンではエラーになるという場合があります。  以下は利用できるリソースの一部を表示したものです。 6 $ heat resource-type-list +------------------------------------------+ | resource_type | +------------------------------------------+ | AWS::AutoScaling::AutoScalingGroup | | AWS::AutoScaling::LaunchConfiguration | | AWS::AutoScaling::ScalingPolicy | | AWS::CloudFormation::Stack | | AWS::CloudFormation::WaitCondition | | AWS::CloudFormation::WaitConditionHandle | | AWS::CloudWatch::Alarm | | AWS::EC2::EIP | | AWS::EC2::EIPAssociation | | AWS::EC2::Instance | | AWS::EC2::InternetGateway | | AWS::EC2::NetworkInterface | | AWS::EC2::RouteTable | | AWS::EC2::SecurityGroup | | AWS::EC2::Subnet | | AWS::EC2::SubnetRouteTableAssociation | | AWS::EC2::VPC | | AWS::EC2::VPCGatewayAttachment | | AWS::EC2::Volume | | AWS::EC2::VolumeAttachment | | AWS::ElasticLoadBalancing::LoadBalancer | | AWS::IAM::AccessKey | | AWS::IAM::User | | AWS::RDS::DBInstance | | AWS::S3::Bucket | | OS::Ceilometer::Alarm | | OS::Ceilometer::CombinationAlarm | | OS::Cinder::Volume | | OS::Cinder::VolumeAttachment | | OS::Glance::Image | | OS::Heat::AccessPolicy | | OS::Heat::AutoScalingGroup | | OS::Heat::CWLiteAlarm | | OS::Heat::CloudConfig | | OS::Heat::HARestarter | | OS::Heat::InstanceGroup | | OS::Heat::MultipartMime | | OS::Heat::RandomString | | OS::Heat::ResourceGroup | | OS::Heat::ScalingPolicy | | OS::Heat::SoftwareComponent | | OS::Heat::SoftwareConfig | | OS::Heat::SoftwareDeployment | | OS::Heat::SoftwareDeployments | | OS::Heat::Stack | | OS::Heat::StructuredConfig | | OS::Heat::StructuredDeployment | | OS::Heat::StructuredDeployments | | OS::Heat::SwiftSignal | | OS::Heat::SwiftSignalHandle | | OS::Heat::UpdateWaitConditionHandle | | OS::Heat::WaitCondition | | OS::Heat::WaitConditionHandle | | OS::Neutron::Firewall | | OS::Neutron::FirewallPolicy | | OS::Neutron::FirewallRule | | OS::Neutron::FloatingIP | | OS::Neutron::FloatingIPAssociation | | OS::Neutron::HealthMonitor | | OS::Neutron::IKEPolicy | | OS::Neutron::IPsecPolicy | | OS::Neutron::IPsecSiteConnection | | OS::Neutron::LoadBalancer | | OS::Neutron::MeteringLabel | | OS::Neutron::MeteringRule | | OS::Neutron::Net | | OS::Neutron::NetworkGateway | | OS::Neutron::Pool | | OS::Neutron::PoolMember | | OS::Neutron::Port | | OS::Neutron::ProviderNet | | OS::Neutron::Router | | OS::Neutron::RouterGateway | | OS::Neutron::RouterInterface | heat_template_version: 2015-04-30
  7. 7. テンプレートのバージョン  Heatはバージョンごとサポートされるリソースと、DSL内関数の機能が異 なっています。  基本的に新しいHeatは過去のテンプレートバージョンをサポートしています。  テンプレートの先頭にどのバージョンを利用するか宣言します。  利用可能なバージョンは以下  年月日の部分がバージョン番号です。 7 2013-05-23 Icehouse 2014-10-16 Juno 2015-04-30 Kilo 2015-10-15 Liberty 2016-04-08 Mitaka DSLで利用でき る関数 get_attr get_file get_param get_resource list_join resource_facade str_replace Fn::Base64 Fn::GetAZs Fn::Join Fn::MemberListTo Map Fn::Replace Fn::ResourceFaca de Fn::Select Fn::Split Ref get_attr get_file get_param get_resource list_join resource_facade str_replace Fn::Select get_attr get_file get_param get_resource list_join repeat digest resource_facade str_replace Fn::Select get_attr get_file get_param get_resource list_join repeat digest resource_facade str_replace str_split digest get_attr get_file get_param get_resource list_join map_merge repeat resource_facade str_replace str_split http://docs.openstack.org/developer/heat/template_guide/hot_spec.html#heat-template-version
  8. 8. シンプルなテンプレート  以下は1台のインスタンスを作成するテンプレートです。  nova boot コマンドと同じようなパラメータを与えています。  テンプレートはYAMLのデータ構造でシステム全体の構造を定義するのが役割です。  システムの構造とは、以下のような情報を指します。  そのシステムがどのようなネットワークをいくつ持つか、そのシステムはどのような役割のインスタンスをいくつ持つか  システムの起動順序、システムが障害を起こした際にどうするか?そのシステムを制御するための変数は何か?  テンプレートを実行すると「スタック(stack)」が作成されます。 8 heat_template_version: 2015-04-30 resources: server1: type: OS::Nova::Server properties: image: d33f51a3-6a18-4b96-bde6-2a68782336ca flavor: "m1.small" key_name: "temp-key-001" networks: - network: 1a684f4a-4f06-4741-b4f9-daa28676f74b single-instance.yaml テンプレートのバージョンを宣言します。 操作するリソースについて記述します。 ここれは1台のインスタンスを作成しています。 ここでは1つのリソースのみ記述していますが、実際 にはいくつでも記載可能です。 # heat stack-create -f single-instance.yaml test-stack +--------------------------------------+------------+--------------------+----------------------+ | id | stack_name | stack_status | creation_time | +--------------------------------------+------------+--------------------+----------------------+ | b4b8d078-7f84-4ab3-b8ca-87dc80d2480e | test-stack | CREATE_IN_PROGRESS | 2015-12-21T14:52:57Z | +--------------------------------------+------------+--------------------+----------------------+ # nova list +--------------------------------------+---------------------------------+--------+------------+-------------+----------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+---------------------------------+--------+------------+-------------+----------------------+ | abbbbc96-f301-4d63-b13b-b9733d3b6404 | test-stack-server1-cg4vev4dgxga | ACTIVE | - | Running | work-net=10.10.10.16 | +--------------------------------------+---------------------------------+--------+------------+-------------+----------------------+
  9. 9. スタック  スタックとはテンプレートから作成されたシステム全体を表すリ ソースです。  Heatはこのスタックを操作対象にするテンプレートを記述可能です。 9 heat_template_version: 2015- 04-30 resources: server1: type: OS::Nova::Server properties: image: d33f51a3-6a18- 4b96-bde6-2a68782336ca flavor: "m1.small" key_name: "temp-key- 001" networks: - network: 1a684f4a- 4f06-4741-b4f9-daa28676f74b テンプレート スタック1 スタック2 stack-create stack-create
  10. 10. スタックの状態  作成されたスタックは状態を持ちます。  管理するリソースの状態、操作の状況によってスタックは様々 な状態へ変化します。  以下は状態の一例です。 10 init_in_progress init_complete init_failed create_in_progress create_complete create_failed delete_in_progress delete_complete delete_failed update_in_progress update_complete update_failed snapshot_in_progress snapshot_complete snapshot_failed check_in_progress check_complete check_failed rollback_in_progress rollback_complete rollback_failed suspend_in_progress suspend_complete suspend_failed resume_in_progress resume_complete resume_failed adopt_in_progress adopt_complete adopt_failed
  11. 11. スタックの状態の基本  HeatはOpenStackの各APIサーバーと通信してリソースの状 態を取得します。  つまり、実体のリソースの本当の状態をHeatは知ることはでき ません。  例)  インスタンスをHeatのテンプレートで作成した際に、Nova側で「ACTIVE」と なれば、Heatはそのリソースが正常に作成されたと判断します。  実際はまだOSの起動中で、起動に失敗するという事もありえます。  Heatはこの問題を解決する方法を用意しています。方法は後述します。  これが問題となるのはNovaインスタンスを扱う場合です。  作成したインスタンスの中で様々な動作を行うため。 11
  12. 12. HOTの構造  先にシンプルなテンプレート例を紹介しましたが、実際のテン プレートはもっと多くの情報を含んでいます。  ここではトップレベルの構造を紹介します。現在のテンプレート は5つのセクションをテンプレート内に持ちます。  heat_template_version, resources 以外は省略可能です。 12 heat_template_version: 2015-04-30 description: Demo template for the 09th lecture. parameters: image: type: string label: Image name or ID description: Image to be used for the server. default: CentOS-7-x86_64-GenericCloud-1509-witn-cfntools-1.3.0-2 resources: private_network: type: OS::Neutron::Net outputs: instance_ip: description: The IP address of the deployed instance value: { get_attr: [floating_ip, floating_ip_address] } テンプレートのバージョン テンプレートの説明 外部から変更可能なパラメータを定義する 作成するリソースを記述する。最も重要。 スタック内の情報を外部へ出力する
  13. 13. テンプレート例  以下は仮想ルーター、仮想ネットワークを作成・接続し、論理ポートを作 成した後で、インスタンスを一台起動して、Floating IPを与える例です。 13 parameters: image: type: string label: Image name or ID description: Image to be used for the server. default: CentOS-7-x86_64-GenericCloud-1509-witn-cfntools-1.3.0-2 flavor: type: string label: Flavor description: Type of instance (flavor) to be used on the compute instance. default: m1.small key: type: string label: Key name description: Name of key-pair to be installed on the compute instance. default: temp-key-001 public_network: type: string label: Public network name or ID description: Public network with floating IP addresses. default: public ext_router: type: string label: Router name description: Router name or ID to connect to an external network. default: Ext-Router secgroup: type: string label: Secgroup name description: Security group name. default: web_server_security_group resources: private_network: type: OS::Neutron::Net private_subnet: type: OS::Neutron::Subnet properties: network_id: { get_resource: private_network } cidr: 10.10.20.0/24 dns_nameservers: - 8.8.8.8 - 8.8.4.4 router-interface: type: OS::Neutron::RouterInterface properties: router_id: { get_param: ext_router } subnet: { get_resource: private_subnet } neutron-port: type: OS::Neutron::Port properties: network: { get_resource: private_network } security_groups: - { get_param: secgroup } test-instance: type: OS::Nova::Server properties: image: { get_param: image } flavor: { get_param: flavor } key_name: { get_param: key } networks: - port: { get_resource: neutron-port } floating_ip: type: OS::Neutron::FloatingIP properties: floating_network: { get_param: public_network } floating_ip_assoc: type: OS::Neutron::FloatingIPAssociation properties: floatingip_id: { get_resource: floating_ip } port_id: { get_resource: flasky_port }
  14. 14. Parameters セクション  定義したパラメーターの値はテンプレート内から get_param 関数で参照可能です。  パラメーターにはデフォルト値を設定することが可能。  デフォルト値は、スタック作成時に上書き可能。 14 parameters: image: type: string label: Image name or ID description: Image to be used for the server. default: CentOS-7-x86_64-GenericCloud-1509-witn-cfntools-1.3.0-2 flavor: type: string label: Flavor description: Type of instance (flavor) to be used on the compute instance. default: m1.small $ heat stack-create -f heat.yaml -P 'image=Ubuntu14.04lts;flavor=m1.medium' stack-name test-instance: type: OS::Nova::Server properties: image: { get_param: image } flavor: { get_param: flavor } key_name: { get_param: key } networks: - port: { get_resource: neutron-port } パラメーターの値を参照 (通常はデフォルト値が参 照される) パラメーターを上書きしてスタックを作成 する例
  15. 15. Resources セクション  作成するリソースを記述していく。  リソースは作成する単位ごとに1つのタイプを持つ。  get_resource, get_attr 関数で他のリソースの値を参照可能。 15 resources: wait_condition: type: OS::Heat::WaitCondition properties: handle: { get_resource: wait_handle } count: 1 timeout: 600 wait_handle: type: OS::Heat::WaitConditionHandle web_server_security_group: type: OS::Neutron::SecurityGroup properties: name: web_server_security_group rules: - protocol: icmp - protocol: tcp port_range_min: 22 port_range_max: 22 - protocol: tcp port_range_min: 443 port_range_max: 443 - protocol: tcp port_range_min: 80 port_range_max: 80 private_network: type: OS::Neutron::Net private_subnet: type: OS::Neutron::Subnet properties: network_id: { get_resource: private_network } cidr: 10.10.20.0/24 dns_nameservers: - 8.8.8.8 - 8.8.4.4 router-interface: type: OS::Neutron::RouterInterface properties: router_id: { get_param: ext_router } subnet: { get_resource: private_subnet } neutron-port: type: OS::Neutron::Port properties: network: { get_resource: private_network } security_groups: - { get_resource: web_server_security_group } test-instance: type: OS::Nova::Server properties: image: { get_param: image } flavor: { get_param: flavor } key_name: { get_param: key } networks: - port: { get_resource: neutron-port } user_data_format: RAW user_data: str_replace: params: wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } template: | #!/bin/bash -ex sleep 3 echo "Hello" wc_notify --data-binary '{"status": "SUCCESS"}' echo '--- end ---'
  16. 16. Outputs セクション  作成したスタックの情報を外部に出力する。  他のプログラムとの連携や、別のテンプレートで仕様する。 16 outputs: instance_name: description: Name of the instance value: { get_attr: [test-instance, name] } instance_ip: description: The IP address of the deployed instance value: { get_attr: [floating_ip, floating_ip_address] } [ { "output_value": "test3-test-instance-2xmjvlijsyrz", "description": "Name of the instance", "output_key": "instance_name" }, { "output_value": "172.16.0.104", "description": "The IP address of the deployed instance", "output_key": "instance_ip" } ]
  17. 17. リソースの依存関係  Resourcesセクションでは get_resource, get_attr で他のリソースを参照した場合に、Heat側で自動で依存関係が設定されます。  リソース作成時に、 depend_on パラメーターを与える事で、ユーザーが依存関係を設定することも可能。  依存関係が設定されている場合、依存元のリソースの作成が完了してから、リソースの作成が行われる。  それ以外のリソースは平行で作成されていく。  以下のテンプレートからスタックを作成した場合・・・ 17 heat_template_version: 2015-04-30 description: Demo template for the 09th lecture. parameters: image: type: string label: Image name or ID description: Image to be used for the server. default: CentOS-7-x86_64-GenericCloud-1509-witn-cfntools-1.3.0-2 flavor: type: string label: Flavor description: Type of instance (flavor) to be used on the compute instance. default: m1.small key: type: string label: Key name description: Name of key-pair to be installed on the compute instance. default: temp-key-001 public_network: type: string label: Public network name or ID description: Public network with floating IP addresses. default: public ext_router: type: string label: Router name description: Router name or ID to connect to an external network. default: a3f094b5-fe83-4a92-a161-dece054ff0b0 resources: wait_condition: type: OS::Heat::WaitCondition properties: handle: { get_resource: wait_handle } count: 1 timeout: 600 wait_handle: type: OS::Heat::WaitConditionHandle web_server_security_group: type: OS::Neutron::SecurityGroup properties: name: web_server_security_group rules: - protocol: icmp - protocol: tcp port_range_min: 22 port_range_max: 22 - protocol: tcp port_range_min: 443 port_range_max: 443 - protocol: tcp port_range_min: 80 port_range_max: 80 private_network: type: OS::Neutron::Net
  18. 18. リソースの依存関係  右下図の依存関係が自動で設定される。 18 private_subnet: type: OS::Neutron::Subnet properties: network_id: { get_resource: private_network } cidr: 10.10.20.0/24 dns_nameservers: - 8.8.8.8 - 8.8.4.4 router-interface: type: OS::Neutron::RouterInterface properties: router_id: { get_param: ext_router } subnet: { get_resource: private_subnet } neutron-port: type: OS::Neutron::Port properties: network: { get_resource: private_network } security_groups: - { get_resource: web_server_security_group } test-instance: type: OS::Nova::Server properties: image: { get_param: image } flavor: { get_param: flavor } key_name: { get_param: key } networks: - port: { get_resource: neutron-port } user_data_format: RAW user_data: str_replace: params: wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } template: | #!/bin/bash -ex sleep 3 echo "Hello" wc_notify --data-binary '{"status": "SUCCESS"}' echo '--- end ---' floating_ip: type: OS::Neutron::FloatingIP properties: floating_network: { get_param: public_network } floating_ip_assoc: type: OS::Neutron::FloatingIPAssociation properties: floatingip_id: { get_resource: floating_ip } port_id: { get_resource: neutron-port } outputs: instance_name: description: Name of the instance value: { get_attr: [test-instance, name] } instance_ip: description: The IP address of the deployed instance value: { get_attr: [floating_ip, floating_ip_address] }
  19. 19. リソースの依存関係  作成された依存関係 19 OS::Heat::WaitCondition OS::Heat::WaitConditionHandle OS::Nova::Server OS::Neutron::Port OS::Neutron::SecurityGroup OS::Neutron::FloatingIP OS::Neutron::FloatingIPAssociation OS::Neutron::Subnet OS::Neutron::Net OS::Neutron::RouterInterface
  20. 20. 発展 20
  21. 21. 特殊なリソース  HOTで記述するリソースは基本的にOpenStackが持つリソー スが対象になります。  インスタンス、ネットワーク、ボリューム等々・・・  しかし、システム構成を記述する場合には、単純にリソースを 配置していくだけでは対応できません。  特殊な動作を行わせるために、Heatはいくつかの独自リソース を備えています。  これらのリソースはHeat::XX に属しています。  以下では、よく使うHeatリソースを紹介します。 21
  22. 22.  続く 22

×