Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Learn why MongoDB was selected as a leader in the 2024 Gartner® Magic Quadrant™
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Automação do cluster do Atlas usando triggers agendados

Brian Leonard11 min read • Published Jan 08, 2020 • Updated Jun 25, 2024
AtlasJavaScript
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Cada ação que você pode realizar na interface de usuário do Atlas é apoiada por uma API de administração correspondente, que permite levar a automação facilmente para os sistemas do Atlas. Algumas das formas mais comuns de automação do Atlas ocorrem em um agendamento, como pausar um cluster que é usado apenas para testes à noite e retomar o cluster novamente pela manhã.
Ter uma API para automatizar as ações do Atlas é ótimo, mas você ainda precisa escrever o script que chama a API, encontrar um local para hospedar o script e configurar o trabalho para chamar o script na programação desejada. É aqui que os triggers agendados do Atlas vêm ajudar.
Neste artigo Automação de clusters do Atlas usando triggers agendados, mostrarei como um trigger agendado pode ser usado para incorporar facilmente a automação em seu ambiente. Além de pausar e retomar um cluster, mostrarei como os eventos de aumento e redução do cluster também podem ser colocados em uma programação. Ambas as atividades permitem economizar nos custos quando você não precisa do cluster (pausado) ou não precisa dele para oferecer suporte a cargas de trabalho de pico (redução).

Arquitetura

Três exemplos de triggers programados são fornecidos nesta solução. Cada trigger tem uma função de acionamento associada. A maior parte do trabalho é tratada pela função modifyCluster, que, como o nome indica, é uma função genérica para fazer modificações em um cluster. É um wrapper em torno da API de administração Modificar um cluster de um projeto do Atlas.
Arquitetura

Preparação

Gerar uma chave API

Para chamar as APIs administrativas do Atlas, primeiro você precisará de uma chave de API com privilégios de proprietário do projeto para os projetos que desejam agendar alterações de cluster.
As chaves de API são criadas no Gerenciador de acesso. Selecione Gerenciador de acesso no menu na barra de navegação superior e selecione Acesso ao projeto:
Em seguida, selecione a aba Chaves de API.
Crie uma nova chave, dando-lhe uma boa descrição e atribua à chave permissões de proprietário do projeto.
Chave API
Clique em Avançar e anote sua chave privada:
Salve a chave API
Vamos limitar quem pode usar nossa chave de API adicionando uma lista de acesso. No nosso caso, a chave de API será usada por um trigger, que é um componente do Atlas App Services. Você encontrará a lista de endereços IP usados pelo App Services na documentação em Configuração de firewall. Observe que cada endereço IP deve ser adicionado individualmente. VocÊ pode votar nesta ideia para resolver isso: Capacidade de fornecer endereços IP como uma lista para acesso à rede
Adicionar entrada da lista de acesso
Lista de acesso à API
Clique em Concluído.

Implantação

Crie um projeto para automação

Como essa solução funciona em toda a sua organização do Atlas, eu gosto de hospedá-la em seu próprio projeto do Atlas dedicado.
Criar um projeto

Crie um aplicativo

Hospedaremos nosso trigger em um aplicativo Atlas App Services. Para começar, basta clicar na aba App Services:
Serviços de App
Você verá que o App Services oferece vários modelos para você começar. Para esse caso de uso, basta selecionar a primeira opção para Criar seu próprio aplicativo:
Boas-vindas ao App Services
Em seguida, você verá opções para vincular uma fonte de dados, nomear seu aplicativo e escolher um modelo de implantação. A iteração atual desse utilitário não usa uma fonte de dados, então você pode ignorar essa etapa (independentemente disso, um cluster gratuito para você). Você também pode deixar o modelo de implantação como padrão (Global), a menos que queira limitar o aplicativo a uma região específica.
Dei o nome de Aplicativo de automação ao aplicativo:
Boas-vindas ao App Services
Clique em Create App Service. Se for apresentado a você um conjunto de guias, clique em Close Guides, pois hoje eu sou o seu guia.
A partir daqui, você tem a opção de simplesmente importar o aplicativo App Services e ajustar qualquer uma das funções para atender às suas necessidades. Se preferir criar o aplicativo do zero, pule para a próxima seção.

Importar opção

Etapa 1: armazene a chave secreta da API

A extração depende da chave secreta da API, portanto, a importação falhará se ela não for configurada previamente.
Use o menu Valores à esquerda para Criar um segredo chamado AtlasPrivateKeySecret contendo sua chave privada (o segredo não está entre aspas):
Criar um segredo

Etapa 2: instale o App Services CLI

O App Services CLI está disponível no npm. Para instalar o App Services CLI em seu sistema, certifique-se de ter o Node.js instalado e execute o seguinte comando em seu shell:
1✗ npm install -g atlas-app-services-cli

Etapa 3: extraia o arquivo do aplicativo

Baixe e extraia o AutomationApp.zip.

Etapa 4: faça login no Atlas

Para configurar seu aplicativo com o App Services CLI, você deve se conectar ao Atlas usando suas chaves de API:
1✗ appservices login --api-key="<Public API Key>" --private-api-key="<Private API Key>"
2
3Successfully logged in

Etapa 5: obtenha a ID do aplicativo

Selecione o menu Configurações do aplicativo e copie o ID do seu aplicativo:
appId

Etapa 6: importe o aplicativo

Execute o seguinte comando appservices push no diretório em que você extraiu a exportação:
1appservices push --remote="<Your App ID>"
2
3...
4A summary of changes
5...
6
7? Please confirm the changes shown above Yes
8
9Creating draft
10Pushing changes
11Deploying draft
12Deployment complete
13Successfully pushed app up:
Após a importação, substitua o AtlasPublicKey pelo valor da chave pública da API.
Chave pública do Atlas

Revise o aplicativo importado

O aplicativo importado inclui 3 triggers agendados de amostra autoexplicativos :
Acionadores
Os 3 triggers têm 3 funções associadas. As funções pauseClustersTrigger e resumeClustersTrigger fornecem um conjunto de projetos e clusters para pausar, então elas precisam ser ajustadas para atender às suas necessidades:
1 // Supply projectIDs and clusterNames...
2 const projectIDs =[
3 {
4 id: '5c5db514c56c983b7e4a8701',
5 names: [
6 'Demo',
7 'Demo2'
8 ]
9 },
10 {
11 id: '62d05595f08bd53924fa3634',
12 names: [
13 'ShardedMultiRegion'
14 ]
15 }
16];
Todas as três funções de trigger chamam a função modifyCluster, onde a maior parte do trabalho é feita.
Além disso, você encontrará duas funções de utilitário, getProjectClusters e getProjects. Essas funções não são utilizadas nesta solução, mas são fornecidas para referência se você quiser automatizar ainda mais esses processos (ou seja, remover os IDs de projeto e os nomes de cluster codificados nas funções de trigger):
Funções
Agora que você revisou o rascunho, como etapa final, implante o aplicativo do App Services.
Revisar rascunho e implantar

Opção "construa você mesmo"

Para entender o que está incluído no aplicativo, estas são as etapas para criá-lo do zero.

Etapa 1: armazene as chaves de API

As funções que precisamos criar chamarão as APIs de administração do Atlas, portanto, precisamos armazenar nossas chaves públicas e privadas de API, o que vamos fazer usando Valores e segredos. O código de amostra que forneço faz referência a esses valores como AtlasPublicKey e AtlasPrivateKey, portanto, use esses mesmos nomes, a menos que queira alterar o código em que eles são referenciados.
Você encontrará Valores no menu CRIAR:
Valores
Primeiro, crie um Valor para sua chave pública (observe que a chave está entre aspas):
Chave pública do Atlas
Crie um Segredo contendo sua chave privada (o segredo não está entre aspas):
Criar um segredo
O Segredo não pode ser acessado diretamente, portanto, crie um segundo Valor que se vincule ao segredo:
Vincular ao secret

Etapa 2: observe o(s) ID(s) do projeto

Precisamos observar os IDs dos projetos que têm clusters que queremos automatizar. Clique nos 3 pontos no canto superior esquerdo da IU para abrir as Configurações do projeto:
Configurações do projeto
Você encontrará seu ID do projeto:
ID do Projeto

Etapa 3: crie as funções

Criarei duas funções, uma função genérica para modificar um cluster e uma funçãode trigger para iterar sobre os clusters a serem pausados.
Você encontrará funções no menu CRIAR :
Funções

modifyCluster

Estou apenas demonstrando algumas coisas que você pode fazer com a automação de cluster, mas as opções são ilimitadas. A função modifyCluster a seguir é um wrapper genérico em torno da API Modificar um cluster multinuvem de um projeto para chamar a API do App Services (ou Node.js, nesse caso).
Crie uma nova função chamada modifyCluster. Defina a função como Privada, pois ela só será chamada pelo nosso trigger. As outras configurações padrão estão corretas:
Modificar função do cluster
Alterne para a aba Editor de funções e cole o seguinte código:
1/*
2 * Modifies the cluster as defined by the body parameter.
3 * See https://www.mongodb.com/pt-br/docs/atlas/reference/api-resources-spec/v2/#tag/Clusters/operation/updateCluster
4 *
5 */
6exports = async function(username, password, projectID, clusterName, body) {
7
8 // Easy testing from the console
9 if (username == "Hello world!") {
10 username = await context.values.get("AtlasPublicKey");
11 password = await context.values.get("AtlasPrivateKey");
12 projectID = "5c5db514c56c983b7e4a8701";
13 clusterName = "Demo";
14 body = {paused: false}
15 }
16
17 const arg = {
18 scheme: 'https',
19 host: 'cloud.mongodb.com',
20 path: 'api/atlas/v2/groups/' + projectID + '/clusters/' + clusterName,
21 username: username,
22 password: password,
23 headers: {'Accept': ['application/vnd.atlas.2023-11-15+json'], 'Content-Type': ['application/json'], 'Accept-Encoding': ['bzip, deflate']},
24 digestAuth:true,
25 body: JSON.stringify(body)
26 };
27
28 // The response body is a BSON.Binary object. Parse it and return.
29 response = await context.http.patch(arg);
30
31 return EJSON.parse(response.body.text());
32};
Para testar essa função, é necessário fornecer uma chave de API, um segredo de API, um ID do projeto, um nome de cluster associado a ser modificado e uma carga útil contendo as modificações que você deseja fazer. Em nosso caso, trata-se apenas de definir a propriedade pausada.
Nota: por padrão, o Console fornece "Hello world!" ao testar a execução de uma função, então meu código de função testa essa entrada e fornece alguns valores padrão para facilitar o teste.
console
1 // Easy testing from the console
2 if (username == "Hello world!") {
3 username = await context.values.get("AtlasPublicKey");
4 password = await context.values.get("AtlasPrivateKey");
5 projectID = "5c5db514c56c983b7e4a8701";
6 clusterName = "Demo";
7 body = {paused: false}
8 }
Pressione o botão Executar para ver os resultados, que serão exibidos na janela Resultado:
EXECUTAR
E você deve encontrar seu cluster sendo retomado (ou pausado):
cluster

pauseClustersTrigger

Esta função será chamada por um trigger. Como não é possível passar parâmetros para um trigger agendado, ele usa uma lista codificada de IDs do projeto e nomes de cluster associados para pausar. O ideal é que esses valores sejam armazenados em uma coleção com uma IU legal para gerenciar tudo, mas isso fica para outro dia :-).
No apêndice deste artigo, forneço funções que abrangerão todos os projetos e clusters da organização. Isso criaria uma operação verdadeiramente dinâmica que pausaria todos os clusters. Como alternativa, você poderia refatorar o código para usar uma lista de exclusão em vez de uma lista de permissão.
1/*
2 * Iterates over the provided projects and clusters, pausing those clusters
3 */
4exports = async function() {
5
6 // Supply projectIDs and clusterNames...
7 const projectIDs = [{id:'5c5db514c56c983b7e4a8701', names:['Demo', 'Demo2']}, {id:'62d05595f08bd53924fa3634', names:['ShardedMultiRegion']}];
8
9 // Get stored credentials...
10 const username = context.values.get("AtlasPublicKey");
11 const password = context.values.get("AtlasPrivateKey");
12
13 // Set desired state...
14 const body = {paused: true};
15
16 var result = "";
17
18 projectIDs.forEach(async function (project) {
19
20 project.names.forEach(async function (cluster) {
21 result = await context.functions.execute('modifyCluster', username, password, project.id, cluster, body);
22 console.log("Cluster " + cluster + ": " + EJSON.stringify(result));
23 });
24 });
25
26 return "Clusters Paused";
27};

Etapa 4: criar um trigger - pauseClusters

A capacidade de pausar e retomar um cluster é suportada pela API Modificar um cluster de um projeto. Para começar, selecione Triggers no menu à esquerda:
Menu de triggers
E adicione um gatilho.
Defina o tipo de Trigger como Agendado e o nome como pauseClusters:
Adicionar um trigger
Quanto à programação, você tem todo o poder das Expressões CRON ao seu alcance. Para este exercício, vamos presumir que queremos pausar o cluster todas as tardes às 6h. Selecione Avançado e defina o agendamento do CRON para 0 22 * * *.
Observe que a hora está em GMT, portanto, ajuste de acordo com seu fuso horário. Como esse cluster está sendo executado no Leste dos EUA, adicionarei 4 horas:
Tipo de agendamento
Verifique a janela Próximos eventos para validar a tarefa será executada quando você desejar.
A etapa final é selecionar a função a ser executada pelo trigger. Selecione a função pauseClustersTrigger.
Função do trigger
E salve o trigger.
A etapa final é REVISAR RASCUNHO E IMPLANTAR.
Revisar rascunho e implantar

Retomar o cluster

Você pode optar por retomar manualmente o(s) cluster(s) conforme necessário. Mas, para completar, vamos supor que queremos que o(s) cluster(s) seja(m) retomado(s) automaticamente às 8h no Leste dos EUA todos os dias da semana.
Duplique a função pauseClustersTrigger para uma nova função chamada resumeClustersTriggger
Função duplicada
No mínimo, edite a configuração do código de função pausada para false. Você também pode ajustar os projectIDs e clusterNames para um subconjunto de projetos a serem retomados:
1/*
2 * Iterates over the provided projects and clusters, resuming those clusters
3 */
4exports = async function() {
5
6 // Supply projectIDs and clusterNames...
7 const projectIDs = [{id:'5c5db514c56c983b7e4a8701', names:['Demo', 'Demo2']}, {id:'62d05595f08bd53924fa3634', names:['ShardedMultiRegion']}];
8
9 // Get stored credentials...
10 const username = context.values.get("AtlasPublicKey");
11 const password = context.values.get("AtlasPrivateKey");
12
13 // Set desired state...
14 const body = {paused: false};
15
16 var result = "";
17
18 projectIDs.forEach(async function (project) {
19
20 project.names.forEach(async function (cluster) {
21 result = await context.functions.execute('modifyCluster', username, password, project.id, cluster, body);
22 console.log("Cluster " + cluster + ": " + EJSON.stringify(result));
23 });
24 });
25
26 return "Clusters Paused";
27};
Em seguida, adicione um novo trigger agendado chamado resumeClusters. Defina a programação do CRON para: 0 12 * * 1-5. Próximos eventos valida para nós que isso é exatamente o que queremos:
Resumo do tipo de programação

Crie triggers: dimensionando para cima e para baixo

É comum ter cargas de trabalho que são mais exigentes durante determinadas horas do dia ou dias da semana. Em vez de executar o cluster para suportar a capacidade de pico, você pode usar essa mesma abordagem para programar o cluster para aumentar e diminuir conforme a necessidade da carga de trabalho.
OBSERVAÇÃO: os Atlas Clusters já oferecem suporte ao dimensionamento automático, o que pode muito bem atender às suas necessidades. A abordagem descrita aqui permite controlar quando seu cluster aumenta e diminui.
Digamos que queremos expandir nosso cluster todos os dias às 9h antes da nossa loja abrir.
Adicione uma nova função chamada scaleClusterUpTrigger. Aqui está o código da função. Ele é muito semelhante ao anterior, exceto pelo fato de o corpo ter sido alterado para modificar as configurações do provedor:
OBSERVAÇÃO: este exemplo representa uma topologia de região única. Se você tiver várias regiões e/ou clusters assimétricos usando nós somente leitura e/ou analíticos, basta verificar a documentação da API Modificar um cluster de um projeto para obter os detalhes da carga útil.
1exports = async function() {
2
3 // Supply projectID and clusterNames...
4 const projectID = '<Project ID>';
5 const clusterName = '<Cluster Name>';
6
7 // Get stored credentials...
8 const username = context.values.get("AtlasPublicKey");
9 const password = context.values.get("AtlasPrivateKey");
10
11 // Set the desired instance size...
12 const body = {
13 "replicationSpecs": [
14 {
15 "regionConfigs": [
16 {
17 "electableSpecs": {
18 "instanceSize": "M10",
19 "nodeCount":3
20 },
21 "priority":7,
22 "providerName": "AZURE",
23 "regionName": "US_EAST_2",
24 },
25 ]
26 }
27 ]
28 };
29
30 result = await context.functions.execute('modifyCluster', username, password, projectID, clusterName, body);
31 console.log(EJSON.stringify(result));
32
33 if (result.error) {
34 return result;
35 }
36
37 return clusterName + " scaled up";
38};
Em seguida, adicione um trigger agendado chamado scaleClusterUp. Defina a programação do CRON para: 0 13 * * *.
A redução de um cluster seria simplesmente outro trigger, agendado para ser executado quando você quiser, usando o mesmo código acima, definindo o instanceSizeName para o que você desejar.
E é isso. Espero que seja útil. Você deve ser capaz de usar as técnicas descritas aqui para chamar facilmente qualquer endpoint da API Admin do MongoDB Atlas a partir do Atlas App Services.

Apêndice

getProjects

Essa função autônoma pode ser testada no console do App Services para ver a lista de todos os projetos da sua organização. Você também pode chamá-la de outras funções para obter uma lista de projetos:
1/*
2 * Returns an array of the projects in the organization
3 * See https://docs.atlas.mongodb.com/reference/api/project-get-all/
4 *
5 * Returns an array of objects, e.g.
6 *
7 * {
8 * "clusterCount": {
9 * "$numberInt": "1"
10 * },
11 * "created": "2021-05-11T18:24:48Z",
12 * "id": "609acbef1b76b53fcd37c8e1",
13 * "links": [
14 * {
15 * "href": "https://cloud.mongodb.com/api/atlas/v1.0/groups/609acbef1b76b53fcd37c8e1",
16 * "rel": "self"
17 * }
18 * ],
19 * "name": "mg-training-sample",
20 * "orgId": "5b4e2d803b34b965050f1835"
21 * }
22 *
23 */
24exports = async function() {
25
26 // Get stored credentials...
27 const username = await context.values.get("AtlasPublicKey");
28 const password = await context.values.get("AtlasPrivateKey");
29
30 const arg = {
31 scheme: 'https',
32 host: 'cloud.mongodb.com',
33 path: 'api/atlas/v1.0/groups',
34 username: username,
35 password: password,
36 headers: {'Content-Type': ['application/json'], 'Accept-Encoding': ['bzip, deflate']},
37 digestAuth:true,
38 };
39
40 // The response body is a BSON.Binary object. Parse it and return.
41 response = await context.http.get(arg);
42
43 return EJSON.parse(response.body.text()).results;
44};

getProjectClusters

Outro exemplo de função que retorna os detalhes do cluster para um projeto fornecido.
Observe que, para testar esta função, é necessário fornecer um projectId. Por padrão, o console fornece “Hello world!”, por isso testo essa entrada e forneço alguns valores padrão para facilitar o teste.
1/*
2 * Returns an array of the clusters for the supplied project ID.
3 * See https://docs.atlas.mongodb.com/reference/api/clusters-get-all/
4 *
5 * Returns an array of objects. See the API documentation for details.
6 *
7 */
8exports = async function(project_id) {
9
10 if (project_id == "Hello world!") { // Easy testing from the console
11 project_id = "5e8f8268d896f55ac04969a1"
12 }
13
14 // Get stored credentials...
15 const username = await context.values.get("AtlasPublicKey");
16 const password = await context.values.get("AtlasPrivateKey");
17
18 const arg = {
19 scheme: 'https',
20 host: 'cloud.mongodb.com',
21 path: `api/atlas/v1.0/groups/${project_id}/clusters`,
22 username: username,
23 password: password,
24 headers: {'Content-Type': ['application/json'], 'Accept-Encoding': ['bzip, deflate']},
25 digestAuth:true,
26 };
27
28 // The response body is a BSON.Binary object. Parse it and return.
29 response = await context.http.get(arg);
30
31 return EJSON.parse(response.body.text()).results;
32};
Questões? Comentários? Vamos continuar a conversa. Junte-se a nós na comunidade de desenvolvedores do MongoDB para continuar.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Além do básico: aprimorando a API Kotlin Ktor com pesquisa vetorial


Sep 18, 2024 | 9 min read
Tutorial

Como implantar o MongoDB Atlas com o Terraform na AWS


Jan 23, 2024 | 12 min read
Artigo

Crie um site de boletim informativo com a plataforma de dados MongoDB


Sep 09, 2024 | 9 min read
Artigo

Implementação de pipelines RAG robustos: integração do Gemma 2 do Google (2B) técnicas de avaliação do MongoDB e LLM


Sep 12, 2024 | 20 min read
Sumário
  • Apêndice