# Azure — Application Gateway, App Service, Front Door

> Runbook Azure Automation раз в сутки забирает свежий сертификат и добавляет новую версию в Key Vault — сервисы Azure подхватывают её сами.

URL: https://zrazu.com/ru/docs/ssl-auto-azure/

Подходит, если сертификат сайта лежит в **Azure Key Vault** и его берёт Application Gateway v2, App Service или Front Door (Standard/Premium). Эти сервисы сами переходят на новую версию сертификата в Key Vault, если подключены «без версии» (Latest): Application Gateway — в течение 4 часов, App Service — в течение суток, Front Door — до 72 часов.

Как это работает: runbook в Azure Automation раз в сутки забирает сертификат по ссылке, сравнивает с текущим в Key Vault и, если он новый, собирает PFX с вашим ключом (ключ лежит в том же Key Vault как секрет) и импортирует новую версию. Мы не получаем доступа к вашему Azure.

## Что понадобится

- Ссылка на сертификат из кабинета: `https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН`.
- Закрытый ключ без пароля — файл `key.pem`. Для Front Door — только RSA: ключи ECDSA Front Door не принимает.
- Key Vault в модели доступа **Azure role-based access control** и права Owner на него.

## Шаг 1. Сертификат и ключ в Key Vault

Откройте **Cloud Shell** (кнопка `>_` вверху портала, режим Bash), загрузите `key.pem` (**Manage files → Upload**) и выполните, подставив название своего Key Vault:

```sh
VAULT=ИМЯ_KEY_VAULT
curl -fsS -o fullchain.pem "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН/fullchain.pem"
az keyvault secret set --vault-name $VAULT --name zrazu-ssl-key --file key.pem
openssl pkcs12 -export -in fullchain.pem -inkey key.pem -out zrazu.pfx -passout pass:
az keyvault certificate import --vault-name $VAULT --name zrazu-ssl --file zrazu.pfx
rm key.pem zrazu.pfx
```

Если сертификат уже есть в Key Vault под другим названием, последний импорт пропустите, а в runbook (шаг 3) измените `$CertName`.

Подключите сертификат к сервису без версии, если ещё не подключили: Application Gateway — **Listeners → сертификат из Key Vault**; App Service — **Certificates → Bring your own certificates → Import from Key Vault**; Front Door — **Secrets → Add certificate → версия Latest**.

## Шаг 2. Учётная запись Automation

1. **Automation Accounts → Create** → группа ресурсов и регион те же, что у Key Vault → **Review + Create**.
2. В учётной записи **Account Settings → Identity** → **System assigned: On** → **Save**.
3. В Key Vault **Access control (IAM) → Add role assignment**: роль **Key Vault Certificates Officer** → **Managed identity** → ваша учётная запись Automation → **Review + assign**. Повторите для роли **Key Vault Secrets User**.

## Шаг 3. Runbook

1. В учётной записи Automation **Process Automation → Runbooks → Create a runbook**: название `zrazu-ssl-update`, **Runbook type** — PowerShell, **Runtime version** — 7.2 → **Create**.
2. Вставьте текст ниже, в строке `$Vault` укажите название Key Vault → **Save** → **Publish**.

```powershell file=zrazu-azure-runbook.ps1
# ZRAZU: обновление сертификата в Azure Key Vault по личной ссылке. Запускается раз в сутки.
$ErrorActionPreference = "Stop"
$Pull = "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
$Vault = "ИМЯ_KEY_VAULT"
$CertName = "zrazu-ssl"
$KeySecret = "zrazu-ssl-key"
$X509 = [Security.Cryptography.X509Certificates.X509Certificate2]

Connect-AzAccount -Identity | Out-Null
$full = (Invoke-WebRequest -Uri "$Pull/fullchain.pem" -UseBasicParsing).Content
if ($full -is [byte[]]) { $full = [Text.Encoding]::ASCII.GetString($full) }
$pems = @([regex]::Matches($full, "-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----") | ForEach-Object { $_.Value })
if ($pems.Count -eq 0) { throw "ZRAZU: not a certificate" }
$leaf = $X509::CreateFromPem($pems[0])
$current = Get-AzKeyVaultCertificate -VaultName $Vault -Name $CertName
if ($current -and $current.Thumbprint -eq $leaf.Thumbprint) { "ZRAZU: unchanged"; return }
if ($leaf.NotAfter -le (Get-Date)) { throw "ZRAZU: certificate expired" }
$key = Get-AzKeyVaultSecret -VaultName $Vault -Name $KeySecret -AsPlainText
$withKey = $X509::CreateFromPem($pems[0], $key)
$all = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection
[void]$all.Add($withKey)
foreach ($pem in ($pems | Select-Object -Skip 1)) { [void]$all.Add($X509::CreateFromPem($pem)) }
$pfx = $all.Export([Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12)
Import-AzKeyVaultCertificate -VaultName $Vault -Name $CertName -CertificateString ([Convert]::ToBase64String($pfx)) | Out-Null
"ZRAZU: updated, valid until $($leaf.NotAfter.ToString('yyyy-MM-dd'))"
```

Если ключ не подходит к сертификату, `CreateFromPem` остановится с ошибкой и ничего не будет импортировано.

## Шаг 4. Расписание

В runbook **Link to schedule → Link a schedule to your runbook → Add a schedule**: название `zrazu-daily`, **Recurrence** — Recurring, каждый 1 день, время — любое ночное → **Create** → **OK**.

## Проверка

1. В runbook **Start** → **OK**. Откройте задачу (**Jobs**), вкладка **Output**: «updated» или «unchanged».
2. В Key Vault **Certificates → zrazu-ssl** — новая версия с новой датой.
3. Сайт: [https://zrazu.com/tools/ssl/example.com/](https://zrazu.com/tools/ssl/example.com/) — с учётом того, как быстро ваш сервис подхватывает новую версию (см. вверху).

## Если не получилось

- `Forbidden` / `does not have secrets get permission` — не выдана одна из двух ролей шага 2, либо Key Vault в модели access policy: тогда в **Access policies** дайте identity права Certificates: Get, Import и Secrets: Get.
- «The provided key does not match» — сертификат перевыпускали с новым ключом: `az keyvault secret set --vault-name $VAULT --name zrazu-ssl-key --file новый-key.pem`.
- `404` — ссылка отключена или заменена: создайте новую в карточке сертификата и замените `$Pull`.
- Front Door не берёт сертификат — ключ ECDSA или сертификат подключён с конкретной версией, а не Latest.
