自分の勉強のために,Cloud Deployment Managerについてまとめました.
Terraformとの比較
Infrastructure as CodeのソリューションとしてTerraformが有名ですが,あえてCloud Deployment Managerを使います.以下に理由を述べます.
- Cloud Deployment Managerは実行環境を含めて完全無料だが,Terraformは使い方によっては料金がかかる.
- Cloud Deployment Managerはデフォルトで実行が可能なIAMが設定されるが,Terraformを使うにはGCPでIAMを設定しなければならない.
- Cloud Deployment Managerは2015年にGAとなっており,十分に枯れた技術になっているが,Terraformは2021年現在でまだバージョンが0.14であり,最新のバージョンに追従するコストが発生する*1, *2.
- 現時点でGCP以外を使う予定がないので,マルチクラウドに対応するメリットがない.
- yamlやjinjaは既に習得済みであるが,Terraformは触ったことがない.
- Terraformは遠目から面白そうに見える.
それでは,Cloud Deployment Managerを使っていきましょう.
Cloud Deployment Manager の最小構成
Cloud Pub/Sub の topic を作成してみます.以下のような,main.yaml
を用意します.
resources: - name: my-pubsub type: pubsub.v1.topic properties: topic: my-sample-pubsub
type
は以下のサポートされるリソースの APIのリストから選択します.
Supported resource types | Cloud Deployment Manager Documentation
β版として,gcp-typesというものもあります.
Supported GCP type providers | Cloud Deployment Manager Documentation
なお,これらのリストは最新の情報でない可能性がある点に注意します.
create
一連の Google Cloud リソースを作成し、デプロイと呼ばれる 1 つの単位として管理できます。Getting started with Deployment Manager
と記載されているように,gcloudコマンドでデプロイに名前を指定して,リソースを作成するためのコマンドcreate
を使います.例えば,デプロイの名前がsampleの場合は,以下のようになります.
gcloud deployment-manager deployments create sample --config main.yaml --project [project name]
これで,Pub/Sub topicが完成します.
gcloud deployment-manager deployments create | Cloud SDK Documentation
update
createしたデプロイを更新するには,update
コマンドを使います.任意に変更したmain.yaml
に対して以下のコマンドを実行することで,リソースが新しいmain.yaml
の内容に更新されます.
gcloud deployment-manager deployments update sample --config main.yaml --project [project name]
もしも,プレビューしたい場合は,--preview
オプションを追加し,確定します.
gcloud deployment-manager deployments update sample --config main.yaml --project [project name] --preview
gcloud deployment-manager deployments update sample --project [project name]
gcloud deployment-manager deployments update | Cloud SDK Documentation
delete
作成したデプロイを削除する時は,delete
コマンドを使います.この時に,作成済みのリソースを同時に削除するかを選択するために,--delete-policy
を指定します.abandon
ならば作成済みのリソースを残し,delete
ならば,作成したリソースを全て削除します.
gcloud deployment-manager deployments delete sample --project [project name] --delete-policy=DELETE
gcloud deployment-manager deployments delete | Cloud SDK Documentation
以上で,Deployment Managerを使って自由にリソースを作成,更新,削除ができるようになりました.しかし,yamlファイルが巨大になると管理が大変になっていくので,汎用性を高めるために工夫していきます.
jinjaテンプレートを使用する
テンプレートを使って,繰り返す表現を回避します.Deployment Managerでは,.py と .jinja が使えます.公式ドキュメントでは.pyの使用が推奨されていますが,.jinjaの方がyamlに近い表現が可能なので,この記事では.jinjaを使うことにします.*3
Jinja — Jinja Documentation (2.11.x)
template_pubsub.jinja
resources: - name: my-pubsub type: pubsub.v1.topic properties: topic: my-sample-pubsub
main.yaml
imports: - path: template_pubsub.jinja resources: - name: my-sample type: template_pubsub.jinja
main.yaml
をデプロイすると,my-sample-pubsubという名前のPub/Sub topicが作成されます.これだけではテンプレートのありがたさがわかりませんが,次のセクションから便利になります.
環境変数
Deployment Manager を実行する時に,以下の環境変数が自動的に設定されます.
環境変数 | 値 |
---|---|
deployment |
デプロイメントの名前。 |
name |
テンプレートを使用している構成で宣言されている name 。構成で宣言する名前をテンプレート内のリソース名にする場合に便利です。 |
project |
このデプロイメントのプロジェクト ID。 |
project_number |
このデプロイメントのプロジェクト番号。 |
current_time |
デプロイメントで展開が開始したタイムスタンプ(UTC)。 |
type |
最上位の構成で宣言されているリソースタイプ。 |
username |
現在の Deployment Manager ユーザー。 |
デプロイメント固有の環境変数の使用 | Cloud Deployment Manager のドキュメント | Google Cloud
これをjinjaテンプレートで利用するには,{{ env["project"] }}
などと記載します.これで現在のプロジェクトIDが代入されます.
これらの機能を利用して,Pub/Sub topicとそれに関連するsubscriptionを2組作成してみます.
template_pubsub.jinja
{% set PREFIX = env["deployment"] + "-" + env["name"] %} {% set TOPIC_NAME = PREFIX + "-topic" %} {% set SUBSCRIPTION_NAME = PREFIX + "-subscription" %} resources: - name: {{ TOPIC_NAME }} type: pubsub.v1.topic properties: topic: {{ TOPIC_NAME }} - name: {{ SUBSCRIPTION_NAME }} type: pubsub.v1.subscription properties: subscription: {{ SUBSCRIPTION_NAME }} topic: projects/{{ env["project"] }}/topics/{{ TOPIC_NAME }} metadata: dependsOn: - {{ TOPIC_NAME }}
main.yaml
imports: - path: template_pubsub.jinja resources: - name: one type: template_pubsub.jinja - name: two type: template_pubsub.jinja
main.yaml
をデプロイすると,以下のようなリソースが作成されます.
NAME | TYPE | STATE |
---|---|---|
main-one-subscription | pubsub.v1.subscription | COMPLETED |
main-one-topic | pubsub.v1.topic | COMPLETED |
main-two-subscription | pubsub.v1.subscription | COMPLETED |
main-two-topic | pubsub.v1.topic | COMPLETED |
PREFIX
変数に,デプロイの名前を示す環境変数であるenv["deployment"]
と,現在のname
を示す環境変数であるenv["name"]
を結合した文字列を代入しており,その結果上記のように,main-one, main-twoという名前になります.
dependsOn
Pub/Subのsubscriptionを作成する時にtopicが存在しないとエラーになるので,依存関係を明示しています.
Creating Explicit Dependencies
テンプレート プロパティ
Pub/Subを起動するCloud Schedulerを作成するために,上記のテンプレートを拡張します.
template_pubsub.jinja
{% set PREFIX = env["deployment"] + "-" + env["name"] %} {% set TOPIC_NAME = PREFIX + "-topic" %} {% set SUBSCRIPTION_NAME = PREFIX + "-subscription" %} {% set SCHEDULER_NAME = PREFIX + "-scheduler" %} resources: - name: {{ TOPIC_NAME }} type: pubsub.v1.topic properties: topic: {{ TOPIC_NAME }} - name: {{ SUBSCRIPTION_NAME }} type: pubsub.v1.subscription properties: subscription: {{ SUBSCRIPTION_NAME }} topic: projects/{{ env["project"] }}/topics/{{ TOPIC_NAME }} metadata: dependsOn: - {{ TOPIC_NAME }} - name: {{ SCHEDULER_NAME }} type: gcp-types/cloudscheduler-v1:projects.locations.jobs properties: parent: projects/{{ env["project"] }}/locations/{{ properties["zone"] }} description: my scheduler schedule: "* * * * *" timeZone: "Asia/Tokyo" pubsubTarget: topicName: projects/{{ env["project"] }}/topics/{{ TOPIC_NAME }} data: e30= # base64 encoded "{}"
main.yaml
imports: - path: template_pubsub.jinja resources: - name: one type: template_pubsub.jinja properties: zone: asia-northeast1 - name: two type: template_pubsub.jinja properties: zone: asia-northeast1
テンプレート プロパティとは,properties["zone"]
のように,呼び出し元のpropertiesを参照する機能のことです.main.yamlにzone: asia-northeast1
が指定されているので,この値が代入されます.
main.yaml
をデプロイすると,asia-northeast1に以下のリソースが作成されます.
NAME | TYPE | STATE |
---|---|---|
main-one-scheduler | gcp-types/cloudscheduler-v1:projects.locations.jobs | COMPLETED |
main-one-subscription | pubsub.v1.subscription | COMPLETED |
main-one-topic | pubsub.v1.topic | COMPLETED |
main-two-scheduler | gcp-types/cloudscheduler-v1:projects.locations.jobs | COMPLETED |
main-two-subscription | pubsub.v1.subscription | COMPLETED |
main-two-topic | pubsub.v1.topic | COMPLETED |
Cloud Schedulerはデプロイ後は自動的に有効になり,1分毎に (" * * * * * ") Pub/Subを起動します.
以上で,Cloud Deployment Managerを使ってデプロイができるようになりました.また,jinjaテンプレート,環境変数,テンプレート プロパティを使うことで,効率的にリソースを記述することができるようになりました.
*1:Release Notes | Cloud Deployment Manager Documentation | Google Cloud
*2:Announcing HashiCorp Terraform 0.14 General Availability
*3:「Deployment Manager のテンプレートを作成するには、Python または Jinja2 を使用します。Python テンプレートの使用をおすすめします。 」再利用可能なテンプレートについて | Cloud Deployment Manager のドキュメント | Google Cloud より