この記事は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)
の所)になっていなかったので修正しました。参照表記を使用して依存関係を明示しないとインスタンスが作られる前にデータベースを作ろうとして失敗します。また、database
のname
もそのまま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
のパラメータの多くが弄れます。ですが、CloudSQL
はdatabase
を作る際に一緒に指定する項目となっており、charset
やcollation
と独自に省略されていて、実際文字コードくらいしか弄れません。4
サービスとしての自由度(≒複雑度)が違います。なので、一概にCloudFormationが複雑でDeployment Managerは簡潔で勝っているとは言えない面はあります。他のサービスやプラットフォーム全体としても然りです。
私見なまとめ
- 人が書くならJSONよりYAML
- Deployment Managerつらくない(主観)
- 公式でjinja2やPythonをサポートしているのは嬉しい
- APIとかを見てると各社の思想の違いみたいなのが垣間見えて面白い
最終的には好みもあるので、参考までに。
Deployment Managerは動的な記述ができるので、もっと使う人が増えれば色々な便利な使い方が出てくるんじゃないかと思ってます。是非使ってみてください :-)