Сначала выберите исходное имя
https://go.example.com/docs/start?tag=a&tag=bhttps://www.example.com/docs/start?tag=a&tag=bСобственный HTTPS-хост → API Gateway → функция → фиксированное назначение.
Нужны аккаунт и каталог Yandex Cloud с оплатой, права на создание функции, шлюза, сервисного аккаунта и сертификата, а также управление DNS источника. Пример использует отдельный поддомен go.example.com, не занятый живым сайтом.
При стороннем DNS официальная схема подключения поддерживает поддомен через CNAME. Для корневого example.com текущая инструкция требует делегирования в Yandex Cloud DNS и записи ANAME. Прежде чем выбирать apex, оцените перенос всей DNS-зоны: заранее сохраните MX, TXT и записи работающего назначения. Один CNAME не решает этот вопрос.
Все адреса example.com и example.org здесь демонстрационные. Замените их своими. Меняйте только исходный хост: рабочие DNS-записи назначения должны остаться на месте. Источник и назначение не должны перенаправлять друг на друга.
Для проверки нового правила можно сначала выбрать 302. После подтверждённого постоянного переезда переключите его на 301: браузер способен кешировать постоянный редирект, и откат серверной настройки не удаляет уже сохранённый ответ у посетителя.
Если нужны и HTTP-, и HTTPS-ссылки, для HTTP потребуется отдельно проверенная точка входа. В этом рецепте поведение порта 80 не подтверждается. Рассмотрите Caddy или два правила Cloudflare, где обе схемы заданы явно. Ресурс Yandex CDN здесь не нужен.
1. Создайте функцию Node.js
В Cloud Functions создайте функцию и её версию с поддерживаемой средой Node.js. Добавьте файл index.js, задайте точку входа index.handler. Зависимости для этого кода не требуются.
exports.handler = async (event) => {
const path = event.rawPath || '/';
const query = event.rawQueryString || '';
return {
statusCode: 301,
headers: {
Location: 'https://www.example.com' + path + (query ? '?' + query : '')
},
body: '',
isBase64Encoded: false
};
};Назначение фиксировано. Функция использует rawPath и rawQueryString формата события 2.0, не пересобирая query из словаря с потерей повторов. Пустой путь получает /; при пустой query знак вопроса не добавляется. Код не проксирует тело запроса и не исполняет переход сам — это сделает клиент.
Сохраните идентификатор функции. Не открывайте её вызов всем пользователям отдельно: шлюз будет обращаться к ней через сервисный аккаунт.
2. Подключите два маршрута API Gateway
Создайте сервисный аккаунт шлюза и дайте ему роль functions.functionInvoker на эту функцию. Для вызова не нужна широкая роль editor на весь каталог. В API Gateway создайте шлюз со следующим полным документом OpenAPI; в обоих местах замените идентификаторы функции и аккаунта.
openapi: 3.0.0
info:
title: Domain redirect
version: 1.0.0
paths:
/:
x-yc-apigateway-any-method:
responses:
'301':
description: Permanent redirect
headers:
Location:
schema:
type: string
x-yc-apigateway-integration:
type: cloud_functions
function_id: REPLACE_WITH_FUNCTION_ID
service_account_id: REPLACE_WITH_SERVICE_ACCOUNT_ID
payload_format_version: '2.0'
/{path+}:
x-yc-apigateway-any-method:
parameters:
- name: path
in: path
required: true
schema:
type: string
responses:
'301':
description: Permanent redirect
headers:
Location:
schema:
type: string
x-yc-apigateway-integration:
type: cloud_functions
function_id: REPLACE_WITH_FUNCTION_ID
service_account_id: REPLACE_WITH_SERVICE_ACCOUNT_ID
payload_format_version: '2.0'Маршрут / обрабатывает корень отдельно, /{path+} — вложенные пути. Нельзя рассчитывать, что greedy-вариант сам закроет корень. Расширение x-yc-apigateway-any-method направляет методы в одну интеграцию; ниже проверяются веб-запросы GET и HEAD.
Этот пример для ссылок, не для повторной отправки произвольных API-тел. При 301/302 клиент может заменить POST на GET. Для API, где нужен исходный метод, сначала разберите соответствующую семантику, а не применяйте это правило вслепую.
3. Привяжите сертификат и DNS
- В Certificate Manager запросите управляемый сертификат для
go.example.com. Выполните выбранную проверку владения доменом и дождитесь статусаIssued. - В разделе Domains шлюза добавьте полное имя источника и выберите этот сертификат.
- Возьмите служебное имя созданного шлюза из его карточки и задайте для go требуемую CNAME-запись. Не угадывайте имя endpoint по идентификатору функции.
- Дождитесь применения DNS и проверьте HTTPS на собственном имени. Сохраните записи, необходимые для продления управляемого сертификата.
Для apex используйте предусмотренные провайдером Cloud DNS и ANAME после подготовки переноса зоны. Сертификат функции на её служебном URL не покрывает автоматически ваш домен. Сертификат www остаётся отдельной задачей целевого хостинга.
4. Проверьте HTTPS и данные события
curl -sS -o /dev/null -D - 'https://go.example.com/'
curl -sS -o /dev/null -D - 'https://go.example.com/docs/start?tag=a&tag=b&utm_source=mail'Ожидайте код 301. Для корня заголовок Location должен быть https://www.example.com/, для вложенного адреса — https://www.example.com/docs/start?tag=a&tag=b&utm_source=mail. Версия HTTP и регистр имени заголовка в выводе могут отличаться. Если временно выбрали 302, ожидаемый код — 302.
curl -sS -I 'https://go.example.com/docs/start?tag=a&tag=b'
curl --path-as-is -sS -o /dev/null -D - 'https://go.example.com/files/report%20one.pdf?tag=a&tag=b&q=a%2Fb'Не добавляйте -L к первой проверке: важно увидеть ответ источника, а не скрыть его за переходом. Затем отдельно откройте адрес назначения и убедитесь, что там есть нужная страница. DNS не создаёт HTTP-ответ, а сертификат назначения не заменяет сертификат источника.
Для encoded-примера ожидается https://www.example.com/files/report%20one.pdf?tag=a&tag=b&q=a%2Fb. Код сохраняет строки, которые пришли в событии. Это не доказательство побайтового сохранения на живом шлюзе: после развёртывания проверьте %20, %2F, кириллицу и повторяющиеся query на фактическом API Gateway.
{
"version": "2.0",
"rawPath": "/files/report%20one.pdf",
"rawQueryString": "tag=a&tag=b&q=a%2Fb"
}При таком входе функция должна вернуть statusCode 301 и указанный Location. Вызов функции отдельно проверяет только обработчик; запрос к собственному HTTPS-домену нужен для проверки DNS, TLS, маршрутизации и прав вместе. Успех HTTPS не подтверждает работу HTTP.
Диагностика и откат
| Симптом | Что проверить |
|---|---|
| На вложенном пути ответ есть, на / — 404 | Убедитесь, что в опубликованной спецификации есть отдельный маршрут корня. |
| Ошибка вызова функции | Сверьте function_id, service_account_id, права functionInvoker именно на функцию и наличие рабочей версии. |
| Путь всегда / или пропали повторы | Проверьте payload_format_version 2.0 у обеих интеграций и использование rawPath/rawQueryString. |
| Служебный адрес работает, свой домен — нет | Проверьте CNAME/ANAME, привязку домена, покрытие сертификатом и Issued. |
| HTTPS работает, HTTP — нет | Этот рецепт не настраивает HTTP-вход; нужна отдельная проверенная схема для порта 80. |
Перед изменением сохраните предыдущую версию функции, спецификацию и DNS. Для отката восстановите версию/спецификацию или переведите источник на заранее готовый прежний обработчик. Не удаляйте шлюз и сертификат, пока DNS ещё ведёт на них; кешированный 301 также может пережить откат.
Ресурсы и расходы
ОС сервера обновлять не нужно, но остаются версия функции, спецификация, права сервисного аккаунта, доменная привязка, сертификат и DNS. Следите за ошибками вызовов и состоянием продления сертификата. Потребление Cloud Functions, API Gateway и Cloud DNS при его использовании учитывается по отдельным правилам.
Универсальной фиксированной суммы для этой комбинации нет. Оцените свой трафик по официальным условиям:
Этот пример не развёрнут в вашем облаке. Провайдерские настройки и результат на вашем домене нужно проверить после применения.