# Instâncias de função no Firewall

Uma instância de função vincula uma função a um [firewall](/pt-br/documentacao/plataforma/firewall/) e contém os argumentos que essa função recebe nesse firewall. A instância só é executada quando uma regra no [Rules Engine para Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/) a nomeia em um comportamento *Run Function*. Por exemplo, um firewall pode ter duas instâncias de [Bot Manager Lite](/pt-br/documentacao/plataforma/firewall/bot-manager/bot-manager-lite/) com valores de `threshold` diferentes, e cada regra executa a instância que nomeia.

---

## Campos da instância

Cada firewall tem as suas próprias instâncias de função. Azion Console as lista na aba **Functions Instances** do firewall, onde o botão **Function** abre um drawer com três seções: **General**, **Function** e **Arguments**. A API disponibiliza os mesmos registros em `/v4/workspace/firewalls/<firewall-id>/functions`, e Azion CLI com o substantivo `firewall-instance`. Uma instância carrega nove campos: cinco que uma requisição define e quatro que a plataforma define e retorna.

| Campo           | Tipo                                    | Obrigatório     | Descrição                                                                                                                                                                                                                          |
| --------------- | --------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`            | integer                                 | Somente leitura | O ID da instância. Um comportamento *Run Function* o envia em `value`, e toda chamada sobre uma instância o recebe no caminho                                                                                                      |
| `name`          | string, de 1 a 100 caracteres           | Sim             | O nome da instância. Azion Console o mostra como o campo **Name** e pede um nome único e descritivo. Com mais de 100 caracteres, a API responde `Ensure this field has no more than 100 characters.`                               |
| `function`      | integer                                 | Sim             | O ID da função que a instância vincula, que não é o ID da instância. A função precisa declarar o ambiente de execução `firewall`. Azion Console o mostra como o seletor **Function**                                               |
| `args`          | objeto ou array JSON, até 100.000 bytes | Não             | Os argumentos que a função recebe, armazenados exatamente como enviados e nunca verificados em relação à função. Azion Console os mostra como o editor **Arguments**. Os padrões e a validação deles estão descritos em Argumentos |
| `azion_form`    | objeto JSON                             | Não             | Um JSON Schema que renderiza os argumentos como um formulário. Quando uma requisição não envia nenhum, a plataforma armazena `{}`                                                                                                  |
| `active`        | boolean                                 | Não             | Se a instância está ativa. Somente uma instância ativa aparece na lista do Azion Console de um comportamento *Run Function*. Azion Console envia `true` quando cria uma instância e não oferece nenhum controle para alterá-lo     |
| `last_editor`   | string                                  | Somente leitura | A conta que alterou a instância pela última vez, mostrada na coluna **Last Editor**                                                                                                                                                |
| `last_modified` | date-time                               | Somente leitura | Quando a instância foi alterada pela última vez, mostrado na coluna **Last Modified**                                                                                                                                              |
| `created_at`    | date-time                               | Somente leitura | Quando a instância foi criada                                                                                                                                                                                                      |

A lista **Functions Instances** mostra as colunas **Name**, **Function**, **Last Editor** e **Last Modified**. Ela não tem coluna de status, e **Delete** é a única ação de linha.

O seletor **Function** lista somente as funções da conta cujo `execution_environment` é `firewall`, e o rodapé **Create Function** dele cria uma. A API recusa uma função com qualquer outro ambiente, com `Invalid edge function runtime. You should use a function designed for Edge Firewall.` As funções do Azion Marketplace, como Bot Manager Lite, Secure Token e JWT, também são funções de firewall. Uma função do Marketplace chega à conta pelo Azion Console, porque nem Azion CLI nem a API têm uma operação de instalação. O registro dela não expõe o código-fonte.

Uma instância nunca altera o código da sua função. Ela define o nome, os argumentos e se a instância está ativa.

A aba **Functions Instances** só aparece quando [Functions](/pt-br/documentacao/plataforma/functions/) está habilitado no firewall. O switch é **Functions**, na aba **Main Settings** do firewall, e `modules.functions.enabled` na API. Functions está ativado quando um firewall é criado pela API, pela CLI ou pela página de criação do Azion Console. O drawer de criação do Azion Console é a exceção e começa com Functions desativado.

Uma aplicação tem o mesmo objeto em uma aba de mesmo nome. Uma instância em um firewall executa a sua função antes que a requisição chegue à aplicação, então a função pode interromper a requisição ali. Uma instância em uma aplicação executa a sua função como parte de servir a requisição. Para mais informações, consulte [Instâncias de função](/pt-br/documentacao/plataforma/applications/functions-instances/).

---

## Argumentos

Os argumentos de uma instância são o valor JSON no campo `args`, e a função os lê cada vez que a instância é executada. Eles permitem que uma função se comporte de forma diferente em cada instância: o código continua o mesmo, e só os valores mudam. No Azion Console, a seção **Arguments** do drawer da instância os edita. Quando a função selecionada carrega um `azion_form` não vazio, a seção oferece dois modos: *Form*, o padrão, que monta um formulário a partir desse schema, e *JSON*. Caso contrário, o editor JSON aparece sozinho.

O texto de ajuda do editor diz que o código lê um argumento com `event.args('arg_name')`. Para o lado do código de uma função de firewall, consulte [Functions no Firewall](/pt-br/documentacao/plataforma/firewall/functions/).

Um objeto `args` que define quatro argumentos do Bot Manager Lite:

```json
{
  "threshold": 30,
  "action": "deny",
  "internal_logs": 2,
  "log_tag": "storefront-bots"
}
```

As quatro chaves estão entre os argumentos para os quais Bot Manager Lite traz valores padrão. Uma chave que a função não lê é salva da mesma forma, e a função a ignora.

### Argumentos padrão

O registro de uma função carrega `default_args`, os valores de argumento com que a função é distribuída, ao lado do seu `azion_form`. O comando `azion describe function --function-id <function-id>` retorna os dois. Quando uma instância não fornece argumentos, a função é executada com os seus `default_args`. Uma chave que a instância define assume o valor que a instância lhe dá.

O fallback acontece em tempo de execução, não no registro da instância. O registro guarda apenas o que recebeu, então uma instância criada com `{}` retorna `{}` na leitura, e não os padrões da sua função. Por exemplo, Bot Manager Lite traz um `threshold` de `30` nos seus `default_args`. Uma instância dele com `args` igual a `{}` não mostra nenhum `threshold` e é executada com `30`.

Os oito argumentos padrão do Bot Manager Lite são `action`, `bad_fingerprint_list`, `disabled_rules`, `good_fingerprint_list`, `internal_logs`, `log_headers`, `log_tag` e `threshold`. Para saber o que cada um faz, consulte [Argumentos](/pt-br/documentacao/plataforma/firewall/bot-manager/argumentos/).

### Validação de argumentos

A plataforma verifica apenas duas coisas em `args`. Azion Console recusa um conteúdo que não pode ser interpretado, com `Invalid JSON`, e a API recusa um valor maior que 100.000 bytes. O limite é decimal: um payload de 102.400 bytes é recusado com `Value size (in bytes) is too big. Maximum size allowed is 100000 bytes.` Para todos os limites que um firewall aplica, consulte [Limites de Firewall](/pt-br/documentacao/plataforma/firewall/limites/).

Nada verifica as chaves ou os valores em relação à função. A plataforma armazena cada chave como foi enviada, com o seu tipo JSON, inclusive uma chave que a função nunca lê, e o salvamento é concluído. Por exemplo, uma instância do Bot Manager Lite com `"thresold": 5` é salva e retorna na leitura exatamente como foi digitada, e não reduz o limite. Nenhuma interface informa a chave com erro de digitação, então compare o nome de cada chave com a documentação da função antes de salvar.

---

## Comportamento Run Function

Uma instância de função só é executada quando uma regra de firewall a nomeia em um comportamento *Run Function*. Quando uma requisição corresponde aos critérios dessa regra, a plataforma executa a função com os argumentos da instância. A função é executada na infraestrutura distribuída da Azion, antes que a requisição chegue à aplicação. O que o cliente recebe depende, então, do que a função faz com a requisição.

Na API, o comportamento é `run_function`, e o atributo `value` contém o `id` da instância, nunca o ID da função:

```json
{ "type": "run_function", "attributes": { "value": <function-instance-id> } }
```

No Azion Console, escolher *Run Function* adiciona a lista **Select a Function**. A lista contém as instâncias ativas deste firewall, e não as funções da conta, e o rodapé **Create Function Instance** dela cria uma. Cada regra pode ter um comportamento *Run Function*, então uma regra executa uma instância.

O comportamento exige Functions habilitado no firewall e acesso a Functions na conta. Sem um dos dois, Azion Console mostra *Run Function - required Functions* e não permite selecioná-lo.

Uma regra que executa uma instância em toda requisição, porque `${request_uri}` `starts_with` `/` corresponde a toda URI:

```json
{
  "name": "Run Bot Manager on every request",
  "active": true,
  "criteria": [[{ "variable": "${request_uri}", "conditional": "if", "operator": "starts_with", "argument": "/" }]],
  "behaviors": [{ "type": "run_function", "attributes": { "value": <function-instance-id> } }]
}
```

Para a ordem em que um firewall executa as suas regras, consulte [Como Firewall funciona](/pt-br/documentacao/plataforma/firewall/como-funciona/).

---

## API

As operações de instância ficam em `https://api.azion.com/v4/workspace/firewalls/<firewall-id>/functions`. Cada chamada se autentica com um personal token no header `Authorization: Token [TOKEN VALUE]`, e uma chamada com corpo adiciona `Content-Type: application/json`.

| Operação                            | Método e caminho                  |
| ----------------------------------- | --------------------------------- |
| Listar as instâncias de um firewall | `GET /functions`                  |
| Criar uma instância                 | `POST /functions`                 |
| Consultar uma instância             | `GET /functions/{function_id}`    |
| Substituir uma instância            | `PUT /functions/{function_id}`    |
| Atualizar parte de uma instância    | `PATCH /functions/{function_id}`  |
| Excluir uma instância               | `DELETE /functions/{function_id}` |

Nesses caminhos, `{function_id}` recebe o ID da instância, não o ID da função. Criar ou excluir uma instância responde `202`. Ler uma instância responde `200`, com o registro em `data` e sem a chave `state`.

Crie uma instância do Bot Manager Lite com quatro argumentos definidos, em que `<function-id>` é o ID da função Bot Manager Lite na sua conta:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/firewalls/<firewall-id>/functions \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "bot-manager-lite",
  "function": <function-id>,
  "active": true,
  "args": { "threshold": 30, "action": "deny", "internal_logs": 2, "log_tag": "storefront-bots" }
}'
```

A resposta é `202`, com um `state` igual a `pending` e a instância em `data`. Este trecho mantém `id` e os campos que a chamada enviou:

```json
{
  "state": "pending",
  "data": {
    "id": <function-instance-id>,
    "name": "bot-manager-lite",
    "args": { "threshold": 30, "action": "deny", "internal_logs": 2, "log_tag": "storefront-bots" },
    "azion_form": {},
    "function": <function-id>,
    "active": true
  }
}
```

A plataforma armazena `azion_form` como `{}` porque a chamada não enviou nenhum. O `id` em `data` é o valor que um comportamento *Run Function* envia.

---

## CLI

O substantivo `firewall-instance` da Azion CLI cria, lista e lê instâncias.

| Comando                            | O que faz                                                                                        |
| ---------------------------------- | ------------------------------------------------------------------------------------------------ |
| `azion create firewall-instance`   | Cria uma instância, com `--name`, `--firewall-id`, `--function-id`, `--args` e `--active`        |
| `azion list firewall-instance`     | Lista as instâncias de um firewall, com `--firewall-id`                                          |
| `azion describe firewall-instance` | Retorna uma instância, com `--firewall-id` e `--instance-id`. `--format json` imprime o registro |

A flag `--args` recebe o caminho de um arquivo JSON, não JSON inline. Um arquivo que define três argumentos:

```json
{"threshold": 10, "action": "deny", "log_tag": "bm-probe"}
```

Salve-o como `args.json` e, depois, crie a instância:

```bash
azion create firewall-instance --name my-instance --firewall-id <firewall-id> \
  --function-id <function-id> --args args.json --active true
```

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

Releia a instância:

```bash
azion describe firewall-instance --firewall-id <firewall-id> --instance-id <function-instance-id> --format json
```

Os argumentos retornam com as chaves, os valores e os tipos JSON que o arquivo enviou. Um trecho do registro:

```json
{
 "active": true,
 "args": { "action": "deny", "log_tag": "bm-probe", "threshold": 10 },
 "azion_form": {},
 "function": <function-id>,
 "id": <function-instance-id>,
 "name": "my-instance"
}
```

---

## Erros

Azion CLI imprime a mensagem da plataforma dentro de `Error: failed to create the Firewall Function Instance: [...]`, ou dentro de `Error: failed to create the Firewall Rule: [...]` para uma regra. A tabela lista cada mensagem como ela aparece, com o que a causa.

| Mensagem                                                                                                                 | O que causa                                                                                                    | O que fazer                                                      |
| ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `Ensure this field has no more than 100 characters.`                                                                     | Um `name` com mais de 100 caracteres                                                                           | Envie um nome com 100 caracteres ou menos                        |
| `Value size (in bytes) is too big. Maximum size allowed is 100000 bytes.`                                                | Um valor de `args` maior que 100.000 bytes, como 102.400 bytes                                                 | Reduza `args` para 100.000 bytes ou menos                        |
| `Invalid edge function runtime. You should use a function designed for Edge Firewall.`                                   | Uma `function` cujo `execution_environment` é `application`                                                    | Instancie uma função cujo `execution_environment` é `firewall`   |
| `The function was not found.`                                                                                            | Um ID de `function` que não nomeia nenhuma função da conta, como `99999999`                                    | Envie o ID de uma função de firewall existente                   |
| `Function Instance '99999999' not found.`                                                                                | Uma regra cujo comportamento `run_function` envia um `value` que não nomeia nenhuma instância, aqui `99999999` | Envie o `id` de uma instância existente, não o ID da função dela |
| `Error: failed to read args file: open {"threshold":10,"action":"deny","log_tag":"bm-probe"}: no such file or directory` | `azion create firewall-instance` com JSON inline em `--args`                                                   | Salve os argumentos em um arquivo e passe o caminho dele         |
| `Invalid JSON`                                                                                                           | Conteúdo no editor **Arguments** do Azion Console que não pode ser interpretado como JSON                      | Corrija o JSON e, depois, salve                                  |

---

## Recursos relacionados

- [Instancie uma função em um firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/instanciar-functions.md): O procedimento que cria uma instância pelo Azion Console ou pela API.
- [Crie uma regra de firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/trabalhar-com-rules-engine.md): O procedimento que cria uma regra de firewall no Azion Console.
- [Como Firewall funciona](/pt-br/documentacao/plataforma/firewall/como-funciona.md): Onde um comportamento Run Function fica entre as regras que um firewall executa em uma requisição.
- [Limites de Functions](/pt-br/documentacao/plataforma/functions/limites.md): Os tetos que limitam uma execução da função que uma instância vincula.
