---
name: azion-migre-da-aws-para-a-azion
description: >-
  Migre um projeto da AWS para a Azion: faça o deploy, recrie Lambda, CloudFront e regras de WAF, mova dados de S3, DynamoDB e RDS e troque o DNS.
---

# Migre da AWS para a Azion

Um projeto na AWS se distribui entre distribuições do CloudFront, funções Lambda, rotas do API Gateway, buckets S3, tabelas DynamoDB, bancos de dados RDS, regras de WAF, zonas do Route 53 e CloudWatch. Com o tempo, cada um ganha seus próprios comportamentos de cache, dependências, políticas de acesso, configurações de capacidade, health checks e alarmes. Mover o projeto significa recriar cada um desses itens na Azion e confirmar que o projeto responde corretamente antes da mudança de DNS.

Na Azion, uma [aplicação](/pt-br/documentacao/plataforma/applications/) e suas regras assumem a entrega, o roteamento e o cache, e [Connectors](/pt-br/documentacao/plataforma/connectors/) alcança as origens. [Functions](/pt-br/documentacao/plataforma/functions/) executa o código Lambda. [KV Store](/pt-br/documentacao/plataforma/kv-store/), [Object Storage](/pt-br/documentacao/plataforma/object-storage/) e [SQL Database](/pt-br/documentacao/plataforma/sql-database/) guardam os dados. [Firewall](/pt-br/documentacao/plataforma/firewall/) filtra o tráfego, um [workload](/pt-br/documentacao/plataforma/workloads/) atende o domínio e [Edge DNS](/pt-br/documentacao/plataforma/edge-dns/) responde pela 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/) mostram o que acontece com cada requisição.

Cada etapa deste guia move uma camada, na ordem em que uma migração acontece: inventário, deployment, código e regras, dados, segurança, monitoramento e DNS. O código Lambda migra com mudanças pontuais: o formato do handler, a linguagem do runtime e como o código abre o armazenamento e 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 passo, então os dados não precisam de sincronização paralela.

---

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). Para mais informações, consulte [Crie uma conta](/pt-br/documentacao/fundamentos/criar-uma-conta/).
- A conta AWS, com acesso às suas distribuições, funções, armazenamentos de dados e hosted zones.
- 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 da conta AWS

Não comece pela aplicação mais complexa do portfólio. Escolha um projeto importante o bastante para testar o caminho completo e pequeno o bastante para migrar rápido. Um bom primeiro projeto tem uma distribuição do CloudFront, algumas funções Lambda, um bucket S3 e talvez uma tabela DynamoDB. Use-o para documentar o processo e os padrões que sua equipe reutiliza. Depois mova mais comportamentos de cache, funções, dados, observabilidade e regras de segurança, na mesma ordem. Mantenha o primeiro deployment pequeno e comprove que ele faz o build e roda na Azion antes de mover domínios, armazenamento ou bancos de dados.

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

- Templates SAM, apps CDK e stacks CloudFormation, com seus comandos de build e deploy.
- Variáveis de ambiente e secrets, da configuração do Lambda, do AWS Secrets Manager, do Systems Manager Parameter Store, das propriedades de ambiente do Elastic Beanstalk, das configurações do CodePipeline e do CodeBuild e do código-fonte.
- Funções Lambda, seus runtimes, triggers e fontes de eventos.
- APIs do API Gateway, suas rotas, authorizers, stages e usage plans.
- State machines do Step Functions e regras do EventBridge.
- Distribuições do CloudFront: origens, comportamentos de cache, políticas de cache e de requisição à origem, políticas de headers de resposta, CloudFront Functions e triggers do Lambda\@Edge.
- Load balancers e seus target groups.
- Transformações de imagem e chamadas ao Bedrock.
- Buckets S3, tabelas DynamoDB, bancos de dados RDS e Aurora e clusters ElastiCache.
- Hosted zones, registros, políticas de roteamento e DNSSEC do Route 53 e certificados do ACM.
- Web ACLs do WAF, managed rule groups, IP sets, regras baseadas em taxa, Bot Control, configurações do Shield e findings do GuardDuty, do Inspector e do Security Hub.
- Dashboards, alarmes, log groups e metric filters do CloudWatch, traces do X-Ray, streams do Firehose e monitores do RUM.

Cada item da lista corresponde a uma etapa deste guia. A tabela em Mapeie cada produto da AWS para a Azion indica o destino de cada um.

---

## Mapeie cada produto da AWS para a Azion

Todo produto da AWS do inventário tem um destino na Azion. Encontre o produto na primeira coluna e mova-o com a etapa que indica seu destino. Um traço (`-`) na última coluna significa que a Azion não tem um equivalente direto.

| Produto da AWS                                  | O que cobre                                                                                      | Destino na Azion                                                                                                                                                                                 |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Amazon CloudFront                               | Entrega de conteúdo estático e dinâmico, APIs, aplicações e vídeo                                | Applications, atendido por um workload, com Connectors para as origens                                                                                                                           |
| Distribuições do CloudFront                     | Domínios, origens, comportamento de cache, certificados e segurança de uma entrega               | Applications, Connectors e [Workloads](/pt-br/documentacao/plataforma/workloads/)                                                                                                                |
| Alternate domain names do CloudFront            | Domínios personalizados de uma distribuição                                                      | Os **Domains** de um workload                                                                                                                                                                    |
| Cache behaviors do CloudFront                   | Política de cache, política de requisição à origem, métodos e associações de funções por caminho | [Rules Engine para Applications](/pt-br/documentacao/plataforma/applications/rules-engine/)                                                                                                      |
| Cache policies do CloudFront                    | Chaves de cache, TTLs, headers, cookies, query strings e compressão                              | [Cache settings](/pt-br/documentacao/plataforma/applications/cache/cache-settings/)                                                                                                              |
| Origin request policies do CloudFront           | Os valores da requisição encaminhados à origem                                                   | Rules Engine para Applications e Connectors                                                                                                                                                      |
| Response headers policies do CloudFront         | Headers de segurança e headers de CORS nas respostas                                             | Rules Engine para Applications                                                                                                                                                                   |
| CloudFront Origin Shield                        | Uma camada central de cache na frente da origem                                                  | [Tiered Cache](/pt-br/documentacao/plataforma/applications/cache/tiered-cache/), uma funcionalidade de Cache                                                                                     |
| Invalidação do CloudFront                       | Remoção de conteúdo do cache antes de ele expirar                                                | [Real-Time Purge](/pt-br/documentacao/plataforma/applications/cache/real-time-purge/)                                                                                                            |
| CloudFront Functions                            | JavaScript leve para redirecionamentos, reescritas, headers e chaves de cache                    | Functions                                                                                                                                                                                        |
| Lambda\@Edge                                    | Funções Node.js ou Python em eventos do CloudFront                                               | Functions                                                                                                                                                                                        |
| Lambda\@Edge para lógica de segurança           | Validação de requisições, autenticação e bloqueio                                                | [Functions para Firewall](/pt-br/documentacao/plataforma/firewall/functions/)                                                                                                                    |
| Detecção de dispositivos do CloudFront          | Tipo de dispositivo repassado à origem                                                           | [Device Groups](/pt-br/documentacao/plataforma/applications/device-groups/)                                                                                                                      |
| AWS Elemental MediaLive                         | Codificação de vídeo ao vivo em tempo real                                                       | [Live Ingest](/pt-br/documentacao/plataforma/connectors/#live-ingest), um módulo de Connectors                                                                                                   |
| AWS Elemental MediaPackage                      | Empacotamento e originação de transmissões ao vivo para HLS e DASH                               | Live Ingest e Applications                                                                                                                                                                       |
| CloudFront para transmissões ao vivo            | Entrega de vídeo ao vivo com AWS Media Services                                                  | Applications e Live Ingest                                                                                                                                                                       |
| AWS Lambda                                      | Computação serverless para código orientado a eventos                                            | Functions                                                                                                                                                                                        |
| Amazon API Gateway                              | APIs REST, HTTP e WebSocket com integrações de backend                                           | Applications e Functions                                                                                                                                                                         |
| Validação e throttling do API Gateway           | Controles de requisição, throttling e validação                                                  | Rules Engine para Applications e Firewall                                                                                                                                                        |
| AWS Amplify Hosting                             | CI/CD baseado em Git e hospedagem para apps estáticos e renderizados no servidor                 | Applications, atendido por um workload, e [Azion CLI](/pt-br/documentacao/devtools/cli/)                                                                                                         |
| AWS App Runner                                  | Aplicações web gerenciadas a partir de código-fonte ou imagens de contêiner                      | Applications e [Orchestrator](/pt-br/documentacao/plataforma/orchestrator/)                                                                                                                      |
| Amazon Bedrock                                  | Modelos de fundação e desenvolvimento de IA generativa                                           | [AI Inference](/pt-br/documentacao/plataforma/ai-inference/)                                                                                                                                     |
| Inferência de modelos do Bedrock                | Chamadas a modelos de texto, imagem e embedding                                                  | AI Inference                                                                                                                                                                                     |
| Fine-tuning do Bedrock                          | Personalização de modelos de fundação                                                            | [LoRA Fine-Tune](https://www.azion.com/en/learning/ai/what-is-lora-fine-tuning/)                                                                                                                 |
| Importação de modelos personalizados do Bedrock | Importação de modelos de fundação personalizados                                                 | AI Inference e LoRA Fine-Tune. AI Inference executa um catálogo de modelos open source e não importa nenhum                                                                                      |
| Inferência em tempo real do SageMaker AI        | Endpoints gerenciados de inferência em tempo real                                                | AI Inference                                                                                                                                                                                     |
| Amazon S3                                       | Armazenamento de objetos para assets, backups, arquivos e sites                                  | Object Storage                                                                                                                                                                                   |
| Hospedagem de sites estáticos do S3             | Sites estáticos servidos a partir de um bucket                                                   | Object Storage e Applications, por meio de um storage connector                                                                                                                                  |
| S3 Object Lambda                                | Objetos transformados pelo Lambda na saída                                                       | Object Storage e Functions                                                                                                                                                                       |
| S3 Object Lambda para imagens                   | Redimensionamento, marca d'água e ocultação de conteúdo recuperado                               | [Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/) e Functions                                                                                     |
| Amazon Aurora DSQL                              | SQL distribuído serverless para transações                                                       | SQL Database                                                                                                                                                                                     |
| Amazon DynamoDB                                 | Banco de dados serverless chave-valor e de documentos                                            | KV Store, ou SQL Database para consultas                                                                                                                                                         |
| Global tables do DynamoDB                       | Replicação de dados NoSQL entre várias Regions                                                   | KV Store                                                                                                                                                                                         |
| AWS WAF                                         | Web application firewall para aplicações e APIs                                                  | [Web Application Firewall](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos/), um módulo de Firewall                                                                                 |
| AWS Managed Rules for AWS WAF                   | Managed rule groups para vulnerabilidades comuns                                                 | [Rule sets do WAF](/pt-br/documentacao/plataforma/firewall/waf/rule-sets/)                                                                                                                       |
| Regras personalizadas do AWS WAF                | Condições de correspondência e ações personalizadas                                              | [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/)                                                                                                              |
| AWS WAF Bot Control                             | Detecção e mitigação gerenciadas de bots                                                         | [Bot Manager](/pt-br/documentacao/plataforma/firewall/bot-manager/primeiros-passos/) e [Bot Manager Lite](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/bot-manager-lite/) |
| Regras baseadas em taxa do AWS WAF              | Rate limits por IP, headers, URI ou método                                                       | Firewall e Functions                                                                                                                                                                             |
| IP sets do AWS WAF                              | Listas reutilizáveis de IPs e CIDRs para regras de permissão ou bloqueio                         | [Network lists](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/)                                                                                                           |
| AWS Shield Standard                             | Proteção DDoS padrão                                                                             | [DDoS Protection](/pt-br/documentacao/plataforma/workloads/#ddos-protection)                                                                                                                     |
| AWS Shield Advanced                             | Proteção DDoS com mais visibilidade e opções de mitigação                                        | DDoS Protection                                                                                                                                                                                  |
| Mitigação automática do Shield Advanced         | Proteções de WAF criadas durante ataques à camada de aplicação                                   | DDoS Protection e Web Application Firewall                                                                                                                                                       |
| AWS Network Firewall                            | Firewall de rede gerenciado para uma VPC                                                         | Firewall e [Network Shield](/pt-br/documentacao/plataforma/firewall/network-shield/primeiros-passos/)                                                                                            |
| Elastic Load Balancing                          | Tráfego distribuído entre targets e zonas                                                        | [Load Balancer](/pt-br/documentacao/plataforma/connectors/load-balancer/primeiros-passos/), um módulo de Connectors                                                                              |
| Application Load Balancer                       | Balanceamento de carga HTTP e HTTPS na camada 7                                                  | Load Balancer                                                                                                                                                                                    |
| Network Load Balancer                           | Balanceamento de carga TCP, UDP e TLS na camada 4                                                | Load Balancer, apenas para origens HTTP e HTTPS                                                                                                                                                  |
| AWS Global Accelerator                          | Endereços IP anycast globais e roteamento pela rede da AWS                                       | Applications e Load Balancer                                                                                                                                                                     |
| Origin access control do CloudFront             | Origens S3 acessíveis apenas pelo CloudFront                                                     | Connectors e Origin Shield, um módulo de Connectors, com Origin IP ACL e HMAC                                                                                                                    |
| Signed URLs e cookies do CloudFront             | Acesso a conteúdo privado                                                                        | Rules Engine para Applications, Functions e a integração [Secure Token](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/secure-token/) em um firewall                        |
| Restrições geográficas do CloudFront            | Acesso permitido ou bloqueado por país                                                           | Rules Engine para Applications e Network Shield                                                                                                                                                  |
| Amazon Route 53                                 | DNS autoritativo, registro, políticas de roteamento e health checks                              | Edge DNS                                                                                                                                                                                         |
| AWS Certificate Manager                         | Certificados TLS: provisionamento, importação, implantação e renovação                           | [Certificate Manager](/pt-br/documentacao/plataforma/workloads/certificate-manager/certificados/)                                                                                                |
| AWS Private CA                                  | Autoridades certificadoras privadas                                                              | Certificate Manager, que guarda certificados Trusted CA                                                                                                                                          |
| AWS Private CA para autenticação de clientes    | Autenticação de clientes baseada em certificados                                                 | [mTLS](/pt-br/documentacao/plataforma/workloads/mtls/)                                                                                                                                           |
| AWS IoT Greengrass                              | Componentes gerenciados e processamento local nos dispositivos                                   | Orchestrator                                                                                                                                                                                     |
| Deployments do AWS IoT Greengrass               | Componentes e configurações enviados aos dispositivos                                            | Orchestrator                                                                                                                                                                                     |
| Amazon ECS Anywhere                             | Servidores on-premise registrados em clusters ECS                                                | Orchestrator                                                                                                                                                                                     |
| AWS Outposts                                    | Infraestrutura da AWS nas instalações do cliente                                                 | Orchestrator                                                                                                                                                                                     |
| Hybrid activations do AWS Systems Manager       | Gerenciamento de máquinas que não são EC2                                                        | Orchestrator                                                                                                                                                                                     |
| Métricas do Amazon CloudWatch                   | Métricas coletadas, consultadas, exibidas em gráficos e com alarmes                              | Real-Time Metrics                                                                                                                                                                                |
| Amazon CloudWatch Logs                          | Logs coletados, monitorados e consultados                                                        | Real-Time Events e Data Stream                                                                                                                                                                   |
| CloudWatch Logs Insights                        | Consultas interativas de logs                                                                    | Real-Time Events                                                                                                                                                                                 |
| Amazon Data Firehose                            | Dados de streaming entregues ao S3, Redshift, OpenSearch e HTTP                                  | Data Stream                                                                                                                                                                                      |
| CloudWatch RUM                                  | Monitoramento de usuários reais para apps de navegador e mobile                                  | [Edge Pulse](/pt-br/documentacao/plataforma/edge-pulse/)                                                                                                                                         |
| AWS X-Ray                                       | Tracing distribuído entre serviços                                                               | Data Stream e Functions                                                                                                                                                                          |
| AWS Step Functions                              | Orquestração de workflows com state machines                                                     | Functions. A Azion não tem um serviço de workflows                                                                                                                                               |
| Amazon EventBridge                              | Roteamento de eventos com regras e targets                                                       | -                                                                                                                                                                                                |
| Amazon ElastiCache                              | Cache em memória com Redis ou Memcached                                                          | Cache e KV Store                                                                                                                                                                                 |
| Amazon RDS e Aurora                             | Bancos de dados relacionais gerenciados                                                          | SQL Database                                                                                                                                                                                     |
| Amazon GuardDuty                                | Detecção de ameaças                                                                              | Firewall e network lists                                                                                                                                                                         |
| Amazon Inspector                                | Varredura de vulnerabilidades                                                                    | -                                                                                                                                                                                                |
| AWS Security Hub                                | Findings de segurança centralizados                                                              | Real-Time Events e Data Stream                                                                                                                                                                   |
| AWS Marketplace                                 | Software, dados e serviços de terceiros                                                          | [Marketplace](/pt-br/documentacao/plataforma/marketplace/)                                                                                                                                       |
| AWS Management Console                          | Interface web para os serviços da AWS                                                            | [Azion Console](https://console.azion.com/)                                                                                                                                                      |
| APIs da AWS                                     | Acesso programático aos serviços da AWS                                                          | [Azion API](/pt-br/documentacao/devtools/api/)                                                                                                                                                   |
| APIs do CloudWatch                              | Acesso programático a métricas, logs e alarmes                                                   | [GraphQL API](/pt-br/documentacao/devtools/graphql/primeiros-passos/)                                                                                                                            |
| AWS CLI                                         | Gerenciamento dos serviços da AWS pela linha de comando                                          | Azion CLI                                                                                                                                                                                        |
| AWS SDK for JavaScript                          | Bibliotecas JavaScript para os serviços da AWS                                                   | [Azion Lib](/pt-br/documentacao/devtools/azion-lib/)                                                                                                                                             |
| AWS CloudFormation                              | Infraestrutura como código para recursos da AWS                                                  | [Terraform Provider](/pt-br/documentacao/devtools/terraform/)                                                                                                                                    |
| AWS Cloud Development Kit                       | Infraestrutura definida em código e sintetizada para CloudFormation                              | Terraform Provider e Azion API                                                                                                                                                                   |
| Terraform AWS Provider                          | Gerenciamento de recursos da AWS com Terraform                                                   | Terraform Provider                                                                                                                                                                               |
| Ambiente de runtime do Lambda                   | A camada de runtime das funções Lambda                                                           | [Azion Runtime](/pt-br/documentacao/devtools/runtime/)                                                                                                                                           |
| Runtime do CloudFront                           | O runtime das CloudFront Functions e do Lambda\@Edge                                             | Azion Runtime                                                                                                                                                                                    |

A Azion possui um relatório SOC 2 Type 2 e um relatório SOC 3 e é PCI DSS 4.0.1 Level 1 Service Provider. Para as atestações, consulte [SOC 2 e SOC 3](/pt-br/documentacao/fundamentos/soc/) e [Certificação PCI DSS](/pt-br/documentacao/fundamentos/pci-dss-certification/).

---

## Faça o deploy do projeto na Azion

Na Azion, um projeto vira uma aplicação, e um workload atende essa aplicação em um domínio. A AWS guarda o build e a infraestrutura no `template.yaml` para SAM ou no `cdk.json` para CDK. A Azion os guarda no [`azion.config.js`](/pt-br/documentacao/devtools/cli/azion-config-js/), que também pode ser `azion.config.mjs` ou `azion.config.cjs`, conforme o preset.

| Tarefa              | AWS                                     | Azion CLI                                                                                                |
| ------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Instalar            | `pip install awscli`                    | `curl -fsSL https://cli.azion.app/install.sh \| bash` ou `brew install azion`                            |
| Entrar              | `aws configure`                         | `azion login`                                                                                            |
| Executar localmente | `sam local start-api`                   | `azion dev`, que serve em `http://localhost:3333`                                                        |
| Fazer o deploy      | `sam deploy --guided` ou `cdk deploy`   | `azion link` e depois `azion deploy`                                                                     |
| Ver logs            | `aws logs tail /aws/lambda/my-function` | `azion logs cells` para os logs de console das funções ou `azion logs http` para os logs de eventos HTTP |
| Fazer rollback      | Rollback do stack                       | `azion rollback`, que volta a servir os arquivos estáticos de um deploy anterior                         |

| Aspecto                    | AWS SAM ou CDK               | Azion                                            |
| -------------------------- | ---------------------------- | ------------------------------------------------ |
| Infraestrutura como código | Templates YAML ou TypeScript | Um arquivo de configuração JavaScript            |
| Testes locais              | Emulador local do SAM        | `azion dev`                                      |
| Deployment                 | Stacks CloudFormation        | Recursos criados diretamente pelo `azion deploy` |
| Frameworks                 | Configurados manualmente     | 19 frameworks e 5 presets genéricos              |

`azion logs cells` e `azion logs http` retornam os logs dos últimos 5 minutos, e `--tail` continua exibindo os novos. `azion rollback` recebe o `--connector-id` do storage connector que entrega o site. Para as flags, consulte [azion logs](/pt-br/documentacao/devtools/cli/logs/) e [azion rollback](/pt-br/documentacao/devtools/cli/rollback/).

O Azion Console importa um repositório com um de seis presets, e a Azion CLI pede o preset em um seletor. Nenhum dos dois detecta o framework por você.

**Console**

Para importar o repositório no Azion Console:

1. **Abra o diálogo de criação**

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

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

   No diálogo **New**, selecione a aba **Import from GitHub** e depois selecione o card.

3. **Conecte sua conta do GitHub**

   Na seção **GitHub Connection**, selecione **Connect with GitHub** e instale o Azion GitHub App para o repositório.

4. **Selecione o repositório**

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

5. **Selecione o preset**

   Em **Preset**, selecione o framework: *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 projeto e cria sua aplicação e seu workload. Para cada campo da página, consulte [Importe um projeto do GitHub](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/automacao/importar-um-projeto-existente-do-github/).

**CLI**

A Azion CLI faz o deploy do projeto a partir da sua máquina. Na raiz do projeto, vincule-o à Azion e selecione o preset quando a CLI pedir:

```bash
azion link
```

Depois faça o deploy. O `azion deploy` precisa das configurações do projeto que o `azion link` grava:

```bash
azion deploy
```

A CLI faz o build do projeto e o deploy na Azion. Para definir o preset no código, coloque-o em `build.preset` do `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`. O pacote `azion` que amostras antigas importam está obsoleto: importe `defineConfig` de `@aziontech/config`. 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/).

**API**

A API cria a aplicação, suas regras e o workload, um recurso por vez. Para montar essa cadeia, consulte [Primeiros passos com Applications](/pt-br/documentacao/plataforma/applications/primeiros-passos/).

O deployment responde em um domínio de workload que a Azion atribui sob `map.azionedge.net`. Antes de mover qualquer domínio de produção, envie uma requisição para o caminho raiz, com esse domínio no lugar de `<your-workload-domain>`:

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

A resposta traz o status, os headers e o corpo que o projeto retorna para `/`. Envie a mesma requisição para cada rota crítica. Um build que passa ainda pode se comportar de outro jeito em tempo de execução, então compare as respostas com as que a AWS retorna.

Se o build falhar na Azion, compare o preset com o framework do projeto e verifique `build.preset`, `build.entry` e `build.bundler` no `azion.config.js`. O bloco `build` não tem campo de comando.

---

## Mova as variáveis de ambiente

Variáveis de ambiente guardam chaves de API, credenciais de banco de dados, secrets de autenticação, endpoints de serviços, feature flags e configurações por ambiente. Uma variável que não chega à Azion quebra o projeto em tempo de execução, mesmo quando o deployment tem sucesso.

Na AWS, uma função Lambda lê uma variável de `process.env`, e os secrets muitas vezes ficam no AWS Secrets Manager ou no Parameter Store. Na Azion, as variáveis pertencem à conta, até 100 delas, e uma função as lê com `Azion.env.get()`. Cada variável tem uma chave, um valor e uma flag que a marca como secret.

| Aspecto | AWS                                                   | Azion                                                 |
| ------- | ----------------------------------------------------- | ----------------------------------------------------- |
| Acesso  | `process.env.VARIABLE`                                | `Azion.env.get('VARIABLE')` ou `process.env.VARIABLE` |
| Secrets | AWS Secrets Manager e Systems Manager Parameter Store | Variáveis com a flag de secret ativada                |
| Tamanho | Definido por função                                   | 32 KB para todas as variáveis de uma função           |

**Console**

Para criar as variáveis no Azion Console, abra a página **Variables** do menu **Account** e crie cada variável com sua chave e seu valor. Transforme em secret uma variável que guarda uma credencial.

**CLI**

Para criar cada variável com Azion CLI:

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

A CLI responde com o UUID da nova variável:

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

Defina `--secret true` para uma credencial. Para listar as variáveis, execute `azion list variables`. Para os outros comandos, consulte [variables](/pt-br/documentacao/devtools/cli/recursos/variables/).

**API**

Azion CLI e Azion Console criam as variáveis. Para as interfaces que criam, listam e alteram uma variável, consulte [Variáveis de ambiente](/pt-br/documentacao/plataforma/functions/environment-variables/).

Depois altere o código que lê as variáveis. Um valor buscado no Secrets Manager passa a ser a leitura de uma variável:

```javascript diff
-// Before: AWS Lambda
-const apiKey = process.env.API_KEY;
-const dbHost = process.env.DB_HOST;
 
-// Before: AWS Secrets Manager
-const { SecretsManager } = require('@aws-sdk/client-secrets-manager');
-const client = new SecretsManager();
-const secret = await client.getSecretValue({ SecretId: 'my-secret' });
-const secretValue = JSON.parse(secret.SecretString);
 
+// After: Azion
+const apiKey = Azion.env.get('API_KEY');
+const dbHost = Azion.env.get('DB_HOST');
```

O código que lê `process.env.API_KEY` continua funcionando em uma função em produção, porque o Azion Runtime suporta `process.env` para compatibilidade com Node.js. No `azion dev`, uma função lê o arquivo `.env` do projeto em vez das variáveis da conta, ou todo o ambiente do shell quando não há arquivo `.env`. Uma chave que não existe retorna `undefined`, não um erro. Se uma função lê uma variável como `undefined`, confirme que a variável existe na conta.

> **Atenção**
>
> Mantenha os secrets em sistemas aprovados e limite o acesso aos processos que precisam deles. Nunca copie um secret para notas locais, tickets, mensagens de chat ou documentos temporários.

---

## Mova funções Lambda para Functions

As funções Lambda costumam carregar a lógica mais crítica de um projeto: autenticação, personalização, orquestração de APIs e integrações com serviços de terceiros. Na Azion, esse código roda em [Functions](/pt-br/documentacao/plataforma/functions/). Uma função guarda o código JavaScript, uma [instância de função](/pt-br/documentacao/plataforma/applications/functions-instances/) o executa em uma aplicação, e uma regra decide quais requisições chegam até ela.

| Aspecto    | AWS Lambda                                | Azion Functions                                                                 |
| ---------- | ----------------------------------------- | ------------------------------------------------------------------------------- |
| Handler    | `exports.handler = async (event) => {}`   | `export default { async fetch(request, env, ctx) {} }`                          |
| Runtimes   | Node.js, Python, Java, Go, .NET e Ruby    | JavaScript, em isolates V8                                                      |
| Memória    | 128 MB - 10.240 MB                        | 512 MB por isolate, em todos os planos                                          |
| Timeout    | 1 s - 15 min                              | 2 s de tempo de CPU e 5 minutos de tempo real por invocação                     |
| Cold start | Comum, especialmente em uma VPC           | Nenhum                                                                          |
| Triggers   | SQS, SNS, Kinesis, DynamoDB e API Gateway | Requisições HTTP a que uma regra de uma aplicação ou de um firewall corresponde |

Uma função Lambda escrita em Java, Python ou outro runtime precisa ser reescrita em JavaScript. Builds de frameworks também podem gerar WebAssembly. Uma função faz no máximo 50 chamadas `fetch()` de saída em uma invocação. Para todos os limites, consulte [Limites de Functions](/pt-br/documentacao/plataforma/functions/limites/).

| Cenário          | Cold start do AWS Lambda | Cold start do Azion Functions |
| ---------------- | ------------------------ | ----------------------------- |
| Node.js, sem VPC | 100-300ms                | Nenhum                        |
| Node.js, com VPC | 500ms-2s                 | Nenhum                        |
| Java ou Spring   | 1-5s                     | Nenhum                        |
| Python           | 100-500ms                | Nenhum                        |

O handler recebe um `Request` padrão e retorna um `Response`. Leia o corpo, a query string e o caminho da requisição em vez do evento:

```javascript diff
-// Before: AWS Lambda
-exports.handler = async (event) => {
-  const body = JSON.parse(event.body);
-  const pathParams = event.pathParameters;
-  const queryParams = event.queryStringParameters;
-
-  return {
-    statusCode: 200,
-    headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify({ message: 'Hello', data: body })
-  };
-};
 
+// After: Azion
+export default {
+  async fetch(request, env, ctx) {
+    const body = await request.json();
+    const url = new URL(request.url);
+    const queryParams = Object.fromEntries(url.searchParams);
+
+    return new Response(JSON.stringify({ message: 'Hello', data: body }), {
+      status: 200,
+      headers: { 'Content-Type': 'application/json' }
+    });
+  }
+};
```

`env` é um objeto vazio em uma função em produção, e `ctx` traz `args` e `waitUntil`. O contexto do Lambda e o contexto de requisição do API Gateway passam para `request.metadata`:

```javascript diff
-// Before: AWS Lambda
-exports.handler = async (event, context) => {
-  const requestId = context.awsRequestId;
-  const functionName = context.functionName;
-  const remainingTime = context.getRemainingTimeInMillis();
-  const sourceIp = event.requestContext.identity.sourceIp;
-  const userAgent = event.requestContext.identity.userAgent;
-  const country = event.headers['CloudFront-Viewer-Country'];
-  return { statusCode: 200, body: 'OK' };
-};
 
+// After: Azion
+export default {
+  async fetch(request, env, ctx) {
+    const requestId = request.metadata['request_id'];
+    const sourceIp = request.metadata['remote_addr'];
+    const userAgent = request.headers.get('user-agent');
+    const country = request.metadata['geoip_country_code'];
+    const city = request.metadata['geoip_city'];
+    const region = request.metadata['geoip_region'];
+    return new Response('OK', { status: 200 });
+  }
+};
```

`request_id` guarda o mesmo valor do header de resposta `x-azion-request-id`. `geoip_city` e `geoip_region` guardam códigos. No `azion dev`, `request.metadata` é `undefined`, então teste o código que o lê em uma função em produção. Para todos os campos, consulte [Metadata](/pt-br/documentacao/devtools/runtime/api-reference/metadata/).

### Mapeie triggers do CloudFront para as fases das regras

Uma aplicação processa cada requisição em duas fases. A Request Phase trata o que o usuário enviou, e a Response Phase trata o que a aplicação devolve. Os triggers do Lambda\@Edge correspondem a essas fases:

| Trigger do CloudFront | Equivalente na Azion                                                                 |
| --------------------- | ------------------------------------------------------------------------------------ |
| Viewer request        | Uma regra da Request Phase, que pode executar uma função                             |
| Origin request        | Uma regra da Request Phase. Nenhuma fase roda entre o cache e a origem               |
| Origin response       | Uma regra da Response Phase com comportamentos de header, cookie ou redirecionamento |
| Viewer response       | Uma regra da Response Phase com comportamentos de header, cookie ou redirecionamento |

Uma função JavaScript roda na Request Phase. Para a Response Phase, o formulário de instância de função do Console informa `Only Lua functions can be used in the Response phase.` Mova a lógica de resposta para comportamentos da Response Phase, como *Add Request Header*, que adiciona um header de resposta nessa fase.

O código que lê KV, SQL ou um modelo também muda suas chamadas. As etapas sobre KV Store, SQL Database e AI Inference mostram as novas chamadas. Para as APIs de runtime, consulte [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript/).

---

## Roteie caminhos do API Gateway para funções

O API Gateway roteia cada método e caminho para um backend, com authorizers, throttling e stages ao redor. Na Azion, uma regra da aplicação corresponde ao método e ao caminho, e seu comportamento *Run Function* executa uma instância de função. *Run Function* requer Application Accelerator e Functions na aplicação.

| Aspecto                 | AWS API Gateway                   | Azion                                                    |
| ----------------------- | --------------------------------- | -------------------------------------------------------- |
| Tipos de API            | REST APIs e HTTP APIs             | Functions, alcançadas por meio de regras do Rules Engine |
| Rotas                   | Caminhos de recursos e métodos    | Critérios sobre `${uri}` e `${request_method}`           |
| Authorizers             | Authorizers Lambda, Cognito e JWT | Uma função em um firewall, que roda antes da aplicação   |
| Stages                  | Stage variables e deployments     | -                                                        |
| Throttling              | Usage plans e rate limiting       | *Set Rate Limit* em uma regra de firewall                |
| Domínios personalizados | Mapeamentos de domínio            | Os **Domains** de um workload                            |

Uma função se torna alcançável em três passos: crie a função, crie uma instância dela na aplicação e crie a regra.

**Console**

Para rotear um caminho para uma função no Azion Console:

1. **Abra a página Functions**

   Acesse [Azion Console](https://console.azion.com/) > **Products Menu** > **Libraries** > **Functions**.

2. **Selecione + Function**

3. **Dê um nome à função**

   Informe um nome. Por exemplo: `api-handler`.

4. **Cole o código**

   Na aba **Code**, cole o código do handler e selecione **Save**.

5. **Ative Functions na aplicação**

   Vá para **Applications**, selecione a aplicação e ative o módulo **Functions** na aba **Main Settings**. Selecione **Save**.

6. **Crie a instância**

   Na aba **Functions Instances**, selecione **+ Function Instance**. Informe um nome, selecione a função e selecione **Save**.

7. **Crie a regra**

   Na aba **Rules Engine**, selecione **+ Rule** e selecione **Request Phase**. Defina o critério `${uri}` *starts with* `/api/`.

8. **Adicione Run Function**

   Na seção **Behaviors**, selecione **Run Function** e a instância. Selecione **Save**.

A regra executa a instância em toda requisição cujo caminho começa com `/api/`. Se **Run Function** não estiver na lista, ative Application Accelerator na aplicação.

**CLI**

Para criar a função com Azion CLI, salve o código em `index.js` e execute:

```bash
azion create function --name api-handler --code ./index.js --active true
```

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

Crie a instância na aplicação, com o ID da função:

```bash
azion create function-instance --application-id <application-id> --function-id <function-id> --name "api-handler instance"
```

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

Depois crie a regra a partir de um arquivo JSON com `azion create rules-engine --application-id <application-id> --phase request --file rule.json`. O arquivo traz o corpo do painel da API. Para o procedimento completo, consulte [Primeiros passos com Functions](/pt-br/documentacao/plataforma/functions/primeiros-passos/).

**API**

Para criar a função, envie uma requisição `POST` para o endpoint de funções. O código é uma string JSON, então as quebras de linha são escapadas como `\n`:

```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": "api-handler",
  "code": "export default {\n  async fetch(request, env, ctx) {\n    return new Response(JSON.stringify({ message: \"Hello\" }), { headers: { \"Content-Type\": \"application/json\" } });\n  },\n};"
}'
```

A resposta traz `202`, o `id` da função, `"runtime": "azion_js"` e `"execution_environment": "application"`. Crie a instância na aplicação com o `id` da função:

```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": "api-handler instance",
  "function": <function-id>,
  "args": {},
  "active": true
}'
```

A resposta traz `202` e o `id` da instância. Salve este corpo de regra como `rule.json`, com o `id` da instância em `attributes.value`:

```json
{
  "name": "api-route",
  "active": true,
  "criteria": [[{ "variable": "${uri}", "conditional": "if", "operator": "starts_with", "argument": "/api/" }]],
  "behaviors": [{ "type": "run_function", "attributes": { "value": <function-instance-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
```

A resposta traz `202` e a regra com seu `order`. `run_function` recebe o ID da instância, não o da função.

Novas regras podem levar alguns minutos para propagar. Diante de uma resposta inesperada, aguarde e tente de novo antes de diagnosticar.

Para rotear cada método e caminho para sua própria função, crie uma função e uma instância por rota, como mostra o procedimento anterior. Depois dê a cada rota sua própria regra. Uma regra que corresponde a um método une `${request_method}` ao critério de caminho com `and`:

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

Envie cada objeto para as regras de requisição da aplicação, como mostra o painel API. Essas duas regras substituem as rotas do API Gateway `GET /users/{id}` e `POST /users`. Adicione uma regra do mesmo formato para `PUT /users/{id}` e `DELETE /users/{id}`. Para declarar as mesmas funções, instâncias e regras como código, consulte [azion.config.js](/pt-br/documentacao/devtools/cli/azion-config-js/).

### Mova um authorizer para uma função do firewall

Um Lambda authorizer retorna uma política IAM que permite ou nega a chamada:

```javascript
// Before: AWS Lambda authorizer
exports.handler = async (event) => {
  const token = event.authorizationToken;
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    return {
      principalId: decoded.sub,
      policyDocument: {
        Version: '2012-10-17',
        Statement: [{ Action: 'execute-api:Invoke', Effect: 'Allow', Resource: event.methodArn }]
      }
    };
  } catch (err) {
    throw new Error('Unauthorized');
  }
};
```

Na Azion, uma função em um [firewall](/pt-br/documentacao/plataforma/firewall/) decide antes de a aplicação rodar. Toda função em um firewall precisa terminar com um desfecho final: `event.continue()` deixa a requisição seguir, e `event.deny()` responde `403 Forbidden`. Esta função deixa passar apenas as requisições que trazem o bearer token esperado:

```javascript
addEventListener('firewall', (event) => {
  const authHeader = event.request.headers.get('Authorization') || '';
  const token = authHeader.replace('Bearer ', '');
  if (token !== '' && token === Azion.env.get('API_TOKEN')) {
    event.continue();
  } else {
    event.deny();
  }
});
```

Coloque a verificação que seu authorizer faz, como uma checagem de JWT, no lugar da comparação. Uma requisição sem um token válido recebe `403`. Para responder `401`, chame `event.respondWith(new Response('Unauthorized', { status: 401 }))`.

A função precisa do ambiente de execução `firewall`: `execution_environment` na API ou `--execution-environment` na Azion CLI. Um firewall com o módulo **Functions** a executa por meio de uma instância e de uma regra com *Run Function*. Para os passos, consulte [Functions para Firewall](/pt-br/documentacao/plataforma/firewall/functions/) e [Instâncias de funções](/pt-br/documentacao/plataforma/firewall/functions-instances/).

---

## Substitua Step Functions e EventBridge

A Azion não tem um serviço de orquestração de workflows nem um barramento de eventos. Um workflow do Step Functions vira um código que chama cada passo em sequência dentro de uma função. Uma regra do EventBridge vira uma rota de função que o produtor do evento chama por HTTP.

| Aspecto               | AWS Step Functions           | Azion Functions                                                                   |
| --------------------- | ---------------------------- | --------------------------------------------------------------------------------- |
| Definição do workflow | Amazon States Language       | JavaScript                                                                        |
| Estado                | State machine integrada      | Seu código. O estado persistente vai para KV Store ou SQL Database                |
| Tratamento de erros   | Retry, catch e fallback      | `try` e `catch`                                                                   |
| Visualização          | Workflow Studio              | O código                                                                          |
| Limites               | Definidos pela state machine | 50 chamadas de saída, 2 s de tempo de CPU e 5 minutos de tempo real por invocação |

| Aspecto               | Amazon EventBridge          | Azion                                                              |
| --------------------- | --------------------------- | ------------------------------------------------------------------ |
| Roteamento de eventos | Regras e targets            | Uma regra da aplicação que executa uma função no caminho do evento |
| Padrões de eventos    | Correspondência de padrões  | Condições no código da função                                      |
| Targets               | Mais de 100 serviços da AWS | Endpoints HTTP que a função chama com `fetch()`                    |

Esta definição do Step Functions valida um pedido, faz a cobrança e o atende, com um ramo de falha:

```json
{
  "Comment": "Order processing workflow",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789:function:validate-order", "Next": "ProcessPayment" },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789:function:process-payment",
      "Catch": [{ "ErrorEquals": ["PaymentFailed"], "Next": "NotifyFailure" }],
      "Next": "FulfillOrder"
    },
    "FulfillOrder": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789:function:fulfill-order", "End": true },
    "NotifyFailure": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789:function:notify-failure", "End": true }
  }
}
```

O mesmo fluxo roda como uma função. Cada passo é uma chamada de função, e o bloco `catch` segue o ramo de falha:

```javascript
async function validateOrder(order) {
  if (!order.items || order.items.length === 0) {
    throw new Error('Invalid order: no items');
  }
  return { ...order, validated: true };
}

async function processPayment(order) {
  const response = await fetch('https://payment-api.example.com/charge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ amount: order.total, currency: 'USD' })
  });
  if (!response.ok) {
    throw new Error('PaymentFailed');
  }
  return { ...order, paid: true };
}

async function fulfillOrder(order) {
  return { ...order, fulfilled: true, fulfilledAt: new Date().toISOString() };
}

async function notifyFailure(details) {
  await fetch('https://notifications.example.com/failure', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(details)
  });
}

export default {
  async fetch(request, env, ctx) {
    const order = await request.json();
    try {
      const validated = await validateOrder(order);
      const payment = await processPayment(validated);
      const fulfillment = await fulfillOrder(payment);
      return new Response(JSON.stringify(fulfillment), {
        headers: { 'Content-Type': 'application/json' }
      });
    } catch (error) {
      await notifyFailure({ order, error: error.message });
      return new Response(JSON.stringify({ error: error.message }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' }
      });
    }
  }
};
```

Um workflow que espera por horas, ou que precisa sobreviver a uma invocação com falha, não cabe em uma invocação. Mantenha seu estado no [KV Store](/pt-br/documentacao/plataforma/kv-store/) ou no [SQL Database](/pt-br/documentacao/plataforma/sql-database/) e deixe cada chamada avançar um passo.

Uma regra do EventBridge corresponde a eventos por origem, tipo e conteúdo:

```json
{
  "source": ["com.mycompany.orders"],
  "detail-type": ["OrderCreated"],
  "detail": { "amount": [{ "numeric": [">", 100] }] }
}
```

Na Azion, o produtor envia os eventos para uma rota de função, e a função aplica o padrão:

```javascript
async function processHighValueOrder(data) {
  await fetch('https://orders.example.com/high-value', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
}

export default {
  async fetch(request, env, ctx) {
    const events = await request.json();
    for (const event of events) {
      if (event.source === 'com.mycompany.orders' && event.type === 'OrderCreated' && event.data.amount > 100) {
        await processHighValueOrder(event.data);
      }
    }
    return new Response('OK');
  }
};
```

A função responde `OK` depois de tratar cada evento do lote. [Data Stream](/pt-br/documentacao/plataforma/data-stream/) não substitui o barramento: ele envia apenas os logs da própria Azion, de Activity History, Applications, Functions e WAF Events.

---

## Recrie distribuições do CloudFront

Uma distribuição do CloudFront guarda as origens, os comportamentos de cache, o certificado e os domínios em um único recurso. Na Azion, um [connector](/pt-br/documentacao/plataforma/connectors/) guarda cada origem, uma aplicação guarda as regras e o cache, e um workload guarda os domínios e o certificado.

| Aspecto                   | AWS CloudFront                   | Azion                                                                                   |
| ------------------------- | -------------------------------- | --------------------------------------------------------------------------------------- |
| Configuração              | XML ou JSON no CloudFormation    | Azion Console, a API, a Azion CLI ou `azion.config.js`                                  |
| Origens                   | S3, ALB e origens personalizadas | Connectors do tipo `http`, `storage` para um bucket do Object Storage, ou `live_ingest` |
| Comportamentos            | Cache behaviors por caminho      | Regras com critérios e *Set Connector* para escolher a origem                           |
| Certificados              | ACM, apenas em us-east-1         | Certificate Manager, no workload                                                        |
| Funções                   | Lambda\@Edge, em 4 triggers      | Functions, em regras da Request Phase                                                   |
| Response headers policies | Headers de segurança e de CORS   | Regras da Response Phase com *Add Request Header*                                       |

Uma nova aplicação tem Cache e Functions ativados, e Application Accelerator e Image Processor desativados. Uma regra com *Set Connector* envia as requisições a que ela corresponde para um connector. Quando várias regras correspondentes trazem *Set Connector*, apenas a última roda, então mantenha uma regra por caminho depois da regra genérica.

**Console**

Para recriar uma origem e seu comportamento no Azion Console:

1. **Abra a página Connectors**

   Acesse [Azion Console](https://console.azion.com/) > **Connectors**. A página **Create Connector** abre a partir dela.

2. **Dê um nome ao connector**

   Em **General**, informe um **Name**. Por exemplo: `api-origin`.

3. **Selecione o tipo**

   Em **Connector Type**, selecione *HTTP* para um servidor ou *Object Storage* para um bucket.

4. **Informe a origem**

   Para *HTTP*, informe o host da origem em **Address**, sem protocolo nem porta. Em **Host**, informe o nome pelo qual a origem responde.

5. **Selecione Create**

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

   Vá para **Applications**, selecione a aplicação e selecione a aba **Rules Engine**.

7. **Crie a regra**

   Selecione **+ Rule**, informe um **Name** e selecione *Request Phase*. Defina o critério `${uri}` *starts with* `/api/`.

8. **Selecione o connector**

   Em **Behaviors**, selecione *Set Connector* e o connector. Selecione **Save**.

As requisições cujo caminho começa com `/api/` chegam à origem do connector. Para a cadeia completa, consulte [Primeiros passos com Applications](/pt-br/documentacao/plataforma/applications/primeiros-passos/) e [Primeiros passos com Connectors](/pt-br/documentacao/plataforma/connectors/primeiros-passos/).

**CLI**

Para criar o connector com Azion CLI, salve o corpo do painel da API como `connector.json` e execute:

```bash
azion create connector --type http --file connector.json
```

```text
Created Connector with ID <connector-id>
```

Crie a regra de *Set Connector* a partir de um arquivo com `azion create rules-engine`, como mostra [Primeiros passos com Connectors](/pt-br/documentacao/plataforma/connectors/primeiros-passos/).

**API**

Para criar a aplicação, envie uma requisição `POST` para o endpoint de aplicações:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{"name": "my-app", "active": true}'
```

A resposta traz o `id` da aplicação e seus `modules`. Depois crie o connector:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/connectors \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "api-origin",
  "type": "http",
  "attributes": {
    "addresses": [{ "address": "origin.example.com" }],
    "connection_options": { "transport_policy": "force_https", "host": "origin.example.com" }
  }
}'
```

A resposta traz `202` e o `id` do connector. Envie uma regra de requisição com `{ "type": "set_connector", "attributes": { "value": <connector-id> } }` para `/v4/workspace/applications/<application-id>/request_rules`. As configurações de cache são um recurso separado, tratado em Recrie as configurações de cache.

Uma mudança de connector chega à infraestrutura da Azion em alguns minutos, sem um novo deployment. Para servir um prefixo de bucket com cache de um dia e enviar `/api/` para uma função sem cache, a distribuição usa estes recursos:

- Um connector do tipo `storage` com o bucket e o prefixo, como `assets/`. O build recusa um connector `storage` sem `prefix`.
- Uma configuração de cache com TTL de navegador de 3.600 segundos, TTL de cache de 86.400 segundos, stale cache ativado, Tiered Cache desativado e nenhuma variação por cookie ou query string.
- Uma regra de requisição em `${uri}` *starts with* `/` com *Set Connector* e *Set Cache Policy*.
- Uma regra de requisição em `${uri}` *starts with* `/api/` com *Bypass Cache* e *Run Function*.

`bypass_cache` e `run_function` requerem Application Accelerator. *Bypass Cache* não altera o cache do navegador nem o Tiered Cache. Para declarar esses recursos como código, consulte [azion.config.js](/pt-br/documentacao/devtools/cli/azion-config-js/).

Para adicionar os headers de segurança ou os headers de CORS de uma response headers policy, crie uma regra da Response Phase com `add_response_header`. Seu valor tem o formato `Name: value`, como `Access-Control-Allow-Origin: https://example.com` ou `Access-Control-Allow-Methods: GET, POST`. A regra não adiciona nada a um `404` que a Azion gera sem origem.

O origin access control do CloudFront mantém uma origem S3 privada. Na Azion, [Origin Shield](/pt-br/documentacao/plataforma/connectors/origin-shield/origin-ip-acl-e-hmac/) em um connector `http` faz o mesmo com Origin IP ACL e HMAC. O HMAC assina cada requisição com `aws4_hmac_sha256`, uma região, um serviço e um par de chaves. Para um bucket na sua conta Azion, use um connector `storage`.

---

## Recrie as configurações de cache

Na Azion, uma [configuração de cache](/pt-br/documentacao/plataforma/applications/cache/cache-settings/) define por quanto tempo uma resposta fica em cache e o que faz duas requisições compartilharem uma cópia em cache. Uma regra com *Set Cache Policy* aplica a configuração às requisições a que corresponde. A regra seleciona uma configuração, e a configuração guarda o TTL e a chave de cache.

| Aspecto         | AWS CloudFront                                          | Azion                                                                                                       |
| --------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Níveis de cache | Caches regionais e os caches de cada site do CloudFront | Cache, [Tiered Cache](/pt-br/documentacao/plataforma/applications/cache/tiered-cache/) e cache do navegador |
| Chave de cache  | Cache policy e origin request policy                    | Controles **Cache vary by** da configuração de cache, que requerem Application Accelerator                  |
| TTL             | Padrão de 24h, máximo de 1 ano                          | **Max Age** de cada configuração de cache, de 0 a 31.536.000 segundos                                       |
| Purge           | Invalidações por caminho                                | URL, chave de cache e wildcard                                                                              |
| Conteúdo stale  | Origin Shield e `stale-while-revalidate`                | **Stale cache**, que entrega uma cópia expirada quando a revalidação falha                                  |

Associe cada managed cache policy do CloudFront a uma configuração ou a um comportamento:

| Cache policy do CloudFront | Equivalente na Azion                                                                                                                                     |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CachingOptimized           | Uma configuração de cache com *Override cache behavior* e um **Max Age** alto                                                                            |
| CachingDisabled            | O comportamento *Bypass Cache* em uma regra da Request Phase                                                                                             |
| Elemental-MediaPackage     | *Enforce HLS cache*, que a Azion adiciona quando você seleciona uma fonte Live Ingest: 5 segundos para playlists `.m3u8` e 60 segundos para chunks `.ts` |
| Uma política personalizada | Uma configuração de cache e uma regra com *Set Cache Policy*                                                                                             |

**Max Age** tem padrão de 60 segundos. Um valor abaixo de 60 requer Application Accelerator, e uma configuração de cache com Tiered Cache ativado precisa de pelo menos 3 segundos e de *Override cache behavior*. **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 por padrão no Azion Console e desativado na API e na CLI.

**Console**

Para criar a configuração de 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 `static-assets`.

5. **Mantenha Override cache behavior selecionado**

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

6. **Defina Max Age**

   Em **Max Age**, informe o TTL em segundos. Por exemplo: `300`.

7. **(Opcional) Ative Tiered Cache**

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

8. **Selecione Save**

A nova configuração aparece na lista **Cache Settings**. Para aplicá-la, crie uma regra da Request Phase na aba **Rules Engine**. Use critérios como `${uri}` *starts with* `/static/` e o comportamento **Set Cache Policy** definido como `static-assets`.

**CLI**

As flags da CLI não definem o TTL do cache, o comportamento do cache nem Tiered Cache. Envie o corpo completo da configuração de cache a partir de um arquivo com `--file`, como mostra [Primeiros passos com Cache](/pt-br/documentacao/plataforma/applications/cache/primeiros-passos/).

**API**

Para criar a configuração de cache, envie uma requisição `POST` para as 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 '{
  "name": "static-assets",
  "browser_cache": { "behavior": "override", "max_age": 3600 },
  "modules": {
    "cache": {
      "behavior": "override",
      "max_age": 86400,
      "stale_cache": { "enabled": true },
      "tiered_cache": { "enabled": true, "topology": "nearest-region" }
    }
  }
}'
```

As configurações de cache são sub-recursos de uma aplicação. Para alterar uma, envie os mesmos campos em uma requisição `PATCH` para `/v4/workspace/applications/<application-id>/cache_settings/<cache-setting-id>`. Depois aplique a configuração com uma regra de requisição:

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

A regra aplica `static-assets` a toda requisição cujo caminho começa com `/static/`.

Para variar o cache por query string, cookie ou dispositivo, use os controles **Cache vary by** da configuração de cache: **Cache vary by Query String**, **Cache vary by Cookies** e **Cache vary by Devices**. Eles requerem Application Accelerator na aplicação. No `azion.config.js`, uma configuração de cache que varia apenas pelos parâmetros `version` e `lang` traz `cacheByQueryString: { option: 'allowlist', list: ['version', 'lang'] }`. As opções são `ignore`, `all`, `allowlist` e `denylist`. Para os controles, consulte [Variação de cache](/pt-br/documentacao/plataforma/applications/application-accelerator/variacao-de-cache/).

Uma invalidação do CloudFront indica uma distribuição e caminhos:

```bash
aws cloudfront create-invalidation \
  --distribution-id E123456789ABCD \
  --paths "/images/*" "/css/*"
```

Na Azion, o purge é um endpoint de nível superior, não aninhado em uma aplicação. Um purge por wildcard recebe uma expressão, então cada padrão de caminho é uma requisição própria:

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

Envie uma segunda requisição com `https://example.com/css/*`. Um purge por URL, em `/v4/workspace/purge/url`, aceita até 50 itens. Apenas um purge por chave de cache, em `/v4/workspace/purge/cachekey`, alcança o Tiered Cache com `"layer": "tiered_cache"`. Um purge por URL ou por wildcard com essa camada falha com `30001`. Um purge leva tempo para propagar e aparece no histórico de purges quando termina. Para verificar um objeto purgado, solicite-o com `curl -I` e leia os headers da resposta. Para os tipos de purge, consulte [Real-Time Purge](/pt-br/documentacao/plataforma/applications/cache/real-time-purge/).

---

## Balanceie o tráfego entre origens

Na Azion, [Load Balancer](/pt-br/documentacao/plataforma/connectors/load-balancer/metodos-de-balanceamento/) é um módulo de um connector, não um recurso separado. Um connector do tipo `http` guarda cada origem como um endereço, até 15 endereços com Load Balancer ativado e um endereço sem ele. Uma regra com *Set Connector* envia as requisições da aplicação para o connector.

| Aspecto                  | AWS ALB e NLB                                 | Azion Load Balancer                                                                                                                             |
| ------------------------ | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Métodos de balanceamento | Round-robin, least connections e IP hash      | *Round Robin*, *Least Connections* e *IP Hash*, que são `round_robin`, `least_conn` e `ip_hash` na API. Nenhum método direciona por localização |
| Health checks            | HTTP, HTTPS e TCP                             | Nenhum. O failover é passivo: **Max Retries** e os timeouts tratam uma conexão com falha                                                        |
| Failover                 | Failover de target group                      | Vários endereços *Primary* com pesos e endereços *Backup* que recebem tráfego apenas quando todos os primários falham                           |
| Afinidade de sessão      | Cookie e hash de IP                           | Apenas *IP Hash*, que associa cada endereço IP de cliente a um endereço                                                                         |
| Targets                  | Instâncias EC2, funções Lambda e endereços IP | Endereços de um connector                                                                                                                       |
| Protocolo                | Camada 4 para NLB, camada 7 para ALB          | Origens HTTP e HTTPS, em connectors do tipo `http`                                                                                              |

Um target group do ALB vira um connector. O caminho, o intervalo e os limites de saudável e não saudável do seu health check não têm campo equivalente.

Cada endereço tem um **Weight** de 1 a 100, que define sua parcela do tráfego. *IP Hash* recusa endereços *Backup*, com `28005` na API. **Max Retries** aceita de 0 a 20, **Connection Timeout** de 1 a 300 segundos e **Read/Write Timeout** de 1 a 600 segundos. Esses campos existem apenas com Load Balancer ativado. Quando você o ativa no Azion Console, o formulário preenche *Round Robin*, `3`, `30` e `60`. Os padrões da API são `0`, `60` e `120`.

**Console**

Para ativar Load Balancer no Azion Console:

1. **Abra a página Connectors**

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

2. **Abra o connector da origem**

3. **Ative Load Balancer**

   Em **Modules**, ative **Load Balancer**.

4. **Selecione o método de balanceamento**

   Em **Load Balancer Configuration**, defina **Method** como *Round Robin*, *Least Connections* ou *IP Hash*.

5. **Configure o primeiro endereço**

   Em **Address Management**, no endereço existente, defina **Server Role** e **Weight**.

6. **Selecione Add Address**

7. **Informe a próxima origem**

   No novo **Address**, informe o host da origem, sem protocolo nem porta. Depois defina seu **Server Role** e seu **Weight**.

8. **Selecione Save**

O Console mostra `Connector has been updated`. O connector tem Load Balancer ativado e um endereço para cada origem.

**CLI**

O comando de atualização precisa do corpo completo do connector. Coloque-o em um arquivo JSON e envie-o com `--file`, como mostra [Primeiros passos com Load Balancer](/pt-br/documentacao/plataforma/connectors/load-balancer/primeiros-passos/).

**API**

Para ativar Load Balancer, envie uma requisição `PATCH` para o connector. O endereço traz `server_role` e `weight`, e o método, as tentativas e os timeouts ficam em `attributes.modules.load_balancer.config`:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/connectors/<connector-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "attributes": {
    "addresses": [
      { "address": "us-east-origin1.example.com", "active": true, "modules": { "load_balancer": { "server_role": "primary", "weight": 3 } } },
      { "address": "us-east-origin2.example.com", "active": true, "modules": { "load_balancer": { "server_role": "primary", "weight": 1 } } }
    ],
    "modules": {
      "load_balancer": {
        "enabled": true,
        "config": { "method": "round_robin", "max_retries": 3, "connection_timeout": 10, "read_write_timeout": 30 }
      }
    }
  }
}'
```

A resposta traz `"state": "pending"`. Dois endereços com Load Balancer desativado são recusados com `28004`, e `"enabled": true` com um `config` vazio é recusado com `28014`. `"active": false` tira um endereço da rotação.

Um connector sem Load Balancer não tem timeout configurável. Se uma origem atingir o timeout, verifique o endereço e suas portas e ative Load Balancer para definir os timeouts. Para os campos do connector, consulte [Configurações de connectors](/pt-br/documentacao/plataforma/connectors/configuracoes/).

---

## Entregue imagens otimizadas

Na AWS, transformações de imagem geralmente precisam de Lambda\@Edge ou de uma origem personalizada. [Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/) redimensiona, recorta, converte e aplica filtros a imagens sob demanda, sem código. Ele não armazena nada: lê a imagem de origem da origem da aplicação, que pode ser um bucket do Object Storage atrás de um connector.

| Aspecto        | AWS CloudFront e Lambda\@Edge     | Azion Image Processor                                                                                                                   |
| -------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Armazenamento  | Uma origem S3                     | A origem da aplicação, como Object Storage                                                                                              |
| Transformações | Código Lambda\@Edge personalizado | Redimensionamento, formato, qualidade, recorte, rotação, preenchimento e marca d'água                                                   |
| Formato da URL | Uma implementação personalizada   | `/image.png?ims=<OPTIONS>`                                                                                                              |
| Formatos       | Uma implementação personalizada   | WebP, AVIF, JPEG, GIF e PNG                                                                                                             |
| URLs assinadas | Signed URLs do CloudFront         | Por meio da integração [Secure Token](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/secure-token/) em um firewall |

Image Processor funciona em dois passos: ative o módulo na aplicação e depois crie uma regra com o comportamento *Optimize Images*. Uma requisição que nenhuma regra desse tipo atende é entregue sem processamento.

**Console**

Para ativar 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**. Para mais informações, consulte [Main Settings](/pt-br/documentacao/plataforma/applications/main-settings/).

3. **Selecione Save**

4. **Adicione a regra Optimize Images**

   Na aba **Rules Engine**, crie uma regra da Request Phase com `${uri}` *matches* `\.(jpg|jpeg|gif|bmp|png|ico|webp|avif)` e o comportamento *Optimize Images*.

As requisições de imagem que atendem à regra agora são processadas.

**CLI**

Para ativar Image Processor com Azion CLI, siga o painel CLI de [Primeiros passos com Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/).

**API**

Para ativar o módulo, envie uma requisição `PATCH` para a aplicação. `image_processor` fica em `modules`, no nível da 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 }
  }
}'
```

Depois crie uma regra de requisição com o comportamento `optimize_images`, como mostra [Primeiros passos com Image Processor](/pt-br/documentacao/plataforma/applications/image-processor/primeiros-passos/).

Image Processor lê a transformação do parâmetro de query `ims`:

```text
# AWS, com uma implementação personalizada em Lambda@Edge
https://d12345.cloudfront.net/images/photo.jpg?w=400&q=80

# Azion
https://example.com/images/photo.jpg?ims=400x/filters:quality(80)
```

| 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 converte para WebP quando o header `Accept` do cliente permite. AVIF precisa de `?ims=filters:format(avif)` e de um cliente que aceite `image/avif`. Para manter em cache uma cópia para cada valor de `ims`, ative Application Accelerator e varie o cache por query string. Para cada parâmetro, consulte [Parâmetros de URL](/pt-br/documentacao/plataforma/applications/image-processor/parametros-de-url/).

---

## Mova Bedrock para AI Inference

[AI Inference](/pt-br/documentacao/plataforma/ai-inference/) executa um catálogo de [modelos](/pt-br/documentacao/plataforma/ai-inference/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()` e não precisa de credencial.

| Aspecto         | Amazon Bedrock                                                                | Azion AI Inference                                                                   |
| --------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Modelos         | Modelos de fundação gerenciados, como Claude, Llama, Titan e Stable Diffusion | Um catálogo de modelos open source. Para adaptar um modelo, use fine-tuning com LoRA |
| Interface       | Bedrock Runtime API                                                           | `Azion.AI.run()` dentro de uma função                                                |
| Tipos de modelo | Modelos de texto, imagem e embedding                                          | LLMs, vision language models, um modelo de embedding e um reranker                   |
| Cobrança        | Por token ou por imagem                                                       | Compute Time e Requests                                                              |

Uma chamada ao Bedrock indica um modelo e envia um corpo específico do provedor:

```javascript
// Before: Amazon Bedrock
import { BedrockRuntime } from '@aws-sdk/client-bedrock-runtime';

const client = new BedrockRuntime({ region: 'us-east-1' });

const response = await client.invokeModel({
  modelId: 'anthropic.claude-3-sonnet-20240229-v1:0',
  contentType: 'application/json',
  accept: 'application/json',
  body: JSON.stringify({
    anthropic_version: 'bedrock-2023-05-31',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Hello, world!' }]
  })
});
```

Na Azion, a função passa o ID do modelo e um corpo de chat:

```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
```

`answer` guarda o texto da resposta. Campos como `max_tokens` e `temperature` moldam a saída. 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/).

Para um endpoint `/v1/chat/completions` compatível com OpenAI, 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. Para fazer o deploy, acesse [Azion Console](https://console.azion.com/) > **Create**, selecione o template e selecione **Deploy**. Azion CLI não tem flag de template.

---

## Mova dados chave-valor do DynamoDB para KV Store

O DynamoDB atende dados chave-valor e de documentos. Buscas por chave, sessões, feature flags e configurações vão para o [KV Store](/pt-br/documentacao/plataforma/kv-store/). Consultas com filtros, índices secundários, agregações e joins vão para o SQL Database, na etapa Mova consultas do DynamoDB e bancos de dados RDS para SQL Database.

| Aspecto         | Amazon DynamoDB                   | Azion KV Store                                                             | Azion SQL Database                            |
| --------------- | --------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------- |
| Modelo de dados | Chave-valor e documentos          | Chave-valor                                                                | Relacional, no dialeto do SQLite              |
| Consultas       | Buscas por chave, queries e scans | Buscas por chave                                                           | SQL completo                                  |
| Replicação      | Global tables entre Regions       | Infraestrutura distribuída da Azion                                        | Uma instância principal e réplicas de leitura |
| Consistência    | Eventual ou forte                 | Eventual. Uma gravação fica visível em todos os lugares em até 60 segundos | ACID                                          |
| Índices         | GSI e LSI                         | Nenhum                                                                     | Índices SQL                                   |
| Capacidade      | Sob demanda ou provisionada       | Serverless                                                                 | Serverless                                    |

| Uso do DynamoDB                  | Destino na Azion |
| -------------------------------- | ---------------- |
| Buscas por chave primária        | KV Store         |
| Operações chave-valor simples    | KV Store         |
| Armazenamento de sessões         | KV Store         |
| Feature flags e configurações    | KV Store         |
| Consultas com filtros            | SQL Database     |
| Consultas em índices secundários | SQL Database     |
| Agregações e joins               | SQL Database     |
| Dados relacionais                | SQL Database     |

As global tables do DynamoDB resolvem conflitos com last writer wins e cobram por cada gravação replicada. KV Store não tem Region para escolher: uma gravação se aplica onde chega, e as outras partes da infraestrutura convergem em até 60 segundos.

Uma função abre um namespace com `Azion.KV.open()`, um global do runtime que não precisa de linha de import:

```javascript diff
-// Before: DynamoDB
-// const result = await dynamodb.getItem({ TableName: 'Users', Key: { userId: { S: '123' } } }).promise();
-// await dynamodb.putItem({ TableName: 'Users', Item: { userId: { S: '123' }, name: { S: 'John' } } }).promise();
 
+// After: Azion
+const kv = await Azion.KV.open('my-namespace');
+await kv.put('user:123', { name: 'John' }, { expirationTtl: 3600 });
+const userData = await kv.get('user:123', 'json');
```

`put` serializa um objeto em JSON, e `get` com `'json'` o converte de volta. `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 importação em massa, e nenhuma API, comando da CLI ou tela do Console lê ou grava chaves. Para mover os dados:

1. Exporte a tabela da AWS:

   ```bash
   aws dynamodb export-table-to-point-in-time \
     --table-name Users \
     --s3-bucket my-export-bucket \
     --export-format DYNAMODB_JSON
   ```

2. Transforme cada item em uma chave e um valor.

3. Crie o namespace com uma requisição `POST` para `https://api.azion.com/v4/workspace/kv/namespaces`, com `{"name": "my-namespace"}`. O nome aceita de 3 a 63 caracteres, diferencia maiúsculas de minúsculas e é permanente: um namespace não pode ser renomeado nem excluído. Para os campos e os erros, consulte [Namespaces](/pt-br/documentacao/plataforma/kv-store/namespaces/).

4. Grave as chaves a partir de uma função em produção com `kv.put()`.

A função grava uma 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. Associe cada TTL do DynamoDB à opção `expiration`, em segundos Unix, ou a `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. Antes da importação, revise os prefixos das chaves, os formatos dos valores e o código que trata uma chave inexistente. Para o cliente, consulte [API de runtime do KV Store](/pt-br/documentacao/devtools/runtime/api-reference/kv-store/).

---

## Substitua o ElastiCache

O ElastiCache mantém dados em memória, atrás de Redis ou Memcached. Na Azion, as respostas HTTP ficam no Cache, e os valores que uma função lê e grava vão para o KV Store.

| Aspecto             | Amazon ElastiCache                         | Azion Cache                | Azion KV Store                                                           |
| ------------------- | ------------------------------------------ | -------------------------- | ------------------------------------------------------------------------ |
| Tipo                | Cache em memória                           | Cache HTTP                 | Armazenamento chave-valor distribuído                                    |
| Engines             | Redis e Memcached                          | Respostas HTTP             | `Azion.KV`, de dentro de uma função                                      |
| Persistência        | Opcional, com Redis AOF ou RDB             | Expira com **Max Age**     | Persiste até a chave expirar ou ser excluída                             |
| Estruturas de dados | Strings, hashes, lists, sets e sorted sets | Respostas HTTP             | Um valor por chave: uma string, um objeto, um `ArrayBuffer` ou um stream |
| Replicação          | Cluster mode e replication groups          | Tiered Cache               | Infraestrutura distribuída da Azion                                      |
| Acesso              | Conexão TCP                                | Requisição e resposta HTTP | API de runtime                                                           |

`put` recusa um `Map`, um `Set`, um `WeakMap`, um `WeakSet`, um `RegExp` e um `SharedArrayBuffer` com `INVALID_VALUE_TYPE`. Converta-os em arrays antes.

| Uso do ElastiCache                   | Destino na Azion  |
| ------------------------------------ | ----------------- |
| Cache de respostas HTTP              | Cache             |
| Armazenamento de sessões             | KV Store          |
| Contadores de rate limit             | KV Store          |
| Feature flags                        | KV Store          |
| Cache de consultas ao banco de dados | Cache e Functions |
| Mensageria Pub/Sub                   | -                 |
| Leaderboards e sorted sets           | SQL Database      |
| Estruturas de dados complexas        | SQL Database      |

Os comandos do Redis viram chamadas ao KV Store:

```javascript diff
 const kv = await Azion.KV.open('sessions');
 const sessionData = { userId: 42, cart: [] };
 
 // Redis SET with expiration
-await redis.set('session:abc123', JSON.stringify(sessionData), 'EX', 3600);
+await kv.put('session:abc123', sessionData, { expirationTtl: 3600 });
 
 // Redis GET
-const data = await redis.get('session:abc123');
+const data = await kv.get('session:abc123', 'json');
 
 // Redis DEL
-await redis.del('session:abc123');
+await kv.delete('session:abc123');
```

`delete` resolve existindo a chave ou não. Para cache HTTP, consulte Recrie as configurações de cache e [Cache settings](/pt-br/documentacao/plataforma/applications/cache/cache-settings/).

---

## Mova buckets do S3 para Object Storage

[Object Storage](/pt-br/documentacao/plataforma/object-storage/) guarda imagens, documentos, assets estáticos, mídia, uploads e arquivos gerados. Ele fala o protocolo S3, então ferramentas e SDKs S3 o alcançam com um novo endpoint, uma região e um par de chaves.

| Aspecto                  | Amazon S3                               | Azion Object Storage                                                                                                                                     |
| ------------------------ | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Endpoint                 | `https://s3.amazonaws.com/bucket`       | `https://s3.us-east-005.azionstorage.net`                                                                                                                |
| Região                   | Várias regiões                          | `us-east-005`                                                                                                                                            |
| Transferência de dados   | Cobrada por GB                          | Sem cobrança de transferência de dados no Object Storage. A entrega aos usuários passa por um workload, cobrada como transferência de dados de Workloads |
| Classes de armazenamento | Standard, Intelligent-Tiering e Glacier | -                                                                                                                                                        |
| Buckets por conta        | 100 por padrão                          | 100                                                                                                                                                      |

O par de chaves vem de uma credencial do Object Storage. A `secret_key` só volta na resposta de criação, então guarde-a nesse momento. Para migrar, a credencial precisa de pelo menos `listBuckets`, `listFiles` e `writeFiles`, além de `listAllBucketNames` para listar os buckets. `deleteFiles` requer `writeFiles`.

**Console**

Para criar a credencial no Azion Console, use **Create Credential** no Object Storage. Selecione as capabilities **List Files**, **Read Files**, **Write Files**, **List All Bucket Names** e **List Buckets** e depois guarde as chaves que ele mostra.

**CLI**

A Azion CLI cria os buckets de destino. Para os comandos, consulte [Crie e modifique um bucket](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/criar-e-modificar-um-bucket/). Crie a credencial no Azion Console ou pela API.

**API**

Para criar a credencial, envie uma requisição `POST` para o endpoint de credenciais:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/storage/credentials \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "migration-credential",
  "capabilities": ["listFiles", "readFiles", "writeFiles", "listAllBucketNames", "listBuckets"],
  "buckets": ["my-bucket"]
}'
```

A resposta traz `201`, a `access_key` e a `secret_key`. Sem `buckets`, a credencial alcança todos os buckets da conta.

Um script de migração em Node.js alcança Object Storage com o AWS SDK. Apenas a região, o endpoint e as chaves mudam:

```javascript diff
 import { S3Client } from '@aws-sdk/client-s3';
 
-// Before: Amazon S3
-const awsClient = new S3Client({
-  region: 'us-east-1',
-  credentials: {
-    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
-    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
-  }
-});
 
+// After: Azion Object Storage
+const azionClient = 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
+  }
+});
```

Crie o bucket de destino antes de copiar, no Azion Console, na API ou na CLI. Ferramentas S3 não criam nem removem um bucket na Azion: `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`.

Para copiar os dados com o [s3cmd](https://s3tools.org/s3cmd):

1. Execute `s3cmd --configure -c ~/.s3cfg-azion` e informe estes valores:

   - **Access Key** e **Secret Key**: o par de chaves da credencial.
   - **Default Region**: `us-east-005`.
   - **S3 Endpoint**: `s3.us-east-005.azionstorage.net`.
   - **DNS-style bucket+hostname:port template**: `%(bucket).s3.us-east-005.azionstorage.net`.
   - **Use HTTPS protocol**: `true`.

2. Configure um segundo arquivo, `~/.s3cfg-aws`, com as chaves da conta AWS. Uma configuração do s3cmd guarda um endpoint.

3. Baixe os objetos do S3:

   ```bash
   s3cmd -c ~/.s3cfg-aws sync s3://aws-bucket/ ./export/
   ```

4. Envie-os para a Azion:

   ```bash
   s3cmd -c ~/.s3cfg-azion sync ./export/ s3://azion-bucket/
   ```

Os objetos estão no bucket da Azion. Para verificar, liste-os com `s3cmd -c ~/.s3cfg-azion ls s3://azion-bucket/`. `s3cmd ls` sem bucket lista todos os buckets, o que exige `listAllBucketNames`. `s3cmd put file.png s3://my-bucket/` envia um objeto, e `s3cmd get s3://my-bucket/file.png` baixa um.

A AWS CLI alcança a Azion por meio de um perfil e de `--endpoint-url`. Um comando alcança um endpoint, então a cópia também passa por uma pasta local:

```bash
aws configure --profile azion
aws s3 ls --profile azion --endpoint-url https://s3.us-east-005.azionstorage.net
aws s3 sync s3://source-bucket/ ./export/
aws s3 sync ./export/ s3://dest-bucket/ --profile azion --endpoint-url https://s3.us-east-005.azionstorage.net
```

No `aws configure`, informe a access key da Azion, a secret key e `us-east-005` como região. O último comando envia a pasta para o bucket da Azion.

O [rclone](https://rclone.org) guarda um remote para cada provedor, então copia do S3 para a Azion em um comando. Crie os remotes com `rclone config`:

- `aws-s3`: storage `s3`, provider `AWS` e `env_auth` definido como `true`.
- `azion`: storage `s3`, provider `Other`, endpoint `https://s3.us-east-005.azionstorage.net` e `acl` definido como `private`.

Depois sincronize:

```bash
rclone sync aws-s3:source-bucket azion:dest-bucket --progress
```

`--progress` exibe a transferência enquanto ela roda. Azion Console recusa um upload individual acima de 300 MB. A API e as ferramentas S3 não estão sujeitas a esse limite. Antes da migração, mapeie os buckets, os prefixos de objetos, os assets públicos e privados, os padrões de acesso e a lógica de URLs assinadas. O acesso do bucket aos workloads é `read_only`, `read_write` ou `restricted`, e uma credencial funciona de forma independente dele. Para as operações S3, consulte [Compatibilidade com S3](/pt-br/documentacao/plataforma/object-storage/compatibilidade-s3/) e [Use ferramentas compatíveis com S3](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/protocolo-s3-para-object-storage/).

### Entregue um bucket por meio de uma aplicação

A entrega pública passa por um connector e uma aplicação, não pelo endpoint S3. Um connector do tipo `storage` lê um bucket da sua conta, restrito a um prefixo.

**Console**

Para criar o storage connector no Azion Console:

1. **Abra a página Connectors**

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

2. **Selecione o tipo Object Storage**

   Na página **Create Connector**, informe um **Name** e selecione *Object Storage* em **Connector Type**.

3. **Selecione o bucket**

   Em *Select a Bucket*, selecione o bucket. Em **Prefix**, informe o prefixo, como `assets/`. O Console o exige.

4. **Selecione Create**

O connector lê o bucket. Envie requisições para ele com uma regra de *Set Connector* na aplicação.

**CLI**

Para criar o connector com Azion CLI, salve o corpo do painel da API como `connector.json` e execute `azion create connector --type storage --file connector.json`. Para os outros campos, consulte [Configurações de connectors](/pt-br/documentacao/plataforma/connectors/configuracoes/#storage).

**API**

Para criar o connector, envie uma requisição `POST` para o endpoint de connectors:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/connectors \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "assets-origin",
  "type": "storage",
  "attributes": { "bucket": "my-bucket", "prefix": "assets/" }
}'
```

A resposta traz `202` e o connector. Um bucket que não existe é recusado com `28007`. Para não guardar prefixo, omita `prefix`: uma string vazia é recusada com `10018`.

Para os buckets e seus objetos, consulte [Crie e modifique um bucket](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/criar-e-modificar-um-bucket/), [Faça upload e download de objetos](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/upload-e-download-de-objetos-do-bucket/), [Use um bucket como origem](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/bucket-como-connector/) e a [biblioteca Storage](/pt-br/documentacao/devtools/azion-lib/storage/).

---

## Mova consultas do DynamoDB e bancos de dados RDS para SQL Database

[SQL Database](/pt-br/documentacao/plataforma/sql-database/) usa o dialeto SQLite e é totalmente compatível com ACID. Uma instância principal recebe todas as gravações, e réplicas de leitura respondem às leituras. SQL Database está em Preview em todos os planos.

| Aspecto                      | Amazon RDS e Aurora                             | Azion SQL Database                                                                                                                                           |
| ---------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Engines                      | MySQL, PostgreSQL, MariaDB, Oracle e SQL Server | Dialeto do SQLite                                                                                                                                            |
| Arquitetura                  | Primária e réplicas de leitura                  | Uma instância principal e réplicas de leitura                                                                                                                |
| Conexão                      | Connection string e connection pooling          | `Database.open()` do global `Azion.Sql`, sem pool para gerenciar                                                                                             |
| Gravações a partir do código | Pela conexão                                    | Pela API. Uma conexão do runtime é somente leitura                                                                                                           |
| Transações                   | ACID                                            | ACID                                                                                                                                                         |
| Escalabilidade               | Escalabilidade vertical e réplicas de leitura   | Arquitetura distribuída                                                                                                                                      |
| Vector search                | Específico de cada engine                       | Suportado, com colunas vetoriais, `libsql_vector_idx` e `vector_top_k`. Consulte [Vector search](/pt-br/documentacao/plataforma/sql-database/vector-search/) |

Uma função lê o banco de dados por meio de uma conexão de réplica somente leitura. `Azion.Sql` é um global, e o import `azion:sql` faz o build falhar. Um parâmetro de consulta precisa ser um número: uma string JavaScript é recusada com ``TypeError: unknown variant `String` ``. Escreva um valor de texto como literal no SQL:

```javascript diff
-// Before: PostgreSQL
-// const result = await pgClient.query('SELECT id, name, email FROM users WHERE status = $1', ['active']);
 
-// Before: DynamoDB query on an index
-// const result = await dynamodb.query({ TableName: 'Orders', IndexName: 'CustomerIdIndex',
-//   KeyConditionExpression: 'customerId = :cid', FilterExpression: 'orderDate > :date' }).promise();
 
+// After: Azion
+const { Database } = Azion.Sql;
+
+const connection = await Database.open('my-database');
+const rows = await connection.query(
+  "SELECT id, name, email FROM users WHERE status = 'active' AND customer_id = ?",
+  [123]
+);
+let row = await rows.next();
+while (row) {
+  const id = row.getString(0);
+  const name = row.getString(1);
+  const email = row.getString(2);
+  row = await rows.next();
+}
```

`rows.next()` retorna a próxima linha, ou `null` depois da última, e `row.getString(i)` lê uma coluna pelo índice. Um `insert` ou `delete` pela conexão falha com `attempt to write a readonly database`. No `azion dev`, `Azion.Sql` é `undefined`, então teste o código em uma função em produção. Para scripts no servidor, o pacote [`@aziontech/sql`](/pt-br/documentacao/devtools/azion-lib/sql/) gerencia bancos de dados pela API.

**Console**

Para criar o banco de dados no Azion Console:

1. **Abra a lista de bancos de dados**

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

2. **Inicie um novo banco de dados**

   Abra o formulário de criação com o controle **SQL Database** da lista.

3. **Dê um nome ao banco de dados**

   Em **General**, no campo **Name**, informe um nome.

4. **Selecione Save**

O banco de dados aparece na lista com o status `creating`, que muda para `created` em cerca de 15 segundos.

**CLI**

A Azion CLI não tem comando para SQL Database. Crie o banco de dados no Azion Console ou pela API.

**API**

Para criar o banco de dados, envie uma requisição `POST` para o endpoint de bancos de dados:

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

A resposta traz `202` e o banco de dados com `"status": "creating"`. Uma criação aceita apenas `name` e `active`. Depois envie o schema no array `statements` de uma requisição `POST` para o endpoint de consulta:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/sql/databases/<database-id>/query \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{"statements": ["CREATE TABLE users (id TEXT PRIMARY KEY, name TEXT, email TEXT, created_at TEXT);"]}'
```

A resposta traz uma entrada em `data` para cada instrução.

Um nome de banco de dados aceita de 6 a 50 caracteres entre letras, números e hífens e não pode mudar depois da criação. Para os passos, consulte [Crie o banco de dados](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/gerenciar-bancos-dados-edge-sql/).

Para mover os dados, exporte-os da AWS. Um banco de dados PostgreSQL é exportado como instruções `INSERT`:

```bash
pg_dump -h my-db.xxxx.region.rds.amazonaws.com \
  -U admin \
  -d mydb \
  --data-only \
  --inserts \
  > export.sql
```

Um cluster Aurora também pode exportar um snapshot para o S3:

```bash
aws rds start-export-task \
  --export-task-identifier my-export \
  --source-arn arn:aws:rds:region:account:cluster:my-aurora-cluster \
  --s3-bucket-name my-export-bucket \
  --export-only data
```

Uma exportação do DynamoDB vira instruções `INSERT` depois que você transforma seus itens. Depois execute as instruções por um destes caminhos:

- **A API**: envie as instruções no array `statements` de uma requisição `POST` para `https://api.azion.com/v4/workspace/sql/databases/<database-id>/query`. Uma chamada aceita 100 instruções. Uma instrução com falha ainda retorna HTTP `200`, com uma chave `error` no lugar de `results`. Quando nada pode ser executado, a requisição retorna `422` com `14005`.
- **O EdgeSQL Shell**: `.read export.sql` executa o script. O shell não inicia em uma instalação limpa, então verifique [EdgeSQL Shell](/pt-br/documentacao/plataforma/sql-database/edgesql-shell/) antes de depender dele. Para instalá-lo, consulte [Instale o SQL Shell](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/install-edge-sql-shell/).

A Azion não tem API de importação. Para os outros formatos de importação, consulte [Importe dados para o SQL Database](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/importar-dados-edge-sql/). Para a API de runtime, consulte [API de runtime do SQL Database](/pt-br/documentacao/devtools/runtime/api-reference/sql-database/).

O `pg_dump` grava tipos do PostgreSQL, e o SQLite guarda cada valor nas suas próprias classes de tipo. Converta os tipos das colunas no schema antes da importação:

| Tipo do PostgreSQL        | Tipo do SQLite                 |
| ------------------------- | ------------------------------ |
| INTEGER, BIGINT, SMALLINT | INTEGER                        |
| SERIAL, BIGSERIAL         | INTEGER, com autoincremento    |
| VARCHAR(n), CHAR(n), TEXT | TEXT                           |
| BOOLEAN                   | INTEGER, `0` ou `1`            |
| REAL, DOUBLE PRECISION    | REAL                           |
| DECIMAL, NUMERIC          | REAL                           |
| DATE, TIME, TIMESTAMP     | TEXT, no formato ISO 8601      |
| JSON, JSONB               | TEXT, lido com as funções JSON |
| UUID                      | TEXT                           |
| BYTEA                     | BLOB                           |

Para o SQL que cada instrução aceita, consulte a [referência da linguagem SQLite](https://www.sqlite.org/lang.html).

---

## Proteja a aplicação com WAF

[Web Application Firewall](/pt-br/documentacao/plataforma/firewall/waf/primeiros-passos/) 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 guarda uma sensibilidade para cada família, e uma regra de firewall o aplica com *Set WAF*.

| Aspecto               | AWS WAF                                   | Azion WAF                                                                           |
| --------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
| Linguagem de regras   | Regras JSON em uma web ACL                | Critérios do Rules Engine para Firewall                                             |
| Regras gerenciadas    | AWS Managed Rules e regras do Marketplace | Um ruleset gerenciado, pontuado por família de ameaças                              |
| Regras personalizadas | Regras de uma web ACL                     | [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/) |
| Escopo                | Regional ou CloudFront                    | Os workloads aos quais o firewall está vinculado                                    |
| Modos                 | Count e Block                             | *Logging* e *Blocking*                                                              |

Associe cada managed rule group da AWS às famílias do único ruleset da Azion:

| Managed rule group da AWS    | Equivalente na Azion                        |
| ---------------------------- | ------------------------------------------- |
| AWSManagedRulesSQLiRuleSet   | A família de ameaças `sql_injection`        |
| AWSManagedRulesXSSRuleSet    | A família de ameaças `cross_site_scripting` |
| AWSManagedRulesCommonRuleSet | O ruleset gerenciado, com as oito famílias  |
| AWSManagedRulesLinuxRuleSet  | -                                           |
| AWSManagedRulesPHPAppRuleSet | -                                           |

`mode` é obrigatório em todo comportamento *Set WAF* e não tem padrão. Comece em *Logging*, que corresponde à ação Count da AWS, para verificar o que o conjunto de regras bloquearia. Depois mude para *Blocking*. No modo *Blocking*, uma requisição que o conjunto de regras bloqueia recebe `400`. Para evitar que uma requisição legítima corresponda, adicione uma exceção de WAF ou use a aba **Tuning** e revise as requisições bloqueadas no Real-Time Events.

**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. Defina a sensibilidade de cada família em **Threat Type Configuration**.

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.

**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" }
      ]
    }
  }
}'
```

`engine_settings` guarda o ruleset e a sensibilidade de cada família. `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.

Converta cada regra personalizada do AWS WAF em critérios de firewall. 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 correspondida com `${network}`.

```json
{
  "Name": "BlockAdminAccess",
  "Priority": 1,
  "Statement": {
    "AndStatement": {
      "Statements": [
        { "ByteMatchStatement": { "SearchString": "/admin", "FieldToMatch": { "UriPath": {} }, "PositionalConstraint": "CONTAINS" } },
        { "NotStatement": { "Statement": { "IPSetReferenceStatement": { "IPSet": "allowed-ips" } } } }
      ]
    }
  },
  "Action": { "Block": {} }
}
```

A mesma regra como critérios da Azion, com o IP set movido para uma network list:

```text
${request_uri}  starts with     /admin
and
${network}      is not in list  <network-list-id>   (uma network list que guarda os endereços permitidos)
Behavior: Deny (403 Forbidden)
```

O critério `${network}` requer Network Shield no firewall. Para as variáveis e os operadores, consulte [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/). Para código que inspeciona requisições, consulte [Functions para Firewall](/pt-br/documentacao/plataforma/firewall/functions/).

---

## Recrie IP sets e listas de ameaças

Os IP sets do AWS WAF e os findings de ameaças do GuardDuty viram [network lists](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/) na Azion. Uma network list guarda endereços IP e faixas CIDR, ASNs ou países, com 1 a 20.000 itens. Uma regra de firewall compara o endereço do cliente com ela por meio do critério `${network}`, que requer Network Shield.

| Aspecto                       | Serviços de segurança da AWS  | Azion                                                                                |
| ----------------------------- | ----------------------------- | ------------------------------------------------------------------------------------ |
| Detecção de ameaças           | GuardDuty                     | Regras de firewall e network lists                                                   |
| Varredura de vulnerabilidades | Inspector                     | -                                                                                    |
| Findings centralizados        | Security Hub                  | Real-Time Events, com campos de WAF em **HTTP Requests**, e Data Stream para um SIEM |
| Threat intelligence           | Feeds de ameaças do GuardDuty | A lista `Azion IP Tor Exit Nodes`, ID `2`                                            |
| Logs de auditoria             | CloudTrail                    | A fonte de dados Activity History, mantida por 2 anos                                |

A Azion mantém uma lista para todas as contas: `Azion IP Tor Exit Nodes`, com ID `2`. Nenhuma conta pode alterá-la, e uma gravação nela é recusada com `22004`. Uma lista de países é uma lista que você cria com o tipo `countries`.

Mova os findings nesta ordem:

1. Exporte os findings do GuardDuty e coloque os endereços das ameaças baseadas em IP em uma network list.
2. Corrija os findings do Inspector na aplicação antes da migração. O WAF protege a aplicação em tempo de execução.
3. Leia os equivalentes do CloudTrail na fonte de dados Activity History do Real-Time Events.
4. Envie os logs que o Security Hub coletava para um SIEM, como IBM QRadar ou Splunk, com Data Stream.

**Console**

Para criar uma network list no Azion Console:

1. **Abra a página Network Lists**

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

2. **Inicie uma lista**

   Selecione **Network List**.

3. **Dê um nome à lista**

   Na seção **General**, informe um **Name**. Por exemplo: `blocked-ips`.

4. **Selecione o tipo**

   Na seção **Network List Settings**, selecione *IP/CIDR*, *ASN* ou *Countries*. O formulário abre com *ASN* selecionado.

5. **Informe os itens**

   No campo **List**, informe um endereço ou uma faixa por linha. Para *Countries*, selecione os países em **Countries**.

6. **Selecione Save**

Azion Console mostra a mensagem `Your network list has been created`. A lista aparece em **Network Lists**, ao lado das listas mantidas pela Azion.

**CLI**

Para criar uma lista com Azion CLI:

```bash
azion create network-list --name "Blocked countries" --type countries --items "BR,US"
```

`--add-item` e `--remove-item` alteram itens individuais de uma lista existente. Para as flags, consulte [Network lists](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/).

**API**

Para criar uma lista, envie uma requisição `POST` para o endpoint de network lists:

```bash
curl -X POST https://api.azion.com/v4/workspace/network_lists \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"Blocked IPs","type":"ip_cidr","items":["192.0.2.0/24","198.51.100.10"]}'
```

A resposta traz `201`, `"state": "executed"` e a lista com seu `id`. Duplicatas exatas são removidas. Um `PATCH` que envia `items` substitui o array inteiro.

Depois referencie a lista em uma regra de requisição do firewall, em `/v4/workspace/firewalls/<firewall-id>/request_rules`:

```json
{
  "name": "Block listed addresses",
  "active": true,
  "criteria": [[{ "variable": "${network}", "conditional": "if", "operator": "is_in_list", "argument": <network-list-id> }]],
  "behaviors": [{ "type": "deny" }]
}
```

O ID da lista é um inteiro JSON. Um ID enviado como string é recusado com `25042`, e um firewall sem Network Shield recusa a regra com `25047`. Uma lista só é excluída quando nenhuma regra a referencia.

---

## Conte com DDoS Protection

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

| Aspecto            | AWS Shield                             | Azion DDoS Protection                                                                  |
| ------------------ | -------------------------------------- | -------------------------------------------------------------------------------------- |
| Proteção padrão    | Automática, sem custo                  | Automática, e não pode ser desativada                                                  |
| Proteção avançada  | Shield Advanced, com custo adicional   | Regras de firewall personalizadas                                                      |
| Camadas            | 3, 4 e 7                               | 3, 4, 6 e 7                                                                            |
| Equipe de resposta | Apenas com Shield Advanced             | O Security Response Team, um add-on dos suportes Enterprise e Mission-Critical         |
| Cobrança           | Proteção de custos com Shield Advanced | Sem medição para as camadas 3 e 4. A mitigação na camada 7 pode gerar tráfego cobrável |

Um firewall mostra a chave **DDoS Protection Unmetered** em **Main Settings** > **Modules**, sempre ativada. Na API, `modules.ddos_protection` é somente leitura. DDoS Protection não tem limiares, chaves por regra nem alertas. Para uma mitigação direcionada, escreva regras personalizadas no firewall vinculado ao workload. 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/primeiros-passos/) é um módulo diferente do firewall. Ele compara o endereço do cliente com uma network list de endereços IP, faixas CIDR, ASNs ou países, por meio do critério `${network}`. Use-o para bloquear ou permitir conjuntos de clientes, restringir países ou aplicar rate limit a um conjunto de clientes.

---

## Recrie o gerenciamento de bots

[Bot Manager](/pt-br/documentacao/plataforma/firewall/bot-manager/primeiros-passos/) 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     | AWS WAF Bot Control                            | Azion Bot Manager                                                                                                                      |
| ----------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Detecção    | Machine learning, heurísticas e fingerprinting | Regras estáticas, um método comportamental dinâmico no Bot Manager completo, fingerprints de dispositivos e network lists de reputação |
| Desafio     | CAPTCHA e desafio silencioso                   | Uma JavaScript Tag para fingerprinting e ALTCHA pela ação `redirect`                                                                   |
| Ações       | Allow, Count, Block e CAPTCHA                  | `allow`, `custom_html`, `deny`, `drop`, `hold_connection`, `random_delay` e `redirect`                                                 |
| Versão Lite | Não disponível                                 | Bot Manager Lite                                                                                                                       |

Bot Manager Lite pontua uma requisição com 26 regras estáticas, em relação a um `threshold` com padrão de 30, e executa a ação `deny` por padrão. 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. Nos argumentos JSON, defina `threshold` e `action`.

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 as requisições 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 proteção contra bots de terceiros também está disponível pela integração [Radware Bot Manager](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/radware-bot-manager/).

Para bloquear um cliente pelo seu user agent, adicione uma regra de firewall:

```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 um comportamento de permissão. Para isentar um cliente, como o Googlebot, 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 um user agent de navegador, como `Mozilla/5.0`, recebe a resposta normal.

---

## Recrie os rate limits

A Azion limita as taxas de requisições de duas formas, e cada uma cobre uma parte diferente do que as regras baseadas em taxa do AWS WAF fazem. A AWS conta por IP, header, URI ou método, em uma janela de 1 minuto a 1 hora, e bloqueia ou conta. Use o comportamento nativo *Set Rate Limit* de uma regra de firewall para limitar as requisições por segundo ou por minuto. Ele conta por endereço IP do cliente ou entre todos os clientes. Use a integração [Upstash Rate Limiting](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/integracoes/upstash-rate-limiting-integration/), um rate limit com penalidade executado como função de firewall, para chaves personalizadas, janelas personalizadas ou um período de penalidade.

| 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 o caminho com `${request_uri}` ou o método, que requer WAF no firewall. **Rate Limit Type** é *Req/s* ou *Req/min*, e **Limit By** é *Client IP address* ou *Global*. **Average Rate Limit** aceita no mínimo 1, e **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. Uma regra cujos critérios unem vários caminhos com `or` compartilha 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}`, o operador *starts with* e `/api/` como argumento.

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 regra aparece na lista de regras do firewall.

**CLI**

Para criar a regra com Azion CLI, salve o corpo da regra do painel API em um arquivo. Depois 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. As regras de firewall seguem o mesmo padrão de caminho do workspace que as regras de aplicação.

Uma requisição acima da taxa e do burst recebe `429`, com a página de erro intitulada 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). Para as instâncias que um firewall executa, consulte [Instâncias de funções](/pt-br/documentacao/plataforma/firewall/functions-instances/).

### Use o rate limit com penalidade

A função Upstash Rate Limiting mantém 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. Uma requisição durante uma penalidade recebe `403 Forbidden`. Uma requisição válida é contada, e a função 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/).

---

## Reconstrua o monitoramento

A Azion divide a observabilidade em três produtos. [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.

### Real-Time Metrics

| Aspecto               | Métricas do Amazon CloudWatch                 | Azion Real-Time Metrics                                                                                                         |
| --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Atualização dos dados | 1-5 minutos                                   | Até 10 minutos para agregar                                                                                                     |
| Retenção              | 15 meses                                      | 2 anos, exceto 90 dias para `httpBreakdownMetrics` e 60 dias para `botManagerBreakdownMetrics`                                  |
| Método de consulta    | API GetMetricStatistics e CloudWatch Insights | Dashboards, **Copy query**, **Export CSV** e a GraphQL API                                                                      |
| Métricas              | Métricas personalizadas em namespaces         | Requisições, dados transferidos, códigos de status, offload de cache, tempo médio de requisição, ameaças de WAF e consultas DNS |
| Granularidade         | 1 segundo a 1 dia                             | 1 minuto abaixo de 2,5 dias, 1 hora até 60 dias e 1 dia acima disso                                                             |
| Dashboards            | Dashboards do CloudWatch                      | Real-Time Metrics e o plugin do Grafana                                                                                         |
| Alarmes               | Alarmes do CloudWatch                         | Alertas no destino de um stream do Data Stream, como Datadog ou Splunk                                                          |

Os dashboards cobrem estes produtos:

- **Applications**: **Requests**, com o total de requisições, as requisições por método e **Average Request Time**, o tempo médio em segundos que a Azion leva para processar e responder uma requisição. **Status Codes**, com as respostas 2XX, 3XX, 4XX e 5XX. **Data Transferred**, **Bandwidth Saving** e **Edge Offload**.
- **Functions**: **Total Invocations**, dividido em invocações em aplicações e em firewalls.
- **Image Processor**: **Total Requests** e **Total Requests per Second**.
- **Tiered Cache**: o dashboard **Caching Offload**, com os gráficos **Tiered Cache** e **Tiered Cache Offload**.
- **WAF**: **Threats vs Requests**, as ameaças de cross-site scripting, remote file inclusion e SQL injection e as ameaças por país, família e host.
- **Edge DNS**: **Total Queries**.
- **Bot Manager**: **Bad Bot Hits**, **Good Bot Hits**, **Bot Hits** e **Transactions**. A aba precisa de uma assinatura do Bot Manager.
- **Data Stream**: **Total Data Streamed** e **Total 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**. Selecione uma aba de categoria, **Build**, **Secure** ou **Observe**, e depois uma aba de produto. Para restringir um dashboard a um workload, adicione o filtro **Domain** ou **Workload**. Para exportar um gráfico, abra o menu **More options** e selecione **Export CSV**.

Para consultar os mesmos dados, envie uma consulta GraphQL para `https://api.azion.com/v4/metrics/graphql`. Esta consulta conta as requisições por código de status:

```graphql
query {
  workloadMetrics(limit: 20, filter: { tsRange: {begin: "2026-10-01T00:00:00", end: "2026-10-02T00:00:00"} }, aggregate: { sum: requests }, groupBy: [status], orderBy: [sum_DESC]) {
    status
    sum
  }
}
```

Esta consulta soma os bytes enviados para um host, por intervalo de tempo:

```graphql
query {
  workloadMetrics(limit: 500, filter: { tsRange: {begin: "2026-10-01T00:00:00", end: "2026-10-07T00:00:00"}, host: "www.example.com" }, aggregate: { sum: bytesSent }, groupBy: [ts], orderBy: [ts_DESC]) {
    ts
    sum
  }
}
```

Substitua as datas por um intervalo dentro do período de retenção. Um intervalo além dele retorna um array vazio. `limit` aceita até 10.000 linhas e tem padrão de 10. Um campo calculado, como `dataTransferredOut`, não pode ser agregado. O dataset `httpMetrics` de consultas antigas ainda funciona, mas está obsoleto. Para consultar um gráfico de WAF, como as ameaças por país, abra o menu **More options** e selecione **Copy query**.

Para todos os campos, 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 dashboards no Grafana, consulte [Dashboards personalizados com o plugin do Grafana](/pt-br/documentacao/guias/plataforma/observabilidade/azion-plugin-grafana/), [dashboards pré-configurados](/pt-br/documentacao/guias/plataforma/observabilidade/azion-plugin-grafana-dash-pre-configurado/) e o repositório do [plugin Azion para Grafana](https://github.com/aziontech/grafana-plugin). Para ler os dashboards, consulte [Analise métricas](/pt-br/documentacao/guias/plataforma/observabilidade/analisar-metricas/).

### Real-Time Events

| Aspecto               | Amazon CloudWatch Logs                      | Azion Real-Time Events                                                                         |
| --------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Acesso                | API GetLogEvents e CloudWatch Logs Insights | Consultas no Azion Console ou na GraphQL API                                                   |
| Atraso                | De segundos a minutos                       | Até 30 segundos                                                                                |
| Retenção              | 1 dia a 10 anos                             | 7 dias, ou 168 horas. Activity History guarda 2 anos. Para uma retenção maior, use Data Stream |
| Linguagem de consulta | CloudWatch Logs Insights                    | GraphQL, com os campos que você seleciona                                                      |
| Organização           | Log groups com log streams                  | Fontes de dados por produto                                                                    |
| Metric filters        | Métricas criadas a partir de logs           | Data Stream para um destino externo                                                            |

Real-Time Events não precisa de configuração. Cada log group do CloudWatch corresponde a uma fonte de dados:

| Log group do CloudWatch | Fonte de dados do Real-Time Events           |
| ----------------------- | -------------------------------------------- |
| `/aws/cloudfront/...`   | **HTTP Requests**                            |
| `/aws/lambda/...`       | **Functions**                                |
| `/aws/waf/...`          | **HTTP Requests**, que traz os campos de WAF |
| `/aws/route53/...`      | **Edge DNS**                                 |
| CloudTrail              | **Activity History**                         |

As outras fontes de dados são **Functions Console**, **Image Processor**, **Tiered Cache** e **Data Stream**.

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. Em **Filter by**, adicione condições como o host, o status ou o endereço remoto.

4. **Selecione Refresh**

A tabela de resultados lista os eventos. Selecione uma linha para abrir a visualização **More details**, com cada variável do registro. Um intervalo de tempo personalizado fica dentro das últimas 168 horas.

Uma consulta do CloudWatch Logs Insights filtra e ordena as linhas de log:

```text
fields @timestamp, @message
| filter @logGroup = "/aws/cloudfront/distribution"
| filter status >= 500
| sort @timestamp desc
| limit 100
```

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" }, statusGte: 500 }
    orderBy: [ts_DESC]
  ) {
    ts
    remoteAddress
    requestUri
    requestMethod
    host
    status
    upstreamStatus
    upstreamResponseTime
  }
}
```

Substitua as datas por um intervalo dentro dos últimos 7 dias. `statusGte: 500` mantém os erros de servidor, e `statusEq: 500` mantém um status. `upstreamResponseTime` mostra `-` para uma resposta entregue a partir do cache. A fonte de dados Activity History responde a consultas sobre 2 anos.

Os datasets trazem estes campos, entre outros:

- **HTTP Requests**: `ts`, `remoteAddress`, `remotePort`, `host`, `requestUri`, `requestMethod` e `status`. Tempo: `requestTime`, `upstreamResponseTime` e `upstreamHeaderTime`. Bytes: `bytesSent`, `requestLength`, `upstreamBytesReceived` e `upstreamBytesSent`. Cache: `upstreamCacheStatus`. WAF: `wafBlock`, `wafMatch`, `wafScore` e `wafLearning`, que informa o modo *Logging*. Localização: `geolocCountryName`, `geolocRegionName` e `geolocAsn`. TLS: `sslCipher` e `sslProtocol`.
- **Functions**: `functionsInstanceIdList`, `functionsList`, `functionsTime` e `functionLanguage`.
- **Edge DNS**: `level`, `qtype`, `resolutionType`, `statusCode` e `zoneId`.

Para todos os campos, consulte [Campos GraphQL do Real-Time Events](/pt-br/documentacao/devtools/graphql/campos-gql-real-time-events/) e [Investigue requisições com a GraphQL API](/pt-br/documentacao/guias/plataforma/observabilidade/investigar-requisicoes-api-graphql/).

### Data Stream

| Aspecto  | Amazon Data Firehose                             | Azion Data Stream                                                   |
| -------- | ------------------------------------------------ | ------------------------------------------------------------------- |
| Acesso   | Entrega para destinos configurados               | Envio para um destino externo                                       |
| Atraso   | Entrega com buffer                               | Lotes de 2.000 registros ou 60 segundos, entregues em até 3 minutos |
| Retenção | Definida pelo destino                            | Definida pelo destino                                               |
| Formato  | Registros, com transformação opcional por Lambda | Templates que selecionam os campos                                  |
| Destinos | S3, Redshift, OpenSearch e endpoints HTTP        | 11 tipos, listados abaixo                                           |

Um stream envia uma fonte de dados para um destino:

- **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.

Cada destino do Firehose corresponde a um tipo de endpoint:

| Destino do Firehose      | Endpoint do Data Stream                                                                         |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| S3                       | S3, para qualquer armazenamento compatível com S3                                               |
| Redshift                 | Google BigQuery ou Standard HTTP/HTTPS POST                                                     |
| Elasticsearch            | Elasticsearch                                                                                   |
| Endpoint HTTP            | Standard HTTP/HTTPS POST                                                                        |
| Transformação por Lambda | Um template personalizado que seleciona os campos. Data Stream não executa código nos registros |

Um metric filter ou um alarme do CloudWatch vira um stream para um destino de monitoramento, como Datadog ou Splunk, que conta e alerta lá. 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**. Para escolher os campos, selecione **Create Custom Template**.

5. **Selecione o destino**

   Em **Output**, selecione o **Connector**, como *Datadog* ou *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`. Este stream envia as requisições de um workload para um bucket S3:

```json
{
  "name": "s3-archive",
  "active": true,
  "inputs": [
    { "type": "raw_logs", "attributes": { "data_source": "workloads" } }
  ],
  "transform": [
    { "type": "filter_workloads", "attributes": { "workloads": [<workload-id>] } },
    { "type": "render_template", "attributes": { "template": 2 } }
  ],
  "outputs": [
    {
      "type": "s3",
      "attributes": {
        "host_url": "https://s3.amazonaws.com",
        "bucket_name": "my-logs-bucket",
        "region": "us-east-1",
        "access_key": "[ACCESS KEY]",
        "secret_key": "[SECRET KEY]",
        "object_key_prefix": "azion-logs",
        "content_type": "plain/text"
      }
    }
  ]
}
```

Um `POST` retorna `201`. O template `2` é o *Applications Event Collector*. Sem sampling nem filtro de workload, a criação falha com `32002`, e com os dois ela falha com `32007`. Uma saída Datadog recebe `url`, como `https://http-intake.logs.datadoghq.com/v1/input`, e `api_key`.

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 o tracing do X-Ray

A Azion não coleta traces nem desenha um mapa de serviços. Cada log de requisição traz um ID único, `$request_id`, que uma ferramenta de tracing une aos logs dos seus outros serviços. Data Stream envia esses logs para a ferramenta, e uma função repassa um trace ID para a origem.

| Aspecto           | AWS X-Ray                        | Azion                                                                     |
| ----------------- | -------------------------------- | ------------------------------------------------------------------------- |
| Coleta de traces  | Automática com o X-Ray SDK       | Logs de requisições enviados pelo Data Stream para uma ferramenta externa |
| Mapa de serviços  | Mapa de serviços integrado       | A ferramenta externa, como Datadog ou Splunk                              |
| Análise de traces | Console do X-Ray                 | A ferramenta externa                                                      |
| Anotações         | Pares chave-valor personalizados | As variáveis de um template personalizado                                 |
| Sampling          | Regras de sampling               | Uma taxa de sampling de 1 a 100 por cento                                 |
| Destinos          | Console do X-Ray e CloudWatch    | 11 tipos de endpoint                                                      |

| Conceito do X-Ray      | Equivalente na Azion                                                                  |
| ---------------------- | ------------------------------------------------------------------------------------- |
| Segment                | Uma entrada de log de requisição, da fonte de dados **Applications**                  |
| Subsegment             | Uma entrada de log de função, de um segundo stream com a fonte de dados **Functions** |
| Service graph          | O mapa de serviços da ferramenta externa                                              |
| Propagação do trace ID | Um header que uma função adiciona à requisição que ela repassa                        |
| Annotation             | Uma variável do template personalizado                                                |

Data Stream alcança estas ferramentas de tracing: Datadog, Splunk, Elasticsearch, Apache Kafka, que alimenta Jaeger ou Zipkin, Google BigQuery, AWS Kinesis Data Firehose e Standard HTTP/HTTPS POST para um sistema personalizado.

Para enviar os campos de trace, crie um template personalizado com uma requisição `POST` para `https://api.azion.com/v4/workspace/stream/templates`. O `data_set` é um objeto JSON, enviado como string, cujos valores são variáveis:

```json
{
  "name": "trace-template",
  "data_set": "{\"request_id\": \"$request_id\", \"time\": \"$time\", \"host\": \"$host\", \"request_uri\": \"$request_uri\", \"request_method\": \"$request_method\", \"status\": \"$status\", \"upstream_addr\": \"$upstream_addr\", \"upstream_response_time\": \"$upstream_response_time\", \"upstream_status\": \"$upstream_status\", \"remote_addr\": \"$remote_addr\"}"
}
```

A resposta traz o `id` do template. Use-o em `render_template` de um stream com a fonte de dados `workloads`, como mostra a etapa Data Stream, e uma saída Datadog ou Splunk. No Azion Console, **Create Custom Template** na seção **Render Template** abre o mesmo formulário. Um stream guarda uma fonte de dados, então os logs de funções vão em um segundo stream com a fonte de dados `functions_console`.

Para repassar um trace ID para a origem, execute uma função que encaminha a requisição. Ela lê o ID recebido ou usa o ID de requisição da Azion:

```javascript
export default {
  async fetch(request, env, ctx) {
    const traceId = request.headers.get('x-trace-id') || request.metadata['request_id'];
    const headers = new Headers(request.headers);
    headers.set('X-Trace-Id', traceId);
    return fetch(new Request(request, { headers }));
  }
};
```

A origem recebe `X-Trace-Id`, e o cliente recebe o mesmo ID de requisição no header de resposta `x-azion-request-id`. Para as variáveis de cada fonte de dados, consulte [Fontes de dados e variáveis](/pt-br/documentacao/plataforma/data-stream/fontes-de-dados-e-variaveis/).

---

## Substitua CloudWatch RUM por Edge Pulse

[Edge Pulse](/pt-br/documentacao/plataforma/edge-pulse/) mede como os visitantes reais alcançam a infraestrutura da Azion a partir dos seus navegadores: navegação, disponibilidade, latência e largura de banda. Toda conta o tem ativo em todos os planos, sem cobrança adicional, então não há nada para criar.

| Aspecto           | Amazon CloudWatch RUM                                         | Azion Edge Pulse                                                                             |
| ----------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Coleta            | SDK JavaScript                                                | Uma tag JavaScript em cada página, a **Default Tag** ou a **Pre-loading Tag**                |
| Métricas          | Carregamento de página, Core Web Vitals e erros de JavaScript | Navegação, disponibilidade, latência e largura de banda em relação à infraestrutura da Azion |
| Configurações     | Sampling e eventos personalizados                             | Nenhuma. A tag não tem taxa de sampling nem eventos personalizados                           |
| Leitura dos dados | O console do RUM                                              | Consultas à GraphQL API do Real-Time Events, no dataset `pulseEvents`                        |

Para adicionar a tag:

1. **Abra a página Edge Pulse**

   Acesse [Azion Console](https://console.azion.com/) > **Products menu** > **Observe** > **Edge Pulse**.

2. **Selecione a tag de que suas páginas precisam**

   Selecione a **Pre-loading Tag** para páginas cuja Content Security Policy não permite JavaScript inline. Caso contrário, selecione a **Default Tag**.

3. **Selecione Copy to Clipboard**

4. **Cole a tag na página**

   Cole-a antes da tag `body` de fechamento de cada página que você quer medir e publique as páginas.

Cada visitante executa um teste a cada 30 minutos. Azion Console não tem uma página que mostre os resultados em gráficos: leia-os com a GraphQL API do Real-Time Events. Para os passos, consulte [Primeiros passos com Edge Pulse](/pt-br/documentacao/plataforma/edge-pulse/primeiros-passos/).

---

## 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                        | AWS Certificate Manager               | Azion Certificate Manager                                                                                                                                      |
| --------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tipos de certificado        | Públicos, privados e importados       | Azion SAN, Let's Encrypt, certificados personalizados e certificados Trusted CA para mTLS                                                                      |
| Validação                   | DNS e e-mail                          | Desafios HTTP-01 ou DNS-01 do Let's Encrypt                                                                                                                    |
| Renovação                   | Automática                            | 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 |
| Escopo                      | Regional, e us-east-1 para CloudFront | Certificados TLS para workloads                                                                                                                                |
| mTLS                        | Suportado, com AWS Private CA         | Certificados Trusted CA. Azion SAN não suporta mTLS                                                                                                            |
| Custo                       | Gratuito para recursos da AWS         | Let's Encrypt sem custo adicional                                                                                                                              |
| Certificado padrão          | -                                     | Azion SAN cobre o domínio de workload `azionedge.net` e o hostname `azion.app`                                                                                 |
| Certificados personalizados | Certificados importados               | Upload de um certificado e sua chave privada, de domínio único ou SAN, com chaves RSA 2048 ou P-256                                                            |
| Criptografia até a origem   | Origin protocol policy                | **Transport Protocol Policy** do connector: *Preserve*, *Force HTTPS* ou *Force HTTP*                                                                          |

A Azion emite um certificado Let's Encrypt assim que você escolhe um preset Let's Encrypt. Escolha o desafio conforme 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, como o Route 53, 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 AWS, use DNS-01.

**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, e 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 exportado do ACM, 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 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/), e para cada campo de certificado, [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`, e os intermediários seguem o certificado na mesma string. 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 `alternative_names`, opcional.

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. Em uma falha de handshake TLS, verifique se o certificado cobre o hostname e se os intermediários estão no campo do certificado. Depois verifique o `minimum_version` do workload. 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. Um certificado do AWS Private CA pode ser exportado e enviado com o preset **Trusted CA Certificate**. 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 do Route 53 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 quando mantiver o Route 53 e apontar apenas subdomínios, como mostra Aponte o domínio para o workload.

| Aspecto                 | Amazon Route 53                                   | Azion Edge DNS                                                             |
| ----------------------- | ------------------------------------------------- | -------------------------------------------------------------------------- |
| Nameservers             | Atribuídos por hosted zone                        | `ns1.aziondns.net`, `ns2.aziondns.com` e `ns3.aziondns.org` para toda zona |
| Tipos de registro       | A, AAAA, CNAME, MX, TXT, SRV, NS, SOA, PTR e CAA  | A, AAAA, ANAME, CAA, CNAME, DS, MX, NS, PTR, SRV e TXT                     |
| Políticas de roteamento | Simple, weighted, latency, failover e geolocation | *Simple* e *Weighted*                                                      |
| Health checks           | Health checks do Route 53                         | Nenhum                                                                     |
| DNSSEC                  | Suportado                                         | Suportado                                                                  |
| API                     | API REST                                          | `/v4/workspace/dns/zones`                                                  |

Associe cada política de roteamento:

| Política do Route 53 | Equivalente na Azion                                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Simple               | *Simple* (`simple`), que responde com todos os valores do registro                                                        |
| Weighted             | *Weighted* (`weighted`): vários registros compartilham um nome e um tipo, e cada um é respondido na proporção do seu peso |
| Latency              | -                                                                                                                         |
| Failover             | -. Para origens, Load Balancer envia o tráfego para endereços *Backup* quando todos os primários falham                   |
| Geolocation          | -                                                                                                                         |

Um peso aceita de 0 a 255, e `0` mantém o registro sem respondê-lo. A API tem padrão `255`, e o Console preenche `100`. Registros TXT e NS recusam a política *Weighted* com `19017`.

Recrie cada registro do Route 53 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 do Route 53.

A zona responde nos nameservers da Azion. Depois altere os nameservers do domínio no registrador, não no Route 53.

**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, como `["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 e compare a resposta do Route 53 com a resposta do Edge DNS:

```bash
dig example.com NS +short
dig www.example.com A +short
dig @ns-1234.awsdns-12.com example.com A
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 que pode levar até 48 horas. O segundo mostra a resposta que o resolver retorna agora. O terceiro e o quarto mostram as respostas do Route 53, com seu próprio nameserver do Route 53, e do Edge DNS. Com o DNSSEC ativado, o último retorna dois registros DNSKEY, com flags `257` e `256` e algoritmo `13`. Não consulte um nome novo antes de o registro dele existir: 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

A mudança de DNS é a virada: assim que o domínio resolve para o workload, os usuários acessam o projeto pela Azion. Uma mudança de domínio afeta os usuários, o posicionamento nas buscas e a disponibilidade, então trate-a como uma transição controlada. Antes da virada, confirme que:

- O certificado está ativo.
- O hostname está nos **Domains** do workload.
- Os registros DNS estão prontos.
- As rotas críticas e os redirecionamentos respondem como esperado no domínio do workload. Para testá-los com o hostname real antes da virada, 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                                                           | Registro                                    |
| ----------- | ------------------------------------------------------------------ | ------------------------------------------- |
| CNAME       | Um subdomínio, mantendo o Route 53 como provedor de DNS            | `www CNAME <your-workload-domain>`          |
| Nameservers | O apex e todos os outros nomes, com Edge DNS respondendo 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. 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.
- [Data Stream](/pt-br/documentacao/plataforma/data-stream/primeiros-passos.md): Envie os logs para seu SIEM ou suas ferramentas de analytics e configure alertas lá.
- [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.
