Terraform、便利ですよね。
パブリッククラウドの構成管理・構築自動化でよく使われるイメージがありますが、物理ベアメタルサーバをデプロイする事もできるんです。
※ベアメタルサーバ=OSを自由に入れられる専有サーバみたいなもんです
本記事では、Terraformを使ってクラウドに一番近いベアメタルサーバであるEquinix Metal上の物理サーバをデプロイしてみます。
Equinix Metalについては以下サイトを参照してみてください。
Equinix Metal
Terraformで物理サーバをデプロイ??
今回利用するEquinix Metalは、**BMaaS(BareMetal as a Service)**を標榜しているプラットフォームです。
ベアメタルの物理サーバやNWをクラウドのようにデプロイ/利用できるよう、高度にAPI化された物理基盤をサービスとして提供してます。
(ユーザがやらなければいけないことは多いですが、自由度はかなり高いです)
このAPI化されている所がポイントで、Terraformを使ってEquinix MetalのAPIを呼び出す事で、デプロイ/構成管理が可能になっています。
Terraformが主要パブリッククラウドを操作する際も、このAPI化されている操作をIaCツールとしてラップしている為であり、Equinix Metalでも同様にAPI操作に対応した部分を操作/管理可能という訳です。
クラウドに一番近いベアメタルサーバ??
Equinixは主要クラウドへの閉域接続に対応した相互接続サービス- Equinix Fabricを提供しており、Equinix MetalもEquinix Fabricを経由して主要クラウドと接続することができます。
ただ接続するだけであれば、VPNでもなんでも使えばいいと思うのですが、EquinixのDC上にクラウドサービスがそもそも入居しており、DC内で閉域接続されているという点で**【クラウドに一番近いベアメタルサーバ】**と言えるんじゃないかと思ってます。
※本記事では"クラウドに一番近い"感はあまり出ていません、ご了承ください。。
今回やること
前置きはさておき、実際にTerraformでEquinix Metal上のベアメタルサーバをデプロイしていきます。
サーバ上の構成管理もしてみたいので、AWS等パブリッククラウドで利用可能なUserdata(cloud-init)を使い、デプロイ時に簡単なサーバ設定も加えてみます。
- デプロイする場所:シンガポール
- 課金タイプ:オンデマンドサーバ
- インスタンスサイズ:c3.small.x86
- OS:AlmaLinux
事前準備
1. Equinix Metalへサインアップ、プロジェクトIDを確認する
Equinix Metalのアカウント発行・組織/プロジェクト作成を行います。
※登録時はクレカが必要ですが、タイミング良ければクレジット付与の案内メールが来るかもしれないです。
プロジェクト作成後、プロジェクト設定画面からプロジェクトIDを確認します。 ※後で使います
MetalDocs Projects
2. Metalポータルで、APIキーを発行する
Equinix Metal登録後は、Terraformで使うためのAPIキーを発行します。
ログイン後、ユーザ画面から編集許可を設定したAPIキーを発行してください。
なお、現在の仕様では編集許可を付与したAPIキーの操作範囲が細かく制御できない仕様のため、[同一プロジェクト内の他のユーザーが作成したサーバ]を削除できたりします。
APIを使った操作・キー自体の取り扱いには十分ご注意ください。
※今後のロードマップでRBACの導入が予定されています。
Role Based Access Control (RBAC) / Delegated Administration
3. Metalポータルで、SSHキーを登録する
デプロイしたサーバで利用するためのSSHキー(公開鍵ファイル)を登録します。
以下ガイドに沿って登録してみてください。
MetalDocs ssh-keys
4. 作業用PCに、Terraformをインストールする
インストール手順はこちらを参照してみてください。
筆者はWindows10+WSL(ubuntu)にインストールして使っています。
Install Terraform
※以降の手順も、WSL環境でTerraformを操作するイメージで記載していきます。
他環境の方は適宜読み替えてご利用ください。
Terraformプロジェクトを作成・デプロイ
任意のディレクトリを作成して、Terraformプロジェクトを作っていきます。
ファイル構成
Terraformコードを記述していくmain.tfファイル、ポータルで発行したAPIキーを記載した**.metal_keyファイル、プロジェクトIDを記載した.metal_pjid**ファイルを配置します。
※公式手順では環境変数にAPIキーを設定する案内になってますが、面倒(というか設定したことを忘れる)な為、構成管理コードにベタ書きを控える為、別ファイル参照としています。
※git管理される場合は.gitignoreファイルへ登録する等、取り扱いにご注意ください。
pj_root
└main.tf #Terraformコードを書くファイル
└.metal_key #APIキーを記載したファイル
└.metal_pjid #プロジェクトIDを記載したファイル
なお、再利用可能にする場合はモジュール化すると便利だったりします。
※モジュール化については機会があれば別記事を書きます。
main.tf
以下内容のコードを記述・保存します。
各設定項目の詳細についてはEquinix MetalのTerraformプロバイダードキュメントを参照してみてください。
EquinixMetal Provider
なお、ただリソースを記述するだけではデプロイ完了後にサーバの情報が分かりづらいので、Outputsでサーバ情報を出力する親切設計となっております(キリッ)
terraform {
required_providers {
metal = {
source = "equinix/metal"
version = "3.0.0"
}
}
}
provider "metal" {
auth_token = file("./metal_token")
}
resource "metal_device" "device" {
hostname = "test.sg.c3.small.x86-tf" # ホスト名
plan = "c3.small.x86" #インスタンスサイズ
metro = "SG" #デプロイするロケーション
operating_system = "alma_8" #インストールOS(AlmaLinux)
billing_cycle = "hourly" #オンデマンドサーバを指定
project_id = file("./metal_pjid")
ip_address {
type = "private_ipv4"
cidr = "30"
}
ip_address {
type = "public_ipv4"
cidr = "30"
}
# タイムゾーン・言語設定・Apacheインストール/起動
user_data = <<DATA
#cloud-config
timezone: Asia/Tokyo
locale: en_US.utf8
runcmd:
- dnf install httpd -y
- systemctl start httpd
DATA
}
# サーバ情報出力用
output "device_info" {
value = {
"hostname" = metal_device.device.hostname,
"os" = metal_device.device.operating_system,
"plan" = metal_device.device.plan,
"ipaddress_public_ipv4" = metal_device.device.access_public_ipv4,
"created" = metal_device.device.created,
"ssh_cmd_example" = format("ssh root@%s -i [ssh_key]", metal_device.device.network[0].address),
"SOS_cmd_example" = format("ssh %s@sos.%s.platformequinix.com -i [ssh_key]", metal_device.device.id, metal_device.device.deployed_facility),
"root_PW" = metal_device.device.root_password
}
metal_key、metal_pjid
参考までに、こんな感じの桁数/フォーマットになります ※値はダミーです
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
デプロイしてみる
Terraform デプロイ開始
ファイルの準備ができたら、いよいよ実行します。
初期化(init)・構成確認(plan)・実行(apply)の順で操作します。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of equinix/metal from the dependency lock file
- Using previously-installed equinix/metal v3.0.0
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$ terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# metal_device.device will be created
+ resource "metal_device" "device" {
+ access_private_ipv4 = (known after apply)
+ access_public_ipv4 = (known after apply)
+ access_public_ipv6 = (known after apply)
+ always_pxe = false
+ billing_cycle = "hourly"
+ created = (known after apply)
+ deployed_facility = (known after apply)
+ deployed_hardware_reservation_id = (known after apply)
+ force_detach_volumes = false
+ hostname = "test.sg.c3.small.x86-tf"
+ id = (known after apply)
+ locked = (known after apply)
+ metro = "ty"
+ network = (known after apply)
+ network_type = (known after apply)
+ operating_system = "alma_8"
+ plan = "c3.small.x86"
+ ports = (known after apply)
+ project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ root_password = (sensitive value)
+ ssh_key_ids = (known after apply)
+ state = (known after apply)
+ updated = (known after apply)
+ user_data = (sensitive value)
+ wait_for_reservation_deprovision = false
+ ip_address {
+ cidr = 30
+ type = "private_ipv4"
}
+ ip_address {
+ cidr = 30
+ type = "public_ipv4"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ device_info = {
+ SOS_cmd_example = (known after apply)
+ created = (known after apply)
+ hostname = "test.sg.c3.small.x86-tf"
+ ipaddress_public_ipv4 = (known after apply)
+ os = "alma_8"
+ plan = "c3.small.x86"
+ root_PW = (known after apply)
+ ssh_cmd_example = (known after apply)
}
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
$ terraform apply --auto-approve
metal_device.device: Creating...
metal_device.device: Still creating... [10s elapsed]
metal_device.device: Still creating... [20s elapsed]
metal_device.device: Still creating... [30s elapsed]
(中略)
実行後、Metalポータル上でも以下キャプチャのようにデプロイ処理が走り始めます。
Terraform デプロイ完了
デプロイ完了すると以下のような出力が表示されます。
(中略)
metal_device.device: Still creating... [10m40s elapsed]
metal_device.device: Creation complete after 10m48s [id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
device_info = {
"SOS_cmd_example" = "ssh xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@sos.sg1.platformequinix.com -i [ssh_key]"
"created" = "2021-12-22T14:44:47Z"
"hostname" = "test.sg.c3.small.x86-tf"
"ipaddress_public_ipv4" = "[サーバのパブリックIPアドレス]"
"os" = "alma_8"
"plan" = "c3.small.x86"
"root_PW" = "XXXXXXXXXX"
"ssh_cmd_example" = "ssh root@[サーバのパブリックIPアドレス] -i [ssh_key]"
}
無事にデプロイされたので、サーバに乗り込んで確認してみます。
デプロイ後の動作確認
サーバへSSHログイン
サーバ情報出力に記載のある、sshコマンドサンプルでログインします。
[ssh_key]は、事前準備で設定した公開鍵に対応した秘密鍵を指定します。
# 通常のSSHログインの場合
ssh root@[サーバのパブリックIPアドレス] -i [ssh_key]
# SOSログインの場合
ssh xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@sos.sg1.platformequinix.com -i [ssh_key]
SOSはちょっとおもしろ機能で、サーバのシリアルコンソールにSSHからログインする事ができます。
使い方はこちらのガイドを参照してみてください。
MetalDocs SOS
サーバの状態確認
通常のSSHログイン後、設定状態を確認してみます。
諸々設定できていて、インストールしたApacheも起動してます。
※SSH接続しただけでは実感湧きませんが、物理サーバをデプロイしてます。
[root@test ~]# hostname
test.sg.c3.small.x86-tf
[root@test ~]# cat /etc/redhat-release
AlmaLinux release 8.5 (Arctic Sphynx)
[root@test ~]# date
Thu Dec 22 10:24:46 JST 2021
[root@test ~]# localectl
System Locale: LANG=en_US.utf8
VC Keymap: us
X11 Layout: us
[root@test ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2021-12-23 00:23:41 JST; 3min 38s ago
Docs: man:httpd.service(8)
ブラウザからApacheスタートページを確認
ブラウザからサーバのパブリックIPアドレスにアクセスすると、Apacheスタートページが表示されます。
こちらも問題ないようです。
後片付け
Terraformでサーバ削除
うまくデプロイできて気が済んだので、リソース削除(destroy)します。
$ terraform destroy --auto-approve
metal_device.device: Destroying... [id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx]
metal_device.device: Destruction complete after 4s
Destroy complete! Resources: 1 destroyed.
まとめ
TerraformでEquinix Metalのベアメタルサーバをデプロイしてみました。
使用感は正直、パブリッククラウドでVM建てるのとほぼ同じ。なのに物理サーバをデプロイしているという不思議体験でしたね。
今後もTerraformで面白デプロイを試してみたいと思います。