A Pulumi package for creating and managing Amazon Web Services (AWS) cloud resources with infrastructure-as-code.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Guide to selecting and using AWS compute services with Pulumi.
Run code without managing servers - Automatic scaling, pay-per-use
Deploy and manage containerized applications
Full control over compute instances
Large-scale parallel workloads
Start: What are you running?
┌─ Web application or API
│ ├─ Containerized?
│ │ ├─ Yes → Need Kubernetes? → Yes: EKS | No: ECS/Fargate
│ │ └─ No → Simple deployment? → Yes: App Runner | No: EC2 + ALB
│ └─ Static site → CloudFront + S3
│
┌─ Event-driven processing
│ ├─ < 15 min execution → Lambda
│ ├─ Stateful workflows → Step Functions + Lambda/Fargate
│ └─ Long-running → ECS/EKS
│
┌─ Batch processing
│ ├─ Big data → EMR
│ ├─ Video/media → Batch + GPU instances
│ └─ General batch → Batch or Lambda
│
┌─ Machine learning
│ ├─ Training → SageMaker or EC2 with GPUs
│ ├─ Inference → Lambda, SageMaker, or ECS
│ └─ Batch predictions → Batch
│
└─ Specific requirements
├─ Need specific OS/kernel → EC2
├─ Compliance/isolation → EC2 Dedicated Hosts
├─ High-performance computing → ParallelCluster
└─ Legacy migration → EC2Example use cases:
Anti-patterns:
Example use cases:
ECS vs Fargate:
Example use cases:
Consider costs:
Instance selection:
Scaling strategies:
Benefits:
Lambda + API Gateway + DynamoDB
import * as aws from "@pulumi/aws";
// Lambda function
const handler = new aws.lambda.Function("api", {
runtime: "nodejs20.x",
handler: "index.handler",
role: lambdaRole.arn,
code: new pulumi.asset.FileArchive("./app"),
});
// API Gateway
const api = new aws.apigatewayv2.Api("api", {
protocolType: "HTTP",
});
const integration = new aws.apigatewayv2.Integration("integration", {
apiId: api.id,
integrationType: "AWS_PROXY",
integrationUri: handler.arn,
});
const route = new aws.apigatewayv2.Route("route", {
apiId: api.id,
routeKey: "POST /users",
target: pulumi.interpolate`integrations/${integration.id}`,
});Use when: Building REST APIs, microservices, mobile backends
ECS Fargate + ALB
// ECS cluster
const cluster = new aws.ecs.Cluster("app-cluster");
// Task definition
const taskDef = new aws.ecs.TaskDefinition("app-task", {
family: "app",
cpu: "256",
memory: "512",
networkMode: "awsvpc",
requiresCompatibilities: ["FARGATE"],
containerDefinitions: JSON.stringify([{
name: "app",
image: "nginx:latest",
portMappings: [{ containerPort: 80 }],
}]),
});
// Service with load balancer
const service = new aws.ecs.Service("app-service", {
cluster: cluster.arn,
taskDefinition: taskDef.arn,
desiredCount: 2,
launchType: "FARGATE",
networkConfiguration: {
subnets: subnetIds,
securityGroups: [securityGroup.id],
},
loadBalancers: [{
targetGroupArn: targetGroup.arn,
containerName: "app",
containerPort: 80,
}],
});Use when: Running containerized web apps, APIs, microservices
Auto Scaling Group + ALB
// Launch template
const launchTemplate = new aws.ec2.LaunchTemplate("app-template", {
imageId: "ami-0c55b159cbfafe1f0",
instanceType: "t3.micro",
userData: Buffer.from(`#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
`).toString("base64"),
});
// Auto Scaling Group
const asg = new aws.autoscaling.Group("app-asg", {
launchTemplate: {
id: launchTemplate.id,
version: "$Latest",
},
minSize: 2,
maxSize: 10,
desiredCapacity: 2,
vpcZoneIdentifiers: subnetIds,
targetGroupArns: [targetGroup.arn],
healthCheckType: "ELB",
healthCheckGracePeriod: 300,
});
// Scaling policy
const scaleUp = new aws.autoscaling.Policy("scale-up", {
autoscalingGroupName: asg.name,
scalingAdjustment: 1,
adjustmentType: "ChangeInCapacity",
cooldown: 300,
});Use when: High-availability web apps, variable traffic, need HA
S3 + Lambda + SQS + DynamoDB
// S3 bucket for uploads
const bucket = new aws.s3.BucketV2("uploads");
// SQS queue for processing
const queue = new aws.sqs.Queue("processing-queue", {
visibilityTimeoutSeconds: 300,
});
// Lambda processor
const processor = new aws.lambda.Function("processor", {
runtime: "python3.11",
handler: "lambda_function.handler",
role: role.arn,
code: new pulumi.asset.FileArchive("./processor"),
environment: {
variables: {
QUEUE_URL: queue.url,
},
},
});
// S3 notification to Lambda
const notification = new aws.s3.BucketNotification("notification", {
bucket: bucket.id,
lambdaFunctions: [{
lambdaFunctionArn: processor.arn,
events: ["s3:ObjectCreated:*"],
}],
});Use when: Processing uploads, ETL pipelines, event-driven workflows
EKS + Managed Node Groups
// EKS cluster
const cluster = new aws.eks.Cluster("k8s-cluster", {
roleArn: clusterRole.arn,
vpcConfig: {
subnetIds: subnetIds,
},
});
// Managed node group
const nodeGroup = new aws.eks.NodeGroup("app-nodes", {
clusterName: cluster.name,
nodeRoleArn: nodeRole.arn,
subnetIds: subnetIds,
scalingConfig: {
desiredSize: 2,
minSize: 1,
maxSize: 4,
},
instanceTypes: ["t3.medium"],
});
// Export kubeconfig
export const kubeconfig = cluster.kubeconfig;Use when: Need Kubernetes, complex orchestration, multi-cloud
Right-sizing
Reserved Instances & Savings Plans
Spot Instances
Lambda Optimization
Container Optimization
Install with Tessl CLI
npx tessl i tessl/npm-pulumi--aws@7.16.0