# Azure — Application Gateway, App Service, Front Door

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

URL: https://zrazu.com/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.
