---
name: azion-migre-da-vercel-para-a-azion
description: >-
  Migre um projeto da Vercel para a Azion: faça o deploy, recrie funções, regras e cache, mova dados do Blob e do Edge Config e troque o DNS.
---

# Migre da Vercel para a Azion

Um projeto na Vercel guarda seu comportamento em vários lugares: configurações de build, `vercel.json`, funções de servidor, stores do Blob, Edge Config, regras de firewall e um domínio de produção. Migrá-lo significa recriar cada parte na Azion e confirmar que o projeto responde corretamente antes da mudança do domínio.

Na Azion, uma [aplicação](/pt-br/documentacao/plataforma/applications/) e suas regras assumem a entrega, o roteamento e o cache. [Functions](/pt-br/documentacao/plataforma/functions/) executa as rotas de API e o código de servidor, e [AI Inference](/pt-br/documentacao/plataforma/ai-inference/) executa modelos. [KV Store](/pt-br/documentacao/plataforma/kv-store/) recebe os dados do Edge Config, e [Object Storage](/pt-br/documentacao/plataforma/object-storage/) recebe os arquivos do Blob. [Firewall](/pt-br/documentacao/plataforma/firewall/) filtra as requisições, um [workload](/pt-br/documentacao/plataforma/workloads/) atende o domínio e [Edge DNS](/pt-br/documentacao/plataforma/edge-dns/) pode hospedar a zona. [Real-Time Metrics](/pt-br/documentacao/plataforma/real-time-metrics/), [Real-Time Events](/pt-br/documentacao/plataforma/real-time-events/) e [Data Stream](/pt-br/documentacao/plataforma/data-stream/) informam sobre o tráfego.

As etapas abaixo seguem a ordem em que uma migração acontece: inventário, deployment, código e regras, dados, segurança, monitoramento e DNS. A maior parte do código migra com mudanças pontuais: como uma função lê uma variável, como abre o armazenamento e como chama um modelo. Quando um downtime próximo de zero não é um requisito, migre em fases com janelas de manutenção. As gravações param durante cada janela, então os dados não precisam ficar sincronizados entre duas plataformas.

---

Os pré-requisitos e os procedimentos desta página mudam conforme a interface que você seleciona:

## Pré-requisitos

- Uma conta Azion. Para abrir uma, [cadastre-se no Azion Console](https://console.azion.com/signup), como descreve [Crie uma conta](/pt-br/documentacao/fundamentos/criar-uma-conta/).
- Acesso ao projeto da Vercel: seu repositório, suas configurações e suas variáveis de ambiente.
- Acesso aos registros DNS ou ao registrador de cada domínio que você move.
- `curl` e `dig`, para verificar as respostas HTTP e as respostas DNS.

**Console**

- Acesso ao Azion Console. Para entrar, consulte [Acesse Azion Console](/pt-br/documentacao/guias/plataforma/conta-e-billing/como-acessar-o-azion-console/).

**CLI**

- [Azion CLI](/pt-br/documentacao/devtools/cli/), instalada e autorizada com sua conta. Os comandos desta página correspondem à Azion CLI 4.23.0.

**API**

- Um personal token, enviado no header `Authorization` como `Token [TOKEN VALUE]`. Para criar um, consulte [Gerencie um personal token](/pt-br/documentacao/guias/plataforma/conta-e-billing/personal-tokens/). Toda requisição desta página vai para `https://api.azion.com/v4`.

---

## Faça o inventário do projeto da Vercel

Comece por um único projeto que teste o caminho completo e ainda migre rápido. Um bom primeiro projeto tem um domínio parecido com o de produção, algumas rotas, redirecionamentos e headers e uma função. Ele também tem um store do Blob, um store do Edge Config e um fluxo de analytics. Registre cada passo durante o processo e depois repita a mesma ordem nos outros projetos. Comprove que o primeiro deployment faz o build e roda na Azion antes de mover seus domínios, seu armazenamento ou seu firewall.

Antes de criar qualquer coisa na Azion, liste o que o projeto usa:

- Projetos, equipes, deployments de produção e preview deployments.
- Comandos de build, diretórios de saída, presets de framework e comandos de instalação.
- `vercel.json`, a configuração do framework, o middleware e as definições de rotas.
- Variáveis de ambiente de produção, preview e desenvolvimento.
- Rotas de API, server actions, funções e workloads do Fluid Compute.
- Redirecionamentos, reescritas, headers, comportamento do cache e configurações de otimização de imagens.
- Rotas de IA, provedores de modelos e configurações do AI Gateway.
- Stores do Blob, stores do Edge Config, feature flags e experimentos.
- Regras de firewall, controles de WAF, rate limits, proteções contra bots e controles de acesso a deployments.
- SAML Single Sign-On e as funções de equipe que dependem dele.
- Dashboards de observabilidade, Speed Insights, Web Analytics, alertas, fluxos de logs e integrações do Marketplace.
- Domínios, registros DNS, nameservers e o status de cada certificado.

Cada item tem uma etapa própria nesta página. Mapeie cada produto da Vercel para a Azion indica o destino de cada um.

---

## Mapeie cada produto da Vercel para a Azion

Encontre cada item do inventário na primeira coluna. A última coluna indica o destino na Azion, e a etapa com o nome desse destino o move. Todo produto da Vercel da lista tem um destino, então nenhuma linha traz um traço.

| Produto da Vercel              | O que cobre                                                                                                               | Destino na Azion                                                                                                                                                                       |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Advanced Deployment Protection | Controle de acesso às URLs de deployment por autenticação, IPs confiáveis, senhas ou bypasses                             | Firewall, Rules Engine para Firewall e Network Lists                                                                                                                                   |
| AI Cloud                       | Construção e execução de aplicações de IA                                                                                 | AI Inference, Functions e Applications                                                                                                                                                 |
| AI Gateway                     | Um endpoint para acesso a modelos, roteamento, fallbacks, novas tentativas, monitoramento de uso e observabilidade        | AI Inference, Functions e Real-Time Events                                                                                                                                             |
| AI SDK                         | Um toolkit TypeScript para aplicações de IA, agentes, interfaces de streaming e chamadas de ferramentas                   | AI Inference, chamado com `Azion.AI.run()` a partir de uma função                                                                                                                      |
| Bot Management                 | Controles de detecção, mitigação, desafio, permissão e bloqueio para tráfego automatizado                                 | [Bot Manager](/pt-br/documentacao/plataforma/firewall/#bot-manager) e [Bot Manager Lite](/pt-br/documentacao/plataforma/firewall/bot-manager/bot-manager-lite/)                        |
| BotID                          | Verificação de bots para ações sensíveis, invisível para o usuário                                                        | Bot Manager                                                                                                                                                                            |
| CI/CD and Preview Deployments  | Builds a partir do Git, com um ambiente de preview para cada mudança                                                      | Applications e Azion CLI                                                                                                                                                               |
| Content Delivery Network       | Cache, roteamento, compressão, TLS, redirecionamentos e reescritas                                                        | Applications, [Cache](/pt-br/documentacao/plataforma/applications/#cache) e [Rules Engine para Applications](/pt-br/documentacao/plataforma/applications/rules-engine/)                |
| Domains and DNS                | Domínios personalizados, registros DNS, nameservers e automação de certificados                                           | Workloads, Edge DNS e [Certificate Manager](/pt-br/documentacao/plataforma/workloads/#certificate-manager)                                                                             |
| Edge Config                    | Um store replicado para feature flags, experimentos, redirecionamentos e configuração                                     | KV Store                                                                                                                                                                               |
| Environment Variables          | Valores para os ambientes de produção, preview e desenvolvimento                                                          | [Variáveis de ambiente](/pt-br/documentacao/plataforma/functions/environment-variables/), armazenadas na conta                                                                         |
| Fluid Compute                  | Um modelo de computação do lado do servidor para workloads dinâmicos concorrentes                                         | Functions                                                                                                                                                                              |
| Headers                        | Headers de requisição ou de resposta personalizados para rotas                                                            | Rules Engine para Applications                                                                                                                                                         |
| Image Optimization             | Transformação e entrega de imagens sob demanda                                                                            | [Image Processor](/pt-br/documentacao/plataforma/applications/#image-processor)                                                                                                        |
| Microfrontends                 | Projetos de frontend com deploy independente, atrás de uma camada de roteamento                                           | Applications e Rules Engine para Applications                                                                                                                                          |
| Observability                  | Monitoramento de tráfego, builds, funções, chamadas a APIs externas, performance, erros e uso                             | Real-Time Metrics, Real-Time Events e Data Stream                                                                                                                                      |
| Observability Plus             | Retenção maior, métricas, dados de requisições, consultas, notebooks, monitoramento e alertas                             | Real-Time Metrics, Real-Time Events e Data Stream                                                                                                                                      |
| Platform Security              | Mitigação de DDoS, TLS, firewall da plataforma, controles de acesso e monitoramento de segurança                          | Firewall, [DDoS Protection](/pt-br/documentacao/plataforma/workloads/#ddos-protection) e [Network Shield](/pt-br/documentacao/plataforma/firewall/#network-shield)                     |
| Production Deployments         | Builds promovidos aos domínios que os clientes usam                                                                       | Applications e Azion CLI                                                                                                                                                               |
| Projects                       | As configurações de build, deployment, ambiente, domínio e runtime de um projeto                                          | Applications, atendido por um workload                                                                                                                                                 |
| Redirects and rewrites         | Roteamento por caminho e por host a partir das configurações do projeto, da configuração do framework ou do `vercel.json` | Rules Engine para Applications                                                                                                                                                         |
| SAML Single Sign-On            | Login da equipe por um provedor de identidade SAML                                                                        | [Single Sign-On](/pt-br/documentacao/fundamentos/single-sign-on/)                                                                                                                      |
| Speed Insights                 | Monitoramento de performance de usuários reais com base nos Core Web Vitals                                               | [Edge Pulse](/pt-br/documentacao/plataforma/edge-pulse/) e Real-Time Metrics                                                                                                           |
| Vercel Blob                    | Armazenamento de objetos para arquivos, uploads, imagens, documentos e vídeos                                             | Object Storage                                                                                                                                                                         |
| Vercel CLI                     | Projetos, deployments, logs, domínios e variáveis de ambiente a partir de um terminal                                     | Azion CLI                                                                                                                                                                              |
| Vercel Firewall                | Regras de tráfego, bloqueios de IP, rate limits, redirecionamentos, desafios, Attack Mode e exceções                      | Firewall, [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/) e [Network Lists](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/) |
| Vercel Functions               | Funções do lado do servidor para APIs, páginas dinâmicas e integrações de backend                                         | Functions                                                                                                                                                                              |
| Vercel Marketplace             | Integrações para bancos de dados, armazenamento, autenticação, IA, observabilidade, CMS, comércio, mensagens e segurança  | [Marketplace](/pt-br/documentacao/plataforma/marketplace/)                                                                                                                             |
| Web Analytics                  | Visualizações de página, visitantes, referenciadores, dados demográficos, eventos personalizados e uso de funcionalidades | Edge Pulse e Real-Time Metrics                                                                                                                                                         |
| Web Analytics Plus             | Janelas de relatório maiores e mais dados de atribuição                                                                   | Edge Pulse e Real-Time Metrics                                                                                                                                                         |
| Web Application Firewall       | Proteção gerenciada e personalizada contra ataques na camada de aplicação                                                 | [Web Application Firewall](/pt-br/documentacao/plataforma/firewall/#waf)                                                                                                               |

Para verificar uma função antes que ela receba tráfego, [Preview deployment](/pt-br/documentacao/plataforma/functions/preview-deployment/) a executa contra uma requisição simulada no editor de código do Azion Console. Ele testa uma função e não cria um ambiente separado para cada mudança.

---

## Faça o deploy do projeto na Azion

Na Azion, um projeto da Vercel se torna uma aplicação, e um workload atende essa aplicação em um domínio. A Vercel lê a configuração de build do `vercel.json`, da configuração do framework e das configurações do projeto. A Azion a lê do [`azion.config.js`](/pt-br/documentacao/devtools/cli/azion-config-js/), que alguns presets chamam de `azion.config.mjs` ou `azion.config.cjs`.

| Tarefa           | Azion CLI                                                                      |
| ---------------- | ------------------------------------------------------------------------------ |
| Instalar         | `curl -fsSL https://cli.azion.app/install.sh \| bash`, ou `brew install azion` |
| Entrar           | `azion login`                                                                  |
| Rodar localmente | `azion dev`                                                                    |
| Fazer o deploy   | `azion link`, depois `azion deploy`                                            |

A Azion suporta 19 frameworks e 5 presets genéricos. Nenhuma interface detecta o framework sozinha: Azion Console oferece seis presets para escolher, e Azion CLI lista os presets em um seletor.

**Console**

Para importar o repositório no Azion Console:

1. **Abra o diálogo New**

   Acesse [Azion Console](https://console.azion.com/) > **Create**. O diálogo **New** abre.

2. **Abra a aba Import from GitHub**

   Selecione a aba **Import from GitHub** e depois selecione o card.

3. **Conecte a conta do GitHub**

   Em **GitHub Connection**, selecione **Connect with GitHub** e instale o Azion GitHub App no repositório.

4. **Selecione o repositório**

   Em **Git Scope**, selecione a conta do GitHub. Em **Repository**, selecione o repositório do projeto da Vercel.

5. **Selecione o preset**

   Em **Preset**, selecione o framework do projeto: *Next.js*, *Angular*, *Astro*, *Hexo*, *React* ou *Vue*.

6. **Informe o comando de instalação**

   Em **Install Command**, informe o comando que instala o projeto. Por exemplo: `npm install`.

7. **Selecione Deploy**

A Azion faz o build do repositório e depois cria sua aplicação e seu workload. Para cada campo da página de importação, consulte [Importe um projeto do GitHub](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/automacao/importar-um-projeto-existente-do-github/).

**CLI**

Para fazer o deploy a partir da sua máquina com Azion CLI, vincule o projeto primeiro. Execute o comando na raiz do projeto da Vercel e selecione o preset quando a CLI listá-los:

```bash
azion link
```

O `azion link` grava as configurações do projeto que o deploy lê. Depois faça o deploy:

```bash
azion deploy
```

A CLI faz o build do projeto e o deploy na Azion. Para definir o preset no código em vez do seletor, defina `build.preset` no `azion.config.js`:

```javascript
import { defineConfig } from '@aziontech/config'

export default defineConfig({
  build: {
    preset: 'javascript',
    polyfills: true
  }
})
```

O preset de um projeto Next.js é `next`. Importe `defineConfig` de `@aziontech/config`, porque o pacote `azion` de exemplos antigos está obsoleto. Instale esse pacote no projeto antes, com `npm install -D @aziontech/config`. Sem ele, a CLI falha com `Failed to load configuration file`. Para os comandos, consulte [Primeiros passos com Azion CLI](/pt-br/documentacao/devtools/cli/primeiros-passos/) e [azion deploy](/pt-br/documentacao/devtools/cli/deploy/). Para o conjunto completo de comandos, consulte [Azion CLI](/pt-br/documentacao/devtools/cli/).

**API**

A API monta a cadeia um recurso por vez: a aplicação, suas regras e o workload. Para criá-los em ordem, consulte [Primeiros passos com Applications](/pt-br/documentacao/plataforma/applications/primeiros-passos/).

A Azion dá ao workload um domínio sob `map.azionedge.net`. Teste o projeto nele antes de mover qualquer domínio de produção. Requisite o caminho raiz, com o domínio do workload no lugar de `<your-workload-domain>`:

```bash
curl -i https://<your-workload-domain>/
```

A resposta traz o código de status, os headers e o corpo que o projeto serve para `/`. Repita a requisição para cada rota importante, como o caminho de health check de uma API:

```bash
curl -i https://<your-workload-domain>/api/health
```

Até que o vínculo com a aplicação se propague, um workload novo responde com um `404` provisório. Isso pode levar vários minutos, e nenhuma duração é garantida. Envie a requisição de novo até que a resposta venha do projeto.

Se o build falhar na Azion, compare o preset com o framework do projeto da Vercel. Depois verifique `build.preset`, `build.entry` e `build.bundler` no `azion.config.js`, além do comando de instalação e dos scripts do pacote. O bloco `build` não tem campo para um comando de build.

---

## Mova as variáveis de ambiente

Um projeto lê de suas variáveis chaves de API, credenciais de banco de dados, secrets de autenticação, endpoints de terceiros, tokens de provedores de IA e feature flags. Quando uma delas falta na Azion, o deployment ainda tem sucesso, e o projeto falha em tempo de execução.

Reúna todas as variáveis antes de mudar qualquer código. Na Vercel, elas vêm destes lugares:

- As configurações de ambiente do projeto.
- Variáveis gerenciadas com a Vercel CLI.
- Os arquivos `.env` do framework usados no desenvolvimento local.
- Chaves de provedores de IA e configurações do gateway de modelos.
- Tokens do Blob e credenciais de armazenamento.
- IDs, tokens e chaves do Edge Config.
- O ambiente de CI/CD.
- Configurações escritas no código-fonte.

A Azion armazena as variáveis na conta, até 100 delas. Cada uma tem uma chave, um valor e uma flag que a marca como secret. Uma função lê uma variável com `Azion.env.get()`.

**Console**

Para criar as variáveis no Azion Console, abra a página **Variables** do menu **Account**. Adicione cada variável com sua chave e seu valor e marque uma credencial como secret.

**CLI**

Para criar uma variável com Azion CLI:

```bash
azion create variables --key API_KEY --value <your-value> --secret false
```

A CLI responde com o UUID da variável que criou:

```text
Created variable with UUID 00000000-0000-0000-0000-000000000001
```

Para uma credencial, passe `--secret true`. `azion list variables` lista todas as variáveis da conta. Para os outros comandos, consulte [variables](/pt-br/documentacao/devtools/cli/recursos/variables/).

**API**

As variáveis são criadas no Azion Console ou com Azion CLI. Para cada interface que cria, lista ou altera uma variável, consulte [Variáveis de ambiente](/pt-br/documentacao/plataforma/functions/environment-variables/).

Depois altere o código que lê cada variável:

```javascript diff
-// Before: Vercel / Node.js
-const apiKey = process.env.API_KEY;
-const aiApiKey = process.env.AI_API_KEY;
 
+// After: Azion Functions
+const apiKey = Azion.env.get('API_KEY');
+const aiApiKey = Azion.env.get('AI_API_KEY');
```

Uma função em produção também aceita `process.env.API_KEY`. No `azion dev`, uma função lê o arquivo `.env` do projeto em vez das variáveis da conta. Sem um arquivo `.env`, ela lê todo o ambiente do shell. Se uma função informar que uma variável não foi encontrada, confirme que a conta a guarda e que o código a lê com `Azion.env.get()`. Feature flags e configurações guardadas no Edge Config vão para KV Store, em Mova dados do Edge Config para KV Store.

> **Atenção**
>
> Guarde secrets apenas em sistemas aprovados e dê acesso apenas aos processos que os usam. Não cole um secret em notas, tickets, chats ou arquivos temporários.

---

## Mova rotas de API e funções de servidor

Rotas de API, server actions, webhooks, autenticação, personalização, orquestração de IA e chamadas de backend costumam ficar em Vercel Functions e Fluid Compute. Na Azion, esse código roda em Functions. Uma função guarda o código, uma [instância de função](/pt-br/documentacao/plataforma/applications/functions-instances/) o executa em uma aplicação, e uma regra escolhe as requisições que chegam até ela.

| Aspecto            | Vercel Functions             | Azion Functions                                               |
| ------------------ | ---------------------------- | ------------------------------------------------------------- |
| Handler            | `handler(req, res)`          | `fetch(request, env, ctx)`, com `Request` e `Response` padrão |
| Variáveis          | `process.env.VARIABLE`       | `Azion.env.get('VARIABLE')` ou `process.env.VARIABLE`         |
| Roteamento         | O caminho do arquivo da rota | Uma regra com o comportamento *Run Function*                  |
| Blob e Edge Config | Os SDKs da Vercel            | APIs de runtime do Object Storage e do KV Store               |

Em uma função em produção, `env` é um objeto vazio, e `ctx` traz `args` e `waitUntil`. O handler lê o corpo do `Request` e retorna um `Response`:

```javascript diff
-// Before: Vercel API route style
-export default async function handler(req, res) {
-  const body = req.body;
-
-  res.status(200).json({
-    message: 'Hello',
-    data: body
-  });
-}
 
+// After: Azion Functions
+export default {
+  async fetch(request, env, ctx) {
+    const body = await request.json();
+
+    return new Response(JSON.stringify({ message: 'Hello', data: body }), {
+      status: 200,
+      headers: { 'Content-Type': 'application/json' }
+    });
+  }
+};
```

A Vercel associa uma requisição a uma função pelo caminho do arquivo, como `app/api/users/[id]/route.ts` ou `pages/api/users/[id].ts`. Na Azion, quem faz essa associação é uma regra da aplicação. A regra abaixo envia cada requisição `GET` para `/api/users/<id>` a uma instância de função:

```json
{
  "name": "GET /api/users/:id",
  "active": true,
  "criteria": [
    [
      { "variable": "${uri}", "conditional": "if", "operator": "matches", "argument": "^/api/users/([^/]+)$" },
      { "variable": "${request_method}", "conditional": "and", "operator": "is_equal", "argument": "GET" }
    ]
  ],
  "behaviors": [
    { "type": "run_function", "attributes": { "value": <function-instance-id> } }
  ]
}
```

*Run Function* (`run_function`) recebe o ID da instância, não o ID da função. A aplicação precisa de [Application Accelerator](/pt-br/documentacao/plataforma/applications/application-accelerator/configuracoes/) e Functions ativados, e uma aplicação nova já vem com Functions ativado. Para o comportamento, consulte [Run Function](/pt-br/documentacao/plataforma/applications/rules-engine/#run-function).

**Console**

Para criar a função, sua instância e a regra no Azion Console, siga os painéis Console de [Primeiros passos com Functions](/pt-br/documentacao/plataforma/functions/primeiros-passos/). Antes de adicionar a regra *Run Function*, ative **Application Accelerator** em **Modules**, na aba **Main Settings** da aplicação.

**CLI**

Para fazer o deploy da função e rotear requisições para ela com Azion CLI, comece no diretório que guarda o código da função, como `index.js`. Crie a função:

```bash
azion create function --name get-user --code ./index.js --active true
```

```text
Created function with ID <function-id>
```

Em seguida, ative Application Accelerator, com o ID da aplicação no lugar de `<application-id>`:

```bash
azion update application --application-id <application-id> --application-accelerator true
```

```text
Updated Application with ID <application-id>
```

Se `azion describe application --application-id <application-id>` mostrar `functions` desativado, envie a mesma atualização com `--functions true`. Depois crie a instância na aplicação:

```bash
azion create function-instance --application-id <application-id> --function-id <function-id> --name "get-user instance"
```

```text
Created Function Instance with ID <function-instance-id>
```

Salve a regra acima como `rule.json`, com o ID da instância no lugar de `<function-instance-id>`. Ler a regra de um arquivo impede que o shell expanda `${uri}`. Crie-a na fase de requisição:

```bash
azion create rules-engine --application-id <application-id> --phase request --file rule.json
```

```text
Created Rules Engine with ID <rule-id>
```

**API**

Para fazer o deploy da função e rotear requisições para ela com a API, crie a função primeiro, com seu código como uma string JSON em `code`:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/functions \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "get-user",
  "code": "<function-code>"
}'
```

Um `202` retorna `"state": "pending"` e a função, com seu `id`, `"runtime": "azion_js"` e `"execution_environment": "application"`. Em seguida, ative Application Accelerator, com o ID da aplicação no lugar de `<application-id>`:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/applications/<application-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "modules": {
    "application_accelerator": {
      "enabled": true
    }
  }
}'
```

A resposta `202` traz `"state": "pending"`. Quando Functions está desativado na aplicação, o mesmo corpo com `functions` no lugar de `application_accelerator` o ativa. Crie a instância, com o ID da função em `function`:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/functions \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "get-user instance",
  "function": <function-id>,
  "args": {},
  "active": true
}'
```

Um `202` retorna a instância, com seu próprio `id` e o ID da função repetido em `function`. Salve a regra acima como `rule.json`, com o ID da instância no lugar de `<function-instance-id>`, para que o shell não altere `${uri}`. Envie-a para as regras de requisição da aplicação:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data @rule.json
```

Um `202` retorna `"state": "pending"` e a regra, com seu `id` e sua `order`.

Uma requisição que corresponde à regra agora executa a função. Se uma rota de API falhar na Azion, confirme que o handler é `fetch(request, env, ctx)`. Ele precisa ler a requisição com [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript/) padrão, não com helpers do runtime da Vercel.

---

## Recrie redirecionamentos e reescritas

Redirecionamentos mantêm funcionando rankings de busca, links de campanhas, backlinks e favoritos, e um redirecionamento quebrado perde tráfego. A Vercel define o roteamento nas rotas do framework, no middleware, no `vercel.json`, nas configurações do projeto e no comportamento da CDN. A Azion guarda redirecionamentos e reescritas nas regras da aplicação, que Azion Console, a API, a CLI e o `azion.config.js` gravam. Cada regra une critérios a comportamentos e pertence à Request Phase ou à Response Phase.

Esta entrada do `vercel.json` move todo caminho sob `/old-blog/` para o mesmo caminho sob `/blog/`, com um redirecionamento permanente:

```json
{
  "redirects": [
    {
      "source": "/old-blog/:path*",
      "destination": "/blog/:path*",
      "permanent": true
    }
  ]
}
```

| Aspecto                    | Vercel                                                              | Azion                                                                                                      |
| -------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Configuração               | `vercel.json`, configuração do framework e configurações do projeto | [Rules Engine para Applications](/pt-br/documentacao/plataforma/applications/rules-engine/)                |
| Correspondência de padrões | Padrões de caminho como `/old-blog/:path*`                          | Expressões regulares com o operador `matches`, como `^/old-blog/(.*)$`, além de `starts_with` e `is_equal` |
| Valores capturados         | `:path*`                                                            | `%{name[index]}`, como `%{capture[1]}`, de um comportamento *Capture Match Groups* na mesma regra          |

Um critério apenas seleciona as requisições e não captura nada. A captura é tarefa do `capture_match_groups`, e o redirecionamento é o `redirect_to_301`. Para levar parte do caminho antigo ao destino, coloque um comportamento *Capture Match Groups* antes do redirecionamento, na mesma regra. Esse comportamento requer Application Accelerator na aplicação. O array capturado é local à sua regra, então nenhuma outra regra pode lê-lo. Para cada argumento, consulte [Capture Match Groups](/pt-br/documentacao/plataforma/applications/rules-engine/#capture-match-groups) e [Redirect To](/pt-br/documentacao/plataforma/applications/rules-engine/#redirect-to).

A regra da Azion corresponde ao caminho antigo, captura o restante dele em `capture` e redireciona com `301` para o novo caminho:

```json
{
  "name": "old-blog-redirect",
  "active": true,
  "criteria": [
    [
      { "variable": "${uri}", "conditional": "if", "operator": "matches", "argument": "^/old-blog/(.*)$" }
    ]
  ],
  "behaviors": [
    {
      "type": "capture_match_groups",
      "attributes": { "captured_array": "capture", "subject": "${uri}", "regex": "^/old-blog/(.*)$" }
    },
    { "type": "redirect_to_301", "attributes": { "value": "/blog/%{capture[1]}" } }
  ]
}
```

**Console**

Para criar o redirecionamento no Azion Console:

1. **Abra a aplicação**

   Acesse [Azion Console](https://console.azion.com/) > **Applications** e selecione a aplicação.

2. **Vá para a aba Rules Engine**

3. **Selecione + Rule**

4. **Dê um nome à regra**

   Informe `old-blog-redirect` como nome e selecione **Request Phase**.

5. **Defina os critérios**

   Em **Criteria**, selecione `${uri}` e o operador *matches*. Como argumento, informe `^/old-blog/(.*)$`.

6. **Adicione o comportamento Capture Match Groups**

   Em **Behaviors**, selecione *Capture Match Groups*. Informe `capture` como nome do array, `${uri}` como **Subject** e `^/old-blog/(.*)$` como **Regex**.

7. **Adicione o redirecionamento**

   Adicione um segundo comportamento, *Redirect To (301 Moved Permanently)*, com `/blog/%{capture[1]}` como argumento.

8. **Selecione Save**

A nova regra aparece na lista de regras de requisição da aplicação.

**CLI**

Para criar o redirecionamento com Azion CLI, salve a regra acima como `rule.json`. Depois crie-a na fase de requisição da aplicação:

```bash
azion create rules-engine --application-id <application-id> --phase request --file rule.json
```

```text
Created Rules Engine with ID <rule-id>
```

**API**

Para criar o redirecionamento com a API, salve a regra acima como `rule.json` e envie uma requisição `POST` para as regras de requisição da aplicação:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data @rule.json
```

Um `202` retorna `"state": "pending"` e a regra, com seu `id` e sua `order`.

Para verificar o redirecionamento, requisite um caminho antigo:

```bash
curl -I https://<your-workload-domain>/old-blog/post
```

A resposta é `301 Moved Permanently`, com um header `location` que termina em `/blog/post`. Um caminho aninhado como `/old-blog/a/b` redireciona para `/blog/a/b`. Uma regra nova pode levar alguns minutos para se propagar. Diante de uma resposta inesperada, aguarde e tente de novo antes de diagnosticar.

Para servir outro caminho sem redirecionamento, use *Rewrite Request* com as mesmas capturas. Mova cada rota restante da mesma forma:

- Converta cada padrão de rota da Vercel em critérios e expressões regulares do Rules Engine.
- Mova os redirecionamentos simples para regras.
- Use Functions para reescritas dinâmicas, autenticação, URLs assinadas e consultas externas.
- Teste barras finais, prefixos de idioma e caminhos canônicos.
- Antes da virada, compare os headers de cache e os redirecionamentos de que o ranking de busca depende.

Em mudanças que afetam a busca, prefira redirecionamentos permanentes e evite cadeias de redirecionamento. Quando um redirecionamento ou uma reescrita se comporta diferente da rota da Vercel, teste os grupos de captura e os critérios em que o padrão se transformou.

---

## Recrie headers personalizados

Headers controlam o cache, a segurança e o comportamento do navegador. Na Vercel, as rotas adicionam headers de requisição ou de resposta. Na Azion, *Add Request Header* altera a requisição enviada à origem. *Add Response Header*, em uma regra da Response Phase, altera a resposta enviada ao usuário.

| Aspecto      | Vercel                     | Azion                                                                            |
| ------------ | -------------------------- | -------------------------------------------------------------------------------- |
| Configuração | Headers de rota no projeto | Rules Engine para Applications, no Azion Console, na API ou no `azion.config.js` |
| Fases        | Requisição ou resposta     | Request Phase e Response Phase                                                   |

Este `azion.config.js` adiciona dois headers de segurança a cada resposta da aplicação:

```javascript
import { defineConfig } from '@aziontech/config'

export default defineConfig({
  applications: [{
    name: 'my-app',
    rules: {
      response: [{
        name: 'Security Headers',
        active: true,
        criteria: [[{
          variable: '${uri}',
          conditional: 'if',
          operator: 'starts_with',
          argument: '/'
        }]],
        behaviors: [
          { type: 'add_response_header', attributes: { value: 'X-Frame-Options: SAMEORIGIN' } },
          { type: 'add_response_header', attributes: { value: 'X-Content-Type-Options: nosniff' } }
        ]
      }]
    }
  }]
})
```

Cada valor tem o formato `Name: value`. Azion Console recusa qualquer outro formato com `Header must follow the header-name: value format`. Um valor também pode trazer uma variável de regra, como `X-Docs-Uri: ${uri}`, que se expande em tempo de execução. Os headers só chegam a um domínio por meio de um workload que atende a aplicação. Execute `azion deploy` e depois verifique uma resposta:

```bash
curl -I https://<your-workload-domain>/
```

A resposta traz `x-frame-options: SAMEORIGIN` e `x-content-type-options: nosniff`. Um `404` que a Azion gera sem origem não traz nenhum dos dois headers.

---

## Recrie as configurações de cache

Um projeto da Vercel pode misturar cache da CDN, configurações de cache do framework, renderização dinâmica, geração estática e comportamento por rota. Na Azion, uma [configuração de cache](/pt-br/documentacao/plataforma/applications/cache/cache-settings/) guarda o TTL e a chave de cache. Uma regra com *Set Cache Policy* aplica a configuração às requisições a que corresponde. Toda configuração de cache pertence a uma aplicação, então cada chamada que cria ou altera uma configuração indica essa aplicação.

| Aspecto                    | Vercel                                                              | Azion                                                                                                                                                                                                         |
| -------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Configuração de cache      | Comportamento de cache do framework, configurações da CDN e headers | Configurações de cache, que as regras aplicam                                                                                                                                                                 |
| Chave de cache             | Comportamento da plataforma e do framework                          | Os controles **Cache vary by** da configuração de cache, de [Variação de cache](/pt-br/documentacao/plataforma/applications/application-accelerator/variacao-de-cache/), que requerem Application Accelerator |
| Purge                      | Novos deploys e invalidação de cache                                | [Real-Time Purge](/pt-br/documentacao/plataforma/applications/cache/real-time-purge/), por URL, chave de cache ou wildcard                                                                                    |
| Conteúdo expirado          | Controles do framework e da CDN                                     | **Stale cache**, que entrega uma cópia expirada quando a revalidação falha                                                                                                                                    |
| Menos requisições à origem | A CDN gerenciada                                                    | [Tiered Cache](/pt-br/documentacao/plataforma/applications/cache/tiered-cache/) e [Origin Shield](/pt-br/documentacao/plataforma/connectors/#origin-shield)                                                   |

O TTL é o **Max Age** de cada configuração de cache, de 0 a 31.536.000 segundos, com padrão de 60. Sem Application Accelerator na aplicação, um valor abaixo de 60 é recusado com `21021`. Com Tiered Cache ativado, uma configuração de cache precisa de *Override cache behavior* e de pelo menos 3 segundos. **Stale cache** respeita o `stale-while-revalidate` que a origem envia, ou mantém uma janela de 300 segundos com *Override cache behavior*. Ele vem ativado no Azion Console e desativado na API e na CLI.

### Crie a configuração de cache

A configuração `dynamic-cache` desta seção mantém uma cópia no navegador por 300 segundos e no cache da Azion por 3.600 segundos. Tiered Cache está ativado.

**Console**

Para criar `dynamic-cache` no Azion Console:

1. **Abra a aplicação**

   Acesse [Azion Console](https://console.azion.com/) > **Applications** e selecione a aplicação.

2. **Vá para a aba Cache Settings**

3. **Selecione + Cache**

4. **Dê um nome à configuração de cache**

   Em **Name**, informe `dynamic-cache`.

5. **Defina o TTL do navegador**

   Em **Browser Cache**, selecione *Override cache settings* e informe `300` no campo de TTL.

6. **Mantenha Override cache behavior selecionado**

   Em **Cache**, mantenha *Override cache behavior*, para que **Max Age** substitua o TTL da origem.

7. **Defina Max Age**

   Em **Max Age**, informe `3600`.

8. **Ative Tiered Cache**

   Ative **Tiered Cache** e selecione a **Tiered Cache Region**.

9. **Selecione Save**

`dynamic-cache` aparece na aba **Cache Settings**.

**CLI**

As flags da CLI não definem **Max Age**, o comportamento do cache nem Tiered Cache, então o comando lê o corpo de um arquivo. Para criar `dynamic-cache` com Azion CLI, salve primeiro este corpo como `cache-setting.json`:

```json
{
  "name": "dynamic-cache",
  "browser_cache": {
    "behavior": "override",
    "max_age": 300
  },
  "modules": {
    "cache": {
      "behavior": "override",
      "max_age": 3600,
      "tiered_cache": {
        "enabled": true,
        "topology": "nearest-region"
      }
    }
  }
}
```

Tiered Cache requer `"behavior": "override"` em `modules.cache`. Crie a configuração na aplicação:

```bash
azion create cache-setting --application-id <application-id> --file cache-setting.json
```

```text
Created Cache Settings configuration with ID <cache-setting-id>
```

A regra em Aplique a configuração de cache a um caminho recebe esse ID como `<cache-setting-id>`.

**API**

Para criar `dynamic-cache` com a API, salve primeiro este corpo como `cache-setting.json`:

```json
{
  "name": "dynamic-cache",
  "browser_cache": {
    "behavior": "override",
    "max_age": 300
  },
  "modules": {
    "cache": {
      "behavior": "override",
      "max_age": 3600,
      "tiered_cache": {
        "enabled": true,
        "topology": "nearest-region"
      }
    }
  }
}
```

Tiered Cache requer `"behavior": "override"` em `modules.cache`. Depois envie-o para o endpoint de configurações de cache da aplicação:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/cache_settings \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data @cache-setting.json
```

Um `201` retorna `"state": "executed"` e a configuração. Os campos que o corpo omite voltam com seus padrões, como `stale_cache`, e `large_file_cache` com seu `offset` fixo de `1024`. A regra em Aplique a configuração de cache a um caminho recebe o `id` como `<cache-setting-id>`. Para alterar a configuração depois, envie os mesmos campos em uma requisição `PATCH` para `/v4/workspace/applications/<application-id>/cache_settings/<cache-setting-id>`.

### Aplique a configuração de cache a um caminho

Uma configuração de cache não tem efeito até que uma regra a indique com *Set Cache Policy*. A regra desta seção aplica `dynamic-cache` a todo caminho sob `/products/`.

**Console**

Para criar `apply-dynamic-cache` no Azion Console:

1. **Abra a aplicação**

   Acesse [Azion Console](https://console.azion.com/) > **Applications** e selecione a aplicação.

2. **Vá para a aba Rules Engine**

3. **Selecione + Rule**

4. **Dê um nome à regra**

   Informe `apply-dynamic-cache` como nome.

5. **Selecione a Request Phase**

   Em **Phase**, selecione *Request Phase*. A fase de uma regra não muda depois que a regra existe.

6. **Defina o critério**

   Em **Criteria**, selecione `${uri}` e o operador *starts with*. Como argumento, informe `/products/`.

7. **Adicione o comportamento Set Cache Policy**

   Em **Behaviors**, selecione **Set Cache Policy** e depois selecione `dynamic-cache` na lista que aparece.

8. **Selecione Save**

`apply-dynamic-cache` aparece na aba **Rules Engine**, sob o título **Request**.

**CLI**

Para criar `apply-dynamic-cache` com Azion CLI, salve este corpo como `rule.json`, com o ID da configuração no lugar de `<cache-setting-id>`:

```json
{
  "name": "apply-dynamic-cache",
  "active": true,
  "criteria": [[{ "variable": "${uri}", "operator": "starts_with", "conditional": "if", "argument": "/products/" }]],
  "behaviors": [{ "type": "set_cache_policy", "attributes": { "value": <cache-setting-id> } }]
}
```

Crie a regra na fase de requisição:

```bash
azion create rules-engine --application-id <application-id> --phase request --file rule.json
```

```text
Created Rules Engine with ID <rule-id>
```

**API**

Para criar `apply-dynamic-cache` com a API, salve este corpo como `rule.json`, com o ID da configuração no lugar de `<cache-setting-id>`:

```json
{
  "name": "apply-dynamic-cache",
  "active": true,
  "criteria": [[{ "variable": "${uri}", "operator": "starts_with", "conditional": "if", "argument": "/products/" }]],
  "behaviors": [{ "type": "set_cache_policy", "attributes": { "value": <cache-setting-id> } }]
}
```

Envie-o para as regras de requisição da aplicação:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data @rule.json
```

Um `202` retorna `"state": "pending"` e a regra, com seu `id` e sua `order`.

A Azion se recusa a excluir uma configuração de cache enquanto uma regra a aplica, com `400` e o código `21014`. Altere ou exclua a regra primeiro.

Para variar o cache por query string, cookie ou dispositivo, use os controles **Cache vary by** da configuração de cache. **Cache vary by Devices** com o comportamento *Allowlist* mantém uma cópia para cada grupo de dispositivos que você seleciona na aba **Device Groups** da aplicação. Os três controles requerem Application Accelerator.

### Faça purge de conteúdo em cache

Um novo deploy invalida o cache da Vercel. Na Azion, Real-Time Purge remove objetos antes do fim do TTL, por uma lista de URLs, uma lista de chaves de cache ou uma expressão wildcard. Um purge por URL aceita até 50 itens, e um purge por wildcard aceita uma expressão por requisição. Um item de purge cujo domínio está fora da sua conta é recusado com `400` e o código `30003`.

**Console**

Para fazer purge pelo Azion Console, siga [Faça purge de conteúdo em cache](/pt-br/documentacao/guias/performance-e-confiabilidade/cache-e-purge/purgar-conteudo-em-cache/).

**CLI**

Para fazer purge dos objetos sob `/products/` com Azion CLI, substitua `<your-domain>` pelo seu domínio:

```bash
azion purge --wildcard "https://<your-domain>/products/*"
```

```text
Purge carried out successfully
```

**API**

Para fazer purge dos objetos sob `/products/` com a API, substitua `<your-domain>` pelo seu domínio e envie uma requisição `POST` para o endpoint de wildcard:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/purge/wildcard \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "items": ["https://<your-domain>/products/*"],
  "layer": "cache"
}'
```

Um `201` retorna `"state": "executed"`, com os itens e `"layer": "cache"` em `data`.

Purge é um endpoint de nível superior, não aninhado em applications. Só um purge por chave de cache, em `/v4/workspace/purge/cachekey`, alcança Tiered Cache com `"layer": "tiered_cache"`. Um purge por URL ou wildcard com essa camada falha com `30001`. Quando o conteúdo em cache se comportar diferente da Vercel depois da migração, compare os TTLs, a chave de cache e as regras com o projeto da Vercel.

---

## Entregue imagens otimizadas

A Vercel transforma uma imagem por uma URL que o framework gera. Na Azion, [Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/) transforma uma imagem quando a requisição traz o parâmetro de query `ims`. Ele redimensiona, recorta, encaixa, preenche, rotaciona, aplica marca d'água, define a qualidade e converte o formato. Ele não armazena nada: a imagem de origem vem da origem da aplicação, um servidor HTTP ou um bucket do Object Storage.

A primeira linha abaixo é uma URL gerada pelo framework, cujo padrão varia conforme o framework. A segunda pede ao Image Processor a mesma imagem com 1.200 pixels de largura. A terceira também traz a qualidade, como faz `q=75`:

```text
/_next/image?url=%2Fhero.jpg&w=1200&q=75
/hero.jpg?ims=1200x
/hero.jpg?ims=1200x/filters:quality(75)
```

| Sintaxe                               | Resultado                                                                                  | Exemplo                                   |
| ------------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------- |
| `?ims=WxH`                            | Redimensiona para a largura e a altura, recortando para caber quando ambas estão definidas | `?ims=400x300`                            |
| `?ims=Wx`                             | Redimensiona para a largura, com a altura proporcional                                     | `?ims=400x`                               |
| `?ims=xH`                             | Redimensiona para a altura, com a largura proporcional                                     | `?ims=x300`                               |
| `?ims=fit-in/WxH`                     | Encaixa a imagem dentro das dimensões, sem nunca ampliá-la                                 | `?ims=fit-in/400x300`                     |
| `?ims=fit-in/WxH/filters:fill(Color)` | Encaixa a imagem e preenche o restante da área com uma cor                                 | `?ims=fit-in/400x300/filters:fill(white)` |

Image Processor entrega WebP quando o header `Accept` do navegador permite. AVIF precisa de `?ims=filters:format(avif)` e de um cliente que aceite `image/avif`. Para cada parâmetro, consulte [Parâmetros de URL do Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/parametros-de-url/).

**Console**

Para ativar o módulo Image Processor no Azion Console:

1. **Abra a aplicação**

   Acesse [Azion Console](https://console.azion.com/) > **Applications** e selecione a aplicação.

2. **Ative Image Processor**

   Na aba **Main Settings**, em **Modules**, ative **Image Processor**.

3. **Selecione Save**

A aplicação tem Image Processor ativado, e suas regras podem trazer o comportamento **Optimize Images**.

**CLI**

Para ativar o módulo Image Processor com Azion CLI:

```bash
azion update application --application-id <application-id> --image-processor true
```

```text
Updated Application with ID <application-id>
```

A aplicação tem Image Processor ativado, e suas regras podem trazer o comportamento `optimize_images`.

**API**

Para ativar o módulo Image Processor com a API, envie uma requisição `PATCH` para a aplicação:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/applications/<application-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "modules": {
    "image_processor": { "enabled": true }
  }
}'
```

Um `202` retorna `"state": "pending"`. A aplicação tem Image Processor ativado, e suas regras podem trazer o comportamento `optimize_images`.

Image Processor atua apenas em uma requisição a que uma regra com **Optimize Images** corresponde, e entrega qualquer outra requisição sem processamento. Uma regra da Request Phase com `${uri}` *matches* `\.(jpg|jpeg|gif|bmp|png|ico|webp|avif)` cobre os arquivos de imagem comuns. Para manter em cache uma cópia para cada valor de `ims`, ative Application Accelerator e varie o cache por query string. Para a regra e a chave de cache, consulte [Primeiros passos com Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/). Para uma aplicação que já recebe tráfego, consulte [Configure Image Processor em uma aplicação](/pt-br/documentacao/guias/performance-e-confiabilidade/otimizacao-de-entrega/processar-imagens/).

Antes da virada, requisite algumas URLs de imagem típicas. Se uma imagem voltar sem transformação, confirme que Image Processor está ativado, que a regra corresponde e que a URL traz `ims`.

---

## Mova rotas de IA para AI Inference

Uma rota de IA na Vercel mistura código da aplicação, chamadas a modelos, streaming, chamadas de ferramentas, roteamento entre provedores, rastreamento de uso e observabilidade. Na Azion, uma função faz a chamada ao modelo, seja para AI Inference ou para um provedor externo. As credenciais dos provedores passam para variáveis de ambiente.

| Tema                   | Na Vercel                                    | Na Azion                                                                                                                               |
| ---------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Acesso a modelos       | AI Gateway e integrações com provedores      | [Modelos do AI Inference](/pt-br/documentacao/plataforma/ai-inference/modelos/), ou um provedor externo chamado a partir de uma função |
| SDK                    | AI SDK                                       | `Azion.AI.run()` e APIs JavaScript padrão                                                                                              |
| Streaming              | Respostas em streaming do framework e do SDK | Functions, com as Web APIs para streams                                                                                                |
| Observabilidade        | AI Gateway e Observability                   | Real-Time Events, Real-Time Metrics e Data Stream                                                                                      |
| Roteamento e fallbacks | AI Gateway                                   | Lógica de roteamento entre provedores dentro da função                                                                                 |

AI Inference executa um catálogo de modelos open source: large language models, vision language models, um modelo de embedding e um reranker. Um modelo não é um objeto que você cria, e a Azion não hospeda um endpoint de inferência para ele. Uma função chama um modelo pelo seu ID com `Azion.AI.run()`, sem credencial:

```javascript
const modelResponse = await Azion.AI.run("Qwen/Qwen3-30B-A3B-Instruct-2507-FP8", {
  "stream": false,
  "messages": [
    { "role": "system", "content": "You are a helpful assistant." },
    { "role": "user", "content": "Name three European capitals." }
  ]
})
const answer = modelResponse?.choices?.[0]?.message?.content
```

No `azion dev`, `Azion.AI` é `undefined`, então teste a chamada em uma função em produção. Para os campos da requisição, consulte [Invocação de modelos](/pt-br/documentacao/plataforma/ai-inference/invocacao-de-modelos/) e a [API de runtime de IA](/pt-br/documentacao/devtools/runtime/api-reference/ai/).

Uma rota que mantém um provedor externo encaminha o corpo da requisição e retorna a resposta do provedor. Esta função lê a chave do provedor de uma variável:

```javascript
export default {
  async fetch(request, env, ctx) {
    const prompt = await request.text();

    const response = await fetch('https://ai-provider.example.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + Azion.env.get('AI_API_KEY')
      },
      body: JSON.stringify({ prompt })
    });

    return response;
  }
};
```

Para um endpoint `/v1/chat/completions` compatível com OpenAI no AI Inference, faça o deploy do template [AI Inference Starter Kit](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/frameworks/ai-inference-starter-kit/). Ele cria uma aplicação e uma função que atendem esse endpoint. Acesse [Azion Console](https://console.azion.com/) > **Create**, selecione o template e selecione **Deploy**. Azion CLI não tem flag de template.

Para mover cada rota de IA:

1. Registre cada modelo, provedor, rota e fallback que o projeto usa.
2. Mova as credenciais dos provedores para variáveis de ambiente.
3. Para cada rota, decida se a inferência roda no AI Inference ou em um provedor externo.
4. Reescreva cada rota como uma função e roteie um caminho para ela com uma regra, como em Mova rotas de API e funções de servidor.
5. Recrie a observabilidade de IA em Real-Time Events, Real-Time Metrics e Data Stream.
6. Teste respostas em streaming, timeouts e o tratamento de erros.

---

## Mova dados do Edge Config para KV Store

O Edge Config costuma guardar feature flags, experimentos, redirecionamentos, configurações e outros dados que um projeto lê com frequência. [KV Store](/pt-br/documentacao/plataforma/kv-store/) guarda pares chave-valor em [namespaces](/pt-br/documentacao/plataforma/kv-store/namespaces/) e cobre esses usos, além de estado de sessão e outros estados leves. Uma função o alcança por [`Azion.KV`](/pt-br/documentacao/devtools/runtime/api-reference/kv-store/), um global do runtime que não precisa de linha de import.

O código que lia o Edge Config passa a [abrir um namespace](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/gerenciar-com-funcoes/):

```javascript diff
-// Before: Vercel Edge Config
-import { get } from '@vercel/edge-config';
-
-const checkoutEnabled = await get('feature:checkout');
 
+// After: Azion KV Store
+const kv = await Azion.KV.open('my-namespace');
+
+const checkoutEnabled = await kv.get('feature:checkout');
```

`Azion.KV.open()` é o único ponto de entrada e é assíncrono. O namespace precisa existir antes, ou `open()` lança `NotFound`. `get()` retorna `null` para uma chave inexistente, assim como para uma chave expirada.

KV Store não tem tela no Azion Console nem comando na Azion CLI, então o namespace é criado pela API em todas as interfaces. O nome aceita de 3 a 63 caracteres e diferencia maiúsculas de minúsculas. Nenhuma interface renomeia ou exclui um namespace, então defina o nome antes.

**Console**

Azion Console não tem tela de KV Store. Crie o namespace com a requisição do painel API.

**CLI**

Azion CLI não tem comando de KV Store. Crie o namespace com a requisição do painel API.

**API**

Para criar o namespace, envie uma requisição `POST` para o endpoint de namespaces:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/kv/namespaces \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{"name": "vercel-migration-kv"}'
```

Um `201` retorna o `name`, o `created_at` e o `last_modified` do namespace, sem envelope `state`. A requisição é síncrona.

KV Store não tem importação em massa, e nenhuma chamada de API, comando da CLI ou tela do Console lê ou grava chaves. Uma função em produção as grava com `kv.put()`. Para mover os dados:

1. Exporte do Edge Config as chaves, os valores, os metadados e os valores por ambiente.
2. Mantenha os prefixos das chaves e as convenções de nomes sempre que possível.
3. Grave cada chave a partir de uma função em produção com `kv.put()`.
4. Documente o que o código faz quando uma chave não existe.
5. Teste cada caminho de leitura antes que o tráfego de produção chegue à Azion.
6. Confirme que os valores mantêm sua codificação e sua serialização JSON.
7. Recrie qualquer fluxo de flags ou de experimentos que dependia de ferramentas da Vercel.

A função grava a mesma chave no máximo uma vez por segundo. Um valor aceita até 25 MB, uma chave até 512 bytes e os metadados até 1.024 bytes. Uma expiração vai na opção `expiration`, em segundos Unix, ou em `expirationTtl`, em segundos com mínimo de 60. Uma gravação fica visível em todos os lugares em até 60 segundos, ou dentro do `cacheTtl` da leitura. Se faltarem dados depois da migração, grave as chaves de novo, verifique o nome do namespace e teste os valores padrão.

---

## Mova arquivos do Blob para Object Storage

O Vercel Blob guarda arquivos como imagens, documentos, vídeos e uploads. [Object Storage](/pt-br/documentacao/plataforma/object-storage/) os guarda como objetos em buckets e fala o protocolo S3. Ferramentas S3, a API, Azion CLI e a API de runtime de uma função o alcançam. O gerenciamento de objetos passa pelo endpoint S3 `s3.us-east-005.azionstorage.net`, na região `us-east-005`.

Uma função que gravava com o SDK do Blob passa a gravar com a classe `Storage` da [API de runtime do Object Storage](/pt-br/documentacao/devtools/runtime/api-reference/storage/). O construtor recebe o nome do bucket e nenhum token. `put` recebe um `ArrayBuffer` ou um `ReadableStream`, não uma string:

```javascript diff
-// Before: Vercel Blob pattern
-import { put } from '@vercel/blob';
-
-const blob = await put('avatar.png', file, {
-  access: 'public'
-});
 
+// After: Azion Object Storage runtime API
+import Storage from 'azion:storage';
+
+export default {
+  async fetch(request, env, ctx) {
+    const storage = new Storage('my-bucket');
+
+    await storage.put('avatar.png', await request.arrayBuffer(), {
+      'content-type': 'image/png'
+    });
+
+    return new Response('Stored', { status: 201 });
+  }
+};
```

No `azion dev`, o módulo guarda os objetos no disco local e se comporta de outra forma, então teste as chamadas de armazenamento em uma função em produção.

Um script de migração em Node.js alcança o endpoint S3 com qualquer SDK S3, informando o endpoint, a região e um par de chaves:

```javascript
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const client = new S3Client({
  region: 'us-east-005',
  endpoint: 'https://s3.us-east-005.azionstorage.net',
  credentials: {
    accessKeyId: process.env.AZION_ACCESS_KEY,
    secretAccessKey: process.env.AZION_SECRET_KEY
  }
});

await client.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'avatar.png',
  Body: file
}));
```

O par de chaves vem de uma credencial do Object Storage, criada no Azion Console ou com uma requisição `POST` para `https://api.azion.com/v4/workspace/storage/credentials`. A `secret_key` só aparece na resposta de criação. Uma migração precisa de `listBuckets`, `listFiles` e `writeFiles` na credencial, além de `listAllBucketNames` para listar os buckets. [Ferramentas compatíveis com S3](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/protocolo-s3-para-object-storage/) como `s3cmd`, `rclone` e a AWS CLI fazem a cópia em massa. Para as operações S3 que Object Storage aceita, e a forma `s3cmd` de cada uma, consulte [Compatibilidade com S3](/pt-br/documentacao/plataforma/object-storage/compatibilidade-s3/).

Crie o bucket de destino antes de uma cópia em massa, no Azion Console, na API ou na CLI. `s3cmd mb` e `s3cmd rb` são recusados com `403 AccessDenied`. Um nome de bucket aceita de 6 a 63 caracteres, é único entre todas as contas e não pode começar com `azion`.

**Console**

Para criar o bucket e enviar arquivos no Azion Console, consulte [Crie e modifique um bucket](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/criar-e-modificar-um-bucket/) e [Faça upload e download de objetos](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/upload-e-download-de-objetos-do-bucket/). Azion Console recusa um upload individual acima de 300 MB. A API e as ferramentas S3 não têm esse limite.

**CLI**

Para criar um bucket com Azion CLI, informe seu nível de acesso. `read_only` permite que os workloads leiam seus objetos:

```bash
azion create storage bucket --name <your-bucket-name> --workloads-access read_only
```

```text
Bucket created successfully
```

Envie um arquivo com sua chave no bucket:

```bash
azion create storage object --bucket-name <your-bucket-name> --object-key images/logo.png --source ./logo.png
```

```text
Object created successfully
```

`--source` recebe um caminho relativo ao diretório atual. A Azion CLI 4.23.0 também adiciona o diretório de trabalho antes de um caminho absoluto, então o arquivo não pode ser aberto. Liste os objetos do bucket:

```bash
azion list storage object --bucket-name <your-bucket-name> --details
```

A saída é uma tabela com as colunas `KEY`, `LAST MODIFIED` e `SIZE`, e `images/logo.png` é uma de suas linhas.

**API**

Para criar um bucket com a API, envie seu nome e seu nível de acesso. `read_only` permite que os workloads leiam seus objetos:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/storage/buckets \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{"name": "<your-bucket-name>", "workloads_access": "read_only"}'
```

Um `201` retorna `"state": "executed"`. Envie um arquivo com sua chave no caminho e com o header `Content-Type` definido como seu tipo de mídia:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/storage/buckets/<your-bucket-name>/objects/images/logo.png \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: image/png' \
  --data-binary @logo.png
```

Um `201` retorna `images/logo.png` em `data.object_key`. Liste os objetos do bucket:

```bash
curl --request GET \
  --url https://api.azion.com/v4/workspace/storage/buckets/<your-bucket-name>/objects \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

Um `200` retorna `results`, em que cada entrada traz o `key`, o `last_modified`, o `size` e o `is_folder` de um objeto.

O acesso do bucket aos workloads é `read_only`, `read_write` ou `restricted`, e uma credencial funciona de forma independente dele. Um arquivo que a Vercel mantinha privado atrás de um token ou de um padrão de URL depende do nível de acesso do seu bucket e da lógica da aplicação. Os usuários recebem os objetos por uma aplicação e um [connector](/pt-br/documentacao/plataforma/connectors/), não pelo endpoint S3. Esse caminho coloca o cache, as regras de firewall e o domínio de produção na frente dos arquivos. Para conectar o bucket, consulte [Use um bucket como origem](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/bucket-como-connector/). Se faltarem arquivos depois da migração, exporte-os de novo e verifique as chaves dos objetos e o nível de acesso do bucket.

---

## Proteja a aplicação com WAF

[Web Application Firewall](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos/) (WAF) pontua as requisições em relação a oito famílias de ameaças: cross-site scripting, directory traversal, evading tricks, file upload, identified attack, remote file inclusion, SQL injection e unwanted access. Um [conjunto de regras WAF](/pt-br/documentacao/plataforma/firewall/waf/rule-sets/) guarda uma sensibilidade para cada família, e uma regra de firewall o aplica com *Set WAF*. O workload faz o deploy do firewall junto com a aplicação, e no Azion Console as **Deployment Settings** do workload o selecionam.

| Aspecto                            | Vercel                                          | Azion                                                                               |
| ---------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------- |
| Regras gerenciadas                 | Proteções do WAF                                | Um ruleset gerenciado, pontuado por família de ameaças                              |
| Regras de tráfego personalizadas   | Regras de firewall                              | [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/) |
| Controles de IP e IPs confiáveis   | Bloqueios de IP e allowlists                    | Network Lists, comparadas com `${network}`                                          |
| Ações                              | Bloqueio, desafio, redirecionamento e permissão | Deny, Drop, Set Rate Limit, Set WAF, Run Function e Set Custom Response             |
| Barreiras de senha ou autenticação | Advanced Deployment Protection                  | Regras de firewall, e Functions para lógica personalizada                           |

`mode` é obrigatório em todo comportamento *Set WAF* e não tem padrão. Comece em *Logging* para verificar o que o conjunto de regras bloquearia e depois mude para *Blocking*. No modo *Blocking*, uma requisição que o conjunto de regras bloqueia recebe `400`. Antes de bloquear, compare os falsos positivos, as regras que mais disparam e as exceções de que a aplicação precisa. Para evitar que uma requisição legítima corresponda, adicione uma exceção de WAF ou use a aba **Tuning**.

**Console**

Para configurar o WAF no Azion Console:

1. **Crie o conjunto de regras**

   Acesse [Azion Console](https://console.azion.com/) > **Edge Libraries** > **WAF Rules** e crie um conjunto de regras. Em **Threat Type Configuration**, defina a sensibilidade de cada família.

2. **Abra o firewall**

   Vá para **Secure** > **Firewalls** e selecione ou crie o firewall.

3. **Ative Web Application Firewall**

   Na aba **Main Settings**, em **Modules**, ative **Web Application Firewall** e selecione **Save**.

4. **Aplique o conjunto de regras**

   Na aba **Rules Engine**, crie uma regra com o comportamento *Set WAF*. Em **Select a WAF**, selecione o conjunto de regras. Em **Select a WAF mode**, selecione *Logging*.

5. **Vincule o firewall ao workload**

   No workload, em **Deployment Settings**, selecione o firewall em **Firewall**.

O firewall aplica o conjunto de regras às requisições do workload. Para os passos completos, consulte [Primeiros passos com WAF](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos/).

**CLI**

Para vincular um firewall com Azion CLI, passe `--firewall-id` para o deployment do workload. Para o conjunto de regras e a regra, siga [Primeiros passos com WAF](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos/).

**API**

Para criar o conjunto de regras, envie uma requisição `POST` para o endpoint de WAF:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/wafs \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "active": true,
  "name": "My WAF",
  "product_version": "1.0",
  "engine_settings": {
    "engine_version": "2021-Q3",
    "type": "score",
    "attributes": {
      "rulesets": [1],
      "thresholds": [
        { "threat": "sql_injection", "sensitivity": "medium" }
      ]
    }
  }
}'
```

`rulesets` aceita apenas `[1]`. Depois aplique o conjunto de regras com uma regra de firewall cujo comportamento é `{ "type": "set_waf", "attributes": { "waf_id": <waf-rule-set-id>, "mode": "logging" } }`. A API recusa `learning` como modo.

Uma regra de proteção de deployment da Vercel se torna uma regra de firewall que nega requisições de fora de uma rede aprovada. As variáveis do firewall diferem das variáveis da aplicação: o caminho é `${request_uri}`, e uma faixa de endereços vai em uma Network List comparada com `${network}`. Esta regra nega `/admin` a qualquer cliente fora de uma Network List que contém `10.0.0.0/8`:

```text
Criteria: ${request_uri}  starts with     /admin
and       ${network}      is not in list  <network-list-id>   (uma Network List que contém 10.0.0.0/8)
Behavior: Deny (403 Forbidden)
```

Uma segunda regra com `${request_uri}` *starts with* `/preview/` protege os caminhos de preview da mesma forma. O critério `${network}` requer Network Shield no firewall. Para escrever as regras, consulte [Crie uma regra de firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/trabalhar-com-rules-engine/). Se uma regra bloquear usuários válidos, volte o conjunto de regras para *Logging*, compare os eventos e ajuste os critérios.

---

## Conte com DDoS Protection

[DDoS Protection](/pt-br/documentacao/plataforma/workloads/#ddos-protection) cobre todo workload, sem nada para criar e nada para configurar. Ele assume a mitigação de DDoS do Vercel Platform Security. Ele mitiga ataques volumétricos, de protocolo e de camada de aplicação nas camadas 3, 4, 6 e 7, como floods UDP e ICMP, SYN floods, fragmentação de pacotes, floods HTTP e slowloris.

| Aspecto        | Azion DDoS Protection                                                                  |
| -------------- | -------------------------------------------------------------------------------------- |
| Ativação       | Automática, e não pode ser desativada                                                  |
| Camadas        | 3, 4, 6 e 7                                                                            |
| Cobrança       | Sem medição para as camadas 3 e 4. A mitigação na camada 7 pode gerar tráfego cobrável |
| Personalização | Regras de firewall personalizadas                                                      |

Todo firewall mostra a chave **DDoS Protection Unmetered** em **Main Settings** > **Modules**, sempre ativada, e `modules.ddos_protection` é somente leitura na API. DDoS Protection não tem limiares, chaves por regra nem alertas. Para uma mitigação direcionada, escreva regras personalizadas no firewall vinculado ao workload. O Security Response Team é um add-on dos suportes Enterprise e Mission-Critical. Para os tipos de ataque, consulte [Mitigação de ataques](/pt-br/documentacao/plataforma/workloads/ddos-protection/ddos-mitigation/).

[Network Shield](/pt-br/documentacao/plataforma/firewall/#network-shield) é um módulo diferente do firewall. Ele compara o endereço do cliente com uma [Network List](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/) de endereços IP, faixas CIDR, ASNs ou países, por meio do critério `${network}`. Use-o para permitir ou bloquear conjuntos de clientes, restringir países ou aplicar rate limit a um conjunto de clientes. Para a configuração, consulte [Primeiros passos com Network Shield](/pt-br/documentacao/plataforma/firewall/network-shield/primeiros-passos/).

---

## Recrie o gerenciamento de bots

Vercel Bot Management e BotID passam para [Bot Manager](/pt-br/documentacao/plataforma/firewall/bot-manager/primeiros-passos/), que pontua cada requisição e age conforme a pontuação. Bot Manager Lite é a função do Marketplace incluída em todos os planos, e Bot Manager completo está disponível no Enterprise.

| Aspecto         | Vercel                                             | Azion Bot Manager                                                                                                                     |
| --------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Controles       | Detecção, mitigação, desafio, permissão e bloqueio | Regras estáticas, um método comportamental dinâmico no Bot Manager completo, fingerprints de dispositivo e Network Lists de reputação |
| Desafio         | Controles de desafio                               | Uma JavaScript Tag para fingerprinting e ALTCHA pela ação `redirect`                                                                  |
| Ações           | Permissão e bloqueio                               | `allow`, `custom_html`, `deny`, `drop`, `hold_connection`, `random_delay` e `redirect`                                                |
| Ações sensíveis | BotID                                              | Bot Manager, com lógica de função onde uma rota precisa de mais                                                                       |

Bot Manager Lite pontua uma requisição com 26 regras estáticas, em relação a um `threshold` cujo padrão é 30, e sua ação padrão é `deny`. Ele também pode verificar o cliente em Network Lists de reputação. Os níveis de tolerância pertencem às regras dinâmicas do Bot Manager completo, que Bot Manager Lite não tem.

Para configurar Bot Manager Lite no Azion Console:

1. **Instale a integração**

   Acesse [Azion Console](https://console.azion.com/) > **Marketplace**, busque **Bot Manager Lite** e selecione **Install**. A instalação tem efeito imediato.

2. **Abra o firewall**

   Vá para **Firewalls** e selecione um firewall com o módulo **Functions** ativado.

3. **Crie a instância de função**

   Na aba **Functions Instances**, crie uma instância do Bot Manager Lite e defina `threshold` e `action` nos argumentos JSON. Para mais informações, consulte [Functions instances](/pt-br/documentacao/plataforma/firewall/functions-instances/).

4. **Execute a função**

   Na aba **Rules Engine**, crie uma regra com o comportamento *Run Function* e a instância.

5. **Vincule o firewall ao workload**

O firewall pontua cada requisição do workload. Para cada argumento, consulte [Instale Bot Manager Lite](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/bot-manager-lite/) e [Bot Manager Lite](/pt-br/documentacao/plataforma/firewall/bot-manager/bot-manager-lite/). Para saber como uma função roda em um firewall, consulte [Functions para Firewall](/pt-br/documentacao/plataforma/firewall/functions/). A integração [Radware Bot Manager](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/radware-bot-manager/) adiciona proteção contra bots de terceiros.

Uma regra de firewall também bloqueia um cliente pelo seu user agent:

```text
Criteria: ${header_user_agent} matches BadBot
Behavior: Deny (403 Forbidden)
```

`${header_user_agent}` requer o módulo WAF no firewall e suporta apenas *matches* e *does not match*. O firewall não tem comportamento de permissão: para isentar um cliente, adicione um critério *does not match* à regra de bloqueio ou ordene as regras. Um cliente pode enviar qualquer user agent, então verifique um bot legítimo de outra forma. Para verificar a regra:

```bash
curl -A "BadBot/1.0" https://<your-domain>/
```

A resposta é `403`, com a página de erro Forbidden. Uma requisição com o user agent de um navegador recebe a resposta normal.

---

## Recrie os rate limits

A Azion limita a taxa de requisições de duas formas, e cada uma cobre uma parte diferente dos controles de taxa do Vercel Firewall. O comportamento nativo *Set Rate Limit* de uma regra de firewall limita as requisições por segundo ou por minuto. Ele conta por endereço IP do cliente ou entre todos os clientes. Para chaves personalizadas, janelas personalizadas ou um período de penalidade, use a integração [Upstash Rate Limiting](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/upstash-rate-limiting-integration/). Ela é um rate limit com penalidade executado como função de firewall.

| Recurso            | *Set Rate Limit* nativo                   | Função Upstash Rate Limiting                                                                      |
| ------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Chave de contagem  | Endereço IP do cliente ou global          | Qualquer combinação de metadados da requisição, headers e hostname                                |
| Janela             | Por segundo ou por minuto                 | Qualquer intervalo em segundos ou minutos, com limites diferentes para diferentes horários do dia |
| Algoritmo          | Leaky bucket, contado em cada data center | Fixed window, sliding window ou token bucket, contado globalmente                                 |
| Resposta           | `429`, sem header de rate limit           | `429` no limite e `403` durante uma penalidade                                                    |
| Ação apenas de log | Nenhuma                                   | Nenhuma                                                                                           |
| Requisitos         | Nenhum                                    | Uma conta Upstash e Global Database                                                               |

### Use o rate limit nativo

Um comportamento *Set Rate Limit* conta as requisições a que sua regra corresponde. Os critérios da regra definem o escopo do limite, como um caminho em `${request_uri}`. **Rate Limit Type** é *Req/s* ou *Req/min*, e **Limit By** é *Client IP address* ou *Global*. **Average Rate Limit** aceita no mínimo 1. **Maximum Burst Size** aceita no mínimo 1 e se aplica apenas a *Req/s*. Nenhum comportamento pode vir depois de *Set Rate Limit* em uma regra. Critérios que unem vários caminhos com `or` compartilham uma contagem entre todos eles.

**Console**

Para criar o rate limit no Azion Console:

1. **Abra o firewall**

   Acesse [Azion Console](https://console.azion.com/) > **Secure** > **Firewalls** e selecione o firewall.

2. **Vá para a aba Rules Engine**

3. **Selecione + Rule**

4. **Defina os critérios**

   Em **Criteria**, selecione `${request_uri}` e o operador *starts with*. Como argumento, informe `/api/`.

5. **Adicione o comportamento Set Rate Limit**

   Em **Behaviors**, selecione *Set Rate Limit*. Defina **Rate Limit Type** como *Req/s*, **Limit By** como *Client IP address*, **Average Rate Limit** como `10` e **Maximum Burst Size** como `10`.

6. **Selecione Save**

A nova regra aparece na lista de regras do firewall.

**CLI**

Para criar o rate limit com Azion CLI, salve o corpo da regra do painel API em um arquivo. Passe o arquivo com `--file` para o comando de regra de firewall. Para os comandos, consulte [Primeiros passos com Firewall](/pt-br/documentacao/plataforma/firewall/primeiros-passos/).

**API**

Para criar o rate limit, envie uma requisição `POST` para as regras de requisição do firewall:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "api rate limit",
  "active": true,
  "criteria": [
    [{ "variable": "${request_uri}", "conditional": "if", "operator": "starts_with", "argument": "/api/" }]
  ],
  "behaviors": [
    { "type": "set_rate_limit", "attributes": { "type": "second", "limit_by": "client_ip", "average_rate_limit": 10, "maximum_burst_size": 10 } }
  ]
}'
```

A resposta traz `"state": "pending"` e a regra.

Uma requisição além da taxa e do burst recebe `429`, com a página de erro Too Many Requests. Para saber como a taxa e o burst admitem requisições, consulte [Set Rate Limit](/pt-br/documentacao/plataforma/firewall/rules-engine/#set-rate-limit).

### Use o rate limit com penalidade

A função Upstash Rate Limiting guarda seus contadores em um Upstash Global Database. Por isso, ela conta cada requisição em toda a rede, e não em cada data center. Um cliente em penalidade recebe `403 Forbidden`. Caso contrário, a função conta a requisição e retorna `429 Too Many Requests` quando a contagem atinge o limite.

Para configurá-la no Azion Console:

1. **Instale a integração**

   Acesse [Azion Console](https://console.azion.com/) > **Marketplace**, busque `Upstash Rate Limiting` e selecione **Install**.

2. **Abra o firewall**

   Vá para **Firewalls** e abra um firewall com **Functions** ativado em **Modules**.

3. **Crie a instância de função**

   Na aba **Functions Instances**, crie uma instância. Em **Function**, selecione a função Upstash Rate Limiting e edite os **Arguments** em JSON.

4. **Execute a função**

   Na aba **Rules Engine**, crie uma regra com critérios como `Host` *matches* `yourdomain.com` e o comportamento *Run Function* com a instância.

5. **Vincule o firewall ao workload**

   Execute o comando da CLI que cria o deployment do workload com o firewall:

   ```bash
   azion create workload-deployment --workload-id <workload-id> --name <deployment-name> --application-id <application-id> --firewall-id <firewall-id> --strategy-type default --active true --current true
   ```

A função conta as requisições a que a regra corresponde. Estes argumentos definem uma sliding window de 2 requisições a cada 20 segundos, da meia-noite ao meio-dia UTC, com uma penalidade de 45 segundos:

```json
{
  "upstash_redis_rest_url": "https://your-database.upstash.io",
  "upstash_redis_rest_token": "<your-upstash-token>",
  "rate_limit_prefix": "my_rate_limit",
  "rate_limit_key_metadata": ["remote_addr"],
  "rate_limit_key_header": ["x-a-custom-header"],
  "rate_limit_key_hostname": true,
  "rate_limit_repenalize": true,
  "rate_limits": [
    {
      "algorithm": "sliding_window",
      "requests": 2,
      "interval": "20 s",
      "start": "00:00",
      "end": "12:00",
      "penalty_in_seconds": 45
    }
  ]
}
```

| Argumento                                            | Descrição                                                                                                           |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `upstash_redis_rest_url`, `upstash_redis_rest_token` | A URL REST e o token do banco de dados Upstash que guarda os contadores e as penalidades                            |
| `rate_limit_prefix`                                  | Um prefixo para cada chave, que mantém separadas duas instâncias da função                                          |
| `rate_limit_key_metadata`                            | Os metadados da requisição que formam a chave, como `remote_addr`                                                   |
| `rate_limit_key_header`                              | Os headers que formam a chave                                                                                       |
| `rate_limit_key_hostname`                            | Quando `true`, o hostname faz parte da chave                                                                        |
| `rate_limit_repenalize`                              | Quando `true`, cada requisição durante uma penalidade a reinicia                                                    |
| `rate_limits`                                        | As janelas, pelo menos uma. Quando duas janelas se sobrepõem, vale a primeira da lista                              |
| `algorithm`                                          | `fixed_window`, `sliding_window` ou `token_bucket`                                                                  |
| `requests`                                           | As requisições permitidas no intervalo                                                                              |
| `interval`                                           | A janela, como um número e `s` ou `m`. Por exemplo: `"120 s"`                                                       |
| `start`, `end`                                       | O horário do dia que a janela cobre, em UTC no formato de 24 horas. Os padrões são `00:00` e `23:59`                |
| `penalty_in_seconds`                                 | Por quanto tempo um cliente que excede o limite recebe `403`. Sem ele, a janela é um rate limit simples             |
| `max_tokens`, `refil_rate`                           | O tamanho do bucket e a recarga por intervalo de uma janela `token_bucket`. `refil_rate` é a grafia que a função lê |

A chave une o prefixo e cada valor que os argumentos selecionam. Neste exemplo, ela é `my_rate_limit + client IP + x-a-custom-header value + hostname`, como `my_rate_limit_127.0.0.1_Value_azion.com`. Para a configuração completa, consulte [Instale a integração Upstash Rate Limiting](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/upstash-rate-limiting-integration/).

---

## Mova o acesso à conta

Uma equipe da Vercel que entra por SAML Single Sign-On mantém esse padrão na Azion com [Single Sign-On](/pt-br/documentacao/fundamentos/single-sign-on/) e um provedor de identidade externo. A Azion documenta apps SAML para Microsoft Entra, Google e Okta como provedores de identidade. O SSO para membros da equipe precisa de um serviço de suporte Enterprise ou Mission-Critical, e apenas um Account Owner o configura.

Antes da migração, registre as configurações do provedor de identidade, os grupos, os acessos de usuários e os runbooks que dependem deles. Depois mova o acesso:

1. Registre cada provedor de identidade e seus metadados SAML.
2. Converta cada função de equipe da Vercel em funções de conta da Azion e em [permissões de equipes](/pt-br/documentacao/fundamentos/teams-permissions/).
3. Configure o SSO na Azion antes que a maior parte da equipe migre.
4. Garanta que um administrador de emergência mantenha uma forma de entrar.
5. Revise a [autenticação multifator](/pt-br/documentacao/fundamentos/multi-factor-authentication/), o [tempo limite de sessão do usuário](/pt-br/documentacao/fundamentos/user-session-timeout/) e a [política de bloqueio de conta](/pt-br/documentacao/fundamentos/account-lockout-policy/).

---

## Reconstrua o monitoramento

Vercel Observability passa para três produtos da Azion, para que a visibilidade da produção, a resolução de problemas e os relatórios de compliance continuem depois da virada. [Real-Time Metrics](/pt-br/documentacao/plataforma/real-time-metrics/) mostra agregados ao longo do tempo em gráficos. [Real-Time Events](/pt-br/documentacao/plataforma/real-time-events/) responde a consultas sobre requisições individuais, e [Data Stream](/pt-br/documentacao/plataforma/data-stream/) envia os logs para destinos externos. Speed Insights e Web Analytics passam para Edge Pulse, em Substitua Speed Insights e Web Analytics.

Para planejar a migração, liste os dashboards, relatórios, alertas e fluxos de logs que o projeto usa. Decida quais deles vão para Real-Time Metrics, Real-Time Events, Data Stream ou uma ferramenta de BI externa. As integrações do Vercel Marketplace vão para o [Marketplace](/pt-br/documentacao/plataforma/marketplace/) da Azion ou para um destino do Data Stream. Configure cada uma antes que o tráfego de produção migre, para que não haja lacuna de analytics na virada.

### Real-Time Metrics

| Aspecto               | Azion Real-Time Metrics                                                                          |
| --------------------- | ------------------------------------------------------------------------------------------------ |
| Atualização dos dados | Até 10 minutos para agregar                                                                      |
| Retenção              | 2 anos, exceto 90 dias para `httpBreakdownMetrics` e 60 dias para `botManagerBreakdownMetrics`   |
| Método de consulta    | Dashboards, **Copy query**, **Export CSV** e a API GraphQL                                       |
| Métricas              | Requisições, dados transferidos, códigos de status, offload de cache e tempo médio de requisição |
| Granularidade         | 1 minuto abaixo de 2,5 dias, 1 hora até 60 dias e 1 dia acima disso                              |

Os dashboards de Applications mostram:

- **Requests**: total de requisições, requisições por método e por esquema e **Average Request Time**. Esse gráfico é o tempo médio, em segundos, que a Azion leva para processar e responder a uma requisição.
- **Status Codes**: as respostas 2XX, 3XX, 4XX e 5XX e a tabela **Requests by Status and Upstream Status**. Essa tabela distingue erros da Azion de erros da origem.
- **Data Transferred**: dados e largura de banda economizados e perdidos e **Edge Offload**.
- Cache: **Requests Offloaded**, **Saved Requests** e **Missed Requests**.

Real-Time Metrics não informa latência, tempo até o primeiro byte nem tempo de resposta da origem. Para ler o status de cache das requisições, filtre um dashboard por **Upstream Cache Status**, cujos valores incluem `HIT`, `MISS`, `STALE` e `EXPIRED`. Para encontrar erros da origem, filtre por **Upstream Status**, que é `0` quando a origem não respondeu.

Para abrir os dashboards, acesse [Azion Console](https://console.azion.com/) > **Real-Time Metrics**. Ele abre em **Build** > **Applications** > **Data Transferred**, nos **Last 5 minutes**. Para restringir um dashboard a um workload, adicione o filtro **Domain** ou **Workload**. Para exportar um gráfico, abra seu menu **More options** e selecione **Export CSV**.

Para consultar os mesmos dados, envie uma consulta GraphQL para `https://api.azion.com/v4/metrics/graphql`:

```graphql
query {
  workloadMetrics(limit: 3, filter: { tsRange: {begin: "2026-10-01T14:00:00", end: "2026-10-03T14:00:00"} }, aggregate: { sum: requests }, groupBy: [ts], orderBy: [ts_DESC]) {
    ts
    sum
  }
}
```

Substitua as datas por um intervalo dentro do período de retenção, porque um intervalo fora dele retorna um array vazio. `limit` aceita até 10.000 linhas e tem padrão 10. O dataset `httpMetrics` de consultas antigas ainda funciona, mas está obsoleto. Para cada campo, consulte [Campos GraphQL do Real-Time Metrics](/pt-br/documentacao/devtools/graphql/campos-gql-real-time-metrics/) e [Crie dashboards](/pt-br/documentacao/plataforma/real-time-metrics/dashboards-build/). Para o Grafana, consulte [Dashboards personalizados do plugin Grafana](/pt-br/documentacao/guias/plataforma/observabilidade/azion-plugin-grafana/) e [dashboards pré-configurados](/pt-br/documentacao/guias/plataforma/observabilidade/azion-plugin-grafana-dash-pre-configurado/). Para ler os dashboards, consulte [Analise métricas](/pt-br/documentacao/guias/plataforma/observabilidade/analisar-metricas/).

### Real-Time Events

| Aspecto  | Azion Real-Time Events                             |
| -------- | -------------------------------------------------- |
| Acesso   | Consultas no Azion Console ou na API GraphQL       |
| Atraso   | Até 30 segundos                                    |
| Retenção | 7 dias. Para uma retenção maior, use Data Stream   |
| Formato  | Respostas GraphQL com os campos que você seleciona |

Real-Time Events guarda [o registro de cada requisição](/pt-br/documentacao/guias/plataforma/observabilidade/entender-logs/) para investigação e não precisa de configuração. Suas fontes de dados são **HTTP Requests**, **Functions**, **Functions Console**, **Image Processor**, **Tiered Cache**, **Edge DNS**, **Data Stream** e **Activity History**. Os resultados do WAF são campos de **HTTP Requests**.

Para consultar os eventos no Azion Console:

1. **Abra Real-Time Events**

   Acesse [Azion Console](https://console.azion.com/) > **Products menu** > **Observe** > **Real-Time Events**.

2. **Selecione a fonte de dados**

   Selecione a fonte de dados, como **HTTP Requests**.

3. **Defina o período e os filtros**

   Defina o **Time Filter**, que abre nos últimos 15 minutos, e adicione condições em **Filter by**.

4. **Selecione Refresh**

A tabela de resultados lista os eventos. Selecione uma linha para abrir o registro completo.

Para consultar os mesmos dados, envie uma consulta GraphQL para `https://api.azion.com/v4/events/graphql`. O dataset `workloadEvents` guarda as requisições HTTP:

```graphql
query {
  workloadEvents(
    limit: 100
    filter: { tsRange: { begin: "2026-10-07T00:00:00", end: "2026-10-07T01:00:00" } }
    orderBy: [ts_DESC]
  ) {
    ts
    remoteAddress
    requestUri
    status
    upstreamResponseTime
  }
}
```

Substitua as datas por um intervalo dentro dos últimos 7 dias. `upstreamResponseTime` e `upstreamHeaderTime` existem apenas como campos brutos de `workloadEvents`, e `upstreamResponseTime` mostra `-` para uma resposta entregue a partir do cache. Para cada campo, consulte [Campos GraphQL do Real-Time Events](/pt-br/documentacao/devtools/graphql/campos-gql-real-time-events/) e [Investigue requisições com a API GraphQL](/pt-br/documentacao/guias/plataforma/observabilidade/investigar-requisicoes-api-graphql/).

### Data Stream

| Aspecto  | Azion Data Stream                                                   |
| -------- | ------------------------------------------------------------------- |
| Acesso   | Push para um destino externo                                        |
| Atraso   | Lotes de 2.000 registros ou 60 segundos, entregues em até 3 minutos |
| Retenção | Definida pelo destino                                               |
| Formato  | Templates que selecionam os campos                                  |
| Destinos | 11 tipos, listados abaixo                                           |

Um [stream](/pt-br/documentacao/plataforma/data-stream/primeiros-passos/) lê uma fonte de dados, como Applications ou WAF Events, e formata cada registro com um template. Ele entrega os registros a um destino, com suas credenciais:

- **Armazenamento**: Amazon S3, Azure Blob Storage e Azion Object Storage, pelo tipo S3.
- **Monitoramento**: Datadog, Splunk, Elasticsearch e Azure Monitor.
- **Streaming**: AWS Kinesis Data Firehose e Apache Kafka.
- **Analytics**: Google BigQuery.
- **Segurança**: IBM QRadar.
- **Personalizado**: Standard HTTP/HTTPS POST.

Um stream precisa de exatamente um entre sampling e um filtro de workload. Salvar um stream ativo com sampling desativa todos os outros streams da conta. Streams com filtro coexistem.

**Console**

Para criar um stream no Azion Console:

1. **Abra Data Stream**

   Acesse [Azion Console](https://console.azion.com/) > **Data Stream**.

2. **Selecione + Stream**

3. **Selecione a fonte de dados**

   Em **Input**, selecione a **Data Source**: *Activity History*, *Applications*, *Functions* ou *WAF Events*.

4. **Selecione o template**

   Em **Render Template**, selecione o **Template**.

5. **Selecione o destino**

   Em **Output**, selecione o **Connector**, como *Simple Storage Service (S3)*, e informe suas credenciais.

6. **Ative Active e selecione Save**

O stream começa a enviar depois de 1 a 2 minutos.

**CLI**

Para criar um stream com Azion CLI, siga o painel CLI de [Primeiros passos com Data Stream](/pt-br/documentacao/plataforma/data-stream/primeiros-passos/).

**API**

Para criar um stream, envie uma requisição `POST` para `https://api.azion.com/v4/workspace/stream/streams`. O corpo tem `inputs`, `transform` e `outputs`:

```json
{
  "name": "activity-to-bucket",
  "active": true,
  "inputs": [
    { "type": "raw_logs", "attributes": { "data_source": "activity_history" } }
  ],
  "transform": [
    { "type": "sampling", "attributes": { "rate": 100 } },
    { "type": "render_template", "attributes": { "template": 251 } }
  ],
  "outputs": [
    {
      "type": "s3",
      "attributes": {
        "host_url": "https://s3.us-east-005.azionstorage.net",
        "bucket_name": "<your-bucket>",
        "region": "us-east-005",
        "access_key": "[ACCESS KEY]",
        "secret_key": "[SECRET KEY]",
        "object_key_prefix": "activity",
        "content_type": "plain/text"
      }
    }
  ]
}
```

Um `POST` retorna `201`. Para um stream de Applications, use `"data_source": "workloads"`. Sem sampling nem filtro de workload, a criação falha com `32002`, e com ambos falha com `32007`. Os templates são criados em `/v4/workspace/stream/templates`.

Para um destino Object Storage, a credencial precisa de `listAllBucketNames`, `listBuckets`, `listFiles` e `writeFiles`, ou todo envio falha com `503`. Para os campos, consulte [Configurações do stream](/pt-br/documentacao/plataforma/data-stream/configuracoes-do-stream/) e [Endpoints](/pt-br/documentacao/plataforma/data-stream/endpoints/). Para guias de destinos, consulte [Amazon S3](/pt-br/documentacao/guias/plataforma/observabilidade/amazon-s3-endpoint/), [Azion Object Storage](/pt-br/documentacao/guias/plataforma/observabilidade/conector-azion-object-storage/), [Datadog](/pt-br/documentacao/guias/plataforma/observabilidade/datadog-endpoint/), [Splunk](/pt-br/documentacao/guias/plataforma/observabilidade/splunk-endpoint/), [Elasticsearch](/pt-br/documentacao/guias/plataforma/observabilidade/elasticsearch-endpoint/), [Kinesis](/pt-br/documentacao/guias/plataforma/observabilidade/amazon-kinesis-endpoint/), [BigQuery](/pt-br/documentacao/guias/plataforma/observabilidade/google-bigquery-endpoint/) e [Configure o sampling](/pt-br/documentacao/guias/plataforma/observabilidade/configurar-sampling/).

---

## Substitua Speed Insights e Web Analytics

[Edge Pulse](/pt-br/documentacao/plataforma/edge-pulse/) assume as medições de usuários reais do Speed Insights e do Web Analytics. Uma tag JavaScript coleta medições de navegação, disponibilidade, latência e largura de banda nos navegadores de visitantes reais. Real-Time Metrics cobre o lado do tráfego dos mesmos relatórios.

Para mover o monitoramento de usuários reais:

1. Liste os Core Web Vitals, os relatórios por página e os dashboards de analytics que o time consulta.
2. Decida quais deles vão para Edge Pulse, Real-Time Metrics ou uma ferramenta de BI externa.
3. Recrie o rastreamento de eventos personalizados onde o projeto precisar.
4. Revise os requisitos de privacidade e de consentimento da tag.
5. Depois da virada, compare as medições de experiência do usuário com a linha de base da Vercel.

---

## Prepare o certificado

[Certificate Manager](/pt-br/documentacao/plataforma/workloads/certificate-manager/primeiros-passos/) guarda os certificados que os workloads servem. Prepare o certificado antes de o domínio apontar para a Azion, para que os usuários acessem o projeto por HTTPS desde a primeira requisição.

| Área                          | Azion Certificate Manager                                                                                                                                      |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Opções de certificado         | Azion SAN, Let's Encrypt, certificados personalizados e certificados Trusted CA para mTLS                                                                      |
| Certificado gerenciado padrão | Let's Encrypt para seus próprios domínios. Azion SAN cobre o domínio de workload `azionedge.net` e o hostname `azion.app`                                      |
| Certificados personalizados   | Upload de um certificado e sua chave privada, de domínio único ou SAN, com chaves RSA 2048 ou P-256                                                            |
| Validação                     | Desafios HTTP-01 ou DNS-01 do Let's Encrypt                                                                                                                    |
| Renovação                     | Os certificados Let's Encrypt são renovados a partir de 30 dias antes da expiração de 90 dias. Os certificados personalizados seguem seu próprio ciclo de vida |
| Criptografia até a origem     | **Transport Protocol Policy** do connector: *Preserve*, *Force HTTPS* ou *Force HTTP*                                                                          |
| mTLS                          | Certificados Trusted CA. Azion SAN não suporta mTLS                                                                                                            |

Assim que você escolhe um preset Let's Encrypt, a Azion emite o certificado sem custo adicional. O desafio depende de onde o DNS responde:

- **HTTP-01** precisa que o hostname, e cada nome alternativo, já apontem para a Azion.
- **DNS-01** funciona antes da migração. Em um provedor de DNS externo, adicione um CNAME de `_acme-challenge.<domain>` para `<domain>.letsencrypt.azion.com`. No Edge DNS, o registro é automático.

Para uma migração a partir da Vercel, use DNS-01, para que o certificado esteja ativo antes da troca do domínio.

**Console**

Para solicitar o certificado no Azion Console:

1. **Abra o workload**

   Acesse [Azion Console](https://console.azion.com/) > **Workloads** e selecione ou crie o workload.

2. **Informe os domínios**

   Em **Domains**, informe cada hostname a que o projeto responde. Wildcards são recusados.

3. **Ative o HTTPS**

   Em **Protocol Settings**, ative **HTTPS support**.

4. **Selecione o certificado**

   Em **Digital Certificate**, selecione *New Let's Encrypt Certificate (DNS-01)*.

5. **Selecione Save**

A primeira tentativa acontece em até 5 minutos depois de salvar. As novas tentativas seguem aos 5, 10, 15, 20 e 30 minutos, depois em um ritmo mais lento. O status passa de `pending` para `challenge_verification` e depois para `active` ou `failed`.

Para enviar um certificado que você já tem, acesse **Certificate Manager** e crie um certificado digital com o preset **Server Certificate**. Cole o certificado PEM e a chave privada. Os certificados intermediários vão no mesmo campo do certificado. Depois selecione o certificado no campo **Digital Certificate** do workload. Para os passos, consulte [Faça upload de um certificado digital](/pt-br/documentacao/guias/seguranca-de-aplicacoes/tls-e-certificados/certificado-digital/). Para cada campo de certificado, consulte [Certificados](/pt-br/documentacao/plataforma/workloads/certificate-manager/certificados/).

**CLI**

Para definir o mTLS ou o certificado de um workload com Azion CLI, execute `azion update workload --file` com o corpo do workload. Para os comandos de certificado, consulte [Primeiros passos com Certificate Manager](/pt-br/documentacao/plataforma/workloads/certificate-manager/primeiros-passos/).

**API**

Para enviar um certificado, envie uma requisição `POST` para o endpoint de certificados:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/tls/certificates \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "my-certificate",
  "type": "edge_certificate",
  "certificate": "-----BEGIN CERTIFICATE-----\n<certificate-body>\n-----END CERTIFICATE-----\n",
  "private_key": "-----BEGIN PRIVATE KEY-----\n<private-key-body>\n-----END PRIVATE KEY-----\n"
}'
```

A API responde `201`. Cada PEM é uma string JSON com quebras de linha `\n`. Para solicitar um certificado Let's Encrypt, envie uma requisição `POST` para `/v4/workspace/tls/certificates/request` com `name`, `"authority": "lets_encrypt"`, `challenge` (`http` ou `dns`), `common_name` e, opcionalmente, `alternative_names`.

Para servir o certificado, defina seu ID em `tls.certificate` do workload, ou `null` para Azion SAN:

```json
{
  "name": "my-workload",
  "active": true,
  "infrastructure": 1,
  "domains": ["www.example.com"],
  "tls": { "certificate": 12345, "ciphers": 4, "minimum_version": "tls_1_2" }
}
```

`infrastructure` `1` é produção. `minimum_version` aceita `tls_1_0`, `tls_1_1`, `tls_1_2` ou `tls_1_3` e tem padrão `tls_1_3`. `ciphers` aceita de 1 a 8 e tem padrão 7. Envie o corpo para `https://api.azion.com/v4/workspace/workloads`.

Se o certificado não ficar ativo, leia seus campos `status` e `status_detail`. Para HTTP-01, verifique se o hostname aponta para a Azion. Para DNS-01, verifique o CNAME `_acme-challenge`. As novas tentativas continuam conforme o cronograma, então um registro corrigido emite o certificado mais tarde. Para as regras de emissão, consulte [Emissão e renovação](/pt-br/documentacao/plataforma/workloads/certificate-manager/emissao-e-renovacao/).

O mTLS precisa de um certificado Trusted CA, e um certificado gerado pela Azion não pode ser o Trusted CA. A equipe de vendas ativa o mTLS na conta. Depois defina `mtls.enabled`, `mtls.config.certificate` e `verification`, `enforce` ou `permissive`, no workload pela API ou com `azion update workload --file`. O mTLS funciona apenas por HTTPS. Para os passos, consulte [Configure o mTLS em um workload](/pt-br/documentacao/guias/seguranca-de-aplicacoes/tls-e-certificados/associar-um-certificado-mtls/) e [mTLS](/pt-br/documentacao/plataforma/workloads/mtls/).

---

## Mova zonas DNS para Edge DNS

Mover a zona para [Edge DNS](/pt-br/documentacao/plataforma/edge-dns/) dá à Azion todos os registros do domínio, incluindo o apex. Toda zona usa os mesmos três nameservers: `ns1.aziondns.net`, `ns2.aziondns.com` e `ns3.aziondns.org`. Pule esta etapa para manter o provedor de DNS atual e apontar apenas subdomínios, como mostra Aponte o domínio para o workload.

| Aspecto           | Azion Edge DNS                                                             |
| ----------------- | -------------------------------------------------------------------------- |
| Nameservers       | `ns1.aziondns.net`, `ns2.aziondns.com` e `ns3.aziondns.org` para toda zona |
| Tipos de registro | A, AAAA, ANAME, CAA, CNAME, DS, MX, NS, PTR, SRV e TXT                     |
| DNSSEC            | Suportado                                                                  |
| API               | `/v4/workspace/dns/zones`                                                  |

Recrie cada registro da zona atual com seu tipo:

| Registro | Uso na Azion                                                                                |
| -------- | ------------------------------------------------------------------------------------------- |
| A        | Endereço IPv4                                                                               |
| AAAA     | Endereço IPv6                                                                               |
| ANAME    | Alias do apex para um hostname da Azion, como o domínio do workload. Seu TTL precisa ser 20 |
| CNAME    | Alias para outro nome. Guarda exatamente um valor e não pode ficar no apex                  |
| MX       | Troca de e-mail, com sua prioridade                                                         |
| TXT      | Texto, como SPF e DKIM                                                                      |
| SRV      | Registros de serviço, um por nome                                                           |
| CAA      | Autoridades certificadoras autorizadas a emitir para o domínio                              |
| NS       | Delegação de um subdomínio                                                                  |
| DS       | Delegation signer de uma zona filha assinada                                                |
| PTR      | Consulta reversa                                                                            |

Edge DNS recusa outros tipos, como SOA. Os registros A, AAAA, ANAME, DS, MX e NS guardam até 10 valores cada.

**Console**

Para criar a zona no Azion Console:

1. **Abra Edge DNS**

   Acesse [Azion Console](https://console.azion.com/) > **Edge DNS**.

2. **Selecione + Zone**

3. **Informe a zona**

   Informe um **Name** para a zona e o **Domain Name**. O domínio não pode mudar depois que a zona é criada.

4. **(Opcional) Ative o DNSSEC**

   Em **DNSSEC**, ative **Enable DNSSEC**.

5. **Selecione Save**

6. **Adicione os registros**

   Na aba **Records**, crie cada registro da zona atual.

A zona responde nos nameservers da Azion. Depois altere os nameservers do domínio no registrador.

**CLI**

Para criar zonas e registros com Azion CLI, siga o painel CLI de [Primeiros passos com Edge DNS](/pt-br/documentacao/plataforma/edge-dns/primeiros-passos/). Flags booleanas precisam de `=`, como `--active=false`.

**API**

Para criar a zona e um registro, envie requisições `POST` para o endpoint de zonas:

```bash
curl -X POST https://api.azion.com/v4/workspace/dns/zones \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Content-Type: application/json" \
  -d '{"name":"example-zone","domain":"example.com","active":true}'
```

```bash
curl -X POST https://api.azion.com/v4/workspace/dns/zones/<zone-id>/records \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Content-Type: application/json" \
  -d '{"name":"www","type":"A","rdata":["192.0.2.1"],"ttl":3600}'
```

Uma zona precisa de `name`, `domain` e `active`. Um registro recebe seu `name` relativo à zona, seu `type` e `rdata` como um array de strings. Por exemplo: `["192.0.2.1"]` para um registro A, ou `["mail.example.com"]` para um CNAME. Para ativar o DNSSEC, envie `{"enabled": true}` em uma requisição `PATCH` para `/v4/workspace/dns/zones/<zone-id>/dnssec`.

Com o DNSSEC ativado, Edge DNS mostra quatro valores DS: **Key Tag**, **Algorithm** `13`, **Digest Type** `2` e **Digest**. Recarregue a página depois de salvar para vê-los. Adicione-os no registrador, que pode levar até 48 horas para publicá-los. Para os passos, consulte [DNSSEC](/pt-br/documentacao/plataforma/edge-dns/dnssec/).

Para verificar a migração, consulte os nameservers e os registros:

```bash
dig example.com NS +short
dig @ns1.aziondns.net example.com A
dig +dnssec example.com DNSKEY
```

O primeiro comando lista os três nameservers da Azion assim que a mudança no registrador se propaga. O segundo mostra a resposta do Edge DNS antes que a mudança chegue a todos os resolvers. Com o DNSSEC ativado, o terceiro retorna dois registros DNSKEY, com flags `257` e `256` e algoritmo `13`. Não consulte um nome novo antes de o registro dele existir, porque Edge DNS mantém a resposta negativa em cache por uma hora. Para mais comandos, consulte [Execute o comando dig](/pt-br/documentacao/guias/seguranca-de-aplicacoes/dns/executar-o-comando-dig/) e [Execute o comando traceroute](/pt-br/documentacao/guias/seguranca-de-aplicacoes/dns/executar-o-comando-traceroute/).

---

## Aponte o domínio para o workload

O domínio é o último a migrar, porque a mudança de DNS é a virada: assim que o domínio resolve para o workload, os usuários acessam o projeto pela Azion. Ela afeta usuários, ranking de busca, confiança na marca e disponibilidade, então trate-a como uma transição planejada. Antes da virada, confirme que:

- O certificado está ativo.
- O hostname está nos **Domains** do workload. Para as configurações de domínio, consulte [Domains](/pt-br/documentacao/plataforma/workloads/domains/).
- Os registros DNS estão prontos.
- As rotas críticas e os redirecionamentos respondem como esperado no domínio do workload. Para testá-los antes com o hostname real, consulte [Teste uma aplicação pelo arquivo hosts](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/primeiros-passos/testar-edge-application-atraves-do-arquivo-hosts/).
- O monitoramento está pronto para acompanhar o tráfego depois da virada.

Aponte cada nome com o registro que sua zona permite:

| Estratégia  | Use para                       | Controle do DNS                       | Registro                                    |
| ----------- | ------------------------------ | ------------------------------------- | ------------------------------------------- |
| CNAME       | Um subdomínio que migra rápido | O provedor de DNS atual mantém a zona | `www CNAME <your-workload-domain>`          |
| Nameservers | O apex e todos os outros nomes | Edge DNS responde pela zona           | Um ANAME no apex para o domínio do workload |

Para verificar um CNAME:

```bash
dig www.example.com CNAME +short
```

A resposta é o domínio do workload, como `xxxxxxxxxx.map.azionedge.net`. Mudanças de DNS levam tempo para se propagar. Assim que o nome resolver, requisite-o, com o domínio no lugar de `<your-domain>`:

```bash
curl -i https://<your-domain>/
```

A resposta vem da aplicação, com o status e os headers que ela retorna para `/`. Se o HTTPS falhar, leia o status do certificado e confirme que o hostname está no workload. Para as configurações do domínio personalizado no Console, consulte [Aponte um domínio para um workload](/pt-br/documentacao/guias/plataforma/migracao/apontar-dominio-para-a-azion/). Para mover os nameservers, consulte [Migre os nameservers para a Azion](/pt-br/documentacao/guias/plataforma/migracao/migrar-ns-para-a-azion/).

---

## Próximos passos

- [Real-Time Metrics](/pt-br/documentacao/plataforma/real-time-metrics/primeiros-passos.md): Acompanhe requisições, dados transferidos, códigos de status e offload de cache depois da virada.
- [Real-Time Events](/pt-br/documentacao/plataforma/real-time-events/primeiros-passos.md): Consulte requisições individuais, logs de funções e resultados do WAF dos últimos 7 dias.
- [Web Application Firewall](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos.md): Mude o conjunto de regras de Logging para Blocking quando o tráfego estiver limpo.
- [Azion CLI](/pt-br/documentacao/devtools/cli.md): Faça o deploy, vincule e gerencie o projeto a partir de um terminal.
- [Comunidade Azion](https://discord.gg/azion): Pergunte à comunidade Azion no Discord como outras pessoas rodam seus projetos na Azion.
- [Suporte Azion](/pt-br/documentacao/suporte.md): Abra um ticket com a equipe de suporte quando a migração precisar de ajuda.
