みーのぺーじ

みーが趣味でやっているPCやソフトウェアについて.Python, Javascript, Processing, Unityなど.

Cloud Deployment Manager まとめ

自分の勉強のために,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が完成します.

Deployment Manager Console

Pub/Sub Console

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を起動します.

f:id:atsuhiro-me:20210104183554p:plain

以上で,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 より