From 15deba2e9bd473e3739eb72ecd09c803fda0d1e6 Mon Sep 17 00:00:00 2001 From: Terraform Bot Date: Tue, 11 Nov 2025 08:03:55 +0000 Subject: [PATCH] =?UTF-8?q?Initial=20commit:=20Terraform=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=D0=BA=D1=82=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=B2=D0=B5=D1=80=D1=82=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20Grafana=20Loki=20=D0=BD=D0=B0=20Proxmox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 47 ++++++++ README.md | 243 +++++++++++++++++++++++++++++++++++++++ main.tf | 181 +++++++++++++++++++++++++++++ outputs.tf | 25 ++++ providers.tf | 18 +++ terraform.tfvars.example | 27 +++++ variables.tf | 100 ++++++++++++++++ 7 files changed, 641 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 main.tf create mode 100644 outputs.tf create mode 100644 providers.tf create mode 100644 terraform.tfvars.example create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8674b12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +*tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# SSH keys +*.pem +*.key +id_rsa* + +# OS files +.DS_Store +Thumbs.db + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo +*~ diff --git a/README.md b/README.md new file mode 100644 index 0000000..087b463 --- /dev/null +++ b/README.md @@ -0,0 +1,243 @@ + +# Terraform: Grafana Loki на Proxmox + +Этот проект Terraform автоматизирует развертывание виртуальной машины на Proxmox с установленными и настроенными **Grafana Loki** и **Promtail**. + +## 📋 Описание + +Проект создает полностью настроенную VM с: +- **Loki** - система агрегации логов (порт 3100) +- **Promtail** - агент для сбора логов (порт 9080) +- Автоматическая установка и настройка systemd сервисов +- Сбор системных логов из `/var/log/*.log` + +## 🔧 Требования + +### Локальные требования +- [Terraform](https://www.terraform.io/downloads.html) >= 1.0 +- SSH ключ для доступа к VM (`~/.ssh/id_rsa` по умолчанию) +- Доступ к Proxmox API + +### Требования к Proxmox +- Proxmox VE 6.x или 7.x +- API токен с правами для создания VM +- Ubuntu 20.04 шаблон с поддержкой cloud-init и DHCP +- Настроенное хранилище (по умолчанию `local-lvm`) +- Сетевой мост (по умолчанию `vmbr0`) + +## 🚀 Быстрый старт + +### 1. Клонируйте репозиторий + +```bash +git clone https://git.mscsrv.ru/your-username/terraform-grafana-loki.git +cd terraform-grafana-loki +``` + +### 2. Настройте переменные + +Создайте файл `terraform.tfvars` на основе примера: + +```bash +cp terraform.tfvars.example terraform.tfvars +``` + +Отредактируйте `terraform.tfvars` и заполните необходимые значения: + +```hcl +proxmox_api_url = "https://your-proxmox-host:8006/api2/json" +proxmox_api_token_id = "terraform-user@pve!token-id" +proxmox_api_token_secret = "your-secret-token" +target_node = "pve" +vm_template = "ubuntu-20.04-template" +``` + +### 3. Инициализируйте Terraform + +```bash +terraform init +``` + +### 4. Проверьте план развертывания + +```bash +terraform plan +``` + +### 5. Примените конфигурацию + +```bash +terraform apply +``` + +Подтвердите создание ресурсов, введя `yes`. + +### 6. Получите информацию о созданной VM + +После успешного развертывания Terraform выведет: +- IP адрес VM +- URL для доступа к Loki +- URL для доступа к Promtail +- Команду для SSH подключения + +```bash +terraform output +``` + +## 📁 Структура проекта + +``` +terraform-grafana-loki/ +├── providers.tf # Конфигурация провайдеров Terraform +├── variables.tf # Определение переменных +├── main.tf # Основной код: ресурс VM и provisioners +├── outputs.tf # Выходные данные (IP, URLs) +├── terraform.tfvars.example # Пример файла с переменными +├── .gitignore # Исключения для Git +└── README.md # Документация проекта +``` + +## ⚙️ Переменные + +### Обязательные переменные + +| Переменная | Описание | +|-----------|----------| +| `proxmox_api_url` | URL адрес Proxmox API | +| `proxmox_api_token_id` | ID токена для API | +| `proxmox_api_token_secret` | Секретный токен | + +### Опциональные переменные + +| Переменная | Значение по умолчанию | Описание | +|-----------|----------------------|----------| +| `target_node` | `pve` | Имя узла Proxmox | +| `vm_name` | `grafana-loki` | Имя VM | +| `vm_template` | `ubuntu-20.04-template` | Шаблон для клонирования | +| `vm_cores` | `2` | Количество CPU ядер | +| `vm_memory` | `4096` | Память в MB | +| `vm_disk_size` | `40G` | Размер диска | +| `loki_version` | `2.9.1` | Версия Loki | +| `loki_port` | `3100` | HTTP порт Loki | +| `promtail_port` | `9080` | HTTP порт Promtail | + +## 🔐 Настройка Proxmox API токена + +1. Войдите в веб-интерфейс Proxmox +2. Перейдите в **Datacenter** → **Permissions** → **API Tokens** +3. Создайте новый токен для пользователя (например, `terraform-user@pve`) +4. Сохраните Token ID и Secret +5. Убедитесь, что у пользователя есть необходимые права (PVEVMAdmin или Administrator) + +## 🖥️ Подготовка Ubuntu шаблона + +Шаблон VM должен соответствовать следующим требованиям: + +1. Ubuntu 20.04 LTS (или новее) +2. Установлен и настроен cloud-init +3. Настроено получение IP через DHCP +4. Включен qemu-guest-agent +5. Добавлен ваш публичный SSH ключ + +## 📊 Проверка работы сервисов + +После развертывания подключитесь к VM: + +```bash +ssh ubuntu@ +``` + +Проверьте статус сервисов: + +```bash +# Статус Loki +sudo systemctl status loki + +# Статус Promtail +sudo systemctl status promtail + +# Логи Loki +sudo journalctl -u loki -f + +# Логи Promtail +sudo journalctl -u promtail -f +``` + +Проверьте доступность Loki API: + +```bash +curl http://localhost:3100/ready +curl http://localhost:3100/metrics +``` + +## 🔍 Интеграция с Grafana + +Для визуализации логов в Grafana: + +1. Установите Grafana (отдельно или на той же VM) +2. Добавьте Loki как Data Source: + - URL: `http://:3100` + - Access: Server (по умолчанию) +3. Создайте дашборды для визуализации логов + +## 🗑️ Удаление ресурсов + +Для удаления созданной VM: + +```bash +terraform destroy +``` + +## 📝 Примечания + +- VM создается с использованием DHCP, IP адрес назначается автоматически +- Loki хранит данные локально в `/var/loki/` +- Promtail собирает логи из `/var/log/*.log` +- Оба сервиса настроены на автоматический запуск при старте системы + +## 🐛 Устранение неполадок + +### Ошибка подключения SSH + +Убедитесь, что: +- SSH ключ правильно настроен в шаблоне VM +- Путь к приватному ключу корректен (`ssh_private_key_path`) +- VM получила IP адрес (проверьте в Proxmox) + +### Loki не запускается + +Проверьте логи: +```bash +sudo journalctl -u loki -n 100 +``` + +Проверьте конфигурацию: +```bash +cat /etc/loki-config.yaml +``` + +### Promtail не отправляет логи + +Проверьте подключение к Loki: +```bash +curl http://localhost:3100/ready +``` + +Проверьте конфигурацию Promtail: +```bash +cat /etc/promtail-config.yaml +``` + +## 📚 Дополнительные ресурсы + +- [Документация Grafana Loki](https://grafana.com/docs/loki/latest/) +- [Документация Promtail](https://grafana.com/docs/loki/latest/clients/promtail/) +- [Terraform Proxmox Provider](https://registry.terraform.io/providers/Telmate/proxmox/latest/docs) + +## 📄 Лицензия + +Этот проект распространяется свободно для использования и модификации. + +## 🤝 Вклад + +Предложения и улучшения приветствуются! Создавайте Issue или Pull Request. diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..f499416 --- /dev/null +++ b/main.tf @@ -0,0 +1,181 @@ + +resource "proxmox_vm_qemu" "grafana_loki" { + name = var.vm_name + target_node = var.target_node + clone = var.vm_template + cores = var.vm_cores + memory = var.vm_memory + sockets = 1 + onboot = true + scsihw = "virtio-scsi-pci" + bootdisk = "scsi0" + boot = "order=scsi0" + agent = 1 + + network { + model = "virtio" + bridge = var.vm_network_bridge + } + + disk { + size = var.vm_disk_size + type = "scsi" + storage = var.vm_storage + storage_type = "lvm" + iothread = 1 + discard = "on" + } + + ciuser = var.vm_user + ipconfig0 = "ip=dhcp" + + lifecycle { + ignore_changes = [ipconfig0] + } + + provisioner "remote-exec" { + connection { + type = "ssh" + host = self.default_ipv4_address + user = var.vm_user + private_key = file(var.ssh_private_key_path) + timeout = "5m" + } + + inline = [ + # Обновление системы и установка необходимых пакетов + "sudo apt-get update", + "sudo apt-get install -y wget curl apt-transport-https software-properties-common unzip", + + # Установка Grafana Loki + "wget https://github.com/grafana/loki/releases/download/v${var.loki_version}/loki-linux-amd64.zip -O /tmp/loki.zip", + "unzip /tmp/loki.zip -d /tmp/", + "sudo mv /tmp/loki-linux-amd64 /usr/local/bin/loki", + "sudo chmod +x /usr/local/bin/loki", + + # Создание директорий для Loki + "sudo mkdir -p /var/loki/index /var/loki/cache /var/loki/chunks", + "sudo chown -R ${var.vm_user}:${var.vm_user} /var/loki", + + # Создание конфигурации Loki + "cat <<'LOKIEOF' | sudo tee /etc/loki-config.yaml", + "auth_enabled: false", + "", + "server:", + " http_listen_port: ${var.loki_port}", + "", + "ingester:", + " lifecycler:", + " ring:", + " kvstore:", + " store: inmemory", + " replication_factor: 1", + " chunk_idle_period: 5m", + " max_chunk_age: 1h", + " chunk_target_size: 1048576", + " max_transfer_retries: 0", + "", + "schema_config:", + " configs:", + " - from: 2020-10-24", + " store: boltdb-shipper", + " object_store: filesystem", + " schema: v11", + " index:", + " prefix: index_", + " period: 24h", + "", + "storage_config:", + " boltdb_shipper:", + " active_index_directory: /var/loki/index", + " cache_location: /var/loki/cache", + " shared_store: filesystem", + " filesystem:", + " directory: /var/loki/chunks", + "", + "limits_config:", + " enforce_metric_name: false", + " reject_old_samples: true", + " reject_old_samples_max_age: 168h", + "LOKIEOF", + + # Создание systemd сервиса для Loki + "cat <<'LOKISVCEOF' | sudo tee /etc/systemd/system/loki.service", + "[Unit]", + "Description=Loki Log Aggregation System", + "After=network.target", + "", + "[Service]", + "Type=simple", + "User=${var.vm_user}", + "ExecStart=/usr/local/bin/loki -config.file=/etc/loki-config.yaml", + "Restart=on-failure", + "RestartSec=5s", + "", + "[Install]", + "WantedBy=multi-user.target", + "LOKISVCEOF", + + # Запуск Loki + "sudo systemctl daemon-reload", + "sudo systemctl enable loki", + "sudo systemctl start loki", + + # Установка Promtail + "wget https://github.com/grafana/loki/releases/download/v${var.loki_version}/promtail-linux-amd64.zip -O /tmp/promtail.zip", + "unzip /tmp/promtail.zip -d /tmp/", + "sudo mv /tmp/promtail-linux-amd64 /usr/local/bin/promtail", + "sudo chmod +x /usr/local/bin/promtail", + + # Создание конфигурации Promtail + "cat <<'PROMTAILEOF' | sudo tee /etc/promtail-config.yaml", + "server:", + " http_listen_port: ${var.promtail_port}", + " grpc_listen_port: 0", + "", + "positions:", + " filename: /var/log/promtail-positions.yaml", + "", + "clients:", + " - url: http://localhost:${var.loki_port}/loki/api/v1/push", + "", + "scrape_configs:", + " - job_name: system", + " static_configs:", + " - targets:", + " - localhost", + " labels:", + " job: varlogs", + " __path__: /var/log/*.log", + "PROMTAILEOF", + + # Создание systemd сервиса для Promtail + "cat <<'PROMTAILSVCEOF' | sudo tee /etc/systemd/system/promtail.service", + "[Unit]", + "Description=Promtail Log Collector", + "After=network.target loki.service", + "", + "[Service]", + "Type=simple", + "User=${var.vm_user}", + "ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail-config.yaml", + "Restart=on-failure", + "RestartSec=5s", + "", + "[Install]", + "WantedBy=multi-user.target", + "PROMTAILSVCEOF", + + # Запуск Promtail + "sudo systemctl daemon-reload", + "sudo systemctl enable promtail", + "sudo systemctl start promtail", + + # Проверка статуса сервисов + "echo '=== Loki Status ==='", + "sudo systemctl status loki --no-pager", + "echo '=== Promtail Status ==='", + "sudo systemctl status promtail --no-pager" + ] + } +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..ef40d88 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,25 @@ + +output "vm_name" { + description = "Имя созданной виртуальной машины" + value = proxmox_vm_qemu.grafana_loki.name +} + +output "vm_ip_address" { + description = "IP адрес созданной виртуальной машины" + value = proxmox_vm_qemu.grafana_loki.default_ipv4_address +} + +output "loki_url" { + description = "URL для доступа к Loki" + value = "http://${proxmox_vm_qemu.grafana_loki.default_ipv4_address}:${var.loki_port}" +} + +output "promtail_url" { + description = "URL для доступа к Promtail" + value = "http://${proxmox_vm_qemu.grafana_loki.default_ipv4_address}:${var.promtail_port}" +} + +output "ssh_command" { + description = "Команда для SSH подключения к VM" + value = "ssh ${var.vm_user}@${proxmox_vm_qemu.grafana_loki.default_ipv4_address}" +} diff --git a/providers.tf b/providers.tf new file mode 100644 index 0000000..3718bd0 --- /dev/null +++ b/providers.tf @@ -0,0 +1,18 @@ + +terraform { + required_version = ">= 1.0" + + required_providers { + proxmox = { + source = "Telmate/proxmox" + version = "~> 2.9.11" + } + } +} + +provider "proxmox" { + pm_api_url = var.proxmox_api_url + pm_api_token_id = var.proxmox_api_token_id + pm_api_token_secret = var.proxmox_api_token_secret + pm_tls_insecure = var.proxmox_tls_insecure +} diff --git a/terraform.tfvars.example b/terraform.tfvars.example new file mode 100644 index 0000000..6b2266f --- /dev/null +++ b/terraform.tfvars.example @@ -0,0 +1,27 @@ + +# Скопируйте этот файл в terraform.tfvars и заполните своими значениями + +# Настройки Proxmox API +proxmox_api_url = "https://your-proxmox-host:8006/api2/json" +proxmox_api_token_id = "terraform-user@pve!token-id" +proxmox_api_token_secret = "your-token-secret-here" +proxmox_tls_insecure = true + +# Настройки виртуальной машины +target_node = "pve" +vm_name = "grafana-loki" +vm_template = "ubuntu-20.04-template" +vm_cores = 2 +vm_memory = 4096 +vm_disk_size = "40G" +vm_storage = "local-lvm" +vm_network_bridge = "vmbr0" + +# Настройки пользователя +vm_user = "ubuntu" +ssh_private_key_path = "~/.ssh/id_rsa" + +# Настройки Loki и Promtail +loki_version = "2.9.1" +loki_port = 3100 +promtail_port = 9080 diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..62ac0c1 --- /dev/null +++ b/variables.tf @@ -0,0 +1,100 @@ + +variable "proxmox_api_url" { + description = "URL адрес Proxmox API (например, https://your-proxmox-host:8006/api2/json)" + type = string +} + +variable "proxmox_api_token_id" { + description = "ID токена для API Proxmox (например, terraform-user@pve!token-id)" + type = string +} + +variable "proxmox_api_token_secret" { + description = "Секретный токен для API Proxmox" + type = string + sensitive = true +} + +variable "proxmox_tls_insecure" { + description = "Игнорировать проверку TLS сертификата" + type = bool + default = true +} + +variable "target_node" { + description = "Имя узла Proxmox для развертывания VM" + type = string + default = "pve" +} + +variable "vm_name" { + description = "Имя создаваемой виртуальной машины" + type = string + default = "grafana-loki" +} + +variable "vm_template" { + description = "Имя шаблона для клонирования VM (должен поддерживать cloud-init)" + type = string + default = "ubuntu-20.04-template" +} + +variable "vm_cores" { + description = "Количество ядер CPU для VM" + type = number + default = 2 +} + +variable "vm_memory" { + description = "Объем оперативной памяти для VM (в MB)" + type = number + default = 4096 +} + +variable "vm_disk_size" { + description = "Размер диска VM" + type = string + default = "40G" +} + +variable "vm_storage" { + description = "Хранилище Proxmox для VM" + type = string + default = "local-lvm" +} + +variable "vm_network_bridge" { + description = "Сетевой мост для VM" + type = string + default = "vmbr0" +} + +variable "vm_user" { + description = "Имя пользователя для cloud-init" + type = string + default = "ubuntu" +} + +variable "ssh_private_key_path" { + description = "Путь к приватному SSH ключу для подключения к VM" + type = string + default = "~/.ssh/id_rsa" +} + +variable "loki_version" { + description = "Версия Grafana Loki для установки" + type = string + default = "2.9.1" +} + +variable "loki_port" { + description = "HTTP порт для Loki" + type = number + default = 3100 +} + +variable "promtail_port" { + description = "HTTP порт для Promtail" + type = number + default = 9080 +}