Aller au contenu principal

Déploiement AWS dans Cursor : Guide complet

Déploiement AWS dans Cursor

Amazon Web Services (AWS) est la plateforme cloud la plus largement adoptée, offrant du calcul, du stockage, des bases de données et des dizaines de services gérés de haut niveau. Déployer des applications sur AWS implique d'écrire du code d'infrastructure, d'empaqueter des fonctions, de gérer le stockage et d'orchestrer les flux de publication. Cursor, avec son assistant IA et son riche écosystème d'extensions, est un environnement puissant pour le développement AWS — il peut générer des gestionnaires Lambda, des modèles CloudFormation et des scripts de déploiement à partir de prompts en langage naturel.

Ce guide vous accompagne à travers le flux de travail complet de déploiement AWS dans Cursor : intégration du SDK AWS, construction et déploiement de fonctions Lambda, utilisation de S3 pour le stockage, création d'infrastructure CloudFormation as code, et utilisation de l'IA pour accélérer chaque étape.

Configuration de la chaîne d'outils AWS dans Cursor​

Installation de l'extension AWS Toolkit​

L'extension AWS Toolkit apporte la navigation des ressources AWS, l'exécution locale de Lambda, la visualisation des CloudWatch Logs et le support SAM (Serverless Application Model) directement dans Cursor.

  1. Ouvrez la vue Extensions (Ctrl+Shift+X).
  2. Recherchez « AWS Toolkit ».
  3. Cliquez sur Install.

Une fois installé, l'icône AWS apparaît dans la barre d'activité. L'extension fournit :

  • Un navigateur de ressources pour Lambda, S3, CloudFormation et DynamoDB.
  • L'appel local de Lambda avec la SAM CLI.
  • Un visualiseur Step Functions.
  • Le streaming des CloudWatch Logs.
  • La génération de projets CDK et SAM.
astuce

AWS Toolkit nécessite que les identifiants AWS soient configurés sur votre machine. Cursor lit le même fichier d'identifiants (~/.aws/credentials) que l'AWS CLI, donc tous les profils existants fonctionnent immédiatement.

Configuration des identifiants AWS​

Créez un profil d'identifiants avec l'AWS CLI :

npm install -g aws-cli
aws configure

L'invite interactive collecte :

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

Pour les configurations multi-comptes, créez des profils nommés :

# ~/.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
attention

Ne commitez jamais d'identifiants AWS dans le contrôle de version. Ajoutez .aws/ à .gitignore, et privilégiez les rôles IAM ou les jetons STS temporaires plutôt que les clés d'accès de longue durée. Pour la production, utilisez aws-vault pour gérer les identifiants avec MFA.

Installation de l'AWS SAM CLI​

La CLI SAM (Serverless Application Model) permet de construire, tester localement et déployer des applications basées sur Lambda :

# Windows (avec winget)
winget install AWS.SAM-CLI

# macOS (avec Homebrew)
brew install aws-sam-cli

# Vérification
sam --version

Intégration du SDK AWS​

Installation du SDK pour JavaScript​

Pour les applications Node.js, installez le SDK AWS v3 modulaire :

npm install @aws-sdk/client-s3 @aws-sdk/client-lambda @aws-sdk/client-dynamodb
astuce

Le SDK AWS v3 est modulaire — vous n'installez que les clients dont vous avez besoin, ce qui réduit considérablement la taille du bundle par rapport au SDK v2 monolithique. Chaque service est un package séparé sous @aws-sdk/client-*.

Configuration du client 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 });

Pour des identifiants spécifiques à l'environnement (utile en CI) :

import { fromIni } from '@aws-sdk/credential-providers';

export const s3Client = new S3Client({
region,
credentials: fromIni({ profile: 'production' }),
});

Construction et déploiement de fonctions Lambda​

Génération d'un gestionnaire Lambda​

Utilisez l'IA de Cursor pour générer un gestionnaire Lambda. Ouvrez Ctrl+K et saisissez :

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.

Le gestionnaire généré :

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

Test local avec SAM​

Créez un template.yaml pour 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'

Appelez la fonction localement avec un événement d'exemple :

sam build
sam local invoke CreateUserFunction --event events/createUser.json

Fichier d'événement d'exemple :

{
"httpMethod": "POST",
"body": "{\"name\":\"Ada Lovelace\",\"email\":\"[email protected]\",\"age\":36}",
"headers": { "Content-Type": "application/json" }
}
astuce

L'extension AWS Toolkit dans Cursor ajoute une commande « Run Locally » pour les fonctions Lambda. Faites un clic droit sur une fonction dans le panneau AWS Explorer et choisissez Invoke on AWS ou Run Locally pour tester sans quitter l'éditeur.

Déploiement avec SAM​

# Premier déploiement (guidé)
sam deploy --guided

# Déploiements suivants
sam deploy --stack-name user-service --capabilities CAPABILITY_IAM

L'invite guidée collecte :

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
attention

Les déploiements SAM créent automatiquement des rôles IAM. Revoyez attentivement le résumé du changeset avant de confirmer — un rôle mal configuré peut accorder des permissions trop larges qui violent le principe du moindre privilège en production.

Utilisation de S3 pour le stockage​

Téléversement de fichiers vers 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 gros fichiers​

Pour les gros téléversements, utilisez l'upload multipart :

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

Utilisez l'IA de Cursor pour générer des flux d'URL présignées. Prompt : « Crée une fonction Lambda qui génère une URL présignée de téléversement S3, valide l'extension du fichier, et stocke les métadonnées dans DynamoDB. »

Infrastructure as Code avec CloudFormation​

Écriture de modèles CloudFormation​

CloudFormation permet de définir toute votre infrastructure en YAML ou JSON déclaratif. L'IA de Cursor excelle à générer des modèles à partir de descriptions.

Exemple de modèle pour une stack d'application 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

Déploiement de stacks CloudFormation​

# Valider le modèle
aws cloudformation validate-template --template-body file://templates/webapp.yaml

# Créer la 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

# Surveiller le déploiement
aws cloudformation describe-stacks --stack-name webapp-production

# Mettre à jour la 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
attention

Les mises à jour CloudFormation peuvent remplacer des ressources. Les ressources avec UpdateReplacePolicy: Retain survivent au remplacement, mais toute ressource sans cette politique est supprimée lors de la suppression de la stack. Revoyez toujours le change set avant d'appliquer :

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

Utilisation du CDK comme alternative​

L'AWS Cloud Development Kit (CDK) permet d'écrire l'infrastructure en TypeScript. L'IA de Cursor génère naturellement des constructs CDK.

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

Déploiement avec CDK :

cdk synth
cdk deploy

Génération d'infrastructure assistée par IA​

Génération de modèles à partir de prompts​

Cursor excelle pour transformer des descriptions en langage naturel en code d'infrastructure. Ouvrez un chat (Ctrl+Shift+P → « Cursor: New Chat ») et décrivez ce dont vous avez besoin :

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.

Cursor produit un modèle YAML complet. Revoyez attentivement les politiques IAM, puis affinez en demandant des permissions plus strictes ou des ressources supplémentaires.

astuce

Lors de la génération de politiques IAM avec l'IA, demandez toujours explicitement des politiques de « moindre privilège ». Les prompts vagues tendent à produire des politiques avec Action: '*' sur Resource: '*', ce qui constitue un sérieux risque de sécurité.

Génération de constructs CDK​

Pour les équipes TypeScript natives, demandez à Cursor de générer du code CDK plutôt que du CloudFormation brut :

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.

Refactorisation de l'infrastructure​

Cursor peut refactoriser l'infrastructure existante. Transformations courantes :

  • Convertir du YAML CloudFormation brut en TypeScript CDK.
  • Scinder un modèle monolithique en stacks imbriquées.
  • Ajouter DeletionPolicy: Retain aux ressources avec état pour la détection de dérive.
  • Remplacer les politiques IAM inline par des politiques gérées.

Flux de déploiement et intégration CI​

Déploiement avec GitHub Actions​

Créez .github/workflows/deploy.yml pour déployer lors d'un push sur 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
attention

Ne stockez jamais de clés d'accès AWS en tant que secrets GitHub Actions. Utilisez la fédération OIDC avec role-to-assume, comme illustré ci-dessus. Cela élimine les identifiants de longue durée et s'aligne sur les meilleures pratiques de sécurité AWS.

Déploiements bleu-vert avec les alias Lambda​

Les alias Lambda permettent le transfert de trafic entre versions pour les déploiements bleu-vert :

# Publier une nouvelle version
aws lambda publish-version --function-name user-service

# Mettre à jour l'alias pour pointer 10% vers la nouvelle version
aws lambda update-alias \
--function-name user-service \
--name production \
--routing-config AdditionalVersionWeights='{"2":0.1}'

# Promouvoir à 100% après validation
aws lambda update-alias \
--function-name user-service \
--name production \
--function-version 2 \
--routing-config AdditionalVersionWeights='{}'

Surveillance et débogage​

Streaming des CloudWatch Logs​

AWS Toolkit diffuse les CloudWatch Logs dans Cursor. Dans l'AWS Explorer :

  1. Développez CloudWatch Logs.
  2. Sélectionnez un groupe de logs (par ex. /aws/lambda/user-service).
  3. Faites un clic droit et choisissez View Log Stream.

Les logs apparaissent dans un onglet d'éditeur en lecture seule avec des mises à jour en direct.

astuce

Utilisez la journalisation structurée dans vos gestionnaires Lambda — les logs au format JSON sont interrogeables dans CloudWatch Logs Insights :

console.log(JSON.stringify({
level: 'info',
message: 'User created',
userId: user.id,
timestamp: new Date().toISOString(),
}));

Tracing X-Ray​

Activez le tracing X-Ray sur Lambda pour visualiser les flux de requêtes :

Resources:
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/handlers
Handler: createUser.handler
Runtime: nodejs20.x
Tracing: Active

Installez le 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
}
);

Meilleures pratiques pour le développement AWS dans Cursor​

Structure du projet​

project/
├── src/
│ ├── handlers/ # Points d'entrée Lambda
│ ├── lib/ # Logique métier partagée
│ ├── aws/ # Configuration des clients SDK
│ └── storage/ # Utilitaires S3 et stockage
├── templates/ # CloudFormation YAML
├── lib/ # Constructs CDK (si CDK utilisé)
├── events/ # Charges utiles d'événements Lambda d'exemple
├── tests/
├── template.yaml # Modèle SAM
└── samconfig.toml # Configuration SAM

Gestion des environnements​

Utilisez des comptes AWS distincts pour le développement, staging et production. Gérez-les avec des profils :

export AWS_PROFILE=production
sam deploy --stack-name webapp-production

Optimisation des coûts​

  • Utilisez la facturation PAY_PER_REQUEST pour les tables DynamoDB au trafic imprévisible.
  • Configurez les règles de cycle de vie S3 pour transférer les objets peu consultés vers des classes de stockage moins chères.
  • Activez la concurrence provisionnée Lambda uniquement pour les fonctions critiques en latence.
astuce

L'IA de Cursor peut auditer les coûts de vos modèles CloudFormation. Prompt : « Revoyez ce modèle et suggérez des optimisations de coûts. Identifiez les ressources surprovisionnées et recommandez un redimensionnement approprié. »

Liste de contrôle de sécurité​

  • Activez S3 Block Public Access sur tous les buckets.
  • Utilisez le chiffrement KMS pour les données sensibles au repos.
  • Appliquez des politiques IAM de moindre privilège — n'utilisez jamais Action: '*'.
  • Activez CloudTrail pour la journalisation d'audit.
  • Faites pivoter les clés d'accès tous les 90 jours, ou éliminez-les avec des rôles IAM.

Pièges courants et comment les éviter​

Codage en dur des ARN et régions​

Évitez d'intégrer des ARN directement dans le code — ils cassent entre comptes et régions :

// FAUX
const tableArn = 'arn:aws:dynamodb:us-east-1:123456789012:table/users';

// CORRECT — passer via une variable d'environnement
const tableName = process.env.TABLE_NAME!;

Oubli des permissions IAM​

Un échec de déploiement courant est une fonction Lambda manquant de permission pour accéder à une ressource. La fonction se déploie avec succès mais échoue à l'exécution avec une erreur AccessDenied. Testez toujours localement avec SAM et vérifiez les CloudWatch Logs après le déploiement.

Ignorer les cold starts​

Les cold starts Lambda peuvent ajouter de la latence à la première requête après une période d'inactivité. Atténuez par :

  • L'utilisation de packages de déploiement plus petits.
  • La provision de concurrence pour les fonctions sensibles à la latence.
  • Le maintien du code d'initialisation en dehors de la fonction gestionnaire.
attention

La concurrence provisionnée entraîne des frais même lorsqu'aucune requête n'est servie. Surveillez attentivement l'utilisation et désactivez-la pour les environnements de développement.

Résumé​

Cursor simplifie le déploiement AWS en combinant AWS Toolkit pour la gestion des ressources, la SAM CLI pour les tests locaux, CloudFormation et CDK pour l'infrastructure as code, et l'assistant IA pour générer des gestionnaires, des modèles et des flux de déploiement. Commencez par installer AWS Toolkit et la SAM CLI, générez une fonction Lambda, et laissez l'IA de Cursor accélérer votre écriture d'infrastructure. Revoyez toujours les politiques IAM pour le moindre privilège, utilisez OIDC pour les déploiements CI, et surveillez avec CloudWatch Logs et X-Ray pour garder vos applications AWS sécurisées et observables.