Help us understand the problem. What is going on with this article?

JSONなアレに疲れたアナタに贈るGoogle Cloud Deployment Managerのススメ

More than 5 years have passed since last update.

この記事はGoogle Cloud Platform Advent Calendar 2015の17日目です。

全国のAWSユーザの皆さん、いつもJSON業お疲れ様です。
全国のGCPユーザの皆さん、これからYAML業頑張りましょう。

はい。

ということ(?)で、「アレ」とはCloudFormationのことです。

AWSの割りとヘビーユーザである私がGCPを使ってみて特に気に入ったサービスの一つである、テンプレートによる一括デプロイメントができるGoogle Cloud Deployment Managerを同種のサービスであるAWS CloudFormationと比べてどこが気に入っているかまとめてみたいと思います。

CloudFormationは素晴らしい

では、ここで素晴らしいと思う点を挙げてみましょう。

  • インフラをテンプレート化
  • 再利用可能な再現性のあるインフラ
  • 自動化された一括デプロイメント
  • 大量にあるAWSのサービス・機能のほとんどをカバー
  • 最近ではGUIで図から作れる機能なんかも出ましたね

いや、ほんとオンプレでは真似できないクラウドを象徴するサービスの一つだと思います。素晴らしいですね。

・・・・・
・・・・
・・・
・・

自分で書かなければな!!1

CloudFormationは何がつらいか

主観です。個人差は大いにあります。

  • JSON
  • テンプレートファイルの分割ができない1 2
  • スタック内での記述の再利用できないため同じような記述が頻出することがある(コピペ地獄)2
  • 独自リソースや特殊な記述法
    「API→操作中心」「CFn→リソース中心」の設計となっており、対応付いていないため指定方法が異なる
  • そして、出来上がる千行を超えるJSON・・・

しかしながら、それを改善するツールなんかもあって、特にkumogata先生に私はいつもお世話になっております。とはいえ、やはりツラい面はある。。。

Cloud Deployment Managerの特徴

テンプレートの記述フォーマットはYAML

好みの問題もありますが、JSONよりは人間に優しいですね。
閉じ括弧が必要ないとか、単純に行数も減ります。

テンプレートの分割が可能

以下のように書きます。

imports:
- path: path/to/template.yml
- path: path/to/template.jinja
- path: path/to/template.py

jinja23とPythonによる記述もサポート

テンプレートエンジンを利用して変数やコードを埋め込んだり、動的にYAMLを組み立てることで冗長な表現を避けたり、可変な部分を外部から受け取るようにすることで再利用性を高めたりすることができます。

APIに対応付いた記述

GCPのAPIはリソース指向でRESTfulなAPIであり、APIへの引数の与え方が大筋でそのままDeployment Managerの記述に対応付くような感じになっています。実際、Deployment Managerのドキュメントを辿っていくと気が付くと別のサービスのAPIリファレンスに到達しますw
https://cloud.google.com/deployment-manager/configuration/create-configuration-file

ドキュメントは(比べると)少なめ

CloudFormationの公式ドキュメントを読むと、豊富なサンプルと各リソースの細かな説明が乗っています。
Deployment Manaegrの公式ドキュメントは(比べると)少なめです。ですが、上述したようにAPIリファレンスが大筋でそのまま対応付くので書いていて特に問題にはならないです。この辺りはそこまで使い込んでいないのでまだ遭遇していませんが、複雑な構成や依存関係が出てきたりすると苦労するかもしれませんね。

記述を比べてみる

では、一例として似たようなサービスであるRDS(MySQL)とCloudSQLのテンプレートの記述を比べてみましょう。

インスタンスの立ち上げとutf8mb4で使うための設定だけを行う記述になります。

RDS

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "sample",
  "Resources" : {
    "MyDB" : {
      "Type" : "AWS::RDS::DBInstance",
      "Properties" : {
        "DBName" : "DBName" ,
        "AllocatedStorage" : "5",
        "DBInstanceClass" : "db.t2.small",
        "Engine" : "MySQL",
        "EngineVersion" : "5.6.19",
        "MasterUsername" : "DBUser",
        "MasterUserPassword" : "DBPassword",
        "DBParameterGroupName" : { "Ref" : "MyRDSParamGroup" }
      }
    },
    "MyRDSParamGroup" : {
      "Type": "AWS::RDS::DBParameterGroup",
      "Properties" : {
        "Family" : "MySQL5.6",
        "Description" : "CloudFormation Sample Database Parameter Group",
          "Parameters" : {
            "character-set-server" : "utf8mb4",
            "collation-server": "utf8mb4_general_ci"
        }
      }
    }
  }
}

CloudSQL

※一部誤りがありましたので修正しました。

2015/12/17追記:
databaseの記述が他のリソースを参照する表記($(ref.sample-cloudsql.name)の所)になっていなかったので修正しました。参照表記を使用して依存関係を明示しないとインスタンスが作られる前にデータベースを作ろうとして失敗します。また、databasenameもそのままMySQLのDB名になるのでハイフンが使えませんのでアンダースコアに修正しました。

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

比べて分かる特徴

なんとなくDeployment Managerが簡潔であることがお分かりいただけるかと思いますが、もう一つの事実も見えてきます。

これは、サービスとしての特性の違いでもあるのですが、RDSは文字コードを指定するための内容がDBParameterGroupとして独立した機能となっており、指定方法はMySQLのパラメータ名そのままで、実際MySQLのパラメータの多くが弄れます。ですが、CloudSQLdatabaseを作る際に一緒に指定する項目となっており、charsetcollationと独自に省略されていて、実際文字コードくらいしか弄れません。4

サービスとしての自由度(≒複雑度)が違います。なので、一概にCloudFormationが複雑でDeployment Managerは簡潔で勝っているとは言えない面はあります。他のサービスやプラットフォーム全体としても然りです。

私見なまとめ

  • 人が書くならJSONよりYAML
  • Deployment Managerつらくない(主観)
  • 公式でjinja2やPythonをサポートしているのは嬉しい
  • APIとかを見てると各社の思想の違いみたいなのが垣間見えて面白い

最終的には好みもあるので、参考までに。
Deployment Managerは動的な記述ができるので、もっと使う人が増えれば色々な便利な使い方が出てくるんじゃないかと思ってます。是非使ってみてください :-)


  1. もちろん複数のスタックに分ければできる。一つのスタックを分割することはできないということ。 

  2. kumogataとかプログラミング言語で記述できる支援ツールを使えばできる 

  3. http://jinja.pocoo.org/docs/dev/ 

  4. 最近出た第2世代のCloudSQLはもっと弄れるんだろうか? 

marcy-terui
Cloud Architect / Developer / Infrastructure as Code / Full-time employee / Part-time freelance / #jawsug / #gcpug / アラサー / 二児の父 / 発言は個人のアレです
https://willy.works
serverless-operations
AWSクラウド技術の豊富な知見を活かし、サーバーレスによる開発や運用の支援、コンサルティングまで行う会社です
https://serverless.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away