Generate bolt targets from Terraform state

Generate bolt targets from Terraform state

現在個人サーバーの管理を Terraform で、サーバーのプロビジョニングを Bolt で行なっています。

Bolt ではインベントリファイルを使用してターゲットとなるサーバーを指定できます。インベントリファイルは例えば以下のような内容です。

groups:
  - name: production
    targets:
      - web.example.com
      - db.example.com
      - app.example.com
    config:
      ssh:
        host-key-check: false
        user: centos
        private-key: ~/.ssh/id_rsa
        run-as: root

↑のようにターゲットのサーバーを指定できるのですが、ドメイン名ではなく Terraform で作成し動的に変化、増減する IP アドレスの場合はどうすべきか悩んでいました。手動でいちいち変更するのはなんだかなーですし。

色々調べた結果、なんとインベントリのプラグインに terraform プラグインがあり、しかもビルトインプラグインなので特にモジュールをインストールせず使えるではありませんか!!
ということで試してみました。 ✨

例えば tf ファイルで以下のように記述されており、Terraform の state ファイルの場所に remote バックエンドを使用している場合、

resource "digitalocean_droplet" "nomad-server-nodes" {
  count              = 3
  image              = "centos-7-x64"
  name               = "nomad-server-${count.index}"
  region             = "sgp1"
  size               = "s-1vcpu-1gb"
  backups            = false
  private_networking = true
  ssh_keys           = [digitalocean_ssh_key.nomad-nodes-ssh.fingerprint]
  tags               = ["nomad-server-node"]
}

先ほどのインベントリファイルはこうなります。

  • dir で terraform のルートディレクトリを指定する。path は Boltdir を起点に相対パスで設定できる。
  • resource_type で tf ファイルで使用しているリソースタイプ (digitalocean_droplet)、ローカル名 (nomad-server-nodes) を . で繋げて指定する。
  • backend で Terraform の state のバックエンドを指定する。私の場合 remote バックエンドを使用しているので remote を指定。
  • target_mapping でターゲットとして指定すべき属性をマッピングする。例えば、digitalocean_droplet タイプはエクスポートされる属性として ipv4_address を持っている。この属性とマッピングすることで作成されたサーバーの IP アドレスがターゲットとしてマッピングされる。
groups:
  - name: production
    targets:
      - _plugin: terraform
        dir: ..
        resource_type: digitalocean_droplet.nomad-server-nodes
        backend: remote
        target_mapping:
          uri: ipv4_address
    config:
      ssh:
        host-key-check: false
        user: centos
        private-key: ~/.ssh/id_rsa
        run-as: root

インベントリファイルに具体的なターゲット名を記述していないのに、以下のようにターゲットの情報を自動で取得しアクセスできるようになりました。 🌈

$ bolt command run 'free -m' --targets production
Started on 157.230.36.124...
Started on 178.128.111.248...
Started on 165.22.100.237...
Finished on 165.22.100.237:
  STDOUT:
                  total        used        free      shared  buff/cache   available
    Mem:            991         360          78          60         552         388
    Swap:          2047           4        2043
Finished on 157.230.36.124:
  STDOUT:
                  total        used        free      shared  buff/cache   available
    Mem:            991         427          72          57         491         320
    Swap:          2047           9        2038
Finished on 178.128.111.248:
  STDOUT:
                  total        used        free      shared  buff/cache   available
    Mem:            991         566          81          33         343         209
    Swap:          2047         102        1945
Successful on 3 targets: 165.22.100.237,157.230.36.124,178.128.111.248

この機能は本当に最の高です!!!!!ぴえん 🥺