サイトアイコン

toLog

CDKTF の GcsBackend (remote backend) の prefix を被らないようにした

  • 更新日:
  • 投稿日:

お困りごと

ここ最近 CDKTF(主に GCP を取り扱いたい)を始めたのですが、スタックの状態(tfstate)をローカルからリモートに保存するために Remote Backend を触り始めたところ、複数のスタックをデプロイ・更新する度に、古いスタックが消されるという状況に陥りました 🤔

この際、prefix には、公式の Example を参考に terraform/state を設定していました。

1class MyStack extends TerraformStack {
2  constructor(scope: Construct, name: string) {
3    super(scope, name);
4
5    new GcsBackend(this, {
6      bucket: "tf-state-prod",
7      prefix: "terraform/state", // <- ここ
8    });
9  }
10}

Cloud Storage に保存される tfstate ファイルを確認すると、別々のスタックをデプロイする度に、tfstate が丸々更新されて一番新しいスタックしか存在しない状態になっていました。
つまり、同じ prefix だと、単一の tfstate ファイルで単一のスタックだけを保存・管理する挙動になっていました。

そこで、ローカルの tfstate ファイルの挙動に注目してみると、スタックごとに別々のファイルで保存されているので、リモート側でも同様に別々で保存する必要があることに気づきました。

公式では prefix オプションは次のように説明されています。

prefix - (Optional) GCS prefix inside the bucket. Named states for workspaces are stored in an object called <prefix>/<name>.tfstate.

prefix - (オプション) バケット内のGCSプレフィックス。ワークスペースの名前付きステートは、<prefix>/<name>.tfstate というオブジェクトに格納されます。

name がどこから来たのかも気になるのですが(name のオプションはない)、この name を基準に別々の tfstate ファイルが生成されそうですが、実際の挙動では、prefix が同じだと上書きされてしまうようです 🤔

私が使い方を大きく勘違いしている気もしますが...よく分かっていない 😅

対応策

サンプルのように GcsBackendprefix にスタック ID を渡してユニークにして、スタックごとに tfstate を分離、別スタックの追加・更新の影響を受けないようにしました。

1import { Construct } from "constructs";
2import { TerraformStack, GcsBackend } from "cdktf";
3import { GoogleProvider } from "@cdktf/provider-google/lib/provider";
4
5export class ExampleStack extends TerraformStack {
6  constructor(scope: Construct, id: string) {
7    super(scope, id);
8
9    new GcsBackend(this, {
10      bucket: "example-bucket-name",
11      prefix: id, // <- ここをユニークな値にする!!!
12    });
13
14    new GoogleProvider(this, "GoogleProvider", {
15      project: "example-project-id",
16      region: "asia-northeast1",
17    });
18
19    // ...
20  }
21}

おわりに

TypeScript & CDK ライク で GCP インフラを書けるのは、最高です 👍


プロフィール画像

canji

とにかく私的にサービスを作りたい発作を起こしている。お腹はペコペコ。

  • toLog Tools icon
  • dots icon