
Cloud Platforms
- 47 installs
- 19 repo stars
- Updated January 20, 2026
- miles990/claude-software-skills
Helps with ai & agent building tasks.
About
cloud-platforms is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- cloud-platforms
- AI & Agent Building
- AI-coding skill
Cloud Platforms by the numbers
- 47 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #7,551 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/miles990/claude-software-skills --skill cloud-platformsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 47 |
|---|---|
| repo stars | ★ 19 |
| Last updated | January 20, 2026 |
| Repository | miles990/claude-software-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Cloud Platforms
Overview
Cloud services, serverless architectures, and cloud-native development patterns for AWS, GCP, and Azure.
---
AWS
Lambda Functions
// lambda/handler.ts
import { APIGatewayProxyHandler, APIGatewayProxyResult } from 'aws-lambda';
export const handler: APIGatewayProxyHandler = async (event) => {
try {
const body = JSON.parse(event.body || '{}');
// Business logic
const result = await processRequest(body);
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify(result),
};
} catch (error) {
console.error('Handler error:', error);
return {
statusCode: error.statusCode || 500,
body: JSON.stringify({
error: error.message || 'Internal server error',
}),
};
}
};
// With middleware (middy)
import middy from '@middy/core';
import jsonBodyParser from '@middy/http-json-body-parser';
import httpErrorHandler from '@middy/http-error-handler';
import cors from '@middy/http-cors';
const baseHandler = async (event) => {
// event.body is already parsed
return {
statusCode: 200,
body: JSON.stringify({ data: event.body }),
};
};
export const handler = middy(baseHandler)
.use(jsonBodyParser())
.use(httpErrorHandler())
.use(cors());S3 Operations
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
const s3 = new S3Client({ region: process.env.AWS_REGION });
// Upload file
async function uploadFile(key: string, body: Buffer, contentType: string) {
await s3.send(new PutObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: key,
Body: body,
ContentType: contentType,
}));
return `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${key}`;
}
// Generate presigned upload URL
async function getUploadUrl(key: string, contentType: string, expiresIn = 3600) {
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: key,
ContentType: contentType,
});
return getSignedUrl(s3, command, { expiresIn });
}
// Generate presigned download URL
async function getDownloadUrl(key: string, expiresIn = 3600) {
const command = new GetObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: key,
});
return getSignedUrl(s3, command, { expiresIn });
}DynamoDB
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import {
DynamoDBDocumentClient,
PutCommand,
GetCommand,
QueryCommand,
UpdateCommand,
} from '@aws-sdk/lib-dynamodb';
const client = new DynamoDBClient({ region: process.env.AWS_REGION });
const docClient = DynamoDBDocumentClient.from(client);
// Single table design patterns
const TABLE_NAME = process.env.DYNAMODB_TABLE;
// Put item
async function createUser(user: User) {
await docClient.send(new PutCommand({
TableName: TABLE_NAME,
Item: {
PK: `USER#${user.id}`,
SK: `PROFILE#${user.id}`,
GSI1PK: `EMAIL#${user.email}`,
GSI1SK: `USER#${user.id}`,
...user,
createdAt: new Date().toISOString(),
},
ConditionExpression: 'attribute_not_exists(PK)',
}));
}
// Get item
async function getUser(userId: string) {
const result = await docClient.send(new GetCommand({
TableName: TABLE_NAME,
Key: {
PK: `USER#${userId}`,
SK: `PROFILE#${userId}`,
},
}));
return result.Item;
}
// Query with GSI
async function getUserByEmail(email: string) {
const result = await docClient.send(new QueryCommand({
TableName: TABLE_NAME,
IndexName: 'GSI1',
KeyConditionExpression: 'GSI1PK = :pk',
ExpressionAttributeValues: {
':pk': `EMAIL#${email}`,
},
}));
return result.Items?.[0];
}
// Update with conditions
async function updateUserStatus(userId: string, status: string) {
await docClient.send(new UpdateCommand({
TableName: TABLE_NAME,
Key: {
PK: `USER#${userId}`,
SK: `PROFILE#${userId}`,
},
UpdateExpression: 'SET #status = :status, updatedAt = :now',
ConditionExpression: 'attribute_exists(PK)',
ExpressionAttributeNames: {
'#status': 'status',
},
ExpressionAttributeValues: {
':status': status,
':now': new Date().toISOString(),
},
}));
}SQS & SNS
import { SQSClient, SendMessageCommand, ReceiveMessageCommand } from '@aws-sdk/client-sqs';
import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';
const sqs = new SQSClient({ region: process.env.AWS_REGION });
const sns = new SNSClient({ region: process.env.AWS_REGION });
// Send to SQS
async function queueJob(job: Job) {
await sqs.send(new SendMessageCommand({
QueueUrl: process.env.SQS_QUEUE_URL,
MessageBody: JSON.stringify(job),
MessageAttributes: {
type: {
DataType: 'String',
StringValue: job.type,
},
},
}));
}
// Publish to SNS
async function publishEvent(topic: string, event: Event) {
await sns.send(new PublishCommand({
TopicArn: `arn:aws:sns:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT}:${topic}`,
Message: JSON.stringify(event),
MessageAttributes: {
eventType: {
DataType: 'String',
StringValue: event.type,
},
},
}));
}
// Lambda SQS handler
export const sqsHandler = async (event: SQSEvent) => {
for (const record of event.Records) {
const job = JSON.parse(record.body);
await processJob(job);
}
};---
Google Cloud Platform
Cloud Functions
import { HttpFunction, CloudEvent } from '@google-cloud/functions-framework';
// HTTP function
export const httpHandler: HttpFunction = async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
res.status(204).send('');
return;
}
try {
const result = await processRequest(req.body);
res.json(result);
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal error' });
}
};
// Pub/Sub triggered function
export const pubsubHandler = async (event: CloudEvent<{ message: { data: string } }>) => {
const data = JSON.parse(
Buffer.from(event.data.message.data, 'base64').toString()
);
await processMessage(data);
};
// Cloud Storage triggered
export const storageHandler = async (event: CloudEvent<StorageObjectData>) => {
const file = event.data;
console.log(`Processing file: ${file.bucket}/${file.name}`);
await processFile(file.bucket, file.name);
};Firestore
import { Firestore, FieldValue } from '@google-cloud/firestore';
const db = new Firestore();
// Create document
async function createUser(user: User) {
const docRef = db.collection('users').doc(user.id);
await docRef.set({
...user,
createdAt: FieldValue.serverTimestamp(),
});
}
// Query with filters
async function getActiveUsers(limit = 10) {
const snapshot = await db.collection('users')
.where('status', '==', 'active')
.orderBy('createdAt', 'desc')
.limit(limit)
.get();
return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}
// Transaction
async function transferCredits(fromId: string, toId: string, amount: number) {
await db.runTransaction(async (t) => {
const fromRef = db.collection('accounts').doc(fromId);
const toRef = db.collection('accounts').doc(toId);
const fromDoc = await t.get(fromRef);
const fromBalance = fromDoc.data()?.balance || 0;
if (fromBalance < amount) {
throw new Error('Insufficient balance');
}
t.update(fromRef, { balance: FieldValue.increment(-amount) });
t.update(toRef, { balance: FieldValue.increment(amount) });
});
}
// Real-time listener
function subscribeToUser(userId: string, callback: (user: User) => void) {
return db.collection('users').doc(userId).onSnapshot((doc) => {
if (doc.exists) {
callback({ id: doc.id, ...doc.data() } as User);
}
});
}---
Serverless Framework
serverless.yml
service: my-api
provider:
name: aws
runtime: nodejs18.x
region: ${opt:region, 'us-east-1'}
stage: ${opt:stage, 'dev'}
environment:
TABLE_NAME: ${self:service}-${self:provider.stage}
BUCKET_NAME: ${self:service}-uploads-${self:provider.stage}
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource:
- !GetAtt DynamoDBTable.Arn
- !Join ['/', [!GetAtt DynamoDBTable.Arn, 'index/*']]
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
Resource:
- !Join ['/', [!GetAtt S3Bucket.Arn, '*']]
functions:
api:
handler: src/handlers/api.handler
events:
- http:
path: /{proxy+}
method: ANY
cors: true
processQueue:
handler: src/handlers/queue.handler
events:
- sqs:
arn: !GetAtt Queue.Arn
batchSize: 10
scheduledTask:
handler: src/handlers/scheduled.handler
events:
- schedule: rate(1 hour)
resources:
Resources:
DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.TABLE_NAME}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: PK
AttributeType: S
- AttributeName: SK
AttributeType: S
- AttributeName: GSI1PK
AttributeType: S
- AttributeName: GSI1SK
AttributeType: S
KeySchema:
- AttributeName: PK
KeyType: HASH
- AttributeName: SK
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: GSI1
KeySchema:
- AttributeName: GSI1PK
KeyType: HASH
- AttributeName: GSI1SK
KeyType: RANGE
Projection:
ProjectionType: ALL
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:provider.environment.BUCKET_NAME}
Queue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:service}-${self:provider.stage}-queue
plugins:
- serverless-esbuild
- serverless-offline---
Cloudflare Workers
// worker.ts
export interface Env {
KV: KVNamespace;
DB: D1Database;
BUCKET: R2Bucket;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const url = new URL(request.url);
// Router
if (url.pathname.startsWith('/api/')) {
return handleAPI(request, env);
}
// Static assets from R2
if (url.pathname.startsWith('/assets/')) {
const key = url.pathname.slice(8);
const object = await env.BUCKET.get(key);
if (!object) {
return new Response('Not found', { status: 404 });
}
return new Response(object.body, {
headers: {
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
'Cache-Control': 'public, max-age=31536000',
},
});
}
return new Response('Not found', { status: 404 });
},
};
async function handleAPI(request: Request, env: Env) {
const url = new URL(request.url);
// KV operations
if (url.pathname === '/api/cache') {
const key = url.searchParams.get('key');
if (request.method === 'GET') {
const value = await env.KV.get(key);
return Response.json({ value });
}
if (request.method === 'PUT') {
const { value, ttl } = await request.json();
await env.KV.put(key, value, { expirationTtl: ttl });
return Response.json({ success: true });
}
}
// D1 (SQLite) operations
if (url.pathname === '/api/users') {
if (request.method === 'GET') {
const { results } = await env.DB.prepare(
'SELECT * FROM users ORDER BY created_at DESC LIMIT 10'
).all();
return Response.json(results);
}
if (request.method === 'POST') {
const { name, email } = await request.json();
const result = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?) RETURNING *'
).bind(name, email).first();
return Response.json(result, { status: 201 });
}
}
return new Response('Not found', { status: 404 });
}---
Related Skills
- [[devops-cicd]] - Cloud deployments
- [[system-design]] - Cloud architecture
- [[reliability-engineering]] - Cloud reliability
/**
* AWS CDK Stack Template
* Usage: Copy to lib/my-stack.ts
* Install: npm install aws-cdk-lib constructs
*/
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
interface MyStackProps extends cdk.StackProps {
environment: string;
}
export class MyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: MyStackProps) {
super(scope, id, props);
const { environment } = props;
// ===========================================
// VPC
// ===========================================
const vpc = new ec2.Vpc(this, 'VPC', {
maxAzs: 2,
natGateways: environment === 'prod' ? 2 : 1,
});
// ===========================================
// ECS Cluster
// ===========================================
const cluster = new ecs.Cluster(this, 'Cluster', {
vpc,
containerInsights: true,
});
// ===========================================
// Fargate Service with ALB
// ===========================================
const fargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(
this,
'FargateService',
{
cluster,
cpu: 256,
memoryLimitMiB: 512,
desiredCount: environment === 'prod' ? 2 : 1,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('nginx:alpine'),
containerPort: 80,
environment: {
NODE_ENV: environment,
},
},
publicLoadBalancer: true,
}
);
// Health check
fargateService.targetGroup.configureHealthCheck({
path: '/health',
healthyHttpCodes: '200',
});
// Auto Scaling
const scaling = fargateService.service.autoScaleTaskCount({
minCapacity: 1,
maxCapacity: environment === 'prod' ? 10 : 2,
});
scaling.scaleOnCpuUtilization('CpuScaling', {
targetUtilizationPercent: 70,
});
// ===========================================
// RDS Database
// ===========================================
const database = new rds.DatabaseInstance(this, 'Database', {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_16,
}),
vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T3,
ec2.InstanceSize.MICRO
),
allocatedStorage: 20,
maxAllocatedStorage: 100,
removalPolicy:
environment === 'prod'
? cdk.RemovalPolicy.RETAIN
: cdk.RemovalPolicy.DESTROY,
});
// Allow ECS to connect to RDS
database.connections.allowFrom(fargateService.service, ec2.Port.tcp(5432));
// ===========================================
// S3 Bucket
// ===========================================
const bucket = new s3.Bucket(this, 'Bucket', {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
removalPolicy:
environment === 'prod'
? cdk.RemovalPolicy.RETAIN
: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: environment !== 'prod',
});
// ===========================================
// Outputs
// ===========================================
new cdk.CfnOutput(this, 'LoadBalancerDNS', {
value: fargateService.loadBalancer.loadBalancerDnsName,
});
new cdk.CfnOutput(this, 'BucketName', {
value: bucket.bucketName,
});
}
}
# Terraform Configuration Template
# Usage: Copy to main.tf, run terraform init && terraform plan
# Provider: AWS (adapt for GCP/Azure)
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
# Remote state (uncomment for production)
# backend "s3" {
# bucket = "my-terraform-state"
# key = "prod/terraform.tfstate"
# region = "us-east-1"
# }
}
# ===========================================
# Variables
# ===========================================
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "project_name" {
description = "Project name for resource naming"
type = string
default = "myproject"
}
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
# ===========================================
# Provider Configuration
# ===========================================
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = var.environment
Project = var.project_name
ManagedBy = "terraform"
}
}
}
# ===========================================
# VPC & Networking
# ===========================================
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project_name}-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.project_name}-public-${count.index + 1}"
}
}
data "aws_availability_zones" "available" {
state = "available"
}
# ===========================================
# Security Group
# ===========================================
resource "aws_security_group" "app" {
name = "${var.project_name}-app-sg"
description = "Security group for application"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# ===========================================
# Outputs
# ===========================================
output "vpc_id" {
description = "VPC ID"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "Public subnet IDs"
value = aws_subnet.public[*].id
}
Cloud Platforms Templates
Infrastructure as Code templates for AWS deployment.
Files
| Template | Purpose |
|---|---|
main.tf | Terraform configuration (VPC, subnets, security groups) |
cdk-stack.ts | AWS CDK stack (ECS Fargate, RDS, S3) |
serverless.yml | Serverless Framework (Lambda, API Gateway, DynamoDB) |
Usage
Terraform
cp templates/main.tf ./main.tf
# Initialize
terraform init
# Preview changes
terraform plan
# Apply
terraform applyAWS CDK
mkdir -p lib
cp templates/cdk-stack.ts lib/my-stack.ts
# Install CDK
npm install -g aws-cdk
npm install aws-cdk-lib constructs
# Bootstrap (first time only)
cdk bootstrap
# Deploy
cdk deployServerless Framework
cp templates/serverless.yml ./serverless.yml
# Install
npm install -g serverless
npm install serverless-offline serverless-esbuild
# Local development
serverless offline
# Deploy
serverless deploy --stage devComparison
| Feature | Terraform | CDK | Serverless |
|---|---|---|---|
| Language | HCL | TypeScript | YAML |
| Best for | Multi-cloud, existing infra | AWS-native, complex apps | Lambda-based APIs |
| Learning curve | Medium | Medium | Low |
| State management | S3 backend | CloudFormation | CloudFormation |
AWS Credentials
# Configure AWS CLI
aws configure
# Or use environment variables
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
export AWS_REGION=us-east-1Environment-Specific Deployments
Terraform
terraform workspace new prod
terraform apply -var="environment=prod"CDK
cdk deploy --context environment=prodServerless
serverless deploy --stage prod# Serverless Framework Configuration Template
# Usage: Copy to serverless.yml
# Install: npm install -g serverless
service: my-service
frameworkVersion: '3'
# ===========================================
# Provider Configuration
# ===========================================
provider:
name: aws
runtime: nodejs20.x
stage: ${opt:stage, 'dev'}
region: ${opt:region, 'us-east-1'}
# Environment variables
environment:
STAGE: ${self:provider.stage}
TABLE_NAME: ${self:service}-${self:provider.stage}
# IAM permissions
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource:
- !GetAtt DynamoDBTable.Arn
- !Sub '${DynamoDBTable.Arn}/index/*'
# API Gateway
httpApi:
cors: true
# ===========================================
# Functions
# ===========================================
functions:
# REST API endpoints
getItems:
handler: src/handlers/items.getAll
events:
- httpApi:
path: /items
method: GET
getItem:
handler: src/handlers/items.getOne
events:
- httpApi:
path: /items/{id}
method: GET
createItem:
handler: src/handlers/items.create
events:
- httpApi:
path: /items
method: POST
updateItem:
handler: src/handlers/items.update
events:
- httpApi:
path: /items/{id}
method: PUT
deleteItem:
handler: src/handlers/items.remove
events:
- httpApi:
path: /items/{id}
method: DELETE
# Scheduled function
scheduledTask:
handler: src/handlers/scheduled.run
events:
- schedule: rate(1 hour)
# SQS trigger
processQueue:
handler: src/handlers/queue.process
events:
- sqs:
arn: !GetAtt ProcessingQueue.Arn
batchSize: 10
# ===========================================
# Resources (CloudFormation)
# ===========================================
resources:
Resources:
# DynamoDB Table
DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${self:provider.stage}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
- AttributeName: sk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: GSI1
KeySchema:
- AttributeName: sk
KeyType: HASH
- AttributeName: pk
KeyType: RANGE
Projection:
ProjectionType: ALL
# SQS Queue
ProcessingQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: ${self:service}-${self:provider.stage}-queue
VisibilityTimeout: 300
Outputs:
ApiEndpoint:
Value: !Sub 'https://${HttpApi}.execute-api.${AWS::Region}.amazonaws.com'
# ===========================================
# Plugins
# ===========================================
plugins:
- serverless-offline
- serverless-esbuild
custom:
esbuild:
bundle: true
minify: false
sourcemap: true
target: node20
serverless-offline:
httpPort: 3000
Related skills
AI & Agent Buildingagents