تغییرات اخیر

در اینجا اطلاعیه‌ها، نسخه‌ها و تغییرات جدید لیارا فهرست می‌شوند.

Terraform در مقابل Ansible: تفاوت‌ها و کاربردها

وقتی وارد دنیای Infrastructure as Code (IaC) می‌شوید، حتماً اسم ابزارهایی مانند Terraform و Ansible را زیاد می‌شنوید. در نگاه اول ممکن است فکر کنید هر دو فقط کار اتوماسیون زیرساخت‌ها را انجام می‌دهند، اما حقیقت این است که Terraform برای ایجاد و مدیریت منابع زیرساختی استفاده می‌شود، در حالی که Ansible بیشتر روی پیکربندی و مدیریت نرم‌افزارها و سرویس‌ها تمرکز دارد. در این مقاله از سری مقالات لیارا می‌خواهیم به شما نشان دهیم که Terraform و Ansible دقیقاً چه کاری انجام می‌دهند، کجاها با هم هم‌پوشانی دارند و چه موقع می‌توان از هرکدام استفاده کرد. پس اگر می‌خواهید انتخاب درست ابزار برای پروژه‌تان را یاد بگیرید و زیرساخت خود را هوشمندانه مدیریت کنید، این مقاله را از دست ندهید.

آنچه در ادامه می‌خوانید:

  • Terraform چه کاربردی دارد؟
  • Ansible چه کاری انجام می‌دهد؟
  • خلاصه جریان کاری Terraform و Ansible
  • آیا Terraform می‌تواند کار Ansible را انجام دهد؟
  • آیا Ansible می‌تواند کار Terraform را انجام دهد؟
  • بهترین روش: استفاده از همزمان از هر دو
  • جمع بندی
  • سوالات متداول
تفاوت Terraform با Ansible

Terraform چه کاربردی دارد؟

Terraform یک ابزار Infrastructure as Code (IaC) است که امکان تعریف و مدیریت منابع زیرساختی را به‌صورت قابل خواندن و قابل اشتراک‌گذاری فراهم می‌کند، چه در محیط‌های ابری و چه on-premise. به بیان ساده‌تر Terraform یک راهکار خودکار برای استقرار و مدیریت محصولات در فضای ابری ارائه می‌دهد.

قابلیت‌های Terraform:

  • ایجاد منابع ابری (مثل VMها، شبکه‌ها، Load Balancerها، دیتابیس‌ها و …)
  • کار با چندین سرویس‌دهنده‌ی ابری به‌صورت هم‌زمان (AWS، Azure، GCP و …)
  • نگه‌داشتن سوابق منابع ایجادشده (با استفاده از چیزی به نام state file)

مثال:

فرض کنید می‌خواهید یک محیط production راه‌اندازی کنید که شامل این‌ موارد باشد:

  • یک VPC
  • دو Subnet (در دو Availability Zone مختلف)
  • یک Internet Gateway و Route Tableها
  • یک Security Group (با دسترسی HTTP و SSH)
  • سه EC2 Instance از طریق Auto Scaling Group
  • یک Application Load Balancer
  • یک دیتابیس RDS PostgreSQL

Terraform می‌تواند تمام این موارد را به‌طور خودکار و فقط از روی یک فایل .tf بسازد. یک بار آن را تعریف می‌کنید، هر زمان که بخواهید می‌توانید مجددا آن را اجرا کنید. این فرایند کمی تکرارپذیر است و تحت کنترل نسخه نیز قرار می‌گیرد.

مثال فایل: main.tf، بخش شبکه و امنیت

provider "aws" {
  region = "us-east-1"
}

# VPC
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags = {
    Name = "production-vpc"
  }
}

# Subnets
resource "aws_subnet" "subnet1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-east-1a"
  tags = {
    Name = "subnet-1"
  }
}

resource "aws_subnet" "subnet2" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "us-east-1b"
  tags = {
    Name = "subnet-2"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id
}

# Route Table
resource "aws_route_table" "rt" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }
}

# Route Table Associations
resource "aws_route_table_association" "a1" {
  subnet_id      = aws_subnet.subnet1.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "a2" {
  subnet_id      = aws_subnet.subnet2.id
  route_table_id = aws_route_table.rt.id
}

# Security Group
resource "aws_security_group" "instance_sg" {
  name        = "instance-sg"
  description = "Allow HTTP, SSH"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

مثال فایل: ec2.tf، منابع محاسباتی (Compute Resources)

# Launch Template
resource "aws_launch_template" "web_template" {
  name_prefix   = "web-template-"
  image_id      = "ami-***" # Replace with latest Amazon Linux or Ubuntu AMI
  instance_type = "t3.micro"

  vpc_security_group_ids = [aws_security_group.instance_sg.id]

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name = "web-server"
    }
  }

  user_data = base64encode(<<-EOF
              #!/bin/bash
              sudo yum update -y
              sudo yum install -y httpd
              sudo systemctl enable httpd
              sudo systemctl start httpd
              echo "<h1>Web Server Running</h1>" > /var/www/html/index.html
            EOF
  )
}

# Auto Scaling Group (3 Instances)
resource "aws_autoscaling_group" "web_asg" {
  desired_capacity     = 3
  max_size             = 3
  min_size             = 3
  vpc_zone_identifier  = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
  launch_template {
    id      = aws_launch_template.web_template.id
    version = "$Latest"
  }
  target_group_arns = [aws_lb_target_group.web_tg.arn]
  health_check_type = "EC2"
}

# Load Balancer
resource "aws_lb" "web_lb" {
  name               = "web-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.instance_sg.id]
  subnets            = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
}

resource "aws_lb_target_group" "web_tg" {
  name     = "web-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id
}

resource "aws_lb_listener" "web_listener" {
  load_balancer_arn = aws_lb.web_lb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_tg.arn
  }
}

مثال فایل: rds.tf، پایگاه داده PostgreSQL

resource "aws_db_subnet_group" "default" {
  name       = "main-db-subnet-group"
  subnet_ids = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
}

resource "aws_db_instance" "postgres" {
  identifier        = "production-db"
  engine            = "postgres"
  instance_class    = "db.t3.micro"
  allocated_storage = 20
  username          = "admin"
  password          = "supersecurepassword"
  db_subnet_group_name = aws_db_subnet_group.default.name
  vpc_security_group_ids = [aws_security_group.instance_sg.id]
  skip_final_snapshot = true
}

مثال فایل: outputs.tf، خروجی‌های مفید (Useful Outputs)

output "load_balancer_dns_name" {
  value = aws_lb.web_lb.dns_name
}

output "db_endpoint" {
  value = aws_db_instance.postgres.endpoint
}
برای آشنایی با انسیبل (Ansible) و کاربردهای آن، مقاله زیر را بخوانید.
انسیبل (Ansible) چیست؟

Ansible چه کاری انجام می‌دهد؟

انسیبل (Ansible) یک ابزار متن‌باز است و شما به‌عنوان یک سیستم‌ادمین یا توسعه‌دهنده می‌توانید از این ابزار برای خودکارسازی فرایند‌هایی مانند استقرار برنامه، نصب یک نرم‌افزار، provision کردن زیرساخت و بسیاری دیگر از فرایند‌های مشابه استفاده کنید تا درنهایت اکثر کارهای روزمره‌ی شما به‌صورت خودکار انجام شود.

قابلیت‌های Ansible:

  • نصب بسته‌های نرم‌افزاری لازم
  • استقرار کد اپلیکیشن
  • پیکربندی متغیرهای محیطی و تنظیمات اپلیکیشن
  • راه‌اندازی سرویس‌های مورد نیاز

پس از Provisioning با Terraform، Ansible برای مدیریت پیکربندی وارد عمل می‌شود. این ابزار با استفاده از IPهای عمومی یا نام‌های DNS عملیات خود را انجام می‌دهد.

مثال Inventory (inventory.ini):

در فایل زیر معمولا لیست سرورها و گروه‌های آن‌ها به همراه آدرس‌ها و پارامترهای اتصال مشخص می‌شود تا Ansible بتواند روی آن‌ها عمل کند.

[webservers]
web1 ansible_host=<ec2-instance-public-ip-1>
web2 ansible_host=<ec2-instance-public-ip-2>
web3 ansible_host=<ec2-instance-public-ip-3>

مثال (Playbook (site.yml:

یک Playbook در Ansible، مجموعه‌ای از دستورات و نقش‌ها (tasks & roles) است که روی سرورها اجرا می‌شود تا پیکربندی‌ها و استقرار اپلیکیشن انجام شود.

در فایل site.yml معمولاً مشخص می‌کنیم:

  • روی کدام گروه از سرورها (از فایل inventory) اعمال شود
  • چه وظایفی (tasks) باید اجرا شود
  • ترتیب اجرای وظایف و وابستگی‌ها

به بیان ساده‌، site.yml نقشه‌ی راه Ansible برای پیکربندی کامل محیط است.

- name: Configure Web Servers
  hosts: webservers
  become: yes
  tasks:
    - name: INSTALL APACHE
      yum:
        name: httpd
        state: present

    - name: COPY APPLICATION FILES
      copy:
        src: ./app/
        dest: /var/www/html/

    - name: START APACHE SERVICE
      service:
        name: httpd
        state: started
        enabled: true

خلاصه جریان کاری Terraform و Ansible

۱. Terraform Init & Apply

terraform init
terraform apply -auto-approve

در کد بالا:

  • terraform init: محیط کاری Terraform را راه‌اندازی می‌کند، providerها و backend را آماده می‌کند.
  • terraform apply -auto-approve: تغییرات تعریف‌شده در فایل‌های .tf را اعمال می‌کند بدون نیاز به تایید دستی.

۲. استخراج IPها(از خروجی‌های Terraform یا CLI)

  • آدرس‌های Public IP یا DNS را می‌توان از خروجی‌های Terraform یابا استفاده از CLI دریافت کرد.
  • این مرحله برای اتصال Ansible به سرورها ضروری است.

۳. پیکربندی (Ansible Inventory (inventory.ini

  • فایل inventory.ini را با آدرس‌های سیستم‌های استخراج شده پر کنید.
  • این فایل مشخص می‌کند Ansible روی کدام سرورها عملیات پیکربندی را اجرا کند.

۴. اجرای Playbook Ansible

ansible-playbook -i inventory.ini site.yml
  • (site.yml) پلی‌بوک شامل تمام دستورات و تنظیمات برای نصب پیکج‌ها، استقرار اپلیکیشن و راه‌اندازی سرویس‌ها است.
  • Ansible از آدرس‌ها و گروه‌های تعریف شده در inventory.ini استفاده می‌کند.

مزایای این رویکرد ترکیبی IaC

  • زیرساخت یا Terraform به‌صورت تکرارپذیر ایجاد می‌شود.
  • سرورها با Ansible به‌صورت یکپارچه و مطابق با تنظیمات مورد نیاز پیکربندی می‌شوند.
  • مناسب برای: محیط‌های Production، تست با اتوماسیون CI/CD.

چرا این جریان کاری درست کار می‌کند؟

این رویکرد ترکیبی Infrastructure as Code (IaC)، بهترین مزایای هر دو ابزار را ارائه می‌دهد:

  • Terraform: تضمین می‌کند که زیرساخت به صورت اعلامی (Declarative) ایجاد شده و به راحتی قابل بازتولید باشد.
  • Ansible: تضمین می‌کند که سرورها به طور یکپارچه پیکربندی شده و آماده اجرای اپلیکیشن باشند.

مناسب برای:

  • استقرار محیط‌های Production
  • راه‌اندازی محیط‌های تست
  • اتوماسیون CI/CD pipelines
اگر به‌دنبال شناخت تفاوت‌های Ansible و Jenkins هستید، مقاله زیر را از دست ندهید.
تفاوت‌های Ansible و Jenkins

آیا Terraform می‌تواند کار Ansible را انجام دهد؟

از نظر فنی بله، اما بهتر است این کار را نکنید. Terraform قابلیت remote-exec دارد که می‌تواند از طریق SSH به سرورها متصل شده و اسکریپت‌های شل را اجرا کند. با این روش می‌توان نرم‌افزار نصب کرد، فایل‌ها را ویرایش نمود و کارهای اولیه پیکربندی را انجام داد.

اما محدودیت‌هایی نیز دارد:

  • Idempotent نیست: اجرای مجدد ممکن است نتایج متفاوت بدهد.
  • مدیریت در مقیاس بزرگ دشوار است.
  • درهم آمیختن مسئولیت‌ها: ترکیب مدیریت زیرساخت و پیکربندی سیستم می‌تواند پیچیدگی ایجاد کند.

بنابراین Terraform می‌تواند تنظیمات پایه‌ای انجام دهدف اما برای مدیریت کامل پیکربندی سیستم و نرم‌افزارها طراحی نشده است.

آیا Ansible می‌تواند کار Terraform را انجام دهد؟

باز هم بله، اما ایده‌آل نیست. Ansible ماژول‌های ابری دارد که می‌توان با آن‌ها منابعی مانند Load Balancer، VM و … ایجاد کرد.

اما این کار نیز محدودیت دارد:

  • ردیابی منابع ندارد: برخلاف Terraform که از state file برای نگه‌داشتن وضعیت زیرساخت استفاده می‌کند، در Ansible باید مدیریت وضعیت منابع را خودتان انجام دهید.
  • پیچیدگی در چند ابر: وقتی روی چند سرویس‌دهنده ابری کار می‌کنید، مدیریت منابع با Ansible پیچیده‌تر می‌شود.

در نتیجه، Ansible می‌تواند منابع را ایجاد کند، اما Terraform برای این‌کار بسیار مناسب‌تر و مقیاس‌پذیرتر است.

بهترین روش: استفاده از همزمان از هر دو

فرض کنید می‌خواهید یک اپلیکیشن تجاری آنلاین (e-commerce) را راه‌اندازی کنید، یک رویکرد قوی به این شکل است:

۱. Terraform:

  • ایجاد محیط ابری شامل VPC، Subnetها، EC2، RDS و سایر منابع زیرساختی

۲. Ansible:

  • پیکربندی EC2 Instanceها: نصب Node.js، استقرار اپلیکیشن و راه‌اندازی سرویس‌ها

هر دو ابزار قدرتمند هستند، اما در مراحل مختلف چرخه استقرار نقش خود را بهتر ایفا می‌کنند:

  • Terraform برای Provisioning زیرساخت
  • Ansible برای مدیریت و پیکربندی نرم‌افزارها و سرویس‌ها

جمع بندی

در آخر این آموزش، اگر Terraform را معمار و تیم ساخت‌وساز در نظر بگیریم، Ansible مانند طراح داخلی و برق‌کار است. تلاش برای انجام همه کارها با یک ابزار ممکن است در ابتدا جواب دهد، اما خیلی سریع پیچیده و غیرقابل مدیریت خواهد شد. هر ابزار را برای نقطه قوت خودش به کار ببرید تا در نهایت به یک زیرساخت ساده‌تر، تمیزتر و قابل‌نگهداری‌تر برسید. امیدواریم این آموزش از لیارا برای شما مفید بوده باشد.

سوالات متداول

۱. Terraform و Ansible چه تفاوتی دارند؟

Terraform برای ایجاد و مدیریت زیرساخت‌ها طراحی شده و Ansible برای پیکربندی سرورها و نرم‌افزارها استفاده می‌شود.

۲. آیا می‌توان فقط از Terraform یا فقط از Ansible استفاده کرد؟

بله، اما هر کدام محدودیت دارند:

  • Terraform می‌تواند کارهای پیکربندی ساده انجام دهد، اما برای مدیریت کامل سیستم مناسب نیست.
  • Ansible می‌تواند منابع ابری بسازد، اما ردیابی وضعیت و مقیاس‌بندی پیچیده است.

۳. بهترین روش استفاده از این دو ابزار چیست؟

ترکیب آن‌ها: Terraform برای Provisioning و Ansible برای Configuration Management، که باعث ایجاد زیرساخت قابل تکرار و سرورهای آماده اجرا می‌شود.

۴. آیا این رویکرد برای محیط‌های تست هم مناسب است؟

بله، این روش برای محیط‌های Production، تست و اتوماسیون CI/CD کاملاً مناسب و استاندارد است.

به اشتراک بگذارید