Pular para o conteúdo

Variáveis e referências

Escopos: env:read, env:write, env:reveal (Tokens e escopos).

  • service: vale só para um serviço. Rota: /v1/projects/{p}/services/{s}/variables[/{name}].
  • shared: guardada no projeto. Rota: /v1/projects/{p}/shared-variables[/{name}]. Ela não entra sozinha no ambiente de nenhum serviço: só chega a um serviço que a referencie com ${{shared.NOME}} (veja abaixo).

Valor literal ou com referências: ${{<servico>.<VAR>}} (variável de outro serviço do projeto) e ${{shared.VAR}} (variável compartilhada). shared é nome reservado: nenhum serviço pode se chamar assim.

Janela do terminal
SUF=$(date +%s)-$RANDOM
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" \
-H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: var-proj-$SUF" -d "{\"name\": \"vars-$SUF\"}" | jq -r .id)
S=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" \
-H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: var-svc-$SUF" \
-d "{\"name\": \"api\", \"kind\": \"app\", \"visibility\": \"private\", \"source\": {\"type\": \"image\", \"ref\": \"ghcr.io/org/api:1.0\"}}" | jq -r .id)
curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" \
-H "Authorization: Bearer $NEBULAR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value": "info"}'
{"name": "LOG_LEVEL", "value": "info", "sensitive": false, "needs_redeploy": []}

O corpo do PUT é {"value": "...", "sensitive": true|false} (sensitive é opcional; uma variável já sensível nunca volta a ser não sensível). A resposta traz a variável e needs_redeploy, a lista de serviços que precisam de novo deploy para ver o valor (vazia quando nenhum serviço usa a variável). Variável sensível: o PUT nunca devolve o valor ("value": null) e as leituras só o mostram a um token com env:reveal; sem ele, value vem null e sensitive vem true.

Para definir várias de uma vez (tudo ou nada, de 1 a 200 itens), use PUT .../variables com {"variables": [{"name": "A", "value": "1"}, {"name": "B", "value": "2", "sensitive": true}]}; a resposta é {"items": [...], "needs_redeploy": [...]}. GET .../variables?resolved=true devolve as variáveis já com as referências expandidas e as automáticas (exige env:reveal).

Variável compartilhada do projeto:

Janela do terminal
SUF=$(date +%s)-$RANDOM
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" \
-H "Authorization: Bearer $NEBULAR_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: var2-proj-$SUF" -d "{\"name\": \"vars2-$SUF\"}" | jq -r .id)
curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/shared-variables/REGION" \
-H "Authorization: Bearer $NEBULAR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value": "br"}'

Para que o serviço enxergue a variável compartilhada REGION, crie nele uma variável própria que a referencie (o nome pode ser o mesmo ou outro). Sem essa referência, REGION não aparece no ambiente do serviço:

PUT /v1/projects/{p}/services/{s}/variables/REGION
{"value": "${{shared.REGION}}"}

Referência a outro serviço (o front lê a URL privada do back):

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: var3-proj-$SUF" -d "{\"name\": \"vars3-$SUF\"}" | jq -r .id)
curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" -H "$H" -H "Content-Type: application/json" \
-d '{"name": "api", "kind": "app", "visibility": "private", "port": 8080, "source": {"type": "image", "ref": "ghcr.io/org/api:1.0"}}' >/dev/null
S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \
-d "{\"visibility\": \"public\", \"slug\": \"vars3-$SUF\", \"source\": {\"type\": \"image\", \"ref\": \"ghcr.io/org/web:1.0\"}}" | jq -r .id)
curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/API_URL" -H "$H" \
-H "Content-Type: application/json" -d '{"value": "${{api.PRIVATE_URL}}"}'

Listar (valores sensíveis vêm mascarados sem env:reveal) e apagar:

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: var4-proj-$SUF" -d "{\"name\": \"var4-$SUF\"}" | jq -r .id)
S=$(curl -sS -X POST "$NEBULAR_API/v1/projects/$P/services" -H "$H" -H "Content-Type: application/json" \
-H "Idempotency-Key: var4-svc-$SUF" \
-d '{"name": "app", "kind": "app", "visibility": "private", "source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)
curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H" \
-H "Content-Type: application/json" -d '{"value": "info"}'
curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/variables" -H "$H"
curl -sS -X DELETE "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H"

Variáveis automáticas (resolvíveis por referência)

Seção intitulada “Variáveis automáticas (resolvíveis por referência)”

Todo serviço ganha, sem você definir:

Variável Valor
NEBULAR_SERVICE_NAME o name do serviço
PORT a porta interna
PRIVATE_HOST <name> (hostname na rede privada)
PRIVATE_URL http://<name>:<port>
PUBLIC_URL URL pública, se o serviço é public; senão vazio
PUBLIC_DOMAIN domínio público do serviço

Serviços de banco também expõem DATABASE_URL e as variáveis do motor (Conexão e referências). Exemplo: ${{api.PRIVATE_URL}}, ${{db.DATABASE_URL}}.

Se um app precisa de um banco ou de disco persistente que ainda não existe, a plataforma detecta e sugere criar o recurso (e, no caso de banco, injetar a referência ${{db.DATABASE_URL}}), sempre esperando sua autorização: veja Sugestões de persistência.

  • Acontece no deploy, por serviço. Quem é referenciado sobe antes (ordem topológica no deploy de grupo).
  • Referência a variável ou serviço inexistente: o POST do deploy responde 422 unresolved_reference e nada é criado; details.references lista os nomes com problema. O PUT da variável aceita a referência: o erro só aparece no deploy.
  • Referências em ciclo: 422 reference_cycle (também com details.references).
  • Outros erros de resolução presentes na API: invalid_reference (um ${{...}} que não é da forma escopo.VAR), reference_too_deep (aninhamento acima de 16 níveis) e value_too_large (valor expandido acima de 64 KiB ou ambiente acima de 256 KiB).
  • Valor resolvido herda a sensibilidade do que foi referenciado (veja a próxima seção).
  • Re-resolução: mudar um valor referenciado marca os dependentes como “precisam de redeploy”. Faça um novo deploy dos dependentes (ou ative auto_deploy).

Uma variável cujo valor é uma referência (DATABASE_URL = ${{db.DATABASE_URL}}) guarda o texto da referência, não o segredo. Por isso:

  • O PUT pode responder "sensitive": false e a leitura sem resolved mostra o texto ${{db.DATABASE_URL}}: nada de segredo trafega ali. Se quiser a variável tratada como sensível já na definição, envie "sensitive": true no PUT (a resposta volta com value: null).
  • O valor resolvido herda a sensibilidade de quem foi referenciado: GET ...?resolved=true mostra DATABASE_URL com "sensitive": true, e o valor fica mascarado em log e painel.
  • Essa leitura resolvida (e env:reveal em geral) entrega o segredo em claro ao token com o escopo env:reveal, que precisa ser pedido explicitamente ao criar o token (Tokens e escopos). Sem o escopo, resolved=true dá 403. Trate a resposta como segredo: não a registre em log nem a cole em chat.
  • depends_on do serviço (usado para a ordem do deploy de grupo) é calculado das referências gravadas: o serviço api passa a listar ["db"] na leitura do serviço assim que a variável com ${{db...}} existe. A resposta de criação do serviço, anterior à variável, vem com depends_on vazio.

GET .../variables?resolved=true devolve os valores já expandidos. Exige o escopo env:reveal (token criado com step-up) e devolve valores sensíveis em claro.

Janela do terminal
SUF=$(date +%s)-$RANDOM
H="Authorization: Bearer $NEBULAR_TOKEN"
P=$(curl -sS -X POST "$NEBULAR_API/v1/projects" -H "$H" -H "Content-Type: application/json" \
-d "{\"name\": \"var5-$SUF\"}" | jq -r .id)
S=$(curl -sS -X PATCH "$NEBULAR_API/v1/projects/$P/services/web" -H "$H" -H "Content-Type: application/json" \
-d '{"source": {"type": "image", "ref": "ghcr.io/org/app:1.0"}}' | jq -r .id)
curl -sS -X PUT "$NEBULAR_API/v1/projects/$P/services/$S/variables/LOG_LEVEL" -H "$H" \
-H "Content-Type: application/json" -d '{"value": "info"}' >/dev/null
curl -sS "$NEBULAR_API/v1/projects/$P/services/$S/variables?resolved=true" \
-H "$H"
{"items": [{"name": "LOG_LEVEL", "value": "info", "sensitive": false}], "next_cursor": null, "has_more": false}
Resposta O que fazer
403 forbidden Falta env:write (escrever), env:read (ler) ou env:reveal (resolved=true). Peça token novo.
404 not_found Projeto, serviço ou variável inexistente ou fora do seu acesso.
422 unresolved_reference no deploy Crie a variável/serviço citado ou corrija o nome na referência; redeploy.
422 reference_cycle no deploy Quebre o ciclo (A referencia B que referencia A).
400 invalid_request Nome ou valor inválido: corrija.