- Home »

Как использовать Terraform с DigitalOcean
Если ты когда-нибудь администрировал серверы, то наверняка знаешь, как утомительно может быть ручное создание и настройка инфраструктуры. Кликать по веб-интерфейсу, запоминать настройки, дублировать конфигурации — это не только скучно, но и чревато ошибками. Terraform в связке с DigitalOcean решает эту проблему раз и навсегда, позволяя описывать инфраструктуру как код и управлять ею через версионирование.
В этой статье я расскажу, как настроить Terraform для работы с DigitalOcean, покажу практические примеры создания дроплетов, настройки сетей и других ресурсов. Ты узнаешь, как автоматизировать развёртывание инфраструктуры, избежать типичных ошибок и использовать продвинутые возможности для масштабирования проектов.
Что такое Terraform и зачем он нужен с DigitalOcean
Terraform — это инструмент для создания, изменения и версионирования инфраструктуры с помощью декларативного языка конфигурации. Простыми словами, ты описываешь, что хочешь получить, а Terraform сам разбирается, как это сделать.
DigitalOcean предоставляет отличный API и официальный провайдер для Terraform, что делает автоматизацию максимально простой. Вместо того чтобы каждый раз заходить в панель управления и создавать дроплеты вручную, ты можешь описать всю инфраструктуру в коде и развернуть её одной командой.
Основные преимущества такого подхода:
- Версионирование — вся инфраструктура в Git, можно откатывать изменения
- Воспроизводимость — одинаковые настройки на dev, staging и production
- Автоматизация — интеграция с CI/CD пайплайнами
- Документирование — код сам себя документирует
Установка и первоначальная настройка
Начнём с установки Terraform. На большинстве Linux-дистрибутивов это делается просто:
# Ubuntu/Debian
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# CentOS/RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform
# macOS
brew install terraform
Проверь установку:
terraform --version
Теперь нужно получить API токен от DigitalOcean. Заходи в контрольную панель, переходи в раздел API и создай новый Personal Access Token с правами на чтение и запись.
Токен можно передать несколькими способами:
- Через переменную окружения
DIGITALOCEAN_TOKEN
- В конфигурационном файле провайдера
- Через Terraform переменные
Рекомендую использовать переменную окружения:
export DIGITALOCEAN_TOKEN="your_token_here"
Создание первой конфигурации
Создай новую директорию для проекта и файл main.tf
:
mkdir terraform-do-example
cd terraform-do-example
touch main.tf
Базовая конфигурация выглядит так:
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
# Configure the DigitalOcean Provider
provider "digitalocean" {
token = var.do_token
}
# Create a new SSH key
resource "digitalocean_ssh_key" "default" {
name = "terraform-key"
public_key = file("~/.ssh/id_rsa.pub")
}
# Create a new Droplet
resource "digitalocean_droplet" "web" {
image = "ubuntu-22-04-x64"
name = "web-server"
region = "fra1"
size = "s-1vcpu-1gb"
ssh_keys = [digitalocean_ssh_key.default.id]
tags = ["web", "terraform"]
}
# Output the IP address
output "droplet_ip" {
value = digitalocean_droplet.web.ipv4_address
}
Создай файл с переменными variables.tf
:
variable "do_token" {
description = "DigitalOcean API Token"
type = string
sensitive = true
}
И файл terraform.tfvars
для значений:
do_token = "your_digitalocean_token_here"
Не забудь добавить terraform.tfvars
в .gitignore
, чтобы не закоммитить токен!
Запуск и управление инфраструктурой
Теперь можно инициализировать проект и создать инфраструктуру:
# Инициализация проекта
terraform init
# Проверка конфигурации
terraform validate
# Планирование изменений
terraform plan
# Применение изменений
terraform apply
# Просмотр состояния
terraform show
# Удаление всех ресурсов
terraform destroy
После выполнения terraform apply
ты увидишь IP-адрес созданного дроплета. Terraform автоматически создаст SSH-ключ и настроит его на сервере.
Продвинутые конфигурации
Рассмотрим более сложный пример с несколькими серверами, балансировщиком нагрузки и базой данных:
# Data sources для получения информации о доступных ресурсах
data "digitalocean_sizes" "web" {
filter {
key = "slug"
values = ["s-1vcpu-1gb", "s-1vcpu-2gb", "s-2vcpu-2gb"]
}
}
data "digitalocean_images" "ubuntu" {
filter {
key = "slug"
values = ["ubuntu-22-04-x64"]
}
}
# VPC для изоляции сети
resource "digitalocean_vpc" "main" {
name = "main-vpc"
region = var.region
}
# Создание нескольких веб-серверов
resource "digitalocean_droplet" "web" {
count = var.web_servers_count
image = data.digitalocean_images.ubuntu.images[0].slug
name = "web-${count.index + 1}"
region = var.region
size = var.droplet_size
vpc_uuid = digitalocean_vpc.main.id
ssh_keys = [digitalocean_ssh_key.default.id]
tags = ["web", "terraform", "production"]
# User data для автоматической настройки
user_data = templatefile("${path.module}/user_data.sh", {
server_name = "web-${count.index + 1}"
})
}
# Load Balancer
resource "digitalocean_loadbalancer" "web" {
name = "web-lb"
region = var.region
vpc_uuid = digitalocean_vpc.main.id
forwarding_rule {
entry_protocol = "http"
entry_port = 80
target_protocol = "http"
target_port = 80
}
forwarding_rule {
entry_protocol = "https"
entry_port = 443
target_protocol = "http"
target_port = 80
tls_passthrough = true
}
healthcheck {
protocol = "http"
port = 80
path = "/"
}
droplet_ids = digitalocean_droplet.web[*].id
}
# Managed Database
resource "digitalocean_database_cluster" "postgres" {
name = "postgres-cluster"
engine = "pg"
version = "14"
size = "db-s-1vcpu-1gb"
region = var.region
node_count = 1
private_network_uuid = digitalocean_vpc.main.id
}
# Firewall rules
resource "digitalocean_firewall" "web" {
name = "web-firewall"
droplet_ids = digitalocean_droplet.web[*].id
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0"]
}
outbound_rule {
protocol = "tcp"
port_range = "1-65535"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
}
Файл user_data.sh
для автоматической настройки серверов:
#!/bin/bash
apt-get update
apt-get install -y nginx
systemctl start nginx
systemctl enable nginx
# Создание простой страницы
echo "Server: ${server_name}
" > /var/www/html/index.html
echo "Deployed with Terraform
" >> /var/www/html/index.html
Сравнение с альтернативными решениями
Инструмент | Преимущества | Недостатки | Подходит для |
---|---|---|---|
Terraform | Мультиоблачность, большое сообщество, декларативный подход | Крутая кривая обучения, состояние может сломаться | Комплексная инфраструктура, multi-cloud |
Pulumi | Использование обычных языков программирования | Меньше провайдеров, платный cloud backend | Разработчики, предпочитающие Python/JS/Go |
Ansible | Простота, идемпотентность, агентлесс | Медленнее на больших масштабах | Настройка и управление конфигурацией |
DigitalOcean CLI | Официальный инструмент, быстрый старт | Только для DO, нет управления состоянием | Простые задачи, скрипты автоматизации |
Лучшие практики и рекомендации
Структура проекта:
- Разделяй конфигурацию на модули
- Используй отдельные файлы для переменных, outputs и locals
- Группируй ресурсы логически (network.tf, compute.tf, database.tf)
Управление состоянием:
- Используй удалённое хранение состояния (S3, Terraform Cloud)
- Включи блокировки состояния для командной работы
- Регулярно делай backup файлов состояния
Безопасность:
- Никогда не коммить токены и пароли в Git
- Используй переменные окружения или внешние системы управления секретами
- Регулярно ротируй API токены
Пример настройки удалённого состояния с S3:
terraform {
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "digitalocean/terraform.tfstate"
region = "us-east-1"
}
}
Интеграция с CI/CD
Terraform отлично интегрируется с пайплайнами CI/CD. Пример для GitHub Actions:
name: 'Terraform'
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.0.0
- name: Terraform Init
run: terraform init
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
- name: Terraform Plan
run: terraform plan
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
Мониторинг и отладка
Terraform предоставляет несколько уровней логирования для отладки:
# Включение debug логов
export TF_LOG=DEBUG
# Логирование в файл
export TF_LOG_PATH=terraform.log
# Проверка состояния ресурсов
terraform refresh
# Импорт существующих ресурсов
terraform import digitalocean_droplet.example 123456789
Для мониторинга созданных ресурсов можешь использовать DigitalOcean Monitoring API или интегрировать с внешними системами мониторинга через outputs:
output "monitoring_endpoints" {
value = {
web_servers = digitalocean_droplet.web[*].ipv4_address
load_balancer = digitalocean_loadbalancer.web.ip
database_host = digitalocean_database_cluster.postgres.host
}
}
Автоматизация с помощью модулей
Создание переиспользуемых модулей — это следующий уровень автоматизации. Пример модуля для веб-приложения:
# modules/web-app/main.tf
variable "name" {
description = "Application name"
type = string
}
variable "region" {
description = "DigitalOcean region"
type = string
default = "fra1"
}
variable "instance_count" {
description = "Number of instances"
type = number
default = 2
}
resource "digitalocean_droplet" "app" {
count = var.instance_count
name = "${var.name}-${count.index + 1}"
image = "ubuntu-22-04-x64"
region = var.region
size = "s-1vcpu-1gb"
tags = ["app", var.name]
}
output "instance_ips" {
value = digitalocean_droplet.app[*].ipv4_address
}
Использование модуля в основной конфигурации:
module "frontend" {
source = "./modules/web-app"
name = "frontend"
region = "fra1"
instance_count = 3
}
module "backend" {
source = "./modules/web-app"
name = "backend"
region = "fra1"
instance_count = 2
}
output "frontend_ips" {
value = module.frontend.instance_ips
}
Интересные факты и нестандартные применения
Terraform можно использовать не только для инфраструктуры:
- Управление DNS записями через провайдер Cloudflare
- Создание пользователей и команд в GitHub
- Настройка мониторинга в Datadog
- Управление Kubernetes ресурсами
Малоизвестные возможности:
- Провайдер
null
для выполнения произвольных команд - Использование
templatefile()
для динамической генерации конфигов - Условные ресурсы через
count = var.enabled ? 1 : 0
- Цикли и условия с помощью
for_each
Пример использования условных ресурсов:
variable "create_database" {
description = "Create database cluster"
type = bool
default = false
}
resource "digitalocean_database_cluster" "postgres" {
count = var.create_database ? 1 : 0
name = "postgres-cluster"
engine = "pg"
version = "14"
size = "db-s-1vcpu-1gb"
region = var.region
node_count = 1
}
Производительность и оптимизация
Для больших инфраструктур важно оптимизировать время выполнения Terraform:
- Параллелизм: Используй флаг
-parallelism=20
для увеличения количества одновременных операций - Таргетинг: Применяй изменения только к определённым ресурсам с помощью
-target
- Частичное обновление: Используй
terraform refresh
вместо полного плана
# Увеличение параллелизма
terraform apply -parallelism=20
# Применение изменений только к определённому ресурсу
terraform apply -target=digitalocean_droplet.web
# Быстрая проверка изменений
terraform plan -refresh=false
Если ты планируешь развернуть серьёзную инфраструктуру, рекомендую арендовать VPS или выделенный сервер для запуска Terraform — это даст тебе больше контроля и производительности.
Заключение и рекомендации
Terraform с DigitalOcean — это мощная связка для автоматизации инфраструктуры. Начни с простых конфигураций, постепенно переходи к модулям и сложным сценариям. Главное — не бойся экспериментировать и читать документацию.
Когда использовать Terraform:
- Нужна воспроизводимая инфраструктура
- Планируешь использовать несколько облачных провайдеров
- Работаешь в команде и нужно версионирование
- Хочешь автоматизировать развёртывание через CI/CD
Когда лучше выбрать альтернативы:
- Простые задачи — используй DigitalOcean CLI
- Только настройка серверов — попробуй Ansible
- Предпочитаешь обычные языки программирования — посмотри на Pulumi
Помни: инфраструктура как код — это не просто модный тренд, а реальная необходимость для современных проектов. Terraform поможет тебе сэкономить время, избежать ошибок и спать спокойно, зная, что твоя инфраструктура документирована и версионирована.
Полезные ссылки для дальнейшего изучения:
- Официальная документация Terraform
- Документация провайдера DigitalOcean
- Исходный код Terraform на GitHub
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.