Implantação AWS no Cursor: Guia Completo

A Amazon Web Services (AWS) é a plataforma de nuvem mais amplamente adotada, oferecendo computação, armazenamento, bancos de dados e dezenas de serviços gerenciados de nível superior. Implantar aplicações na AWS envolve escrever código de infraestrutura, empacotar funções, gerenciar armazenamento e orquestrar fluxos de trabalho de release. O Cursor, com seu assistente de IA e rico ecossistema de extensões, é um ambiente poderoso para desenvolvimento AWS — ele pode gerar manipuladores Lambda, modelos CloudFormation e scripts de implantação a partir de prompts em linguagem natural.
Este guia orienta você pelo fluxo de trabalho completo de implantação AWS no Cursor: integração do SDK AWS, construção e implantação de funções Lambda, trabalho com S3 para armazenamento, criação de infraestrutura CloudFormation as code e uso de IA para acelerar cada etapa.
Configurando a Cadeia de Ferramentas AWS no Cursor
Instalando a Extensão AWS Toolkit
A extensão AWS Toolkit traz navegação de recursos AWS, execução local de Lambda, visualização de CloudWatch Logs e suporte SAM (Serverless Application Model) diretamente para o Cursor.
- Abra a visualização de Extensões (
Ctrl+Shift+X). - Pesquise por "AWS Toolkit".
- Clique em Install.
Após a instalação, o ícone da AWS aparece na barra de atividades. A extensão fornece:
- Um navegador de recursos para Lambda, S3, CloudFormation e DynamoDB.
- Invocação local de Lambda com a SAM CLI.
- Visualizador do Step Functions.
- Streaming de CloudWatch Logs.
- Scaffolding de projetos CDK e SAM.
O AWS Toolkit exige que as credenciais AWS estejam configuradas em sua máquina. O Cursor lê o mesmo arquivo de credenciais (~/.aws/credentials) que a AWS CLI, então quaisquer perfis existentes funcionam imediatamente.
Configurando Credenciais AWS
Crie um perfil de credenciais usando a AWS CLI:
npm install -g aws-cli
aws configure
O prompt interativo coleta:
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json
Para configurações multi-conta, crie perfis nomeados:
# ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[production]
aws_access_key_id = AKIAPRODUCTIONKEY
aws_secret_access_key = productionsecretkeyexample
# ~/.aws/config
[profile production]
region = us-west-2
output = json
Nunca commite credenciais AWS no controle de versão. Adicione .aws/ ao .gitignore e prefira funções IAM ou tokens STS de curta duração em vez de chaves de acesso de longa duração. Para produção, use aws-vault para gerenciar credenciais com MFA.
Instalando a AWS SAM CLI
A CLI SAM (Serverless Application Model) permite construir, testar localmente e implantar aplicações baseadas em Lambda:
# Windows (usando winget)
winget install AWS.SAM-CLI
# macOS (usando Homebrew)
brew install aws-sam-cli
# Verificar
sam --version
Integrando o SDK AWS
Instalando o SDK para JavaScript
Para aplicações Node.js, instale o SDK AWS v3 modular:
npm install @aws-sdk/client-s3 @aws-sdk/client-lambda @aws-sdk/client-dynamodb
O SDK AWS v3 é modular — você instala apenas os clientes necessários, o que reduz drasticamente o tamanho do bundle em comparação com o SDK v2 monolítico. Cada serviço é um pacote separado sob @aws-sdk/client-*.
Configurando o Cliente SDK
// lib/aws/clients.ts
import { S3Client } from '@aws-sdk/client-s3';
import { LambdaClient } from '@aws-sdk/client-lambda';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
const region = process.env.AWS_REGION ?? 'us-east-1';
export const s3Client = new S3Client({ region });
export const lambdaClient = new LambdaClient({ region });
export const dynamoClient = new DynamoDBClient({ region });
Para credenciais específicas de ambiente (útil em CI):
import { fromIni } from '@aws-sdk/credential-providers';
export const s3Client = new S3Client({
region,
credentials: fromIni({ profile: 'production' }),
});
Construindo e Implantando Funções Lambda
Scaffolding de um Manipulador Lambda
Use a IA do Cursor para fazer o scaffolding de um manipulador Lambda. Abra Ctrl+K e insira o prompt:
Create an AWS Lambda handler in TypeScript using the @types/aws-lambda
package. It should accept an API Gateway proxy event, validate the JSON body
against a Zod schema, and return a 200 response with the processed result.
Include structured logging and error handling.
O manipulador gerado:
// src/handlers/createUser.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
age: z.number().int().min(0).optional(),
});
export const handler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
console.log('Received event:', JSON.stringify(event, null, 2));
try {
const body = JSON.parse(event.body ?? '{}');
const parsed = userSchema.parse(body);
const user = {
id: crypto.randomUUID(),
...parsed,
createdAt: new Date().toISOString(),
};
return {
statusCode: 201,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user),
};
} catch (error) {
console.error('Error processing request:', error);
if (error instanceof z.ZodError) {
return {
statusCode: 400,
body: JSON.stringify({ message: 'Validation failed', errors: error.errors }),
};
}
return {
statusCode: 500,
body: JSON.stringify({ message: 'Internal server error' }),
};
}
};
Teste Local com SAM
Crie um template.yaml para SAM:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: User service Lambda
Resources:
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/handlers
Handler: createUser.handler
Runtime: nodejs20.x
MemorySize: 256
Timeout: 30
Events:
CreateUser:
Type: Api
Properties:
Path: /users
Method: POST
Environment:
Variables:
TABLE_NAME: !Ref UsersTable
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: users
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
Outputs:
ApiUrl:
Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/users'
Invoque a função localmente com um evento de exemplo:
sam build
sam local invoke CreateUserFunction --event events/createUser.json
Arquivo de evento de exemplo:
{
"httpMethod": "POST",
"headers": { "Content-Type": "application/json" }
}
A extensão AWS Toolkit no Cursor adiciona um comando "Run Locally" para funções Lambda. Clique com o botão direito em uma função no painel AWS Explorer e escolha Invoke on AWS ou Run Locally para testar sem sair do editor.
Implantando com SAM
# Primeira implantação (guiada)
sam deploy --guided
# Implantações subsequentes
sam deploy --stack-name user-service --capabilities CAPABILITY_IAM
O prompt guiado coleta:
Stack Name [sam-app]: user-service
AWS Region [us-east-1]: us-east-1
Confirm changes before deploy [Y/n]: Y
Allow SAM CLI IAM role creation [Y/n]: Y
Disable rollback [Y/n]: n
Save arguments to configuration file [Y/n]: Y
As implantações SAM criam funções IAM automaticamente. Revise cuidadosamente o resumo do changeset antes de confirmar — uma função mal configurada pode conceder permissões excessivamente amplas que violam o princípio do menor privilégio em produção.
Trabalhando com S3 para Armazenamento
Enviando Arquivos para S3
// src/storage/upload.ts
import { s3Client } from '../aws/clients';
import { PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
const BUCKET = process.env.UPLOAD_BUCKET ?? 'my-app-uploads';
export async function uploadFile(
key: string,
body: Buffer,
contentType: string
): Promise<string> {
const command = new PutObjectCommand({
Bucket: BUCKET,
Key: key,
Body: body,
ContentType: contentType,
});
await s3Client.send(command);
return `s3://${BUCKET}/${key}`;
}
export async function getDownloadUrl(key: string, expiresIn = 3600): Promise<string> {
const command = new GetObjectCommand({ Bucket: BUCKET, Key: key });
return getSignedUrl(s3Client, command, { expiresIn });
}
Streaming de Arquivos Grandes
Para uploads grandes, use multipart upload:
// src/storage/multipart.ts
import { s3Client } from '../aws/clients';
import {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
} from '@aws-sdk/client-s3';
import { createReadStream } from 'fs';
const BUCKET = process.env.UPLOAD_BUCKET ?? 'my-app-uploads';
export async function uploadLargeFile(key: string, filePath: string): Promise<void> {
const create = await s3Client.send(
new CreateMultipartUploadCommand({ Bucket: BUCKET, Key: key })
);
const uploadId = create.UploadId!;
const partSize = 5 * 1024 * 1024; // 5 MB minimum
const stream = createReadStream(filePath, { highWaterMark: partSize });
const parts: { ETag: string; PartNumber: number }[] = [];
let partNumber = 1;
for await (const chunk of stream) {
const upload = await s3Client.send(
new UploadPartCommand({
Bucket: BUCKET,
Key: key,
UploadId: uploadId,
PartNumber: partNumber,
Body: chunk,
})
);
parts.push({ ETag: upload.ETag!, PartNumber: partNumber });
partNumber++;
}
await s3Client.send(
new CompleteMultipartUploadCommand({
Bucket: BUCKET,
Key: key,
UploadId: uploadId,
MultipartUpload: { Parts: parts },
})
);
}
Use a IA do Cursor para gerar fluxos de URL pré-assinada. Prompt: "Crie uma função Lambda que gera uma URL pré-assinada de upload S3, valida a extensão do arquivo e armazena metadados no DynamoDB."
CloudFormation Infrastructure as Code
Escrevendo Modelos CloudFormation
O CloudFormation permite definir toda a sua infraestrutura em YAML ou JSON declarativo. A IA do Cursor é excelente na geração de modelos a partir de descrições.
Modelo de exemplo para uma stack de aplicação web:
# templates/webapp.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Production web application stack
Parameters:
Environment:
Type: String
Default: production
AllowedValues: [staging, production]
DomainName:
Type: String
Description: Custom domain name
Resources:
ApplicationBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${AWS::StackName}-app-${Environment}'
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: ExpireOldVersions
Status: Enabled
NoncurrentVersionExpirationInDays: 90
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
DefaultRootObject: index.html
Origins:
- DomainName: !GetAtt ApplicationBucket.RegionalDomainName
Id: S3Origin
S3OriginConfig: {}
DefaultCacheBehavior:
TargetOriginId: S3Origin
ViewerProtocolPolicy: redirect-to-https
AllowedMethods: [GET, HEAD]
CachedMethods: [GET, HEAD]
ForwardedValues:
QueryString: false
PriceClass: PriceClass_100
ViewerCertificate:
CloudFrontDefaultCertificate: true
ApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Sub '${AWS::StackName}-api'
EndpointConfiguration:
Types: [REGIONAL]
Outputs:
WebsiteUrl:
Value: !Sub 'https://${CloudFrontDistribution.DomainName}'
Description: URL of the deployed website
Implantando Stacks CloudFormation
# Validar o modelo
aws cloudformation validate-template --template-body file://templates/webapp.yaml
# Criar a stack
aws cloudformation create-stack \
--stack-name webapp-production \
--template-body file://templates/webapp.yaml \
--parameters ParameterKey=Environment,ParameterValue=production \
ParameterKey=DomainName,ParameterValue=app.example.com \
--capabilities CAPABILITY_NAMED_IAM
# Monitorar a implantação
aws cloudformation describe-stacks --stack-name webapp-production
# Atualizar a stack
aws cloudformation update-stack \
--stack-name webapp-production \
--template-body file://templates/webapp.yaml \
--parameters ParameterKey=Environment,ParameterValue=production \
ParameterKey=DomainName,ParameterValue=app.example.com \
--capabilities CAPABILITY_NAMED_IAM
Atualizações do CloudFormation podem substituir recursos. Recursos com UpdateReplacePolicy: Retain sobrevivem à substituição, mas qualquer recurso sem isso é excluído quando a stack é excluída. Sempre revise o change set antes de aplicar:
aws cloudformation create-change-set --stack-name webapp-production --change-set-name my-change --template-body file://templates/webapp.yaml
aws cloudformation describe-change-set --stack-name webapp-production --change-set-name my-change
Usando CDK como Alternativa
O AWS Cloud Development Kit (CDK) permite escrever infraestrutura em TypeScript. A IA do Cursor gera constructos CDK naturalmente.
// lib/webapp-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';
export class WebappStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'AppBucket', {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
lifecycleRules: [
{ id: 'ExpireOldVersions', noncurrentVersionExpiration: cdk.Duration.days(90) },
],
});
const distribution = new cloudfront.CloudFrontWebDistribution(this, 'Distribution', {
originConfigs: {
s3: {
s3OriginSource: { s3BucketSource: bucket },
behaviors: [{ isDefaultBehavior: true }],
},
},
});
const api = new apigateway.LambdaRestApi(this, 'Api', {
handler: new lambda.Function(this, 'Handler', {
runtime: lambda.Runtime.NODEJS_20_X,
code: lambda.Code.fromAsset('dist/handlers'),
handler: 'index.handler',
}),
});
new cdk.CfnOutput(this, 'WebsiteUrl', {
value: `https://${distribution.distributionDomainName}`,
});
}
}
Implantar com CDK:
cdk synth
cdk deploy
Geração de Infraestrutura Assistida por IA
Gerando Modelos a partir de Prompts
O Cursor se destaca em transformar descrições em linguagem natural em código de infraestrutura. Abra um chat (Ctrl+Shift+P → "Cursor: New Chat") e descreva o que você precisa:
Generate a CloudFormation template for a serverless blog API. It should
include: an API Gateway with /posts and /posts/{id} routes, Lambda
functions for CRUD operations, a DynamoDB table with a GSI on the
authorId attribute, and an S3 bucket for media uploads with CORS
configured. Use least-privilege IAM roles.
O Cursor produz um modelo YAML completo. Revise as políticas IAM cuidadosamente e refine solicitando permissões mais restritas ou recursos adicionais.
Ao gerar políticas IAM com IA, sempre solicite explicitamente políticas de "menor privilégio". Prompts vagos tendem a produzir políticas com Action: '*' em Resource: '*', o que é um sério risco de segurança.
Gerando Constructos CDK
Para equipes nativas em TypeScript, peça ao Cursor para gerar código CDK em vez de CloudFormation bruto:
Create a CDK construct called ServerlessApi that provisions an API
Gateway, three Lambda functions (get, create, delete), and a DynamoDB
table with on-demand billing. Expose the API URL as a construct property.
Refatorando Infraestrutura
O Cursor pode refatorar infraestrutura existente. Transformações comuns:
- Converter YAML CloudFormation bruto em TypeScript CDK.
- Dividir um modelo monolítico em stacks aninhadas.
- Adicionar
DeletionPolicy: Retaina recursos com estado para detecção de drift. - Substituir políticas IAM inline por políticas gerenciadas.
Fluxos de Implantação e Integração CI
Implantação com GitHub Actions
Crie .github/workflows/deploy.yml para implantar no push para main:
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
aws-region: us-east-1
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Run tests
run: npm test
- name: SAM build
run: sam build
- name: Deploy
run: sam deploy --stack-name ${{ vars.STACK_NAME }} --no-confirm-changeset --no-fail-on-empty-changeset --capabilities CAPABILITY_IAM
Nunca armazene chaves de acesso AWS como secrets do GitHub Actions. Use federação OIDC com role-to-assume, como mostrado acima. Isso elimina credenciais de longa duração e está alinhado com as melhores práticas de segurança da AWS.
Implantações Blue-Green com Alias Lambda
Alias Lambda permitem transferência de tráfego entre versões para implantações blue-green:
# Publicar uma nova versão
aws lambda publish-version --function-name user-service
# Atualizar o alias para apontar 10% para a nova versão
aws lambda update-alias \
--function-name user-service \
--name production \
--routing-config AdditionalVersionWeights='{"2":0.1}'
# Promover para 100% após validação
aws lambda update-alias \
--function-name user-service \
--name production \
--function-version 2 \
--routing-config AdditionalVersionWeights='{}'
Monitoramento e Depuração
Streaming de CloudWatch Logs
O AWS Toolkit transmite CloudWatch Logs para o Cursor. No AWS Explorer:
- Expanda CloudWatch Logs.
- Selecione um grupo de logs (ex.:
/aws/lambda/user-service). - Clique com o botão direito e escolha View Log Stream.
Os logs aparecem em uma aba de editor somente leitura com atualizações em tempo real.
Use logging estruturado em seus manipuladores Lambda — logs formatados em JSON são consultáveis no CloudWatch Logs Insights:
console.log(JSON.stringify({
level: 'info',
message: 'User created',
userId: user.id,
timestamp: new Date().toISOString(),
}));
Tracing X-Ray
Ative o tracing X-Ray no Lambda para visualizar fluxos de requisição:
Resources:
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/handlers
Handler: createUser.handler
Runtime: nodejs20.x
Tracing: Active
Instale o SDK de tracing:
npm install @aws-lambda-powertools/tracer
// src/handlers/createUser.ts
import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
const tracer = new Tracer({ serviceName: 'user-service' });
export const handler = captureLambdaHandler(tracer)(
async (event) => {
// ... handler logic
}
);
Melhores Práticas para Desenvolvimento AWS no Cursor
Estrutura do Projeto
project/
├── src/
│ ├── handlers/ # Pontos de entrada Lambda
│ ├── lib/ # Lógica de negócios compartilhada
│ ├── aws/ # Configuração de clientes SDK
│ └── storage/ # Utilitários S3 e armazenamento
├── templates/ # CloudFormation YAML
├── lib/ # Constructos CDK (se usando CDK)
├── events/ # Payloads de eventos Lambda de exemplo
├── tests/
├── template.yaml # Modelo SAM
└── samconfig.toml # Configuração SAM
Gerenciamento de Ambiente
Use contas AWS separadas para desenvolvimento, staging e produção. Gerencie-as com perfis:
export AWS_PROFILE=production
sam deploy --stack-name webapp-production
Otimização de Custos
- Use cobrança
PAY_PER_REQUESTpara tabelas DynamoDB com tráfego imprevisível. - Configure regras de ciclo de vida S3 para transicionar objetos raramente acessados para classes de armazenamento mais baratas.
- Ative Lambda Provisioned Concurrency apenas para funções críticas em latência.
A IA do Cursor pode auditar seus modelos CloudFormation quanto a custos. Prompt: "Revise este modelo e sugira otimizações de custo. Identifique recursos superprovisionados e recomende redimensionamento adequado."
Lista de Verificação de Segurança
- Ative S3 Block Public Access em todos os buckets.
- Use criptografia KMS para dados sensíveis em repouso.
- Aplique políticas IAM de menor privilégio — nunca use
Action: '*'. - Ative CloudTrail para logging de auditoria.
- Rotacione chaves de acesso a cada 90 dias, ou elimine-as com funções IAM.
Armadilhas Comuns e Como Evitá-las
Hardcoding de ARNs e Regiões
Evite embutir ARNs diretamente no código — eles quebram entre contas e regiões:
// ERRADO
const tableArn = 'arn:aws:dynamodb:us-east-1:123456789012:table/users';
// CORRETO — passar via variável de ambiente
const tableName = process.env.TABLE_NAME!;
Esquecimento de Permissões IAM
Uma falha comum de implantação é uma função Lambda sem permissão para acessar um recurso. A função é implantada com sucesso, mas falha em tempo de execução com um erro AccessDenied. Sempre teste localmente com SAM e verifique os CloudWatch Logs após a implantação.
Ignorando Cold Starts
Cold starts do Lambda podem adicionar latência à primeira requisição após inatividade. Mitigue por:
- Usar pacotes de implantação menores.
- Provisionar concorrência para funções sensíveis a latência.
- Manter o código de inicialização fora da função manipuladora.
A concorrência provisionada incorre em cobranças mesmo quando nenhuma requisição é atendida. Monitore o uso cuidadosamente e desative-a para ambientes de desenvolvimento.
Resumo
O Cursor simplifica a implantação AWS combinando o AWS Toolkit para gerenciamento de recursos, a SAM CLI para testes locais, CloudFormation e CDK para infrastructure as code, e o assistente de IA para gerar manipuladores, modelos e fluxos de trabalho de implantação. Comece instalando o AWS Toolkit e a SAM CLI, faça o scaffolding de uma função Lambda e deixe a IA do Cursor acelerar sua escrita de infraestrutura. Sempre revise as políticas IAM para o menor privilégio, use OIDC para implantações CI e monitore com CloudWatch Logs e X-Ray para manter suas aplicações AWS seguras e observáveis.