0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

terraform workspaceで茨の道を歩いてみた

Last updated at Posted at 2023-12-13

この記事は3-shake Advent Calendar 2023 シリーズ2の14日目の記事です。

ほぼほぼ興味本位でterraform workspaceを用いて使い始めてみたものの、中々に茨の道でした...

そんなお話しです。

背景

とあるお仕事にてAWSにてインフラ構築することになりました。いつものようにTerraformを使おうと思ったのですが、ふと思い出してworkspaceの存在を思い出しました。経験もなかったですしちょっと興味があったので以下の理由もあることから採用してみました。

  • そこまで大きな規模でもなく、
  • 環境間の差分もあまりなさそうだったため
  • 何より使ったことないから試してみようっていう好奇心97%

今回のお話では環境ごとの差分を吸収する目的が前提になります。

Terraform workspaceについて

“面”をworkspaceとして管理し、同じコードベースで複数面を管理できるような仕組みです。
バックエンドにこの複数の面のに対応するtfstateファイルが作られます。

terraform workspace -h
Usage: terraform [global options] workspace

  new, list, show, select and delete Terraform workspaces.

Subcommands:
    delete    Delete a workspace
    list      List Workspaces
    new       Create a new workspace
    select    Select a workspace
    show      Show the name of the current workspace

まずはworkspaceを作りましょう。

terraform workspace new prd
terraform workspace new stg
terraform workspace new dev

terraform workspace list
  default
  dev
  prd
  stg

workspaceを切り替えます。

bucket = "stg-tf"
region = "ap-northeast-1"
key  = "inf.tfstate"
encrypt = true
shared_credentials_file = "[$HOME/.aws/credentials]"
profile = "stg"

workspaceをセレクトして、initします。

terraform workspace select stg
terraform init -reconfigure -backend-config=backends/stg.tfbackend

で、どうだった?

辛くなっちゃった。

Q: 何が辛かった?

A: ユースケースにあっていなかった

当初聞いたところでは環境差分はあまりなく、1回作って複製していこうって話だった。だが、そもそも環境ごとにインフラが管理するスコープが違ったり、シンプルに「この環境にはこれが必要」ということが発生しました。

公式では以下のような注釈があります。

In particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages or different internal teams. In this case, the backend for each deployment often has different credentials and access controls. CLI workspaces within a working directory use the same backend, so they are not a suitable isolation mechanism for this scenario.

平たく言うと dev / stg / prdのような開発段階の違う環境を管理する場合には不向きとのこと。

逆に一般的なユースケースとして以下が挙げられていました。

A common use for multiple workspaces is to create a parallel, distinct copy of a set of infrastructure to test a set of changes before modifying production infrastructure.

同じ環境を複数個作成する、本番を変更する前のテストとしてコピーを作成するみたいなこと。

すなわち茨の道を大地を力強く蹴り上げるように歩き続けていました。

ここからは上記に合わないアンチパターンをどストライクで踏んだ私が、どういう点が不向きなのかを体験をもとに話します。

コーディングが煩雑になる

workspace名を変数にしてリソースの有無を表現することになるので、このような記述があります。

resource "aws_lb" "alb" {
  name               = var.name
  load_balancer_type = "application"
  internal           = var.enable_internal
  idle_timeout       = 60
  enable_deletion_protection = (
    terraform.workspace == "infra-dev" ? false :
    terraform.workspace == "dev" ? false : true
  )

コスト最適化で環境ごとにインスタンスサイズや数、SPOTインスタンス化などなどやりますよね?
そのたびに環境差分が多くなると、こういった記法が乱立します。

バージョンアップをdev→stg→prdのように環境を追って順繰りに行えない

Terraform使っているということは、Core, Providerともにバージョンアップ作業しますよね?
基本的には上記のように環境を追って実施していくと思います。

以下のようなterraformブロックのrequired_versionを書き換えて、再init → 必要に応じて修正 → 差分解消・apply が基本的な流れだと思います。

terraform {
  required_version = "1.3.5"
  backend "s3" {
  }

  required_providers {
    aws = "4.39.0"
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = ">=2.16.0"
    }
    tls = {
      source  = "hashicorp/tls"
      version = ">= 3.0"
    }
  }
}

しかし、terraformブロック自体もlockファイルも環境ごとに用意できません。

先ほどの一般的なユースケースを鑑みるとそりゃそうだよなと思いますので、確かに納得感はあります。

まとめ

こんな感じで使ってみて辛さはあったものの、その分このworkspace機能についてだいぶ解像度見ることができました。
ユースケースにおける所感をまとめると以下のような感じです。

  • dev / stg / prdのように環境差分を吸収するような一般的な目的で使うものではない
  • 逆に複数人に全く同じ開発環境を払い出したり、本番前のテストapplyなどでは有用に感じる

少し大変ですが、後でマージして移行することもできそうな肌感なので、Terraformにおける初手のリポジトリ構造は一旦ワーキングディレクトリの切り替え前提で問題ないと思いました。

ぜひユースケースごとの選択肢の一つとして頭の片隅に置いていただけると幸いです〜

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?