Comece a usar o MongoDB Atlas sem servidor, AWS CDK e AWS sem servidor
Zuhair Ahmed, Pahud Hsieh17 min read • Published Aug 09, 2024 • Updated Aug 09, 2024
Avalie esse Tutorial
O desenvolvimento sem servidor é um modelo de execução de cloud em que os provedores de cloud e SaaS gerenciam dinamicamente a alocação e o provisionamento de servidores em seu nome, caindo para $0 quando não estão em uso. Essa abordagem permite que os desenvolvedores criem e executem aplicativos e serviços sem se preocupar com a infraestrutura subjacente, concentrando-se principalmente em escrever código para seu produto principal e lógica de negócios associada. Os desenvolvedores optam por arquiteturas sem servidor para se beneficiar da redução da sobrecarga operacional, da eficiência de custos por meio do faturamento de pagamento por uso e da capacidade de escalar facilmente os aplicativos em resposta à demanda em tempo real sem intervenção manual.
AsMongoDB Atlas serverless instances eliminam a carga intuitiva do dimensionamento da infraestrutura e permitem que você comece com uma configuração mínima para que você possa se concentrar na criação do seu aplicativo. Basta escolher uma cloud region e começar a criar com documentos que mapeiam diretamente para objetos em seu código. Seu banco de dados sem servidor será dimensionado automaticamente de acordo com o crescimento do seu aplicativo, cobrando apenas pelos recursos utilizados. Se você está apenas começando ou já tem usuários em todo o mundo, o Atlas fornece os recursos para alimentar os aplicativos mais inovadores da atualidade e, ao mesmo tempo, atender aos requisitos mais rigorosos de resiliência, escala e privacidade de dados.
Neste tutorial, mostraremos como começar a criar e implantar um aplicativo simples sem servidor que agrega dados de vendas armazenados em uma instância sem servidor do MongoDB Atlas usando oAWS Lambda como nosso mecanismo de computação e o Amazon API Gateway como nosso serviço totalmente gerenciado para criar um RESTful Interface API. Por último, mostraremos como isso é fácil usar nossas construções recém-publicadas doAWS CDK Nível 3 para incorporar melhor as práticas de infraestrutura como código (IaC) e DevOps em seu ciclo de vida de desenvolvimento de software (SDLC).
Neste guia passo a passo, mostraremos todo o processo. Iniciaremos de um diretório vazio em um Ubuntu 20.04 Ambiente LTS, mas fique à vontade para acompanhar em qualquer sistema operacional compatível de sua preferência.
Vamos começar!
- Crie uma conta MongoDB Atlas. Já tem uma conta AWS? O Atlas oferece suporte ao pagamento por uso por meio do AWS Marketplace (AWS MP) sem qualquer compromisso inicial - basta se inscrever no MongoDB Atlas por meio do AWS Marketplace.
- Criar uma chave de API programática do MongoDB Atlas (PAK)
- Instale as versões mais recentes do Node.js e npm.
- Por último, para o código do playground em execução na função Lambda, usaremos o Python, portanto, também exigiremos o Python3 e o pip instalados em seu terminal.
O AWS CDK é uma estrutura de código aberto que permite definir e provisionar a infraestrutura de cloud usando código por meio do AWS CloudFormation. Ela oferece componentes pré-configurados para facilitar o desenvolvimento de aplicativos na cloud sem a necessidade de experiência. Para obter mais detalhes, consulte o guia Começando do AWS CDK.
Você pode instalar o CDK usando npm:
1 sudo npm install -g aws-cdk
Em seguida, precisamos “bootstrap” nosso ambiente Amazon Web Services para criar os recursos necessários para gerenciar os aplicativos CDK (consulte os Docs Amazon Web Services para obter detalhes completos). Bootstrapping é o processo de preparação de um ambiente para implantação. A inicialização é uma ação única que você deve executar para cada ambiente em que implementa recursos.
O comando
cdk bootstrap
cria um bucket do Amazon S3 para armazenar arquivos, roles do AWS IAM e uma pilha do CloudFormation para gerenciar estes recursos de andaime:1 cdk bootstrap aws://ACCOUNT_NUMBER/REGION
Agora, podemos inicializar um novo aplicativo CDK usando o TypeScript. Isso é feito usando o comando cdk init:
1 cdk init -l typescript
Este comando inicializa um novo aplicativo CDK na linguagem TypeScript. Ele cria um novo diretório com os arquivos e diretórios necessários para um aplicativo CDK. Quando você inicializa um novo aplicativo AWS CDK, o CDK CLI define uma estrutura de projeto que organiza o código do aplicativo em um layout convencional. Esse layout inclui os diretórios bin e lib, entre outros, cada um servindo a uma finalidade específica no contexto de um aplicativo CDK. Veja para que serve cada um desses diretórios:
- O diretório bin contém o ponto de entrada do seu aplicação CDK . É onde você define quais pilhas do seu aplicação devem ser sincronizadas e implantadas. Normalmente, esse diretório terá um <your_project_name> arquivo.ts (com o mesmo nome do seu projeto ou outro nome significativo de sua escolha) que importa pilhas do diretório lib e as inicializa.O script do diretório bin é o ponto de partida que o CDK CLI executa para intitificar modelos do CloudFormation a partir de suas definições. Ele atua como orquestrador, informando ao CDK quais pilhas incluir no processo de síntese.
- O diretório lib é onde reside o núcleo do código de infraestrutura de nuvem do seu aplicativo. Destina-se a definir pilhas e construções de CDK, que são os blocos de construção de sua infraestrutura de Serviços Web da Amazon. Normalmente, esse diretório terá um <your_project_name-stack> arquivo.ts (com o mesmo nome do seu projeto ou outro nome significativo de sua escolha).O diretório lib contém as definições reais dessas pilhas — quais recursos elas incluem, como esses recursos são configurados e como interagem. Você pode definir várias pilhas no diretório lib e instanciá-las seletivamente no diretório bin, conforme necessário.
A
[atlas-cdk-bootstrap
3da estrutura MongoDB Atlas CDK. Essa construção simplifica o processo de preparação de seu ambiente para executar o Atlas CDK automatizando as configurações essenciais e o provisionamento de recursos.Funcionalidades principais:
- Provisionamento de usuários: a construção atlas-cdk-bootstrap cria uma função de execução dedicada no Amazon Web Services Identity and Access Management (IAM) para executar recursos de extensão CloudFormation. Isso ajuda a manter a segurança e o isolamento das operações do Atlas CDK.
- Gerenciamento de chaves de API programáticas: ele configura um AWS Secrets Manager para armazenar e gerenciar com segurança as chaves de API programáticas necessárias para interagir com os serviços do Atlas. Isso garante que credenciais confidenciais estejam protegidas e possam ser facilmente giradas.
- Ativação das extensões do CloudFormation: essa construção simplifica a ativação das extensões públicas do CloudFormation essenciais para o CDK do MongoDB Atlas. Ele fornece uma interface perfeita para os usuários especificarem os recursos específicos do CloudFormation que precisam ser implantados e configurados.
Com o
atlas-cdk-bootstrap
, você pode acelerar o processo de integração do Atlas e reduzir a complexidade da configuração do ambiente. Ao automatizar o provisionamento de usuários, o gerenciamento de credenciais e a ativação de recursos, essa construção de CDK permite que os desenvolvedores se concentrem na criação e na implementação de aplicativos usando o MongoDB Atlas sem serem prejudicados por tarefas de configuração manual.Para usar o atlas-cdk-bootstrap, primeiro precisaremos de um pacote CDK específico chamado
awscdk-resources-mongodbatlas
(veja mais detalhes sobre este pacote em nossoPágina Construct Hub ). Vamos instalá-lo:
1 npm install awscdk-resources-mongodbatlas
Para confirmar que este pacote foi instalado corretamente e para localizar seu número de versão, consulte o arquivo package.json.
Em seguida, no <your_project_name> arquivo.ts no diretório bin (normalmente o mesmo nome do seu projeto, ou seja,
cloudshell-user.ts
), exclua todo o conteúdo e atualize com:1 2 import 'source-map-support/register'; 3 import * as cdk from 'aws-cdk-lib'; 4 import { AtlasBootstrapExample } from '../lib/cloudshell-user-stack'; //replace "cloudshell-user" with name of the .ts file in the lib directory 5 6 const app = new cdk.App(); 7 const env = { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT }; 8 9 new AtlasBootstrapExample(app, 'mongodb-atlas-bootstrap-stack', { env });
Em seguida, no <your_project_name-stack> arquivo.ts no diretório lib (normalmente o mesmo nome do seu projeto concatenado com "-stack ", ou seja,
cloudshell-user-stack.ts
), exclua todo o conteúdo e atualize com:1 import * as cdk from 'aws-cdk-lib' 2 import { Construct } from 'constructs' 3 import { 4 MongoAtlasBootstrap, 5 MongoAtlasBootstrapProps, 6 AtlasBasicResources 7 } from 'awscdk-resources-mongodbatlas' 8 9 export class AtlasBootstrapExample extends cdk.Stack { 10 constructor (scope: Construct, id: string, props?: cdk.StackProps) { 11 super(scope, id, props) 12 13 const roleName = 'MongoDB-Atlas-CDK-Excecution' 14 const mongoDBProfile = 'development' 15 16 const bootstrapProperties: MongoAtlasBootstrapProps = { 17 roleName, secretProfile: mongoDBProfile, 18 typesToActivate: ['ServerlessInstance', ...AtlasBasicResources] 19 } 20 21 new MongoAtlasBootstrap(this, 'mongodb-atlas-bootstrap', bootstrapProperties) 22 } 23 }
Por último, você pode verificar e implantar a construção atlas-cdk-bootstrap CDK com:
1 npx cdk diff mongodb-atlas-bootstrap-stack 2 npx cdk deploy mongodb-atlas-bootstrap-stack
Agora que a construção atlas-cdk-bootstrap CDK foi provisionada, armazenamos nossas chaves de API programáticas do MongoDB Atlascriadas anteriormente no AWS Secrets Manager. Para obter mais informações sobre como criar o MongoDB Atas PAK, consulte a etapa 2 de nossa configuração de pré-requisitos.
Isso permitirá que a função de execução da CloudFormation Extension provisione os principais componentes, incluindo:Instância sem servidordo MongoDB Atlas, Atlas project, Lista de acesso IP do projeto Atlase usuário de banco de dados.
Primeiro, precisamos armazenar esses segredos como variáveis de ambiente:
1 export MONGO_ATLAS_PUBLIC_KEY=’INPUT_YOUR_PUBLIC_KEY' 2 export MONGO_ATLAS_PRIVATE_KEY=’INPUT_YOUR_PRIVATE_KEY'
Em seguida, podemos atualizar o AWS Secrets Manager com o seguinte comando da AWS CLI:
1 aws secretsmanager update-secret --secret-id cfn/atlas/profile/development --secret-string "{\"PublicKey\":\"${MONGO_ATLAS_PUBLIC_KEY}\",\"PrivateKey\":\"${MONGO_ATLAS_PRIVATE_KEY}\"}"
As construções do AWS CDK Level 3 (L3) são abstrações de alto nível que encapsulam um conjunto de recursos e lógica de configuração relacionados da AWS em componentes reutilizáveis, permitindo que os desenvolvedores definam a infraestrutura de nuvem usando linguagens de programação familiares com menos código. Os desenvolvedores usam construções L3 para simplificar o processo de configuração de serviços complexos do AWS e do MongoDB Atlas, garantindo as melhores práticas, reduzindo o código clichê e aumentando a produtividade por meio de sintaxe simplificada.
A construção do MongoDB Atlas AWS CDK L3 para Atlas Serverless Basic oferece aos desenvolvedores uma maneira fácil e idiomática de implementar instâncias sem servidor do MongoDB Atlas em ambientes AWS. Sob o capot, essa construção abstrai os meandros da configuração e implantação de instâncias sem servidor do MongoDB Atlas e da infraestrutura relacionada em seu nome.
Em seguida, atualizamos nosso <your_project_name> arquivo.ts no diretório bin para:
- Adicione o AtlasServerlessBasicStack à declaração de importação.
- Adicione o IP do gateway NAT, que sugerimos ser o único IP na lista de permissões de acesso à MongoDB Atlas serverless instance.
1 2 import 'source-map-support/register'; 3 import * as cdk from 'aws-cdk-lib'; 4 import { AtlasBootstrapExample, AtlasServerlessBasicStack } from '../lib/cloudshell-user-stack'; //update "cloudshell-user" with your stack name 5 6 const app = new cdk.App(); 7 const env = { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT }; 8 9 // the bootstrap stack 10 new AtlasBootstrapExample(app, 'mongodb-atlas-bootstrap-stack', { env }); 11 12 type AccountConfig = { 13 readonly orgId: string; 14 readonly projectId?: string; 15 } 16 17 const MyAccount: AccountConfig = { 18 orgId: '63234d3234ec0946eedcd7da', //update with your Atlas Org ID 19 }; 20 21 const MONGODB_PROFILE_NAME = 'development'; 22 23 // the serverless stack with mongodb atlas serverless instance 24 const serverlessStack = new AtlasServerlessBasicStack(app, 'atlas-serverless-basic-stack', { 25 env, 26 ipAccessList: '46.137.146.59', //input your static IP Address from NAT Gateway 27 profile: MONGODB_PROFILE_NAME, 28 ...MyAccount, 29 });
Para aproveitar isso, podemos atualizar nosso <your_project_name-stack> arquivo.ts no diretório lib para:
- Atualize os blocos de importação para recursos recém-usados.
- Ative os recursos subjacentes do CloudFormation no registro do CloudFormation de terceiros.
- Crie um nome de usuário e senha de banco de dados e armazene-os no AWS Secrets Manager.
- Atualize os blocos de saída para exibir a connection string e o nome do projeto do Atlas sem servidor.
1 import * as path from 'path'; 2 import { 3 App, Stack, StackProps, 4 Duration, 5 CfnOutput, 6 SecretValue, 7 aws_secretsmanager as secretsmanager, 8 } from 'aws-cdk-lib'; 9 import * as cdk from 'aws-cdk-lib'; 10 import { SubnetType } from 'aws-cdk-lib/aws-ec2'; 11 import { 12 MongoAtlasBootstrap, 13 MongoAtlasBootstrapProps, 14 AtlasBasicResources, 15 AtlasServerlessBasic, 16 ServerlessInstanceProviderSettingsProviderName, 17 } from 'awscdk-resources-mongodbatlas'; 18 import { Construct } from 'constructs'; 19 20 21 export class AtlasBootstrapExample extends cdk.Stack { 22 constructor (scope: Construct, id: string, props?: cdk.StackProps) { 23 super(scope, id, props) 24 25 const roleName = 'MongoDB-Atlas-CDK-Excecution' 26 const mongoDBProfile = 'development' 27 28 const bootstrapProperties: MongoAtlasBootstrapProps = { 29 roleName: roleName, 30 secretProfile: mongoDBProfile, 31 typesToActivate: ['ServerlessInstance', ...AtlasBasicResources] 32 } 33 34 new MongoAtlasBootstrap(this, 'mongodb-atlascdk-bootstrap', bootstrapProperties) 35 } 36 } 37 38 export interface AtlasServerlessBasicStackProps extends StackProps { 39 readonly profile: string; 40 readonly orgId: string; 41 readonly ipAccessList: string; 42 } 43 export class AtlasServerlessBasicStack extends Stack { 44 readonly dbUserSecret: secretsmanager.ISecret; 45 readonly connectionString: string; 46 constructor(scope: Construct, id: string, props: AtlasServerlessBasicStackProps) { 47 super(scope, id, props); 48 49 const stack = Stack.of(this); 50 const projectName = `${stack.stackName}-proj`; 51 52 const dbuserSecret = new secretsmanager.Secret(this, 'DatabaseUserSecret', { 53 generateSecretString: { 54 secretStringTemplate: JSON.stringify({ username: 'serverless-user' }), 55 generateStringKey: 'password', 56 excludeCharacters: '%+~`#$&*()|[]{}:;<>?!\'/@"\\=-.,', 57 }, 58 }); 59 60 this.dbUserSecret = dbuserSecret; 61 const ipAccessList = props.ipAccessList; 62 63 // see https://github.com/mongodb/awscdk-resources-mongodbatlas/blob/main/examples/l3-resources/atlas-serverless-basic.ts#L22 64 const basic = new AtlasServerlessBasic(this, 'serverless-basic', { 65 serverlessProps: { 66 profile: props.profile, 67 providerSettings: { 68 providerName: ServerlessInstanceProviderSettingsProviderName.SERVERLESS, 69 regionName: 'EU_WEST_1', 70 }, 71 }, 72 projectProps: { 73 orgId: props.orgId, 74 name: projectName, 75 }, 76 dbUserProps: { 77 username: 'serverless-user', 78 }, 79 ipAccessListProps: { 80 accessList: [ 81 { ipAddress: ipAccessList, comment: 'My first IP address' }, 82 ], 83 }, 84 profile: props.profile, 85 }); 86 87 this.connectionString = basic.mserverless.getAtt('ConnectionStrings.StandardSrv').toString(); 88 89 new CfnOutput(this, 'ProjectName', { value: projectName }); 90 new CfnOutput(this, 'ConnectionString', { value: this.connectionString }); 91 } 92 }
Por último, você pode verificar e implantar a construção atlas-serverless-basic CDK com:
1 npx cdk diff atlas-serverless-basic-stack 2 npx cdk deploy atlas-serverless-basic-stack
Verifique na interface do usuário do Atlas, bem como no Console de gerenciamento da AWS, se todos os recursos subjacentes do MongoDB Atlas foram criados. Observe que o nome de usuário e a senha do banco de dados são armazenados como um novo segredo no AWS Secrets Manager (conforme especificado na região da AWS de sua escolha acima).
Quando criamos inicialmente as credenciais de usuário do banco de dados Atlas, criamos uma senha aleatória e não podemos simplesmente copiá-la para o AWS Secrets Manager porque isso exporia a senha do banco de dados em nosso modelo do CloudFormation.
Para evitar isso, precisamos atualizar manualmente a senha de usuário do banco de dados do MongoDB Atlas a partir do segredo armazenado no AWS Secrets Manager para que eles estejam sincronizados. Em seguida, a função do AWS Lambda selecionará essa senha do AWS Secrets Manager para se autenticar com êxito na instância sem servidor do Atlas.
Podemos fazer isso programaticamente por meio do Atlas CLI. Para começar, primeiro precisamos verificar se configuramos com a PAK correta que criamos como parte de nossa configuração inicial:
1 atlas config init
Em seguida, inserimos a PAK correta e selecionamos o ID do projeto correto. Por exemplo:
Em seguida, podemos simplesmente atualizar nossas credenciais de senha de usuário do banco de dados MongoDB Atlas, que podemos copiar do Console de gerenciamento da AWS. Isso pode ser feito com o comando:
1 atlas dbusers update serverles-user --password INSERT_YOUR_AWS_SECRET_MANAGER_PASSWORD
Você pode verificar essa operação revisando a resposta da interface do usuário do Atlas (“Successfully updated database user
serverless-user
”) ou verificando a seção Acesso ao banco de dados na interface do usuário do Atlas.Neste ponto, todos os seus serviços principais do MongoDB Atlas devem ter sido provisionados com sucesso. Em seguida, passamos a provisionar o AWS Lambda restante, a função Lambda baseada em Python e as construções CDK do Amazon API Gateway.
Em seguida, atualizamos nosso <your_project_name> arquivo.ts no diretório bin:
- Consulte seu VPC ID da criado em sua Amazon Web Services conta do .
- Para recuperar os IDs de VPC na região da AWS em que você deseja implantar, basta usar o comando CLI da AWS:
1 aws ec2 describe-vpcs
- Crie o recurso AWS Lambda e associe-se à função Lambda.
- Crie a API do gateway de API com o manipulador Lambda.
1 2 import 'source-map-support/register'; 3 import * as path from 'path'; 4 import { 5 aws_ec2 as ec2, 6 aws_lambda as lambda, 7 aws_apigateway as apigw, 8 Duration, 9 } from 'aws-cdk-lib'; 10 import * as cdk from 'aws-cdk-lib'; 11 import { SubnetType } from 'aws-cdk-lib/aws-ec2'; 12 import { AtlasBootstrapExample, AtlasServerlessBasicStack } from '../lib/cloudshell-user-stack'; //update "cloudshell-user" with your .ts filename 13 14 const app = new cdk.App(); 15 const env = { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT }; 16 17 // the bootstrap stack 18 new AtlasBootstrapExample(app, 'mongodb-atlas-bootstrap-stack', { env }); 19 20 type AccountConfig = { 21 readonly orgId: string; 22 readonly projectId?: string; 23 } 24 25 const MyAccount: AccountConfig = { 26 orgId: '63234d3234ec0946eedcd7da', //update with your Atlas Org ID 27 }; 28 29 const MONGODB_PROFILE_NAME = 'development'; 30 31 // the serverless stack with mongodb atlas serverless instance 32 const serverlessStack = new AtlasServerlessBasicStack(app, 'atlas-serverless-basic-stack', { 33 env, 34 ipAccessList: '46.137.146.59', //input your static IP Address from NAT Gateway 35 profile: MONGODB_PROFILE_NAME, 36 ...MyAccount, 37 }); 38 39 // Reference your VPC ID created in your AWS Account 40 const vpc = ec2.Vpc.fromLookup(serverlessStack, 'VPC', { 41 vpcId: 'vpc-0060b48b973dbe4a5', // Use your actual VPC ID here 42 }); 43 44 // The demo lambda function. 45 const handler = new lambda.Function(serverlessStack, 'LambdaFunc', { 46 code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/playground')), 47 runtime: lambda.Runtime.PYTHON_3_10, 48 handler: 'index.handler', 49 timeout: Duration.seconds(30), 50 51 vpc, 52 vpcSubnets: { 53 subnetType: SubnetType.PRIVATE_WITH_EGRESS, 54 }, 55 56 environment: { 57 CONN_STRING_STANDARD: serverlessStack.connectionString, 58 DB_USER_SECRET_ARN: serverlessStack.dbUserSecret.secretArn, 59 }, 60 }); 61 62 // allow the handler to read the db user secret 63 serverlessStack.dbUserSecret.grantRead(handler); 64 65 // create the API Gateway REST API with the lambda handler. 66 new apigw.LambdaRestApi(serverlessStack, 'RestAPI', { handler });
Em seguida, criamos diretórios de função Lambda:
1 mkdir -p lambda/playground 2 touch lambda/playground/index.py
O código Python abaixo é uma função demanipulador para uma função do AWS Lambda que interage com a instância sem servidor do MongoDB Atlas por meio de um endpoint público. Ele obtém credenciais de banco de dados do AWS Secrets Manager, constrói uma connection string do MongoDB Atlas usando essas credenciais e se conecta à instância sem servidor do MongoDB Atlas.
Em seguida, a função gera e insere 20 registros de vendas de amostra com dados aleatórios em uma coleção de vendas dentro do banco de dados. Ele também agrega dados de vendas para o ano 2023, contando o número de vendas e somando o valor total de vendas por item. Por fim, ela imprime a contagem de vendas em 2023 e os resultados da agregação, retornando essas informações como uma resposta JSON.
Portanto, preenchemos o Lambda/playground/index.py com:
1 from datetime import datetime, timedelta 2 from pymongo.mongo_client import MongoClient 3 from pymongo.server_api import ServerApi 4 import random, json, os, re, boto3 5 6 # Function to generate a random datetime between two dates 7 def random_date(start_date, end_date): 8 time_delta = end_date - start_date 9 random_days = random.randint(0, time_delta.days) 10 return start_date + timedelta(days=random_days) 11 12 def get_private_endpoint_srv(mongodb_uri, username, password): 13 """ 14 Get the private endpoint SRV address from the given MongoDB URI. 15 e.g. `mongodb+srv://my-cluster.mzvjf.mongodb.net` will be converted to 16 `mongodb+srv://<username>:<password>@my-cluster-pl-0.mzvjf.mongodb.net/?retryWrites=true&w=majority` 17 """ 18 match = re.match(r"mongodb\+srv://(.+)\.(.+).mongodb.net", mongodb_uri) 19 if match: 20 return "mongodb+srv://{}:{}@{}-pl-0.{}.mongodb.net/?retryWrites=true&w=majority".format(username, password, match.group(1), match.group(2)) 21 else: 22 raise ValueError("Invalid MongoDB URI: {}".format(mongodb_uri)) 23 24 def get_public_endpoint_srv(mongodb_uri, username, password): 25 """ 26 Get the private endpoint SRV address from the given MongoDB URI. 27 e.g. `mongodb+srv://my-cluster.mzvjf.mongodb.net` will be converted to 28 `mongodb+srv://<username>:<password>@my-cluster.mzvjf.mongodb.net/?retryWrites=true&w=majority` 29 """ 30 match = re.match(r"mongodb\+srv://(.+)\.(.+).mongodb.net", mongodb_uri) 31 if match: 32 return "mongodb+srv://{}:{}@{}.{}.mongodb.net/?retryWrites=true&w=majority".format(username, password, match.group(1), match.group(2)) 33 else: 34 raise ValueError("Invalid MongoDB URI: {}".format(mongodb_uri)) 35 36 37 client = boto3.client('secretsmanager') 38 conn_string_srv = os.environ.get('CONN_STRING_STANDARD') 39 secretId = os.environ.get('DB_USER_SECRET_ARN') 40 json_secret = json.loads(client.get_secret_value(SecretId=secretId).get('SecretString')) 41 username = json_secret.get('username') 42 password = json_secret.get('password') 43 44 def handler(event, context): 45 # conn_string_private = get_private_endpoint_srv(conn_string_srv, username, password) 46 conn_string = get_public_endpoint_srv(conn_string_srv, username, password) 47 print('conn_string=', conn_string) 48 49 client = MongoClient(conn_string, server_api=ServerApi('1')) 50 51 # Select the database to use. 52 db = client['mongodbVSCodePlaygroundDB'] 53 54 # Create 20 sample entries with dates spread between 2021 and 2023. 55 entries = [] 56 57 for _ in range(20): 58 item = random.choice(['abc', 'jkl', 'xyz', 'def']) 59 price = random.randint(5, 30) 60 quantity = random.randint(1, 20) 61 date = random_date(datetime(2021, 1, 1), datetime(2023, 12, 31)) 62 entries.append({ 63 'item': item, 64 'price': price, 65 'quantity': quantity, 66 'date': date 67 }) 68 69 # Insert a few documents into the sales collection. 70 sales_collection = db['sales'] 71 sales_collection.insert_many(entries) 72 73 # Run a find command to view items sold in 2023. 74 sales_2023 = sales_collection.count_documents({ 75 'date': { 76 '$gte': datetime(2023, 1, 1), 77 '$lt': datetime(2024, 1, 1) 78 } 79 }) 80 81 # Print a message to the output window. 82 print(f"{sales_2023} sales occurred in 2023.") 83 84 pipeline = [ 85 # Find all of the sales that occurred in 2023. 86 { '$match': { 'date': { '$gte': datetime(2023, 1, 1), '$lt': datetime(2024, 1, 1) } } }, 87 # Group the total sales for each product. 88 { '$group': { '_id': '$item', 'totalSaleAmount': { '$sum': { '$multiply': [ '$price', '$quantity' ] } } } } 89 ] 90 91 cursor = sales_collection.aggregate(pipeline) 92 results = list(cursor) 93 print(results) 94 response = { 95 'statusCode': 200, 96 'headers': { 97 'Content-Type': 'application/json' 98 }, 99 'body': json.dumps({ 100 'sales_2023': sales_2023, 101 'results': results 102 }) 103 } 104 105 return response
Por último, precisamos criar um último arquivo que armazenará nossos requisitos para o aplicativo de playground Python com:
1 touch lambda/playground/requirements.txt
Neste arquivo, preenchemos com:
1 pymongo 2 requests 3 boto3 4 testresources 5 urllib3==1.26
Para instalar as dependências usadas em requires.txt:
1 cd lambda/playground 2 pip install -r requirements.txt -t .
Isso instala todos os pacotes Python necessários no diretório do playground e o AWS CDK seria agrupado em um arquivo zip que podemos ver no console do AWS Lambda após a implantação.
As funções do AWS Lambda colocadas em sub-redes públicas não têm acesso automático à Internet porque as funções do Lambda não têm endereços IP públicos e uma sub-rede pública roteia o tráfego por meio de um gateway de internet (IGW). Para acessar a internet, uma função Lambda pode ser associada a uma sub-rede privada com uma rota para um gateway NAT.
Primeiro, certifique-se de ter um gateway NAT criado em sua sub-rede pública. Em seguida, crie uma rota de uma sub-rede privada (onde seu recurso do Amazon Web Services Lambda residirá) para o gateway NAT e roteará a sub-rede pública para o IGW. Os benefícios dessa abordagem de rede é que podemos associar um IP estático ao nosso gateway NAT, de modo que essa será nossa única entrada na lista de acesso IP do projeto Atlas. Isso significa que todo o tráfego ainda vai para a Internet pública por meio do gateway NAT e é criptografado por TLS. A lista de permissões só permite o IP público estático do gateway NAT e nada mais.
Como alternativa, você pode optar por construir com o AWS PrivateLink, que carrega custos adicionais, mas simplificará drasticamente o gerenciamento de rede ao conectar diretamente o AWS Lambda a uma instância sem servidor do MongoDB Atlas sem a necessidade de manter sub-redes, IGWs ou gateways NAT. Além disso, o AWS PrivateLink cria uma conexão privada com os serviços da AWS, reduzindo o risco de exposição de dados à Internet pública.
Selecione qualquer abordagem de rede que melhor se adapte às necessidades da sua organização.
- Um cliente HTTP fora da AWS Cloud envia uma solicitação para o Amazon API Gateway.
- O Amazon API Gateway, representado por um ícone cor-de-laser, recebe a solicitação HTTP e a passa para o AWS Lambda, simbolizado por um ícone laranja. O AWS Lambda é um serviço de computação sem servidor que gerencia automaticamente os recursos de computação.
- O ambiente da nuvem da AWS é dividido em uma nuvem privada virtual (VPC), indicado por uma borda azul.
- Dentro da VPC, existem dois tipos de sub-redes:
- Uma sub-rede pública, que tem acesso direto à Internet por meio de um gateway de Internet, representado por um ícone roxo.
- Uma sub-rede privada, que não tem acesso direto à Internet.
- Para permitir que a função AWS Lambda dentro da sub-rede Privada acesse a Internet, é usado um Gateway NAT (tradução de endereços de rede), mostrado com um ícone NAT púrpura. O Gateway NAT está localizado na sub-rede Pública.
- O tráfego da função do AWS Lambda é roteado por meio do Gateway NAT para acessar serviços externos.
- O serviço externo com o qual a função do AWS Lambda está se comunicando é uma Instância sem Servidor do MongoDB Atlas, indicado por um ícone verde com um símbolo de banco de dados. Essa instância está fora da Nuvem AWS e pode ser acessada pela Internet.”
Os componentes dessa arquitetura são os seguintes:
- No lado esquerdo, um "cliente HTTP" representado por um ícone de cloud, está iniciando uma solicitação.
- Essa solicitação é enviada para o "Amazon API Gateway", indicado por um ícone laranja com dois colchetes e um símbolo de raio, sugerindo que é um ponto de entrada para APIs.
- Abaixo do API Gateway, há uma função "AWS Lambda", simbolizada por um ícone laranja do Lambda (Í), que é um serviço de computação sem servidor na AWS.
- A função Lambda está dentro de um limite da "Amazon Web Services Cloud ", mostrado com um Contorno escuro.
- Dentro da AWS Cloud, há uma "VPC" representada por uma borda azul, que é uma parte segregada da AWS Cloud, isolada de outras redes.
- Dentro da VPC, há um "VPC Endpoint" representado por um ícone circular com uma borda lilas e uma seta voltada para dentro, indicando que é um gateway para conexões privadas.
- O "AWS PrivateLink", mostrado com um ícone púrpura semelhante a uma cloud, facilita a conectividade privada entre serviços na AWS, ignorando a Internet pública.
- À direita, há uma "Instância sem servidor do MongoDB Atlas" representada com um ícone de banco de dados verde e um plug, indicando que é um serviço externo conectado via PrivateLink.”
Finalmente, estamos prontos para verificar e implantar o mongodb-atlas-bootstrap-stack pela última vez:
1 npx cdk diff atlas-serverless-basic-stack 2 npx cdk deploy atlas-serverless-basic-stack
Analise o Console de gerenciamento da AWS. Veja em CloudFormation e Lambda:
Clique em "Rest API Endpoint " para ver se a função Lambda retorna uma resposta:
Revise a função Lambda inserindo em um navegador da web.
A estrutura JSON implica que a função Lambda está funcionando corretamente, pois é capaz de executar e retornar dados estruturados. Se você precisar testar ainda mais essa função do Lambda ou integrá-la a outros serviços, normalmente faria isso chamando esse endpoint da REST API do seu aplicativo com o método HTTP apropriado (GET, POST etc.), cabeçalhos e quaisquer parâmetros necessários. ou conteúdo corporal.
Por último, você também pode curl este endpoint da API:
1 curl -s https://[REDACTED].execute-api.eu-west-1.amazonaws.com/prod/ | jq -r .
1 npx cdk destroy atlas-serverless-basic-stack
E então, finalmente:
1 npx cdk destroy mongodb-atlas-bootstrap-stack
Observação: essa ordem garante que a pilha sem servidor seja destruída primeiro. Se você usar o comando
npx cdk destroy --all
em vez disso, como não especificamos a dependência da pilha, todas as pilhas serão excluídas em paralelo, o que pode causar falhas. Isso ocorre porque perderemos os recursos de bootstrap necessários antes de destruir todos os outros recursos.Parabéns! Você acabou de implementar seu primeiro aplicativo serverless com o MongoDB Atlas serverless, AWS Lambda e Amazon API Gateway com o AWS CDK.
Em seguida, acesse o YouTube para obter uma visão geral passo a passo e instruções passo a passo em um capítulo recente do MongoDB Tv Cloud Connect (que foi ao ar 15 fevereiro 2024). Além disso, consulte o repositório doGitHub com o código fonte aberto completo dos materiais usados neste aplicativo de demonstração sem servidor.
Os recursos do MongoDB Atlas CDK são de código aberto sob o Apache-2.0 licença e aceitamos contribuições da comunidade. Para saber mais, consulte nossas diretrizes de contribuição.
Comece rapidamente criando uma conta do MongoDB Atlas por meio do AWS Marketplace e comece a criar com o MongoDB Atlas e o AWS CDK hoje mesmo!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.