Aws Essentials logo

Aws Essentials

Community
ericrisco
aws-essentials

Use when standing up the core AWS surface a small product needs: hardening a fresh account, a private S3 bucket, encrypted RDS Postgres, ECS Fargate vs EC2, CloudFront + OAC, or scoping an IAM policy to least privilege. NOT the CI pipeline that ships the container (that is `deployment`), NOT app-code access-control review (that is `secure-coding`).

Overview

Publisherericrisco
Repositoryrsc-harness
Skill nameaws-essentials
Stars
239
Forks
24
Bundled files
4
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 4 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by ericrisco on GitHub. Read the source before you install it.

Installation

Install the Aws Essentials AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/ericrisco/rsc-harness/tree/main/skills/aws-essentials
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/ericrisco/rsc-harness.git /tmp/rsc-harness
mkdir -p .claude/skills
cp -r /tmp/rsc-harness/skills/aws-essentials .claude/skills/aws-essentials
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Aws Essentials in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Aws Essentials on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Aws Essentials is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

AWS essentials — the core surface a small product needs, secured from the first command

Stand up the foundational AWS services a one-app product actually uses — IAM, S3, ECS Fargate, RDS, CloudFront — with the security defaults that prevent the incidents (public buckets, god-mode app roles, long-lived keys, unencrypted databases). Pick the right tier for small (one app, modest traffic, two engineers), provision it correctly, and wire it without foot-guns.

text
account hardening → IAM (roles + scoped policies) → S3 (private) / RDS (encrypted) / ECS Fargate → CloudFront (OAC) → infra exists, wired, least-privilege

Service decision table

NeedUseUse instead if
Object/file storage (uploads, assets, backups)S3 (private bucket)—
Relational data (users, orders, anything with joins)RDS (Postgres/MySQL)key-value / serverless access pattern → dynamodb skill
Long-running container/APIECS Fargatesteady ~70%+ CPU 24/7 → EC2 launch type with Savings Plans/Spot; GPU or >120 GB RAM → EC2
Static site / SPA + public assetsS3 + CloudFrontedge functions / global KV → ../cloudflare/SKILL.md
Tiny app, no real AWS need yetbe honest → ../vercel/SKILL.md or ../deployment/SKILL.mdyou genuinely need AWS primitives → stay here

Fargate cold start is ~30–60 s; for spiky/variable small-product load its operational simplicity (no host patching, per-second billing, strong task isolation) wins. EC2 launch type only earns its host-management cost at sustained high utilization. (ECS Managed Instances, Sept 2025, is a newer hybrid — out of scope for a first setup.)

Account zero-day hardening checklist

Do this once, before anything else. Each line has a reason; skip none.

  • Enable MFA on the root user — prefer a passkey / security key (phishing-resistant). Root with no MFA is the single highest-blast-radius account.
  • Stop using root for daily work — root is for the handful of root-only tasks (close account, change support plan). Everything else uses an IAM identity.
  • Create an admin identity via IAM Identity Center (or an assumable admin role). Humans log in to a role with temporary creds, not a static user.
  • Delete any root access keys — root should have zero access keys. If one exists, it is a liability with no upside.
  • No long-lived IAM-user access keys for apps or CI — apps use task roles, CI uses OIDC (see ../deployment/SKILL.md).
  • Set your home region and create resources there consistently (one exception below: ACM certs for CloudFront must be in us-east-1).
  • Create a billing/cost budget alarm — a misconfigured resource should page you, not surprise you on the invoice.

IAM — least privilege without guessing

Two principal types. IAM users = long-lived humans/keys; avoid them for workloads. Roles = an identity something assumes to get temporary credentials — this is what ECS tasks, Lambda, CI, and federated humans use. Default to roles: a temporary credential beats a long-lived AKIA… key that lives forever in a .env. (IAM governs who may call AWS APIs; access control inside your app code is ../secure-coding/SKILL.md.)

A policy is a JSON document. The four parts that matter:

json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:GetObject", "s3:PutObject"],
    "Resource": "arn:aws:s3:::acme-uploads/users/*",
    "Condition": { "StringEquals": { "aws:SecureTransport": "true" } }
  }]
}

Effect (Allow/Deny) · Action (which API calls) · Resource (which ARNs) · Condition (extra constraints). The whole game is keeping Action and Resource narrow.

The workflow — start broad, then tighten (do not hand-author from zero):

  1. Attach the closest AWS managed policy to get the app working.
  2. Let it run, then use IAM Access Analyzer → generate policy from CloudTrail activity to produce a fine-grained policy from what it actually called.
  3. Replace the managed policy with the generated one.
  4. Validate with Access Analyzer (runs 100+ policy checks) and review findings.
  5. Periodically prune with last-accessed data — remove permissions nothing has used.
jsonc
// Bad — one leak owns the account
{ "Effect": "Allow", "Action": "*", "Resource": "*" }

// Good — exactly what this service does, on exactly its resources
{ "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:PutObject"],
  "Resource": "arn:aws:s3:::acme-uploads/users/*" }

An ECS task needs a trust policy (who may assume the role) plus a permission policy (what it may do). Trust policy for a task role:

json
{ "Version": "2012-10-17",
  "Statement": [{ "Effect": "Allow",
    "Principal": { "Service": "ecs-tasks.amazonaws.com" },
    "Action": "sts:AssumeRole" }] }

Policy JSON anatomy, condition keys, Access Analyzer CLI flow, and copy-ready scoped templates (S3 one-prefix R/W, read one Secrets Manager secret, write CloudWatch logs, ECS trust) → references/iam-least-privilege.md.

S3 — private object storage

Create a bucket. The defaults are already what you want:

bash
aws s3api create-bucket \
  --bucket acme-uploads \
  --region eu-west-1 \
  --create-bucket-configuration LocationConstraint=eu-west-1
# Since Apr 2023, this bucket is already: Block Public Access ON (all four),
# Object Ownership = bucket-owner-enforced (ACLs disabled), SSE-S3 on every object.

Keep all of that. Do not re-enable ACLs; do not turn off Block Public Access. Grant access two ways instead: a bucket policy (resource-side, e.g. allow one CloudFront distribution) or an IAM identity policy (subject-side, e.g. the task role above). For browser uploads, hand the client a presigned URL so the app never proxies the bytes and the bucket stays private:

bash
aws s3 presign s3://acme-uploads/users/123/avatar.png --expires-in 900
text
Bad:  set bucket to public-read so the <img> tags work
Good: bucket stays private → presigned URLs for direct upload/download,
      and CloudFront + OAC for public-read web content (see below)

Compute — ECS Fargate first

Run the container on Fargate (rationale in the decision table). The mistake that costs an afternoon every time:

Task role vs execution role — they are different.

  • Execution role: lets ECS itself pull the image from ECR and push logs to CloudWatch. Start from the managed AmazonECSTaskExecutionRolePolicy.
  • Task role: the identity your application code assumes at runtime to call AWS (read the S3 bucket, read a secret). This is where your scoped least-privilege policy goes. Putting app permissions on the execution role (or vice-versa) is the classic "works in console, 403 at runtime" bug.

Network layout: tasks in private subnets, a load balancer (ALB) in public subnets, egress via NAT. The DB and tasks never get public IPs. EC2 launch type only if you hit the steady-utilization or hardware thresholds above. Full task-def + service CLI path lives in ../deployment/SKILL.md (that skill owns the ship step); this skill owns the roles and networking it runs on.

RDS — managed relational DB

bash
aws rds create-db-instance \
  --db-instance-identifier acme-prod \
  --engine postgres \
  --db-instance-class db.t4g.small \
  --allocated-storage 20 \
  --storage-encrypted --kms-key-id <your-rds-cmk> \
  --multi-az \
  --no-publicly-accessible \
  --master-username acme --manage-master-user-password \
  --vpc-security-group-ids sg-app-db

Encrypt at create time — you cannot encrypt an existing instance in place. Storage encryption (AES-256 via KMS) must be set at creation; it then covers backups, read replicas, and snapshots. To fix an unencrypted instance you must snapshot → copy-snapshot with encryption → restore (Multi-AZ clusters can't even do that directly). Prefer a customer-managed KMS key dedicated to RDS.

Two more non-negotiables: the DB security group references the app's security group, never 0.0.0.0/0 (a DB open to the internet is a breach, not a convenience); credentials live in Secrets Manager with managed rotation (--manage-master-user-password above), never in task env vars. Use --multi-az for production HA. Full recipe (SG wiring, Secrets Manager rotation, connecting from ECS) → references/rds-cloudfront-recipes.md. Schema, indexes and query tuning once the instance exists → ../postgresdb/SKILL.md.

CloudFront + OAC — public web content, private bucket

To serve S3 content publicly, do not make the bucket public. Put CloudFront in front and grant it via Origin Access Control (OAC) — the modern replacement for the legacy OAI:

  • OAC uses short-term, rotated credentials and a resource-based bucket policy scoped to the distribution ARN; CloudFront→S3 is always HTTPS with "Sign requests" (the default).
  • OAC supports SSE-KMS origins and all regions. OAI is legacy — never reach for it.
  • The bucket keeps Block Public Access on; you grant only the distribution, by bucket policy.
  • Set the viewer protocol policy to redirect-to-HTTPS; ACM cert for a custom domain must be in us-east-1.

Full CLI: create OAC → distribution → S3 bucket policy JSON → invalidations → custom domain → references/rds-cloudfront-recipes.md.

Anti-patterns

Anti-patternWhy it bitesFix
Public-read S3 bucketAnyone enumerates/downloads everything; classic breach headlineKeep Block Public Access on; presigned URLs or CloudFront+OAC
Re-enabling S3 ACLsBrings back the confused-deputy/ownership mess April-2023 defaults removedLeave bucket-owner-enforced; use bucket/IAM policies
AdministratorAccess on an app/task roleOne leaked task credential = full account compromiseScope to the exact actions+ARNs the service uses
"Action": "*", "Resource": "*" policySame blast radius, just hand-writtenGenerate from CloudTrail via Access Analyzer; validate
IAM-user access keys in app/.env/commitLong-lived, never rotated, leak foreverTask role (app) / OIDC (CI) — temporary creds
Unencrypted RDSCan't encrypt later without snapshot-copy-restore downtime--storage-encrypted at create, customer-managed KMS key
DB security group open to 0.0.0.0/0Database directly reachable from the internetSG references the app SG only; --no-publicly-accessible
CloudFront with OAILegacy; misses SSE-KMS, weaker credential modelUse OAC, bucket policy scoped to the distribution ARN
Secrets in task env varsLeak via logs, console, task definition historySecrets Manager + managed rotation, injected at runtime
Root user for daily opsHighest blast radius, no per-action attributionRoot only for root-only tasks; admin via Identity Center
No MFA on rootOne phished password = total account lossPasskey/security-key MFA on root and every human
Confusing task role and execution roleApp gets 403 at runtime, or ECS can't pull the imageExecution = pull image/logs; task = app's runtime perms

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Aws Essentials AI skill do?

Use when standing up the core AWS surface a small product needs: hardening a fresh account, a private S3 bucket, encrypted RDS Postgres, ECS Fargate vs EC2, CloudFront + OAC, or scoping an IAM policy to least privilege. NOT the CI pipeline that ships the container (that is `deployment`), NOT app-code access-control review (that is `secure-coding`).

Why use Aws Essentials on TypingMind?

Because you install it once and use it with any model. Aws Essentials is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Aws Essentials in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/ericrisco/rsc-harness/tree/main/skills/aws-essentials. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Aws Essentials?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Aws Essentials?

As many as you like. As long as a model supports skills, you can use Aws Essentials with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Aws Essentials AI skill free?

Yes. It is published on GitHub by ericrisco under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇