Google Cloud Deployment ManagerはPreviewができる

この記事はGoogle Cloud Platform Advent Calendar 2015の記事ではありません。

昨日[JSONなアレに疲れたアナタに贈るGoogle Cloud Deployment Managerのススメ](http://qiita.com/marcy-terui/items/1d19aa089fd076873180)という記事を書いたんですが、テンプレートの記述に関する比較に終始してしまい、一つ大きな利点を見逃していたので追加のエントリーです。

# Previewについて
[CloudFormation](https://aws.amazon.com/jp/cloudformation/)にはDry runやPreviewといった機能はありません。
皆さんいつも本番に反映する時は慎重にレビューをし、ドキドキしながら適用していることと思います。あるいは、専用の別アカウントあたりで実際に適用してみて確認するみたいなことをしているかもしれません。

それ、Deployment Managerならできます。
ただし、少し注意点やポイントがあるのでまとめてみます。

# 実際のコマンドを見ながら

コマンドの基本は以下となります。

```shell-session
gcloud deployment-manager deployments <操作名> <デプロイメント名> --config <テンプレートファイルのパス> --preview
```

## まずは作成から

使用するテンプレート↓

```yaml
resources:
- name: cloudsql-instance
  type: sqladmin.v1beta4.instance
  properties:
    region: us-central
    instanceType: CLOUD_SQL_INSTANCE
    settings:
      tier: D1
      activationPolicy: ON_DEMAND
- name: sample_db
  type: sqladmin.v1beta4.database
  properties:
    instance: $(ref.cloudsql-instance.name)
    charset: utf8mb4
    collation: utf8mb4_general_ci
```

### 作成のプレビュー
プレビューを行う場合は`--preview`オプションを付けます。
付けなければいきなり適用されますので注意してください。

```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments create sample-deploy --config cloud-sql.yml --preview
Waiting for create operation-1450429178867-527285bfa6d38-b87344ea-200e0e5d...done.
Create operation operation-1450429178867-527285bfa6d38-b87344ea-200e0e5d completed successfully.
NAME               TYPE                       STATE       ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  IN_PREVIEW  -
sample_db          sqladmin.v1beta4.database  IN_PREVIEW  -
```

状態（STATE）が`IN_PREVIEW`になったのが確認できるかと思います。
この時点ではまだリソースは作られていません。

**プレビュー時のエラーチェックは構文的なバリデーションのみとなっています。実際のサービスの制限や依存関係に起因するエラーはこの時点では分かりません。**

### 作成の適用
プレビューで既にテンプレートを送信済みなので、デプロイメント名のみの指定でOKです。

```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy
Waiting for update operation-1450429201683-527285d56923b-123f8853-97528672...done.
Update operation operation-1450429201683-527285d56923b-123f8853-97528672 completed successfully.
NAME               TYPE                       STATE      ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED  -
sample_db          sqladmin.v1beta4.database  COMPLETED  -
```

状態（STATE）が`COMPLETED`になりました。これでリソースが出来上がっています。

## 更新
では、作成したリソースの一部を更新してみましょう。

### リソースの追加

DBを一つ追加してみます。
先ほどのテンプレートを以下のように更新します。


```yaml
resources:
- name: cloudsql-instance
  type: sqladmin.v1beta4.instance
  properties:
    region: us-central
    instanceType: CLOUD_SQL_INSTANCE
    settings:
      tier: D1
      activationPolicy: ON_DEMAND
- name: sample_db
  type: sqladmin.v1beta4.database
  properties:
    instance: $(ref.cloudsql-instance.name)
    charset: utf8mb4
    collation: utf8mb4_general_ci
- name: sample_db_2
  type: sqladmin.v1beta4.database
  properties:
    instance: $(ref.cloudsql-instance.name)
    charset: utf8mb4
    collation: utf8mb4_general_ci
```

### 追加のプレビュー

```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy --config cloud-sql.yml --preview
Waiting for update operation-1450429831076-5272882da58a0-e242a24a-ccb9de67...done.
Update operation operation-1450429831076-5272882da58a0-e242a24a-ccb9de67 completed successfully.
NAME               TYPE                       STATE       ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED   -
sample_db          sqladmin.v1beta4.database  COMPLETED   -
sample_db_2        sqladmin.v1beta4.database  IN_PREVIEW  -
```

追加されるリソースが`IN_PREVIEW`それ以外は変化無いので`COMPLETED`になっています。

### 追加の適用
```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy
Waiting for update operation-1450429913772-5272887c82fe0-71ea9698-3902a139...done.
Update operation operation-1450429913772-5272887c82fe0-71ea9698-3902a139 completed successfully.
NAME               TYPE                       STATE      ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED  -
sample_db          sqladmin.v1beta4.database  COMPLETED  -
sample_db_2        sqladmin.v1beta4.database  COMPLETED  -
```

全てのリソースが`COMPLETED`になりました。

### リソースの変更
今度は、追加ではなく変更をしてみます。
２つあるDBのうち、片方の文字コードだけ変えてみます（地味ｗｗｗ）

```yaml
resources:
- name: cloudsql-instance
  type: sqladmin.v1beta4.instance
  properties:
    region: us-central
    instanceType: CLOUD_SQL_INSTANCE
    settings:
      tier: D1
      activationPolicy: ON_DEMAND
- name: sample_db
  type: sqladmin.v1beta4.database
  properties:
    instance: $(ref.cloudsql-instance.name)
    charset: utf8mb4
    collation: utf8mb4_general_ci
- name: sample_db_2
  type: sqladmin.v1beta4.database
  properties:
    instance: $(ref.cloudsql-instance.name)
    charset: utf8 # <- here!!
    collation: utf8_general_ci #<-here!!
```

### 変更のプレビュー
```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy --config cloud-sql.yml --preview
Waiting for update operation-1450430214580-5272899b62721-5a3da25c-8b02793a...done.
Update operation operation-1450430214580-5272899b62721-5a3da25c-8b02793a completed successfully.
NAME               TYPE                       STATE       ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED   -
sample_db          sqladmin.v1beta4.database  COMPLETED   -
sample_db_2        sqladmin.v1beta4.database  IN_PREVIEW  -
```

差分があるリソースのみが`IN_PREVIEW`となっていますね。

ちなみにこれはブラウザのコンソールからも見ることができます。
差分がグラフィカルに見れたりすると素敵なんですが、残念ながら状態と今現在の設定のみの表示となってます。

![image](https://qiita-image-store.s3.amazonaws.com/0/57327/e7c21a15-a59e-016a-43f2-efbdd89b3f30.png)


### 変更の適用
```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy
Waiting for update operation-1450434821949-52729ac550648-b01326ac-036f0ea0...done.
Update operation operation-1450434821949-52729ac550648-b01326ac-036f0ea0 completed successfully.
NAME               TYPE                       STATE      ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED  -
sample_db          sqladmin.v1beta4.database  COMPLETED  -
sample_db_2        sqladmin.v1beta4.database  COMPLETED  -
```

# プレビューで問題が見つかったら

例えば、違うリソースを弄っていることが発覚して取り下げたい場合は以下のように`cancel-preview`コマンドで取り下げができます。

```shell-session
marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments update sample-deploy --config cloud-sql.yml --preview
Waiting for update operation-1450436669687-5272a1a7744d8-79551062-f0eb9ff4...done.
Update operation operation-1450436669687-5272a1a7744d8-79551062-f0eb9ff4 completed successfully.
NAME               TYPE                       STATE       ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED   -
sample_db          sqladmin.v1beta4.database  COMPLETED   -
sample_db_2        sqladmin.v1beta4.database  IN_PREVIEW  -

marcy@marcy-ubuntu:~$ gcloud deployment-manager deployments cancel-preview sample-deploy
Waiting for cancel-preview operation-1450436708378-5272a1cc5a590-bb26393f-95ec5cc2...done.
Cancel preview operation operation-1450436708378-5272a1cc5a590-bb26393f-95ec5cc2 completed successfully.
NAME               TYPE                       STATE      ERRORS
cloudsql-instance  sqladmin.v1beta4.instance  COMPLETED  -
sample_db          sqladmin.v1beta4.database  COMPLETED  -
sample_db_2        sqladmin.v1beta4.database  COMPLETED  -
```

便利ですね！

# 重要な注意点
とても便利なプレビュー機能ですが、一つだけ重要な注意点があります。

**差分の判定は実際のリソースではなく、テンプレートの比較で判定しています。
なので、Deployment Managerを介さずにコンソールやコマンド・APIから変更が行われた場合は「差分と検知されずに更新されない」あるいは「別の部分が変わっていた場合は元に戻ってしまう」ということになりますので注意してください。**

以上、補足でした。

この重要なポイントは @rrreeeyyy さんの以下のツイートで思い出すことができました。ありがとうございます。
https://twitter.com/rrreeeyyy/status/677744289305128962