atmosを使ってterraformをいい感じに管理したい
この記事は、tacoms Advent Calendar 2024の10日目です!
他メンバーのAdvent Calendarはこちらからご覧ください!👇
はじめに
Terraformの実装が増えるほど、「もっとDRYに書きたい」「コンポーネントをうまく活用したい」といった願望が生まれてくるのではないでしょうか。そんな中で登場したのが Terragrunt だと考えています。このツールのおかげで、Terraformを比較的DRYに書けるようになったと感じています。個人的には、Terragruntは非常に使いやすく、初心者でも取り組みやすいツールだと思っています。
一方で、他にも似たようなツールがあるのではないかと思い、調べてみたところ、Atoms というツールを見つけました。この記事では、このツールを試して結果を書いていきたいと思います。
atmosとは
Use Atmos to break your architecture into reusable Components that you implement using Terraform "root modules". Then, tie everything together using Stack configurations defined in YAML.
https://atmos.tools/introduction/ より引用
再利用可能なコンポーネントを分割して、それをうまいこと使えるよってことでしょうか。
チュートリアルを試す
使用するチュートリアルはこちら。
ディレクトリ構成
├── atmos.yml
├── components
│ └── terraform
│ └── weather
│ ├── main.tf
│ ├── outputs.tf
│ └── variable.tf
└── stacks
├── catalog
│ └── station.yaml
└── deploy
├── dev.yaml
└── staging.yaml
いろんな言葉が出てきてわからんとなったので、整理していきたいと思います。
- components/terraform
- 最小のリソースのかたまり。ここにterraformの実装が入るぽい。例えば上記例だと
components/terraform/weather
ディレクトリが最小のコンポーネントになる。このcomponents/terraform/
ディレクトリにどんどんcomponentを追加していくことになる
- 最小のリソースのかたまり。ここにterraformの実装が入るぽい。例えば上記例だと
- stacks/deploy
- 実際のdeployの単位。環境毎のファイルをここで用意する
- stacks/catalog
- deployディレクトリで使用する共通の変数を扱う
各ファイル
atmos.yml
にはディレクトリ全体の設定を記載します。
base_path: "./"
components:
terraform:
base_path: "components/terraform"
apply_auto_approve: false
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: false
stacks:
base_path: "stacks"
included_paths:
- "deploy/**/*"
excluded_paths:
- "**/_defaults.yaml"
name_pattern: "{stage}"
logs:
file: "/dev/stderr"
level: Info
stacks/catalog/station.yaml
では、共通のコンポーネントを宣言します。vars セクションでは、そのコンポーネントに渡す必要がある引数を指定しています。これらの引数は、主に stacks/deploy
ディレクトリ内で共通して使用されるものが中心となっています。
components:
terraform:
station:
metadata:
component: weather # 共通のcomponent
vars:
location: Los Angeles
lang: ja
format: ''
options: '10'
units: m
最後にstacks/deploy/dev.yaml
です。これがdev環境にデプロイするという意味合いとなります。catalog/station
をimportしているのは上記で記載した共通の変数を使うためで、dev環境だけ適応したい変数のみこのファイルに記載するようになっています。考え方はkubernetesのkustomizeと似たような感じでしょうか。
vars:
stage: dev
import:
- catalog/station
components:
terraform:
station:
vars:
location: Stockholm
lang: se
上記で説明したdev環境のplanを実行する場合は以下のようなコマンドになります。
$ atmos terraform plan station -s dev
複数環境にさまざまなコンポーネントをデプロイするとき
チュートリアルでなんとなく使い方はわかったので、実際によくあるterraformの構成を考えてみたいと思います。
ディレクトリ
今回想定するディレクトリは以下の通りです。
複数の環境があってその中に複数のcomponentが存在する構成です。まあよくある構成ですね。
└── prod
├── app
│ ├── main.tf
│ └── variable.tf
├── network
│ ├── main.tf
│ └── variable.tf
├── db
│ ├── main.tf
│ └── variable.tf
└── stg
...
└── dev
...
上記をatmosを使うとこんな感じになるかなと思います。
├── atmos.yml
├── components
│ └── terraform
│ └── app
│ ├── main.tf
│ ├── outputs.tf
│ └── variable.tf
│ └── network
│ ├── main.tf
│ ├── outputs.tf
│ └── variable.tf
│ └── db
│ ├── main.tf
│ ├── outputs.tf
│ └── variable.tf
└── stacks
├── catalog
│ └── app.yaml
│ └── network.yaml
│ └── db.yaml
└── deploy
├── dev.yaml
└── staging.yaml
└── prod.yaml
各ファイル
app.yaml
はチュートリアルと同じように共通の引数を渡し、どのcomponentを使うかを宣言します。
components:
terraform:
app:
metadata:
component: app
vars:
project_id: hogehoge
sample: sample
dev.yaml
には複数のcomponentを読み込ませます。その上でcomponent毎に設定を書いていきます。最後にatmos terraform plan app -s dev
のようなコマンドを実行すればplanが実行されます。
vars:
stage: dev
import:
- catalog/app
- catalog/network
- catalog/db
components:
terraform:
app:
metadata:
component: app
inherits:
- app
vars:
project_id: dev
network:
metadata:
component: network
inherits:
- network
vars:
project_id: dev
db:
metadata:
component: db
inherits:
- db
vars:
project_id: dev
おわりに
まだ不慣れなこともあってか、正直terragruntの方が使いやすいなと感じましたw
ただドキュメントにはcomponentの設計パターンが多く書かれており、ここら辺の理解を深めると使いやすいかもしれないです。
Discussion