# Google Cloud — балансувальник із Certificate Manager

> Задача Cloud Run за розкладом Cloud Scheduler раз на добу оновлює сертифікат у Certificate Manager на місці — балансувальник підхоплює його сам.

URL: https://zrazu.com/docs/ssl-auto-gcp/

Підходить для зовнішнього балансувальника Google Cloud, якщо сертифікат підключено через **Certificate Manager** (certificate map). Certificate Manager оновлює сертифікат на місці: прив'язки не змінюються. Для «класичних» сертифікатів балансувальника (`compute ssl-certificates`) оновлення на місці немає — перенесіть сертифікат у Certificate Manager.

Усе робиться командами в **Cloud Shell** (кнопка `>_` угорі консолі Google Cloud) — нічого ставити на свій комп'ютер не треба.

## Що знадобиться

- Посилання на сертифікат із кабінету: `https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН`.
- Закритий ключ без пароля — файл `key.pem`. У Cloud Shell завантажте його через меню **⋮ → Upload**.
- Роль Owner або Editor у проєкті.

## Крок 1. Скрипт оновлення

У Cloud Shell відкрийте редактор `nano zrazu-gcp-update.sh`, вставте текст і збережіть (Ctrl+O, Enter, Ctrl+X). Якщо сертифікат у Certificate Manager уже є під іншою назвою, змініть `CERT`; регіональний сертифікат — змініть `LOCATION`.

```sh file=zrazu-gcp-update.sh
#!/bin/sh
# ZRAZU: оновлення сертифіката в Google Certificate Manager за особистим посиланням. Запускається раз на добу.
set -eu
PULL="https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
CERT="zrazu-ssl"
LOCATION="global"
KEY=/zrazu-key/key.pem

cd /tmp
curl -fsS --retry 3 --max-time 60 -o new.pem "$PULL/fullchain.pem"
grep -q "BEGIN CERTIFICATE" new.pem || { echo "ZRAZU: not a certificate"; exit 1; }
current=$(gcloud certificate-manager certificates describe "$CERT" --location="$LOCATION" --format='value(pemCertificate)' | tr -d '\r\n ')
if [ "$current" = "$(tr -d '\r\n ' < new.pem)" ]; then echo "ZRAZU: unchanged"; exit 0; fi
gcloud certificate-manager certificates update "$CERT" --location="$LOCATION" --certificate-file=new.pem --private-key-file="$KEY" --quiet
echo "ZRAZU: updated"
```

## Крок 2. Перший сертифікат (якщо його ще немає в Certificate Manager)

```sh
curl -fsS -o fullchain.pem "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН/fullchain.pem"
gcloud certificate-manager certificates create zrazu-ssl --certificate-file=fullchain.pem --private-key-file=key.pem
```

Додайте його в certificate map балансувальника (**Certificate Manager → Certificate maps**), якщо ще не додали.

## Крок 3. Задача і розклад

Скопіюйте весь блок у Cloud Shell. Регіон задачі можна змінити на найближчий.

```sh
REGION=europe-west1
PROJECT=$(gcloud config get-value project)
SA=zrazu-ssl@$PROJECT.iam.gserviceaccount.com
gcloud services enable run.googleapis.com cloudscheduler.googleapis.com secretmanager.googleapis.com certificatemanager.googleapis.com
gcloud iam service-accounts create zrazu-ssl --display-name="ZRAZU SSL update"
gcloud secrets create zrazu-ssl-key --data-file=key.pem
gcloud secrets create zrazu-ssl-script --data-file=zrazu-gcp-update.sh
for s in zrazu-ssl-key zrazu-ssl-script; do gcloud secrets add-iam-policy-binding $s --member=serviceAccount:$SA --role=roles/secretmanager.secretAccessor; done
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA --role=roles/certificatemanager.editor
gcloud run jobs create zrazu-ssl --region=$REGION --image=gcr.io/google.com/cloudsdktool/google-cloud-cli:stable --service-account=$SA --set-secrets=/zrazu-key/key.pem=zrazu-ssl-key:latest,/zrazu-script/update.sh=zrazu-ssl-script:latest --command=/bin/sh --args=/zrazu-script/update.sh --max-retries=1
gcloud run jobs add-iam-policy-binding zrazu-ssl --region=$REGION --member=serviceAccount:$SA --role=roles/run.invoker
gcloud scheduler jobs create http zrazu-ssl-daily --location=$REGION --schedule="17 4 * * *" --uri="https://run.googleapis.com/v2/projects/$PROJECT/locations/$REGION/jobs/zrazu-ssl:run" --http-method=POST --oauth-service-account-email=$SA
rm key.pem
```

Ключ тепер лише в Secret Manager, а з Cloud Shell його прибрано.

## Перевірка

1. Запустіть задачу руками: `gcloud run jobs execute zrazu-ssl --region=$REGION --wait`.
2. Журнал: **Cloud Run → Jobs → zrazu-ssl → Logs** — «updated» або «unchanged».
3. Сайт: [https://zrazu.com/tools/ssl/example.com/](https://zrazu.com/tools/ssl/example.com/). Балансувальнику Google потрібно до кількох хвилин.

## Якщо не вийшло

- `PERMISSION_DENIED` — сервісному акаунту не видано роль із кроку 3; повторіть відповідний рядок.
- Помилка про ключ при `update` — сертифікат перевипускали з новим ключем: `gcloud secrets versions add zrazu-ssl-key --data-file=новий-key.pem`.
- Помилка про імена (SAN) — Certificate Manager оновлює сертифікат лише з тим самим списком доменів. Якщо домени змінилися, створіть новий сертифікат і замініть його в certificate map.
- Скрипт змінили — оновіть секрет: `gcloud secrets versions add zrazu-ssl-script --data-file=zrazu-gcp-update.sh`.
