مقدمه
وقتی کار با Terraform را شروع میکنید، معمولاً همه فایلها را داخل یک پوشه قرار میدهید و همه چیز بهخوبی کار میکند. اما با بزرگتر شدن زیرساخت، افزایش تعداد محیطها (Development، Staging و Production) و اضافه شدن اعضای تیم، مدیریت پروژه بهسرعت پیچیده میشود.
به همین دلیل داشتن یک ساختار استاندارد و سازمانیافته برای پروژههای Terraform اهمیت زیادی دارد. یک ساختار مناسب باعث میشود:
- نگهداری پروژه آسانتر شود.
- همکاری تیمی بهبود پیدا کند.
- از تکرار کدها جلوگیری شود.
- مدیریت محیطهای مختلف سادهتر شود.
- مقیاسپذیری پروژه افزایش پیدا کند.
در این مقاله با بهترین روشها برای ساختاربندی پروژههای Terraform آشنا میشویم.
چرا ساختار پروژه اهمیت دارد؟
فرض کنید همه منابع را داخل یک فایل قرار دادهاید:
main.tf
در ابتدا مشکلی وجود ندارد، اما بعد از مدتی ممکن است صدها یا هزاران خط کد داشته باشید:
main.tf
├── VPC
├── EC2
├── Load Balancer
├── Security Groups
├── RDS
├── IAM
└── ...
در چنین شرایطی پیدا کردن خطاها و مدیریت تغییرات بسیار دشوار خواهد شد.
ساختار پیشنهادی Terraform
یک ساختار متداول به شکل زیر است:
terraform-project/
│
├── modules/
│ ├── network/
│ ├── compute/
│ ├── database/
│
├── environments/
│ ├── dev/
│ ├── staging/
│ └── production/
│
├── README.md
└── .gitignore
در این ساختار:
- ماژولها در پوشه
modulesقرار میگیرند. - هر محیط در پوشهای جداگانه نگهداری میشود.
- کدها قابل استفاده مجدد هستند.
استفاده از Modules
ماژولها یکی از مهمترین قابلیتهای Terraform هستند.
بهجای تکرار کدها:
resource "aws_instance" "web1" {
...
}
resource "aws_instance" "web2" {
...
}
میتوانید یک ماژول بسازید:
modules/
└── ec2/
ساختار ماژول:
ec2/
├── main.tf
├── variables.tf
├── outputs.tf
└── versions.tf
فایل main.tf
شامل منابع اصلی:
resource "aws_instance" "this" {
ami = var.ami
instance_type = var.instance_type
}
فایل variables.tf
تعریف ورودیهای ماژول:
variable "ami" {
type = string
}
variable "instance_type" {
type = string
}
فایل outputs.tf
خروجیهای ماژول:
output "instance_id" {
value = aws_instance.this.id
}
ساختار محیطها (Environments)
یکی از رایجترین روشها، جدا کردن محیطها است.
مثال:
environments/
├── dev
├── staging
└── production
هر محیط فایلهای مخصوص خود را دارد.
مثال:
dev/
├── main.tf
├── variables.tf
├── terraform.tfvars
└── backend.tf
فراخوانی ماژولها
در محیط Development:
module "web_server" {
source = "../../modules/ec2"
ami = "ami-123456"
instance_type = "t3.micro"
}
در محیط Production:
module "web_server" {
source = "../../modules/ec2"
ami = "ami-123456"
instance_type = "t3.large"
}
در این روش کد اصلی یکسان باقی میماند و فقط مقادیر تغییر میکنند.
مدیریت متغیرها
بهتر است متغیرها را در فایل جداگانه تعریف کنید:
variables.tf
نمونه:
variable "region" {
type = string
}
و مقداردهی در:
terraform.tfvars
region = "eu-central-1"
این کار مدیریت تنظیمات را سادهتر میکند.
استفاده از فایل backend.tf
State فایل بسیار مهم است و نباید روی سیستم محلی ذخیره شود.
بهتر است از Remote State استفاده کنید:
terraform {
backend "s3" {
bucket = "terraform-state"
key = "prod/terraform.tfstate"
region = "eu-central-1"
}
}
مزایا:
- اشتراکگذاری بین اعضای تیم
- جلوگیری از تداخل تغییرات
- امنیت بیشتر
فایل versions.tf
نسخه Terraform و Providerها را مشخص کنید:
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
این کار از ناسازگاری نسخهها جلوگیری میکند.
فایل providers.tf
بهتر است Providerها را در فایل جداگانه قرار دهید:
provider "aws" {
region = var.region
}
فایل outputs.tf در پروژه اصلی
خروجیهای مهم را تعریف کنید:
output "vpc_id" {
value = module.network.vpc_id
}
این خروجیها برای ماژولهای دیگر یا CI/CD مفید هستند.
استفاده از Naming Convention
نامگذاری استاندارد اهمیت زیادی دارد.
مثال مناسب:
aws_instance.web_server
به جای:
aws_instance.server1
یا:
aws_instance.test
نامهای توصیفی نگهداری پروژه را آسانتر میکنند.
فایلهای مهمی که نباید در Git ذخیره شوند
در فایل .gitignore موارد زیر را قرار دهید:
.terraform/
*.tfstate
*.tfstate.backup
*.tfvars
این فایلها معمولاً شامل اطلاعات حساس هستند.
ساختار پیشنهادی برای پروژههای بزرگ
terraform-project/
│
├── modules/
│ ├── vpc/
│ ├── eks/
│ ├── rds/
│ ├── ec2/
│ └── security-groups/
│
├── environments/
│ ├── dev/
│ ├── staging/
│ └── prod/
│
├── scripts/
│
├── docs/
│
├── README.md
└── .gitignore
این ساختار برای تیمهای DevOps و پروژههای Enterprise بسیار رایج است.
بهترین روشها (Best Practices)
- هر ماژول فقط یک مسئولیت مشخص داشته باشد.
- از کپی کردن کدها خودداری کنید.
- State را بهصورت Remote ذخیره کنید.
- نسخه Terraform را قفل کنید.
- از Naming Convention مشخص استفاده کنید.
- محیطهای مختلف را از هم جدا نگه دارید.
- خروجیهای مهم را تعریف کنید.
- اطلاعات حساس را وارد Git نکنید.
جمعبندی
ساختار مناسب پروژههای Terraform تأثیر مستقیمی بر نگهداری، توسعه و مقیاسپذیری زیرساخت دارد. بهترین رویکرد معمولاً استفاده از Modules برای کدهای قابل استفاده مجدد و Environment Separation برای مدیریت محیطهای مختلف است.
با رعایت این اصول، پروژه Terraform شما خواناتر، قابل نگهداریتر و آماده رشد در مقیاسهای بزرگ خواهد بود.
از همراهی شما با پارمین کلود سپاسگزاریم.
نظرات کاربران