概要
成果物
こちらの記事で構築しているDockerイメージ作成用サーバーをTerraformで、コマンド1発で構築できるようにした。
作成したコードはこちら。
背景
- 様々なAIモデルを含むDockerイメージを何パターンか作成してきたが、その試行錯誤の段階でサーバーの構築・削除が頻発し、コントロールパネルでの操作が面倒になってきた。
- Terraformは触ったことがなく、勉強してみたかった。
- Terraform for さくらのクラウド v3が昨年末にリリースされており、試してみたいと思った。
- 既存記事のソースはv2だったり、鍵生成が手動だったりするため、「最新版で」「最低限安全な環境かつ」「Dockerイメージ作成に適したサーバーを」「コマンド1発で」作れるようにしてみたかった。
学習
Terraform初学者であるため、まずはお勉強。参照した文献は以下の通り:
- さくナレ上の連載記事全5回
- Terraform公式サイトのStyle Guide
- Terraform for さくらのクラウド v3仕様書
Style Guideにはファイル分割TIPSや.gitignoreの推奨設定などが記載されており、非常に勉強になった。
環境構築・実装
環境構築
Terraformのexeを公式から取ってきてpathに繋ぐだけだった。
その後、以下のように記述して、
terraform {
required_providers {
sakura = {
source = "sacloud/sakura"
version = "3.4.0"
}
}
}
Terraform initを叩けばよしなにTerraform for さくらのクラウド v3のexeをインストールしてくれた。したがって、さくらのクラウド向けにpathを張る必要はない。
さくらのクラウド向けの認証情報は、環境変数ではなくterraform.tfvarsに記入する方法を選択したため、環境構築段階では対応不要。
実装内容
構築するサーバーの内容は以下の通り:
- 石狩第3リージョンにCPU2コア、メモリ4GBのサーバー
- 接続するディスクはSSD100GB
- OSはubuntu
- 共有セグメント100Mbpsに接続
- Dockerのbuild、pushに必要なポートとSSHのみを解放するパケットフィルタを適用
- パスワード認証は無効化し、公開鍵認証を設定。鍵ペアは構築時に自動生成
- KMSキーによるディスク暗号化を実施
- スタートアップスクリプトを用いてDockerはサーバー起動時に自動インストール
コード
data "sakura_archive" "ubuntu" {
os_type = "ubuntu2404"
}
resource "sakura_kms" "docker_gen_server_encryption_key" {
name = "docker_gen_server_encryption_key"
description = "Encryption key for the docker generation server."
key_origin = "generated"
}
resource "sakura_disk" "docker_gen_disk" {
name = "docker_gen_disk"
description = "Disk for the docker generation server."
connector = "virtio"
encryption_algorithm = "aes256_xts"
icon_id = var.ubuntu_icon
kms_key_id = sakura_kms.docker_gen_server_encryption_key.id
plan = "ssd"
size = 100
source_archive_id = data.sakura_archive.ubuntu.id
zone = var.zone
}
resource "sakura_packet_filter" "minimum_filter" {
name = "minimum_filter"
description = "Minimum packet filter for the docker generation server."
zone = var.zone
}
resource "sakura_packet_filter_rules" "rules" {
packet_filter_id = sakura_packet_filter.minimum_filter.id
zone = var.zone
expression = [
{
description = "Allow SSH access. Limit source IP addresses, if needed."
destination_port = "22"
protocol = "tcp"
source_network = "0.0.0.0/0"
},
{
destination_port = "80"
protocol = "tcp"
},
{
protocol = "udp"
source_port = "123"
source_network = "0.0.0.0/0"
},
{
protocol = "udp"
destination_port = "68"
},
{
protocol = "icmp"
},
{
protocol = "tcp"
destination_port = "32768-61000"
},
{
protocol = "udp"
destination_port = "32768-61000"
},
{
protocol = "fragment"
},
{
protocol = "ip"
allow = false
description = "Deny all except above rules."
}
]
}
resource "sakura_script" "docker_install_script" {
name = "docker_install_script"
class = "shell"
content = file("scripts/install_docker.sh")
icon_id = var.ubuntu_icon
}
# Generate a temporary SSH key pair for the server.
resource "tls_private_key" "temporary_ssh_key" {
algorithm = "RSA"
rsa_bits = 4096
}
# Save the private key to a local file. Please save it securely, as it will be needed to access the server.
resource "local_sensitive_file" "private_key_file" {
content = tls_private_key.temporary_ssh_key.private_key_pem
filename = ".ssh/id_rsa.pem"
}
resource "sakura_ssh_key" "docker_gen_server_sshkey" {
name = "docker_gen_server_sshkey"
description = "SSH key for the docker generation server. Please save it in .ssh/ directory."
public_key = tls_private_key.temporary_ssh_key.public_key_openssh
}
resource "sakura_server" "docker_gen_server" {
name = "docker_gen_server"
description = "Server for the docker image generation."
core = 2
disks = [sakura_disk.docker_gen_disk.id]
icon_id = var.ubuntu_icon
interface_driver = "virtio"
memory = 4
tags = ["@keyboard-us"]
zone = var.zone
disk_edit_parameter = {
hostname = "ubuntuhost"
password_wo = var.os_password
password_wo_version = 1
disable_pw_auth = true
ssh_key_ids = [sakura_ssh_key.docker_gen_server_sshkey.id]
script = [{
id = sakura_script.docker_install_script.id
}]
}
network_interface = [{
upstream = "shared"
packet_filter_id = sakura_packet_filter.minimum_filter.id
}]
}
工夫した点
鍵ペアの自動生成
初学者でもコマンド1発だけでサーバー構築できるようにしたかったため、なんとかサーバーログイン用の鍵ペア生成も自動化できないか調べたところ、Terraformに生成機能があることを発見。.rsaフォルダに自動生成させるようにした。秘密鍵にパスワードを入れられないため本番運用には向かないが、開発用の使い捨てサーバーであれば、いったん鍵ペアがあれば十分と判断した。
# Generate a temporary SSH key pair for the server.
resource "tls_private_key" "temporary_ssh_key" {
algorithm = "RSA"
rsa_bits = 4096
}
# Save the private key to a local file. Please save it securely, as it will be needed to access the server.
resource "local_sensitive_file" "private_key_file" {
content = tls_private_key.temporary_ssh_key.private_key_pem
filename = ".ssh/id_rsa.pem"
}
スタートアップスクリプト
サーバーを立ち上げるたびにDockerをインストールするの面倒くさいな、と思い、Dockerのインストールをスタートアップスクリプトで自動化した。そういうユースケースが多いのか、なんとさくらのクラウドの公式マニュアルにDockerインストール用のスクリプトサンプルが掲載されていたため、それを拝借。scriptsフォルダ配下に配置し、Terraformに読み込ませる形を取った。
resource "sakura_script" "docker_install_script" {
name = "docker_install_script"
class = "shell"
content = file("scripts/install_docker.sh")
icon_id = var.ubuntu_icon
}
あとは比較的標準的な仕様だと思うので、私のリポジトリか他記事を参照されたし。
費用
サーバー23円/時 + ディスク18円/時 + KMSキー1円/時 = 42円/時
感想
初めてのTerraformだったが、記事が多く、構成がシンプルなこともあって、半日程度でコードを作りきることできた。
秒単位で環境構築できるのは、とても気持ちが良い。
Terraformをインストールして、terraform.tfvars認証情報を記入すれば、誰でも使えるように組んだので、ぜひみなさんも活用して欲しい。