Развёртывание

Установка в Google Cloud

Развёртывание ScanSuite Teams в собственном проекте Google Cloud на Cloud Run с помощью Terraform, с примерами установки.

ScanSuite Teams можно развернуть не на сервере, а в собственном проекте Google Cloud. Конфигурация Terraform из папки gcp репозитория установки создаёт всё одной командой и удаляет другой. Приложение работает в Cloud Run вместе с управляемыми сервисами, так что обслуживать виртуальную машину не нужно.

Охват: статический анализ

В Cloud Run нет демона Docker, поэтому сканеры, которые запускаются отдельными контейнерами, — динамическое сканирование веб-приложений (DAST) и сканирование инфраструктуры — здесь не работают. Анализ кода (SAST), зависимостей (SCA), инфраструктуры как кода, поиск секретов и AI-анализ кода работают полностью. Для динамических сканирований установите ScanSuite на сервер: Установка ScanSuite Teams.

Что создаётся

Всё размещается в одном проекте. Пароли генерируются при первом развёртывании и хранятся в Secret Manager; у базы данных и Redis только внутренние адреса; образы читаются через Artifact Registry проекта и закреплены по точным дайджестам.

ЧастьКак работает
Веб-интерфейс и APIСервис Cloud Run за внешним HTTPS-балансировщиком с Cloud Armor, который пропускает только ваши диапазоны адресов.
Фоновые воркерыПулы воркеров Cloud Run: обслуживание и восстановление прерванных сканирований, планировщик и песочница для AI-проверок proof-of-concept.
СканированияОтдельный запуск задания Cloud Run на каждое сканирование, 4 vCPU и 16 ГиБ; после сканирования он завершается.
Миграция базы данныхЗадание Cloud Run, которое deploy.sh запускает до старта сервисов.
База данныхCloud SQL для PostgreSQL 16, внутренний IP, ежесуточные резервные копии и восстановление на момент времени.
Очередь задачMemorystore для Redis, внутренний IP, TLS.
Артефакты сканированийБакет Cloud Storage; прежние версии хранятся 30 дней.
Исходящий трафикCloud NAT на постоянных адресах — для списков разрешённых адресов на git-сервере и у AI-провайдера.
МониторингПроверка доступности и оповещения об ошибках, сбоях загрузки, нагрузке на базу данных и Redis.

1. Подготовка

  • Проект Google Cloud с подключённым биллингом, в котором ваша учётная запись — Owner или Editor вместе с Project IAM Admin: развёртывание создаёт сервисные аккаунты и выдаёт им роли. Проще всего отвести под ScanSuite отдельный проект.
  • Инструменты на Linux, macOS или Windows с WSL или Git Bash: Google Cloud CLI (gcloud), Terraform 1.6 или новее, git, bash и curl.
  • Из поставки ScanSuite: файл лицензии (<имя>_<код>.lic; код — это и тег образов), а также имя пользователя и токен доступа к реестру образов.
  • Ваш публичный IPv4-адрес или диапазоны, с которых разрешено открывать веб-интерфейс: curl -4 -s https://ifconfig.me.

2. Развёртывание

Загрузите файлы установки, добавьте лицензию и перейдите в папку gcp:

bash
git clone https://github.com/cepxeo/scansuite.git
cp /path/to/<имя>_<код>.lic scansuite/key/
cd scansuite/gcp

Войдите в Google Cloud дважды: один раз для gcloud, второй — для Terraform (Application Default Credentials):

bash
gcloud auth login
gcloud auth application-default login

Скопируйте пример настроек и отредактируйте копию. Готовые примеры — в разделе 3.

Терминал
cp terraform.tfvars.example terraform.tfvars
ПараметрЧто указать
project_idID вашего проекта (gcloud projects list).
regionНапример, europe-west3 (Франкфурт, по умолчанию). Для другого региона задайте также zones и primary_zone — пример D.
image_tagКод вашей лицензии, <код> в <имя>_<код>.lic.
dockerhub_usernameИмя пользователя реестра из поставки.
web_allowed_cidrsДиапазоны адресов, с которых открывается интерфейс, до 10, например ["203.0.113.10/32"].
timezoneДля запланированных сканирований, например Europe/Moscow.
alert_emailНеобязательно. Адрес для оповещений.

Передайте токен реестра через переменную окружения — он хранится в Secret Manager, читать его может только Artifact Registry, и в файл настроек он не попадает — и запустите развёртывание:

bash
export TF_VAR_dockerhub_token='<токен доступа к реестру>'
./deploy.sh

Первый запуск занимает 20–30 минут, большую часть из них создаётся Cloud SQL. До того как что-либо создавать, скрипт проверяет вход в Google Cloud, биллинг проекта и лицензию. Затем он создаёт Artifact Registry проекта и находит точные образы для кода вашей лицензии; создаёт сеть, базу данных, Redis, хранилище и секреты и выполняет миграцию базы данных; после этого запускает сервисы, балансировщик и мониторинг. Когда скрипт завершается строкой Done, установка работает, а её адрес — значение вывода url. Повторно вывести значения можно в любой момент командой terraform output.

3. Примеры установки

Примеры A, B и C — готовые файлы terraform.tfvars; D–G — строки, которые добавляются к одному из них. Токен реестра всегда передаётся через переменную окружения, как в разделе 2.

A. Пробная установка

Небольшие размеры без резервных копий, интерфейс открыт для одного адреса — примерно вдвое дешевле настроек по умолчанию:

terraform.tfvars
project_id  = "acme-scansuite-trial"
region      = "europe-west3"
environment = "dev"

image_tag          = "a1b2c3"
dockerhub_username = "<имя пользователя реестра>"

web_allowed_cidrs = ["203.0.113.10/32"]
timezone          = "Europe/Moscow"

# Меньше производственных размеров и без резервных копий.
cloudsql_ha      = false
cloudsql_tier    = "db-custom-1-3840"   # 1 vCPU, 3,75 ГБ
cloudsql_disk_gb = 20
redis_ha         = false
redis_memory_gb  = 1
poc_replicas     = 1

Когда пробный период закончится, ./destroy.sh --delete-artifacts удалит всё, включая сохранённые артефакты сканирований.

B. Производственная установка

Размеры по умолчанию (база данных и Redis с резервными копиями), собственный домен с сертификатом, выпущенным Google, оповещения и защита от случайного удаления:

terraform.tfvars
project_id  = "acme-scansuite"
region      = "europe-west3"
environment = "prod"

image_tag          = "a1b2c3"
dockerhub_username = "<имя пользователя реестра>"

domain_name       = "scansuite.acme.example"
web_allowed_cidrs = ["198.51.100.0/24", "203.0.113.10/32"]   # офис и VPN
timezone          = "Europe/Moscow"
alert_email       = "secops@acme.example"

deletion_protection = true

После первого развёртывания направьте DNS-запись A домена на значение load_balancer_ip; сертификат выпускается, когда имя начинает разрешаться, — это может занять до часа. С manage_dns = true развёртывание создаст и DNS-зону, которую останется делегировать у регистратора. Прежде чем развёртыванием займётся кто-то ещё, перенесите состояние Terraform в бакет Cloud Storage, как описано в backend.tf.example.

C. Без доступа из интернета

Для корпоративной сети, связанной с VPC проекта через VPN или Interconnect. Балансировщика нет; интерфейс доступен по адресу Cloud Run только изнутри сети:

terraform.tfvars
project_id = "acme-scansuite"
region     = "europe-west3"

image_tag          = "a1b2c3"
dockerhub_username = "<имя пользователя реестра>"

internal_only = true
timezone      = "Europe/Moscow"
alert_email   = "secops@acme.example"

Вывод url в этом случае — адрес вида https://…run.app, который ваша сеть разрешает и маршрутизирует через Private Google Access. web_allowed_cidrs и domain_name не используются, а оповещение о недоступности не создаётся: зонды Google не могут достучаться до внутреннего адреса.

D. Другой регион

Задавайте регион вместе с его зонами: от зон зависит размещение Redis и резервной копии базы данных:

terraform.tfvars
region       = "europe-west4"
zones        = ["europe-west4-a", "europe-west4-b", "europe-west4-c"]
primary_zone = "europe-west4-b"

E. Вторая установка в том же проекте

Например, тестовая рядом с производственной. Разворачивайте её из отдельной копии папки, чтобы у неё было своё состояние Terraform (cp -r scansuite/gcp scansuite/gcp-test), и задайте свой префикс, чтобы все ресурсы получили собственные имена:

terraform.tfvars
name_prefix = "scansuite-test"

Префикс лучше делать коротким: бакет артефактов называется <name_prefix>-artifacts-<project_id>, не длиннее 63 символов.

F. Образы из собственного реестра

Если установка вообще не должна обращаться к Docker Hub, раз в выпуск скопируйте три образа в реестр проекта командой ./scripts/mirror-images.sh <проект> <код> <регион> (нужен Docker с входом под пользователем реестра). Скрипт выведет строки для добавления; image_tag и dockerhub_username тогда не нужны:

terraform.tfvars
image_web        = "europe-west3-docker.pkg.dev/acme-scansuite/scansuite/teams-web:a1b2c3"
image_worker     = "europe-west3-docker.pkg.dev/acme-scansuite/scansuite/teams-worker:a1b2c3"
image_worker_poc = "europe-west3-docker.pkg.dev/acme-scansuite/scansuite/teams-worker-poc:a1b2c3"

G. Повторное развёртывание вскоре после удаления

Cloud SQL резервирует имя удалённого экземпляра примерно на неделю. Чтобы развернуть установку заново в этот срок, задайте базе данных другое имя:

terraform.tfvars
cloudsql_name = "scansuite-pg-2"

4. Первый вход

Сразу откройте адрес из вывода url. Без доменного имени это IP-адрес балансировщика с самоподписанным сертификатом, поэтому браузер один раз выдаст предупреждение. Новая установка показывает страницу настройки, где создаётся первая учётная запись и задаётся имя команды, — так же, как на сервере, см. Установка ScanSuite Teams. Эта учётная запись достаётся тому, кто первым откроет страницу, поэтому web_allowed_cidrs задаётся до развёртывания.

Затем настройте поставщика ИИ в карточке Системный ИИ раздела Настройки системы → Общие сервисы (или для отдельной команды — в разделе Команды → ИИ → Поставщик ИИ), см. Поставщики ИИ и стоимость:

  • Vertex AI не требует ключа: у собственного сервисного аккаунта установки уже есть роль Vertex AI User. Укажите ID проекта, регион, где доступна модель, и ID модели Claude, а поле учётных данных оставьте пустым. Предварительно включите модель для проекта в Vertex AI → Model Garden.
  • Любой OpenAI-совместимый интерфейс тоже подходит, включая Azure OpenAI. Сканирования обращаются к нему с постоянных адресов из вывода scan_egress_ips.

5. Повседневная работа

  • Изменить настройку: отредактируйте terraform.tfvars и снова запустите ./deploy.sh. Повторный запуск всегда безопасен, а пока образы не меняются, идущие сканирования продолжаются.
  • Новый выпуск: положите новый .lic в ../key/ и удалите старый, задайте в image_tag новый код, выполните git pull, а затем ./deploy.sh. Миграция отменяет незавершённые сканирования, поэтому обновляйтесь, когда сканирований нет.
  • Прерванные сканирования восстанавливаются сами: сканирование, запуск которого остановился, 90 минут не показывает прогресса, а затем запускается заново и продолжает AI-анализ с последнего сохранённого этапа.
  • Загрузка через браузер в Cloud Run ограничена 32 МиБ; код большего объёма сканируйте из git-репозитория.
  • Журналы: в консоли в разделе Logging → Logs Explorer или командой gcloud logging read для сервиса scansuite-web и задания scansuite-sast.
  • Берегите состояние Terraform: в terraform.tfstate хранятся сгенерированные пароли и ваша лицензия. Держите файл в закрытом месте, делайте резервную копию после каждого развёртывания и перенесите его в бакет Cloud Storage, прежде чем развёртывать будет второй человек или конвейер CI.

Ориентировочная стоимость в месяц, в долларах США; цены для своего региона уточните в калькуляторе Google Cloud:

СтатьяПо умолчаниюПробная (пример A)
Cloud SQL200–25050–70
Memorystore150–20035–45
Сервисы Cloud Run300–400200–250
Балансировщик, Cloud Armor, Cloud NAT50–8050–80
Хранилище, секреты, реестр, журналы10–3010–30
Сканирования, по 4 vCPU и 16 ГиБоколо 0,5 за час сканированиятак же

6. Удаление

bash
./destroy.sh                      # попросит ввести ID проекта
./destroy.sh --delete-artifacts   # удалить и сохранённые артефакты сканирований

Скрипт примерно за 15 минут удаляет всё, что создало развёртывание, включая базу данных со всеми результатами сканирований; -y отключает вопрос. Бакет с артефактами сканирований остаётся, если не указать --delete-artifacts. Если скрипт остановился на полпути, запустите его снова: он продолжит с оставшегося. Одна остановка — в порядке вещей: после удаления сервисов Cloud Run ещё до двух часов удерживает несколько адресов в сети, и освободить их может только Google. Скрипт сообщает об этом; за оставшееся на этот момент плата не начисляется.

Частые сообщения

billing is not enabled: подключите к проекту платёжный аккаунт. could not find teams-web:<код>: проверьте image_tag, имя пользователя и токен реестра. The Cloud SQL instance already exists: пример G. Ошибка зоны после смены региона: пример D. API «has not been used in project»: только что включённому API нужно несколько минут, запустите ./deploy.sh ещё раз. Страница не открывается: проверьте, что ваш адрес входит в web_allowed_cidrs; новый балансировщик начинает отвечать через 5–10 минут.

Проверено: 2026-10-01