Pular para o conteúdo principal

Implantação AWS no Cursor: Guia Completo

Implantação AWS no Cursor

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.

  1. Abra a visualização de Extensões (Ctrl+Shift+X).
  2. Pesquise por "AWS Toolkit".
  3. 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.
dica

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
aviso

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
dica

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",
"body": "{\"name\":\"Ada Lovelace\",\"email\":\"[email protected]\",\"age\":36}",
"headers": { "Content-Type": "application/json" }
}
dica

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
aviso

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 },
})
);
}
dica

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
aviso

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.

dica

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: Retain a 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
aviso

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:

  1. Expanda CloudWatch Logs.
  2. Selecione um grupo de logs (ex.: /aws/lambda/user-service).
  3. 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.

dica

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_REQUEST para 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.
dica

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

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.