Google Cloud Deployment Managerとは
https://cloud.google.com/deployment-manager
アプリケーションに必要なリソースをyamlで宣言的に記述する、いわゆるInfrastructure as Codeを実現するためのサービスです。 AWSでいうところのCloud Formationですね。
説明するにあたっていくつが用語が出てくるので簡単に説明しておきます。
リソース
デプロイされる個々のインフラストラクチャの単位です。 Compute EngineのVMや、Cloud Storageのバケット、ネットワークのファイアウォール設定などデプロイされるもの全てです。
デプロイメント
アプリケーションをデプロイする単位。リソースを複数含めることができて、それらを一括で管理できます。
構成ファイル
yamlによって記述されるデプロイメントの定義。
特長
DeploymentManagerのページに行くと特長が書いてあるので見ていきましょう。
並行的なデプロイメント
何もしなければすべてのリソースは並行的に作成されます。 つまり、VMを1台作成しても100台作成してもほとんど時間は変わらないということですね。
テンプレート
yaml + jinja または Python でテンプレートを作成することで、設定を使い回せます。
更新
デプロイメントのリソースは一括で管理されるので、一度に作成、一度に削除、コピーが簡単にできます。
入出力パラメータ
作成されたリソースのうち動的に変わるパラメータ、例えばエメフェラルなIPなどを他のリソースの作成条件等に 簡単に使用することができます。
スキーマファイル
テンプレートで与えられなかった値に対してデフォルト値を設けたり、バリデーションをかけたりできます。
参照
入出力パラメータを使用して生じた依存関係は、自動的に解決され、リソースの作成順序が保証されます。 循環参照など問題が起きた場合はデプロイ前にエラーを発します。
プレビューモード
作成、変更内容を事前に確認できます。
使ってみる
最小構成のyamlファイルを使ってDeploymentManagerを使ってみます。
前提条件として gcloud
コマンドがインストールされ、ログイン等の設定が終わっているものとします。
https://cloud.google.com/sdk/downloads
API type の確認
まずは、デプロイしようとするリソースのAPIを確認します。
DeploymentManagerでサポートされるリソースの一覧が下記に書かれています。
https://cloud.google.com/deployment-manager/docs/configuration/supported-resource-types
VMインスタンスの定義
今回は、VMインスタンスを作成することにします。 compute.v1.instance
というリソース type を使用し、 vm.yaml
という名前でデプロイを作成しました。
resources:
- name: vm
type: compute.v1.instance
設定の確認
構成ファイルが正しく記述されているかを調べるには、 --preview
オプションを付けてデプロイするのが一番手っ取り早いです。 glcoud
コマンドを使って my-first-vm
という名前でをつけてデプロイします。 ファイルにデプロイ名を記載しないことで、他のデプロイとしてコピーを簡単に作成できます。 production, staging 環境など複数環境のコピーが簡単に作成できますね。
$ gcloud deployment-manager deployments create my-first-vm --config vm.yaml --preview
ERROR: (gcloud.deployment-manager.deployments.create) Error in Operation
- code: CONDITION_NOT_MET
location: /deployments/my-first-vm/resources/vm->$.properties
message: '"": domain: validation; keyword: properties; message: required property(ies)
not found; missing: ["zone"]; required: ["zone"]'
どうやら zone
というプロパティは必須のようです。 properties 以下に プロパティを定義します。
resources:
- name: vm
type: compute.v1.instance
properties:
zone: us-central1-a
2度目のデプロイ
一度でもデプロイした構成は 失敗 や プレビュー状態 であってもDeploymentManager上に作成されます。 2度目以降のデプロイには update
コマンドを使用します。 zone
を追加したデプロイを再度プレビューしてみましょう。
$ gcloud deployment-manager deployments update my-first-vm --config vm.yaml --preview
Update operation completed successfully.
NAME TYPE STATE ERRORS INTENT
vm compute.v1.instance IN_PREVIEW [] CREATE_OR_ACQUIRE
エラーが表示されなかったので、デプロイ可能になりました。 IN_PREVIEW
という STATE
はまだデプロイされていないことを意味します。
プレビューのコミット
プレビューをコミットするには、設定ファイル(--config
)を指定せずに update
を実行します。
$ gcloud deployment-manager deployments update my-first-vm
ERROR: (gcloud.deployment-manager.deployments.update) Error in Operation
- code: RESOURCE_ERROR
location: /deployments/my-first-vm/resources/vm
message: "{\"ResourceType\":\"compute.v1.instance\",\"ResourceErrorCode\":\"400\"\
,\"ResourceErrorMessage\":{\"code\":400,\"errors\":[{\"domain\":\"global\",\"\
message\":\"Invalid value for field 'resource.machineType': ''. Machine type specified\
\ for the instance is not machine type.\",\"reason\":\"invalid\"}],\"message\"\
:\"Invalid value for field 'resource.machineType': ''. Machine type specified\
\ for the instance is not machine type.\",\"statusMessage\":\"Bad Request\",\"\
requestPath\":\"https://www.googleapis.com/compute/v1/projects/[your-project]/zones/us-central1-a/instances\"\
,\"httpMethod\":\"POST\"}}"
machineType
プロパティがないのでデプロイに失敗しました。このように、デプロイして初めて分かる構文ミスもあるので注意が必要です。
最小の構成ファイル
最終的に、デプロイに成功する最小の構成ファイルは以下のようになります。 [your-project]
にはプロジェクトIDが入ります。
resources:
- name: vm
type: compute.v1.instance
properties:
zone: us-central1-a
machineType: zones/us-central1-a/machineTypes/f1-micro
disks:
- deviceName: boot
boot: true
initializeParams:
sourceImage: projects/debian-cloud/global/images/family/debian-9
networkInterfaces:
- network: projects/[your-project]/global/networks/default
この状態で再度デプロイすると、 STATE
が COMPLETED
になります。
$ gcloud deployment-manager deployments update my-first-vm --config vm.yaml
Update operation completed successfully.
NAME TYPE STATE ERRORS INTENT
vm compute.v1.instance COMPLETED []
作成されたVMを確認
クラウドコンソール( console.cloud.google.com )から Compute Engine を開くと、VMが無事に作成されています。
Deploymentmanagerのページからもここに飛べます。 このVMには goog-dm: my-first-vm
というタグが付いており、デプロイメントから作成されたことがわかります。
下の方にある ボタンを押すとこのVMの作成に使われたパラメータ一覧を見れます。
{
"cpuPlatform": "Intel Sandy Bridge",
"creationTimestamp": "2018-12-11T01:37:48.242-08:00",
"deletionProtection": false,
"disks": [
{
"autoDelete": false,
"boot": true,
"deviceName": "boot",
"guestOsFeatures": [
{
"type": "VIRTIO_SCSI_MULTIQUEUE"
}
],
"index": 0,
"interface": "SCSI",
"kind": "compute#attachedDisk",
"licenses": [
"projects/debian-cloud/global/licenses/debian-9-stretch"
],
"mode": "READ_WRITE",
"source": "projects/[your-project]/zones/us-central1-a/disks/vm",
"type": "PERSISTENT"
}
],
"id": "3042933826887236484",
"kind": "compute#instance",
"labelFingerprint": "isLgN0Vp5Xc=",
"labels": {
"goog-dm": "my-first-vm"
},
"machineType": "projects/[your-project]/zones/us-central1-a/machineTypes/f1-micro",
"metadata": {
"fingerprint": "vp8l7LsNCFw=",
"kind": "compute#metadata"
},
"name": "vm",
"networkInterfaces": [
{
"fingerprint": "oe2Zo41r_OM=",
"kind": "compute#networkInterface",
"name": "nic0",
"network": "projects/[your-project]/global/networks/default",
"networkIP": "10.128.0.2",
"subnetwork": "projects/[your-project]/regions/us-central1/subnetworks/default"
}
],
"scheduling": {
"automaticRestart": true,
"onHostMaintenance": "MIGRATE",
"preemptible": false
},
"selfLink": "projects/[your-project]/zones/us-central1-a/instances/vm",
"startRestricted": false,
"status": "RUNNING",
"tags": {
"fingerprint": "42WmSpB8rSM="
},
"zone": "projects/[your-project]/zones/us-central1-a"
}
このJSONの中身は、REST Resource: instances ページに詳細が載っています。
https://cloud.google.com/compute/docs/reference/rest/v1/instances
[Output Only] になっていないものに着目すると、送信しなかった値のデフォルト値がわかります。 この中で以下の値はデフォルト値を使わないことを推奨します。
autoDelete: false
VMの削除とともにディスクを削除する設定です。特に残す意図がないなら true
にするべきです。
削除
デプロイメントを削除するには delete
サブコマンドを使います。
$ gcloud deployment-manager deployments delete my-first-vm
--delete-policy=ABANDON
オプションで、リソースを残したままデプロイメントを削除することもできます。
$ gcloud deployment-manager deployments delete my-first-vm --delete-policy=ABANDON
テンプレート
先ほど作成した構成ファイルから、以下の値を変数として切り出すと便利そうです。
- zone
- machineType
- project
テンプレートは構成ファイルからimportして使います。構成ファイルに記述した properties
以下の値が変数としてテンプレート上に展開されます。 さらに、 properties
以外にテンプレートとして有効な環境変数が予め用意されています。これらの環境変数は、DeploymentManagerが独自に用意するもので、 手動で編集することはできません。
https://cloud.google.com/deployment-manager/docs/configuration/templates/use-environment-variables
テンプレートの作成
構成ファイルを vm.jinja
という名前でコピーしてテンプレートを作成してみましょう。 2重の中括弧 {{}}
で囲った部分が変数として展開される部分です。 先程の変数をテンプレートに変換すると以下のようになりました。
resources:
- name: vm
type: compute.v1.instance
properties:
zone: {{ properties['zone'] }}
machineType: zones/{{ properties['zone'] }}/machineTypes/{{ properties['machineType'] }}
disks:
- deviceName: boot
autoDelete: true
boot: true
initializeParams:
sourceImage: {{ properties['sourceImage'] }}
networkInterfaces:
- network: projects/{{ env['project'] }}/global/networks/default
構成ファイルからのimport
元の vm.yaml
から vm.jinja
をインポートしましよう。 resources
と同じトップレベルの階層に imports
を追加して、 vm.jinja
を import します。
resources
→ type
は vm.jinja
となります。
テンプレート化した部分を properties
以下に実際の値を追記します。
imports:
- path: vm.jinja
resources:
- name: hoge-vm
type: vm.jinja
properties:
zone: us-central1-a
machineType: f1-micro
sourceImage: projects/debian-cloud/global/images/family/debian-9
テンプレートの利用
テンプレートを用いることで machineType
の異なる3つの VM が少ない記述で作成できました。
imports:
- path: vm.jinja
resources:
- name: vm1
type: vm.jinja
properties:
zone: us-central1-a
machineType: f1-micro
sourceImage: projects/debian-cloud/global/images/family/debian-9
resources:
- name: vm2
type: vm.jinja
properties:
zone: us-central1-a
machineType: n1-standard-1
sourceImage: projects/debian-cloud/global/images/family/debian-9
resources:
- name: vm3
type: vm.jinja
properties:
zone: us-central1-a
machineType: n1-standard-4
sourceImage: projects/debian-cloud/global/images/family/debian-9
参考
公式のチュートリアル、サンプルコードが参考になります。
チュートリアル
https://cloud.google.com/deployment-manager/docs/tutorials
サンプル集
https://github.com/GoogleCloudPlatform/deploymentmanager-samples