Open6

10分でNixOSをデプロイする

natsukiumnatsukium

このスクラップのゴール

執筆速度が遅すぎて完成するまで記事を公開しないという進め方では知識が失われてしまう
そこで散逸的にスクラップとして情報を公開し、ある程度出揃った時点で記事としてまとめて公開する
スクラップ内の情報について正しさは保証しないし、文章としての整合性も重視しない

natsukiumnatsukium

はじめに

NixOSは宣言的に構成を記述できるのがメリットであるが、これまでインストールの際にはどうしても手作業で命令的に操作しなければならなかった。
例えばインストールイメージの用意やディスクのパーティショニングなど、対話的に作業することは多い。

これに対してdiskoというツールが登場し、まだ荒削りではあるものの、宣言的にディスクをパーティショニングできるようになった。

クラウドの仮想マシンに目を向けるとAWSのEC2にはNixOSのイメージが提供されているが、ほとんどのプロバイダでは提供されていない。
したがってそれらの上でNixOSを利用するためには各自イメージをビルドしてアップロードするか、例えばUbuntuなどを起動し、その上で kexec を使ってOSを書き換える必要がある。
これから紹介するnixos-anywhereは先述した disko を利用して、コマンド一つでこれらの面倒な作業を実行し、SSHで到達可能な全てのサーバー上にNixOSをデプロイするツールである。

natsukiumnatsukium

目指すところ

terraformとnixos-anywhereを使って、NixOSマシンを宣言的にデプロイし、すぐに実用的に使い始められるようになる

この記事では terraform を使って、 Oracle Cloud Infrastructure 上に Arm 環境の NixOS をデプロイする。
terraform apply のコマンドひとつで、インスタンスの作成からNixOSの設定まで全て完了した状態に持っていく。

次により実践的な例として私の実際の構成を紹介する。
ここでは上記の内容に加えて、 sops-nix によるシークレット管理、 btrfs と impermanence による非永続なルートシステムを実現している。

terraform の使い方や OCI に関することは対象外とする。

natsukiumnatsukium

必要なもの

  • クラウドプロバイダのアカウント
    • この記事ではOracle Cloud Infrastructureを使用する
  • Nixをインストールしたマシン
    • NixOSである必要はない
  • SSH認証鍵
natsukiumnatsukium

手順

必要なファイルは下記リポジトリを参照のこと。
https://github.com/natsukium/nixos-oci-a1-flex-example

各ファイルについて

  • disko-config.nix
    ディスクのパーティショニングを記述する
    設定例は[disko]にある
    設定例からの変更点は disko.devices.disk.vdb.device の属性を /dev/sda に変更している
    これは事前に適当なインスタンスを立て、 lsblk を実行することで確認できる
    今回は簡単に様々なファイルシステムを定義できることを実証するため、 Linux 6.7 でメインラインに統合された bcachefs を選択した

  • flake.lock
    flake.nix に記述されたインプットのためのロックファイル
    今回は NixOS 23.11 を使用するため頻繁に更新されることはないが、セキュリティアップデートを受けるために時折 nix flake update コマンドで更新すると良い

  • flake.nix
    今回デプロイするシステムの構成を記述する
    また、デプロイに使用する terraform とそのプロバイダを提供する開発環境も提供する

  • hardware-configuration.nix
    各ハードウェア固有の設定が記述された設定ファイルで、システム構成に必要
    適当なインタンス上で nixos-generate-config --no-filesystem を実行することで生成される

  • main.tf
    terraform で管理するリソースを記述する
    OCI でインスタンスを作成するための最低限の設定と、 nixos-anywhere から提供されるモジュールの設定を行う

  • variable.tf
    OCI の資格情報など、各個人により異なるデータを記述する
    https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/developer-tutorials/tutorials/tf-provider/01-summary.htm#prepare
    上記ページを参考に、 RSA キーの作成と必要な情報の収集しておく

natsukiumnatsukium

実例

https://github.com/natsukium/dotfiles/tree/e1bcb14052afdc92746f952a393b4f8304e43cf4/infra
https://github.com/natsukium/dotfiles/tree/e1bcb14052afdc92746f952a393b4f8304e43cf4/nix/systems/nixos/serengeti
https://github.com/natsukium/dotfiles/blob/e1bcb14052afdc92746f952a393b4f8304e43cf4/nix/systems/nixos/common.nix

私が実際に運用しているインスタンスは主に上記のディレクトリ、ファイルで設定している。
この記事の目的で述べたように、このシステムではシークレットの管理に sops-nix 、なるべく状態をイミュータブルに保つために impermanence を採用した。

sops-nix は sops というツールを利用して暗号化されたシークレットを管理するためのツールで、NixOS の設定ファイルに暗号化されたシークレットを埋め込むことができる。

たとえば始めの例ではインスタンスの初期パスワードを設定ファイルにベタ書きしている。

https://github.com/natsukium/nixos-oci-a1-flex-example/blob/2481d4b9eb9e52efed8c056bf43dda9f07fff7d3/flake.nix#L79C2-L85

これではあとから変更できるとはいえ、あまりにもセキュリティの意識に欠けている。さらにあとから変更するというのは設定にミュータブルな状態を付与するということにほかならない。
そこで sops-nix の出番である。

https://github.com/natsukium/dotfiles/blob/e1bcb14052afdc92746f952a393b4f8304e43cf4/nix/systems/nixos/common.nix#L95-L109