پرش به مطلب اصلی

ساخت سرور با Terraform و CLI آریانت

ساختن سرور از پنل برای یک بار خوب است، ولی وقتی چند محیط (آزمایشی و اصلی) یا چند سرور یکسان دارید، بهتر است زیرساخت را با کد تعریف کنید تا هر بار دقیقاً همان را بسازید، تغییرات را در git نگه دارید و پیش از اجرا ببینید چه چیزی عوض می‌شود.

در این آموزش اول با CLI آریانت (arianet) کاتالوگ را می‌بینید و یک سرور آزمایشی می‌سازید و حذف می‌کنید، بعد همان سرور را همراه فایروال و دیسک با پرووایدر Terraform (ariaservice/arianet) به صورت کد تعریف می‌کنید.

پیش‌نیازها​

  • حساب آریانت با موجودی در کیف پول (ساخت سرور هزینه دارد؛ خواندن فهرست‌ها و لیست قیمت رایگان است)
  • یک کلید SSH در ~/.ssh/id_ed25519.pub (ساخت کلید SSH)
  • Terraform نسخه‌ی ۱.۰ یا بالاتر روی کامپیوتر خودتان

۱. ساخت توکن API​

در پنل، صفحه‌ی توکن‌های API یک توکن با دسترسی‌های cloud:servers:read و cloud:servers:write بسازید. توکن فقط یک بار نمایش داده می‌شود. آن را در متغیر محیطی بگذارید؛ هم CLI و هم Terraform همین متغیر را می‌خوانند:

export ARIANET_TOKEN="paste-your-token-here"
نکته

برای CI یک توکن جدا با تاریخ انقضا و IP مجاز بسازید (توکن‌های API). توکن را هرگز در فایل‌های .tf یا مخزن git ننویسید.

۲. نصب CLI و دیدن کاتالوگ​

CLI را طبق راهنمای نصب CLI نصب کنید و بررسی کنید:

arianet version
arianet cloud datacenters # datacenter codes, e.g. ovh
arianet cloud plans --datacenter ovh # plan ids, cpu, ram, disk, price
arianet cloud images list --type system # image names, e.g. ubuntu-24.04
arianet cloud pricing --datacenter ovh # public price list, no token needed

کد دیتاسنتر، شناسه‌ی پلن و نام ایمیج را برای مراحل بعد یادداشت کنید. در مثال‌ها ovh، پلن 3 و ubuntu-24.04 است.

۳. ساخت سرور آزمایشی با CLI​

arianet cloud servers create --name cli-test --datacenter ovh --plan 3 --image ubuntu-24.04 \
--ssh-key "$(cat ~/.ssh/id_ed25519.pub)" --labels env=test --wait
arianet cloud servers list --label-selector env=test

IPv4 سرور را از خروجی بردارید و وارد شوید:

ssh root@SERVER_IP

هزینه‌ی ساعتی و ماهانه‌ی سرور:

arianet cloud servers costs <server-id>

سرور را حذف کنید تا هزینه‌ی آن متوقف شود:

arianet cloud servers delete <server-id> --yes --wait
توجه

هر پلن یک حداقل ساعت کارکرد دارد (minimum_usage_hours در لیست قیمت). اگر سرور را زودتر حذف کنید، همان حداقل حساب می‌شود. برای آزمایش‌های پشت سر هم، سرور را نگه دارید و با arianet cloud servers rebuild دوباره نصب کنید.

۴. پروژه‌ی Terraform​

یک پوشه بسازید:

mkdir arianet-tf && cd arianet-tf

فایل main.tf:

terraform {
required_providers {
arianet = {
source = "ariaservice/arianet"
version = "~> 0.1"
}
}
}

provider "arianet" {} # token from ARIANET_TOKEN

variable "datacenter" {
type = string
default = "ovh"
}

variable "plan_id" {
type = number
description = "Plan id from: arianet cloud plans --datacenter <code>"
}

variable "admin_ip" {
type = string
description = "Your public IP in CIDR form, e.g. 203.0.113.4/32"
}

resource "arianet_firewall" "web" {
name = "web"

rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = [var.admin_ip]
}

rule {
direction = "in"
protocol = "tcp"
port = "80"
source_ips = ["0.0.0.0/0", "::/0"]
}

rule {
direction = "in"
protocol = "tcp"
port = "443"
source_ips = ["0.0.0.0/0", "::/0"]
}
}

resource "arianet_server" "web" {
name = "web-1"
datacenter = var.datacenter
plan_id = var.plan_id
image = "ubuntu-24.04"
ssh_keys = [trimspace(file("~/.ssh/id_ed25519.pub"))]
firewall_ids = [arianet_firewall.web.id]
labels = { role = "web", env = "prod" }

user_data = <<-EOT
#cloud-config
package_update: true
packages: [nginx]
EOT
}

resource "arianet_volume" "data" {
name = "web-1-data"
datacenter = var.datacenter
size = 20
}

resource "arianet_volume_attachment" "data" {
volume_id = arianet_volume.data.id
server_id = arianet_server.web.id
}

output "ipv4" {
value = arianet_server.web.ipv4_address
}

output "ipv6" {
value = arianet_server.web.ipv6_address
}

فایل terraform.tfvars (مقدارها را با خروجی مرحله‌ی ۲ و IP خودتان عوض کنید):

plan_id  = 3
admin_ip = "203.0.113.4/32"

فایل .gitignore، چون state شامل اطلاعات حساس (از جمله root_password هنگام ساخت) است:

.terraform/
*.tfstate
*.tfstate.*

۵. اجرا​

terraform init
terraform plan
terraform apply

plan نشان می‌دهد چه منابعی ساخته می‌شوند؛ با apply و تأیید yes ساخته می‌شوند. Terraform تا پایان عملیات ناهمگام هر منبع صبر می‌کند. در پایان:

terraform output ipv4
ssh root@$(terraform output -raw ipv4)

دیسک web-1-data به سرور وصل است ولی هنوز فرمت و mount نشده است؛ اتصال و mount دیسک را دنبال کنید.

۶. تغییر زیرساخت​

کد را عوض کنید و دوباره plan و apply بزنید. چند نمونه:

  • بزرگ کردن سرور: plan_id را عوض کنید؛ اندازه‌ی سرور در جا تغییر می‌کند.
  • بزرگ کردن دیسک: size را بیشتر کنید؛ در جا انجام می‌شود (فقط افزایش). سپس فایل‌سیستم را بزرگ کنید.
  • پشتیبان‌گیری روزانه: backups = true را به arianet_server اضافه کنید.
  • محافظت در برابر حذف: protection_delete = true.
توجه

تغییر datacenter یا image سرور، آن را جایگزین می‌کند (سرور قبلی و دیسک اصلی‌اش حذف می‌شود). همیشه خروجی terraform plan را بخوانید؛ عبارت must be replaced یعنی حذف و ساخت دوباره.

۷. وارد کردن منابع موجود​

سرور یا منبعی که قبلاً در پنل ساخته‌اید را می‌توانید به Terraform بسپارید:

terraform import arianet_server.web 123

پس از import، terraform plan تفاوت کد با وضعیت واقعی را نشان می‌دهد؛ کد را آن‌قدر اصلاح کنید که plan تغییری نشان ندهد.

۸. حذف همه‌چیز​

terraform destroy

اگر protection_delete = true گذاشته‌اید، اول آن را false کنید و apply بزنید. سرنوشت اسنپ‌شات‌ها و پشتیبان‌ها هنگام حذف با keep_backups و delete_snapshots تعیین می‌شود و باید پیش از destroy اعمال شده باشد (پرووایدر Terraform).

بررسی​

terraform state list
arianet cloud servers list --label-selector role=web
arianet cloud firewalls list

هر منبعی که Terraform ساخته باید در هر دو فهرست دیده شود.

خطاهای رایج​

خطاراه‌حل
401 یا unauthorizedARIANET_TOKEN در همین ترمینال تنظیم نشده یا توکن باطل شده است.
403 یا forbiddenتوکن دسترسی cloud:servers:write ندارد یا به IP دیگری محدود شده است.
402موجودی کیف پول برای سفارش کافی نیست.
identity_neededپیش از احراز هویت فقط یک سرور می‌توانید بسازید.
quota_exceededبه سقف تعداد منابع حساب رسیده‌اید: arianet cloud limits.
plan_sold_out یا datacenter_closedاین پلن یا دیتاسنتر فعلاً سفارش نمی‌پذیرد؛ پلن یا دیتاسنتر دیگری انتخاب کنید.
rate_limit_exceeded (429)سقف ۶۰ درخواست در دقیقه. پرووایدر خودش با رعایت Retry-After دوباره تلاش می‌کند.
terraform init به رجیستری وصل نمی‌شوددسترسی شبکه‌ی شما به registry.terraform.io را بررسی کنید.

قدم بعدی​

زیرساخت خود را به صورت کد بسازید​

در پنل آریانت یک توکن API بسازید و اولین سرور ابری خود را با terraform apply بالا بیاورید. همه‌ی منابع ابر آریانت ساعتی حساب می‌شوند و با terraform destroy هزینه‌شان قطع می‌شود.