TerraformerでGmailフィルタプロバイダーのコードをリバース生成する

はじめに: TerraformerへGmailフィルタプロバイダー対応がマージされた

既存の環境からTerraformのコード(tfファイル)+Stateファイル(terraform.tfstate)を生成してくれるTerraformerというツールがあります。

github.com

本日、このTerraformerにGmailフィルタプロバイダー対応を追加するPRがマージされました。

github.com

これにより、既にブラウザからある程度フィルタを作成済みのアカウントでもterraform-provider-gmailfilterを利用しやすくなりました。

背景

terraform-provider-gmailfilterについては以前以下の記事を書きました。

febc-yamamoto.hatenablog.jp

このプロバイダーはgmailfiltersというツールにインスパイアされて作成したものです。
ただ、gmailfiltersには既存のフィルタをエクスポートする機能がありますがこのプロバイダーでは実装していませんでした。

このため、既にGmail上でラベルやフィルタを作成済みのアカウントではGmailフィルタプロバイダーを導入するのが若干面倒でした。 (インポート機能は実装済みなため、tfファイルを書いて個別にインポートしていけば対応できてましたが面倒ですよね)

エクスポートについては、既に既存の環境からTerraformのコード(tfファイル)+Stateファイル(terraform.tfstate)を生成してくれるツールがいくつか存在するため、 プロバイダー側で提供するのではなくそれらを利用した方が良いと考えていたからです。

このために、それらのツールの中でも個人的に1番のお気に入りであるTerraformerGmailフィルタプロバイダー対応を行い、本日無事にマージされました。

使い方

Terraformerのビルド

今はまだマージされたばかりでこの変更を含めたリリースが行われていない状態ですので、利用するにはソースからビルドする必要があります。
README.mdを参考に手元でビルドします。

今回はDocker上でビルドしてみました。

# ソース一式をクローン
$ git clone https://github.com/GoogleCloudPlatform/terraformer.git; cd terraformer

# ビルド用コンテナ起動
$ docker run -it --rm -v $PWD:$PWD -w $PWD golang:1.14

# 依存モジュールのダウンロード
$ go mod download

# ビルド(ここではmacos向けにビルドしてます)
$ GOOS=darwin GOARCH="amd64" go build -v

これでカレントディレクトリにterraformer実行ファイルが生成されます。

Gmailフィルタプロバイダーのインストール

次にGmailフィルタプロバイダーをインストールしておきます。 こちらのリリースページから実行ファイルをダウンロードし、~/.terraform.d/plugins/darwin_amd64/配下(macosの場合)に配置しておきます。

Gmail APIの認証(Gmailフィルタプロバイダーを利用したことがない方)

次にGmail APIを有効にし、APIを利用するための認証設定を行なっておきます。 今回はApplication Default Credentialsを利用します。

まずは以下に従いAPIコンソールからGmail APIを有効化します。

support.google.com

次にクレデンシャルの作成、OAuthクライアントの作成、シークレットファイルのダウンロードを行います。 ダウンロードしたファイルはclient_secret.jsonという名前で保存しておきます。

保存したら以下のコマンドを実行します。

gcloud auth application-default login \
  --client-id-file=client_secret.json \
  --scopes \
https://www.googleapis.com/auth/gmail.labels,\
https://www.googleapis.com/auth/gmail.settings.basic

実行するとブラウザでアクセスを許可しても良いか尋ねる画面が開きますので画面に従い許可していきます。

これで準備完了です。

Terraformerの実行

あとはTerraformerを実行するだけです。
以下のコマンドで既存のラベルとフィルタからtfファイル+terraform.tfstateファイルを生成できます。

$ ./terraformer import gmailfilter -r label,filter

デフォルトだとカレントディレクトリ配下のgenerated/gmailfilter/{filter,label}ディレクトリに以下のようなファイルが生成されます。

例: generated/gmailfilter/filter/filter.tf

resource "gmailfilter_filter" "tfer--ANe1BmgZqKtSU0e8o24MkdHlWUd6JsoQ9PRIug" {
  action {
    add_label_ids    = ["${data.terraform_remote_state.label.outputs.gmailfilter_label_tfer--Google_id}"]
    remove_label_ids = ["INBOX"]
  }

  criteria {
    exclude_chats  = "false"
    has_attachment = "false"
    query          = "from:mail-noreply@google.com"
    size           = "0"
  }
}

resource "gmailfilter_filter" "tfer--ANe1BmiABTbNsxNxhKfdIlJN-002D-2BJRicNJdqRYQ" {
  action {
    add_label_ids    = ["${data.terraform_remote_state.label.outputs.gmailfilter_label_tfer--parent_child_id}"]
    remove_label_ids = ["INBOX"]
  }

  criteria {
    exclude_chats  = "false"
    from           = "foobar@example.com"
    has_attachment = "false"
    size           = "0"
  }
}

# ...

例: generated/gmailfilter/label/label.tf

resource "gmailfilter_label" "tfer--Google" {
  label_list_visibility   = "labelShow"
  message_list_visibility = "show"
  name                    = "Google"
}

resource "gmailfilter_label" "tfer--parent" {
  label_list_visibility   = "labelShow"
  message_list_visibility = "show"
  name                    = "parent"
}

resource "gmailfilter_label" "tfer--parent_child" {
  label_list_visibility   = "labelShow"
  message_list_visibility = "show"
  name                    = "parent/child"
}

リソース名が若干長いのが気になりますが、1からtfファイルを書くよりこれを編集していく方が楽だと思います。

注意点

生成されるコードではサブラベルでの親ラベルへの依存の設定がうまくいかないです。 サブラベルを利用している場合は適宜tfファイルを書き換える(label.tfのnameなど)必要がありますのでご注意ください。

# 変更前
resource "gmailfilter_label" "tfer--parent_child" {
  label_list_visibility   = "labelShow"
  message_list_visibility = "show"
  name                    = "parent/child"
}

# 変更後
resource "gmailfilter_label" "tfer--parent_child" {
  label_list_visibility   = "labelShow"
  message_list_visibility = "show"
  name                    = "${gmailfilter_label.tfer--parent.name}/child"
}

終わりに

ということでTerraformerを併用することでGmailプロバイダーのコードを書くのが少し楽になりそうです。
是非お試しください。

以上です。