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?

一人アドカレ 24日目: DNSの管理をterraformで

Posted at

イントロ

ここまでTraefikによるリバースプロキシサーバーの構築や各種アプリケーションの導入方法を紹介してきました。
最後にドメインのDNS管理をTerraformで行う方法を紹介しようと思います。

なぜこれが必要なのか?

一つのサーバーだけ、あるいは複数のサーバーでも、ワイルドカードを用いたルール設定をしておけば、いちいちDNS設定をする必要はありません。

  • ServerA --> *.serv.domain.tld
  • ServerB --> *.app.domain.tld

とはいえ、第3レベル・第4レベルドメインを使うとドメインが長くて鬱陶しいです。
しかし、第2レベルドメインをアプリケーション名にしてしまうと、DNS設定が面倒になります。

ということで、yamlによる定義とその定義を読み取ってterraformでDNS設定を行う方法を紹介します。

スクリプトとか

リポジトリは下記です。Forgejoで管理を行って、定期的にGitHubにpushさせています。
私自身はドメインをCloudflareで管理しているので、CloudflareのDNSレコードを管理する例になります。
なお、データベースはNEONを使うことで、無料でサーバーレスPostgreSQLを使っているのでDBの立ち上げも不要です。

https://github.com/sinsky/terraform-dns-management

  1. 構成の全体像
    ルートの main.tf でドメインごとのモジュールを呼び出す構成になっています。

    .
    ├── main.tf              # 全体構成(モジュールの呼び出し)
    ├── variables.tf         # APIトークンやZone IDの定義
    └── modules/             # ドメインごとのモジュール
        ├── domain.tld/
        │   ├── main.tf      # YAMLを読み込み、レコードを生成するロジック
        │   ├── vps.yaml     # サーバー関連のレコード定義(データ)
        │   ├── mail.yaml    # メール関連のレコード定義(データ)
        │   └── ...
        └── example.com/
            └── ...
    
  2. スクリプトのポイント:YAMLベースの管理

    各モジュールの main.tf では、yamldecode を使用してYAMLファイルを読み込み、for_each で動的に cloudflare_dns_record リソースを生成しています。
    そのため、私が管理しないといけないのは各yamlファイルだけです。

    modules/domain.tld/main.tf
    # 抜粋
    locals {
    vps         = yamldecode(file("${path.module}/vps.yaml"))
    mail        = yamldecode(file("${path.module}/mail.yaml"))
    tailscale   = yamldecode(file("${path.module}/tailscale.yaml"))
    # 複数のYAMLファイルをマージして一つのリストにする
    dns_records = merge(local.vps, local.mail, local.tailscale)
    }
    
    resource "cloudflare_dns_record" "records" {
    for_each = local.dns_records
    
    zone_id = var.zone_id
    name    = each.value.name
    type    = each.value.type
    content = each.value.content
    proxied = lookup(each.value, "proxied", false)
    }
    
  3. 設定ファイル(YAML)の形式

    用途ごとにファイルを分割することで、管理のしやすさを向上させています。

    /modules/domain.tld/vps.yaml
    beszel:
        name: beszel
        type: A
        content: 100.x.x.x
        proxied: false
        comment: "Beszel in Tailscale server"
    
  4. この構成のメリット

    • 可読性の向上: DNSレコードの追加・修正時にTerraformの構文を意識せず、シンプルなYAMLを編集するだけで済む
    • 責務の分離: インフラのロジック(モジュール側)と、実際のレコード値(YAML側)が分かれているため、構成の変更が簡単
    • カテゴリ管理: mail.yaml や tailscale.yaml のように役割ごとにファイルを分けることで、自分なりの管理カテゴリが作れる
    • 自動化: .forgejo/workflows/ に定義されたCI/CDパイプラインにより、プルリク前提の組み方が可能

まとめ

TerraformでDNS管理を行うことで、わざわざ管理コンソールにログインして設定を変更する手間が省けました。
YAMLベースの管理によって、私自身のルールでファイルを分割、整理できるため、可読性も向上しています。
CI/CDパイプラインにより、プルリクの際にフォーマットのテスト、マージされたら自動で適用まで行ってくれるため、運用も楽になりました。
ぜひ皆さんも試してみてください。

なお、Terraform経験はあまりないので、生成AIによる作成です。今のところ、うまくいっています。

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?