😆

atmosを使ってterraformをいい感じに管理したい

2024/12/10に公開

この記事は、tacoms Advent Calendar 2024の10日目です!
他メンバーのAdvent Calendarはこちらからご覧ください!👇
https://qiita.com/advent-calendar/2024/tacoms

はじめに

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/ より引用

再利用可能なコンポーネントを分割して、それをうまいこと使えるよってことでしょうか。
https://atmos.tools/introduction/

チュートリアルを試す

使用するチュートリアルはこちら。
https://atmos.tools/quick-start/simple/

ディレクトリ構成

├── 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を追加していくことになる
  • 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の設計パターンが多く書かれており、ここら辺の理解を深めると使いやすいかもしれないです。
https://atmos.tools/best-practices/components

tacomsテックブログ

Discussion