cloud-platforms

Cloud services, serverless architectures, and cloud-native development patterns for AWS, GCP, and Azure.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "cloud-platforms" with this command: npx skills add miles990/claude-software-skills/miles990-claude-software-skills-cloud-platforms

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 &#x3C; 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

game-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

devops-cicd

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

flame-game-dev

No summary provided by upstream source.

Repository SourceNeeds Review