5
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?

さくらインターネットAdvent Calendar 2024

Day 25

さくらのクラウドでcloud-initを使ってみた

Last updated at Posted at 2024-12-25

本記事は、さくらインターネット Advent Calendar2024 25日目の記事です。

さくらのクラウドでcloud-initを使ってみたので、学んだことを利用例と合わせて記載します。

cloud-initって何?

cloud-initは、クラウド環境においてインスタンスの初期設定を自動化するツールです。

cloud-initを使うと、以下のようなことができます。

  • ユーザーの作成
  • SSH鍵の設定
  • パッケージのインストール
  • ホスト名の設定
  • ネットワークの設定
  • スクリプトやコマンドの実行

他にもいろいろなことができます。
詳しいことは公式ドキュメントを参照ください。

さくらのクラウドでも、cloud-initを使ってサーバーの起動時に初期設定を行うことができます。

cloud-initを使ってみる

cloud-init | さくらのクラウド マニュアルを参考に使ってみます。

さくらのクラウドでcloud-initを使うには、名前の末尾に「(cloudimg)」が付くパブリックアーカイブを選ぶ必要があります。
この記事では、「Ubuntu Server 20.04.6 LTS 64bit (cloudimg)」を選びます。

追加ユーザデータには、以下を入力します。

user_data
password: $6$rounds=4096$aUONx5Ru8eTS$a9QMv8zx6C7DQXMvtYeJqxzeCyQ9KF6Aap.mGXECmADcNo/Qe9jWFABKfOWFQojr/grq3rdzNKGvJIzo1ekuU.

これは、デフォルトユーザーのパスワードをpasswordにするための設定です。

サーバーが起動したら、以下でログインできるようになっているかと思います。

  • ユーザー名:ubuntu
  • パスワード:password

Terraformからcloud-initを使ってみる

Terraform for さくらのクラウド(v2)では、sakuracloud_serveruser_dataにユーザデータを与えることでcloud-initを使うことができます。
詳しくはサーバ - Terraform for さくらのクラウド(v2)を参照ください。

例えば、以下のようなコードで、cloud-initで初期設定を行うサーバーを構築することができます。

main.tf
data "sakuracloud_archive" "ubuntu_cloudimg" {
  filter {
    tags = [
      "cloud-init",
      "distro-ubuntu",
    ]
  }
}

resource "sakuracloud_disk" "root" {
  name              = "test"
  description       = "Root volume"
  plan              = "ssd"
  size              = 20
  source_archive_id = data.sakuracloud_archive.ubuntu_cloudimg.id

  lifecycle {
    create_before_destroy = true
    ignore_changes = [
      source_archive_id,
    ]
  }
}

resource "sakuracloud_server" "test" {
  name        = "test"
  core        = 1
  description = "Test server"
  disks       = [sakuracloud_disk.root.id]
  memory      = 1

  user_data = templatefile("templates/cloud-config.yml.tftpl", {
    ssh_public_key = file("files/ssh_key.pub")
  })

  network_interface {
    upstream = "shared"
  }

  lifecycle {
    ignore_changes = [
      user_data,
    ]
  }
}

Terraformのtemplatefile関数を使ってuser_datatemplates/cloud-config.yml.tftplというファイルの内容を入力しています。

user_dataをignore_changesに設定しているのは、user_dataを変更するたびにサーバーの再起動が発生するのを防ぐためです。
cloud-initを使うのがサーバー作成時のみの場合、意図しない再起動を防ぐために設定しておくのがおすすめです。

templates/cloud-config.yml.tftplの内容は以下の通りです。

cloud-config.yml.tftpl
#cloud-config
locale: ja_JP.utf8
ssh_authorized_keys:
  - ${ssh_public_key}
ssh_pwauth: false
chpasswd:
  expire: false
password: $6$rounds=4096$aUONx5Ru8eTS$a9QMv8zx6C7DQXMvtYeJqxzeCyQ9KF6Aap.mGXECmADcNo/Qe9jWFABKfOWFQojr/grq3rdzNKGvJIzo1ekuU.
timezone: Asia/Tokyo

${ssh_public_key}にはtemplatefile関数で入力しているファイルfiles/ssh_key.pubの内容が記述されます。
サーバーを複数台まとめて構築する際など、サーバーごとに設定する公開鍵を変えたいときにTerraformのtemplateと組み合わせて使うと便利です。

メタデータを参照する

cloud-initでは、インスタンスのメタデータを参照することができます。
さくらのクラウドで利用できるメタデータは、cloud-init | さくらのクラウド マニュアルに記載されています。

メタデータはJinjaテンプレートの形式で参照することができます。

cloud-config.yml.tftpl
## template: jinja
#cloud-config
hostname: {{ ds.meta_data.Server.Name }}
locale: ja_JP.utf8
ssh_authorized_keys:
  - ${ssh_public_key}
ssh_pwauth: false
chpasswd:
  expire: false
password: $6$rounds=4096$aUONx5Ru8eTS$a9QMv8zx6C7DQXMvtYeJqxzeCyQ9KF6Aap.mGXECmADcNo/Qe9jWFABKfOWFQojr/grq3rdzNKGvJIzo1ekuU.
timezone: Asia/Tokyo

ds.meta_data.Server.Nameからは、さくらのクラウド上でのサーバーの名前を取得できます。
そのため、上に記載したTerraformのコードとこのユーザデータを使ってサーバーを構築した場合、そのサーバーのホスト名はtestに設定されます。

cloud-initでNICを設定する

サーバーに接続しているネットワークインターフェースの情報もメタデータとして取得することができます。
そこで、cloud-initを使ってサーバーのネットワークインターフェースの設定を行ってみます。

cloud-config.yml.tftpl
## template: jinja
#cloud-config
bootcmd:
  - |
    if [ ! -e "/etc/netplan/60-netcfg.yaml" ]; then
    cat <<EOF > /etc/netplan/60-netcfg.yaml
    network:
      ethernets:
        lo:
          addresses:
            - 127.0.0.1/8
            - ::1/128
        ens3:
          addresses:
            - {{ ds.meta_data.Server.Interfaces[0].IPAddress }}/{{ ds.meta_data.Server.Interfaces[0].Switch.Subnet.NetworkMaskLen }}
          dhcp4: false
          nameservers:
            addresses:
            - 210.188.224.10
            - 210.188.224.11
          routes:
            - to: default
              via: {{ ds.meta_data.Server.Interfaces[0].Switch.Subnet.DefaultRoute }}
      renderer: networkd
      version: 2
    EOF
    netplan apply
    fi
hostname: {{ ds.meta_data.Server.Name }}
locale: ja_JP.utf8
ssh_authorized_keys:
  - ${ssh_public_key}
ssh_pwauth: false
chpasswd:
  expire: false
password: $6$rounds=4096$aUONx5Ru8eTS$a9QMv8zx6C7DQXMvtYeJqxzeCyQ9KF6Aap.mGXECmADcNo/Qe9jWFABKfOWFQojr/grq3rdzNKGvJIzo1ekuU.
timezone: Asia/Tokyo

ネットワークの設定はbootcmdで行っています。
ネットワークの設定ファイルが存在しない場合はネットワークの設定ファイルを書き出し、netplan applyを実行します。

ds.meta_data.Server.Interfaces[0].IPAddressで参照しているのは、サーバーに設定しているひとつめのNICに割り当てられたIPアドレスです。
上に記載したTerraformのコードを使ってサーバーを構築した場合、共有セグメントに接続されたNICのIPアドレスが取得できます。

共有セグメントに接続されたNICは、DHCPによって自動でIPアドレスが割り当てられますが、この機能を使っている場合はSLAの対象外になります。
そのため、共有セグメントに接続するNICをcloud-initで設定するなら、DHCPを無効化する設定も一緒に入れてしまうのがおすすめです。

DHCPにてIPアドレスを取得し通信を行っている際は、SLAの対象外となります。
DHCP | さくらのクラウド マニュアル

まとめ

さくらのクラウドでcloud-initを使ってサーバーの初期設定を行う方法を紹介しました。
ご参考になれば幸いです。

参考

5
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
5
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?