AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Agent Advisor provides a structured, multi-phase workflow to help users determine the optimal AWS runtime for their AI agents. It uses a deterministic scoring engine to evaluate requirements and guides users through a process that includes discovery, architectural design, cost estimation, and the creation of an executable proof-of-concept. The skill supports various AWS compute options, including AgentCore, ECS, EKS, and Lambda, and integrates with migration engines for existing workloads.
What it does
- Recommends AWS runtimes for AI agents based on technical requirements.
- Generates migration plans for existing AI workloads moving to AWS.
- Provides architectural guidance for agentic systems.
- Assembles executable proof-of-concept scaffolding.
- Estimates coarse cost magnitudes for proposed agent deployments.
- Integrates with external migration engines for workload transitions.
When to use it
- When you need to decide which AWS runtime is best for a new AI agent.
- When migrating an existing AI agent workload to AWS.
- When you need to add services like memory, identity, or observability to an existing AWS agent.
- When you require a structured plan and POC for deploying agents on AWS.
Advantages
- Provides a deterministic, repeatable recommendation process.
- Supports a wide range of AWS compute environments.
- Offers a unified flow from initial idea to executable POC.
- Adapts to both technical and business-focused user backgrounds.
Usage examples
- “I have an agent idea, what do I build?”
- The agent initiates the intake process to clarify your requirements and recommend an appropriate AWS architecture.
- “Move my agents to AWS.”
- The agent triggers the migration workflow to assess your existing workload and plan the transition to an AWS runtime.
- “Which runtime for my agent, AgentCore vs ECS vs EKS vs Lambda?”
- The agent runs a scoring analysis to compare these runtimes against your specific agentic needs.
- “Add AgentCore services to an agent already on AWS.”
- The agent enters the add-capabilities branch to guide you through integrating memory, gateway, and observability services.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/agent-advisor/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip agent-advisor.zip -d .agents/skills
Documentation by AWS
AWS Agent Advisor
Helps startups decide how and where to run AI agents on AWS. Deterministic scoring recommends a runtime; the conversation adapts to the user's technical background.
Definitions
"Load" = Read the file with the Read tool and follow it. Do not summarize or skip.
$RUN_DIR= the run directory under.agent-advisor/(e.g..agent-advisor/0630-1430/), created in Intake.$PLUGIN=${CLAUDE_PLUGIN_ROOT}(the installed plugin root). On Claude Code this token substitutes inline. If${CLAUDE_PLUGIN_ROOT}does not resolve (some Cursor/Codex builds, or a literal${CLAUDE_PLUGIN_ROOT}string showing up in a path error), fall back to the skill's own directory: this SKILL.md lives at<plugin>/skills/agent-advisor/SKILL.md, so the engine and its data are all inside this skill — scripts at./scripts/..., runtime profiles at./references/runtimes/..., and decision refs at./references/decision-refs/...relative to it. Prefer${CLAUDE_PLUGIN_ROOT}/skills/agent-advisor/...; use the relative fallback only when it fails to resolve.
Prerequisites
uvavailable (for scoring). Check:uv --version. If missing, tell the user to install it from the official install guide (https://docs.astral.sh/uv/getting-started/installation/ — e.g.brew install uvorpipx install uv) and stop.
Phase Structure (frontmatter)
Phase, fragment, and assembler files carry a YAML frontmatter block that declares how each
phase is composed — its inputs, triggers, fragments, assembler, artifacts, gates, and
ordering. The execution contract is the vendored references/vendored/dsl/INTERPRETER.md:
it defines every frontmatter key, the fragment/assembler model, the gate protocol
(HANDOFF_OK / GATE_FAIL), and the interpreter loop. Load it first (once, at the
start of a run), then execute each phase file's prose body. Elsewhere in this skill,
INTERPRETER.md (without a path) refers to this loaded contract.
Execution
This skill is driven by the interpreter loop in INTERPRETER.md (§ The interpreter loop):
it reads .phase-status.json, determines the current phase, runs each phase's
_preconditions / fragments / _assemble / _postconditions, advances on HANDOFF_OK
via _advances_to, and validates state. The backbone (intake → discover → clarify →
confirm → design → estimate → generate → migration-plan → poc → complete) and the
one sidebar branch (add-capabilities) are derived
from the phase files' frontmatter — they are not restated here.
Cold start (entry phase). With no run under .agent-advisor/ carrying a
.phase-status.json, begin at references/phases/intake/intake.md — this skill's entry
phase (the one carrying _init: true). On a warm start, current_phase in
.phase-status.json is authoritative (INTERPRETER.md § The interpreter loop).
Skill bindings (INTERPRETER.md § Skill bindings). This skill declares:
Run root:
.agent-advisor/—$RUN_DIRis this skill's name for the run directory (.agent-advisor/[MMDD-HHMM]/). Intake's own prose performs the_initbootstrap.State shape: § State file below (advisor-specific keys such as
entry_point,audience,recommendation_reviewed,migration_plan_ctx,migration_plan_unavailable); the shared state schema is not vendored.Run seed (optional):
$RUN_DIR/seed.json, else.agent-advisor/seed.jsonat the run root (schemascripts/schemas/seed.json) supplies machine-readable answers for a non-interactive run — the Clarify dimensions, the two gate answers, the POC mode, the live-probe answer, and aco_recommendtie-break. It is the HIGHEST-precedence source for every value it carries (clarify.md Step 2.5), which is what makes a repeated run's score comparable: the deterministic engine gets byte-identical input. A gate the seed omits is declined; a dimension the seed omits falls through to detection, then prose, then anassumedvalue that MUST be recorded in$RUN_DIR/UNANSWERED.md. With no seed, the interactive flow is unchanged.Resolved statuses:
skipped(routing resolved the phase without running it), plusnot_applicableformigration_planonly.Conditional backbone routing: the entry-point routing below. When a routing rule marks a phase not-applicable, set it
skippedand advance through its_advances_toin the same state write.
Routing & gates (orchestration)
Sidebar placement and conditional backbone routing are orchestration prose owned by
this file (INTERPRETER.md § Skill bindings, § Backbone vs sidebar).
Entry-point routing:
build_scratch→ skip Discover; Clarify → Confirm → Design → Estimate → Generate → Gate 2 → POC (any winning runtime). No migration plan (nothing existing to migrate).build_deploy→ Discover (if code) → Clarify → Confirm → Design → Estimate → Generate → Gate 1 → Migration Plan (if existing non-AWS AI workload detected and user confirms) → Gate 2 → POC (any winning runtime).migrate→ Discover (if code) → Clarify → Confirm → Design → Estimate (target-state run cost; migration TCO comparison stays with the Migration Plan engine) → Generate → Gate 1 → Migration Plan (in-skill, reusing the siblinggcp-to-awsskill) → Gate 2 → POC (any winning runtime, when the plan was produced). Declining Gate 1 keeps the classic handoff: pointer to/aws-startup-advisor:llm-to-bedrockwithhandoff-summary.md.add_capabilities→ loadreferences/phases/add-capabilities/add-capabilities.mdand follow it (no runtime scoring; writescapabilities-recommendation.md). This is a self-contained branch — it does NOT pass through Clarify / Confirm / Design / Estimate / Generate, so the phase gate below never applies to it.Temporal detection routes into
migratewith temporal units pre-seeded (see discover).
Gate semantics (backbone tail):
Gate 1 →
migration_planruns only whengenerateis done ANDrecommendation_reviewed == true(generate.md Step 5.5) AND entry point ∈ {migrate, build_deploy} AND the run is migration-eligible (generate.md Step 6) AND the user confirmed Gate 1. Otherwise resolve it:not_applicable(build_scratch / no migratable workload) orskipped(declined) — and advance.Gate 2 →
pocruns only whenphases.poc == "in_progress"(set when the user answers Gate 2 "yes" — asked in generate.md Step 7 or migration-plan.md Step 6) ANDrecommendation_reviewed == true. Any winning runtime (agentcore / ecs / eks / lambda / lambda_microvms) — the POC shape follows the verdict (poc.md Step 3 dispatch onreferences/decision-refs/poc-shapes.md). Gate 2 is only offered whenmigration_plan∈ {completed, skipped, not_applicable} — orin_progresson build_deploy only (Stage 2 failed/aborted; fallback POC from design.json per migration-plan.md failure handling); for entry pointmigrate, only whenmigration_plan == "completed"(the POC implements the plan) OR when the stage resolvednot_applicablewithmigration_plan_unavailable == "engine_absent"— a standalone deployment that does not bundle the migration engine, where Gate 2 is offered by migration-plan.md Step -1 and the POC is design-backed. A migrate-POC with no plan for any OTHER reason (the user declined) has nothing to implement.Persisting Gate 2 as
phases.poc = "in_progress"BEFORE poc.md loads makes the confirmation resumable: if the session breaks between the "yes" and the load, the interpreter re-enterspocwithout re-asking. (A declared deviation fromINTERPRETER.md§ The interpreter loop step 5's gate-then-in_progressordering — the user's confirmation is the entry event worth persisting.)
Phase gate: Do NOT load design.md / estimate.md / generate.md unless
$RUN_DIR/.phase-status.json exists and BOTH phases.clarify == "completed" AND
phases.confirm == "completed". Confirm confirms the deployment model, the service
set, and (for a co_recommend tie) the user's chosen_runtime — Design and the diagram depend on
its confirm.json output, so it must not be skipped. If the user asks to skip Clarify or Pass 2,
refuse briefly and run it.
State file (.phase-status.json)
{
"run_id": "0630-1430",
"entry_point": "build_scratch",
"audience": "technical",
"current_phase": "clarify",
"phases": {
"intake": "completed",
"discover": "skipped",
"clarify": "in_progress",
"confirm": "pending",
"design": "pending",
"estimate": "pending",
"generate": "pending",
"migration_plan": "pending",
"poc": "pending"
}
}Status values: pending → in_progress → completed, plus skipped. Use read-merge-write:
read before each update, change only the advancing keys, keep prior phases.
recommendation_reviewed (top level, boolean) is set to true by generate.md Step 5.5 when
the user explicitly confirms they have seen the recommendation. Gate 1, Gate 2, and the
migration_plan / poc states all require it — no gate may be asked while it is absent.
migration_plan additionally uses not_applicable (build_scratch, or no migratable workload
detected). When Stage 2 runs, migration_plan_ctx is added at the top level:
{"repo": "<abs path to target repo>", "migration_dir": "<abs path to .migration/<id>/>"} —
Stage 3 reads gcp-to-aws artifacts ONLY via this recorded path, never by re-globbing.
Files
| File | Purpose |
|---|---|
references/vendored/dsl/INTERPRETER.md | Vendored DSL execution contract (interpreter loop + gate protocol) |
references/phases/intake/intake.md | Entry point + technical background + open context |
references/phases/discover/discover.md | Lightweight code detection |
references/phases/clarify/clarify.md | Clarify orchestrator + answer mapping to scoring keys |
references/phases/clarify/clarify-technical.md | Technical-background question wording |
references/phases/clarify/clarify-business.md | Business-background question wording |
references/phases/confirm/confirm.md | Winner-specific follow-ups |
references/phases/design/design.md | Assemble recommendation; Migrate handoff branch |
references/phases/estimate/estimate.md | Coarse cost magnitude |
references/phases/generate/generate.md | Layered recommendation doc + scaffolding |
references/phases/migration-plan/migration-plan.md | Stage 2: full migration plan via the sibling gcp-to-aws engine |
references/decision-refs/temporal.md | Temporal rules: Tier 1/2 tables, adapter, runbooks, commercials (consumed by discover/clarify/design/generate) |
references/decision-refs/poc-shapes.md | Per-runtime POC deploy shapes (ECS/EKS/Lambda/MicroVMs/Temporal) |
references/decision-refs/*.md | Runtime service cards, model defaults, freshness |
references/decision-refs/workload-classes.md | Deterministic verdicts for non-agent workload units (batch/service/io) |
references/runtimes/*.json | Runtime registry (read by scoring.py) |
scripts/scoring.py | Deterministic scoring engine |
scripts/test_temporal_decision_refs.py | Content lock for the Temporal decision reference |
scripts/test_poc_shapes.py | Content lock for the POC deploy shapes |
scripts/test_workload_classes.py | Content lock for workload-classes.md (verdicts table) |
scripts/test_unit_grouping.py | Unit grouping + pattern matching (workload-class assignment) |
scripts/test_collapse_invariant.py | Collapse-invariant ordering enforcement (A→B implies [B] ⊆ [A] outputs) |
Maturity and readiness contract
Intake persists target_maturity (prototype, private_beta, or production) in run state. Clarify carries it and the readable readiness record into answers.json. Current-run verification evidence remains exclusively in the sibling $RUN_DIR/current-run-verifications.json artifact: never copy it into seed.json or answers.json. Design and Generate may consume that artifact only after validating its schema and matching run_id, and may carry forward verified outcomes but not the raw evidence records. Load references/decision-refs/maturity-readiness.md whenever target maturity is selected. A cached volatile fact may inform discovery, but only a record verified in this run can make a verification-required constraint final; otherwise the score remains provisional with deferred verification requirements.
Contextual offers (final step)
Before you finish: your answer is not complete until you have run the Contextual offers (final step) below.
This is a mandatory closing step of every final recommendation — complete it before you consider your answer done. Run this offer check inline yourself; do not depend on loading another skill. The recommendation is decided on merit first; this step never changes, re-ranks, or re-opens it, and the offer is looked up only after the advice is final.
Read
../knowledge-base-for-startups/references/offers.md— the offer index (Offer · Summary · Keywords), one row per offer.Judge relevance against what the founder actually surfaced this session. Surface an offer only if one holds: a named-product match (you recommended a specific partner product by name and it has a row); a direct intent/component match (an offer's Keywords directly serve a concrete workload, a component in the final recommendation, or a need the founder raised). Keep a high bar — if the match is weak, or you would be inferring an unstated need, append nothing. Never surface an offer that competes with a product or provider the founder already uses or decided to keep (e.g. existing auth provider → no Auth0 unless they are already on Auth0, and then only as a credit on it; existing vector DB such as Pinecone → no Qdrant).
If (and only if) one offer clears the bar, open only its detail file
../knowledge-base-for-startups/references/offers/<slug>.mdand append exactly one quiet, dismissible italic line — stating the value and condensing eligibility faithfully from that file (drop no qualifying criterion; never fabricate), with the redeem link built from the canonicalsource_urlplus asourceattribution param — append?source=ide-startupAdvisor-<host>(or&source=...if the url already has a query string), filling<host>from your execution environment (Claude Code →claude; AWS Startup Advisor IDE extension / VS Code →vscode; Cursor →cursor; Kiro →kiro; Codex →codex), or the genericide-startupAdvisorwhen you cannot tell. Only append the query param; never change the destination. When an offer clears the bar you MUST append that single offer line as the last step; do not omit it. The offer is never the pick — only a line under the AWS pick — and stage gates in the references apply (e.g. no Datadog line for an early-stage founder; see../architect-for-startups/references/observability.md). For a single-service pick (auth, payments, vector DB, observability, etc.) where missing budget/team/traffic inputs would not change the pick, assume an early-stage (pre-PMF) startup unless the founder says otherwise and answer in one turn without a stage-only question; this only removes a stage-only question and never skips the Intake/Clarify/Confirm gates before final advice or the POC. Show exactly one, never a list. If none clears the bar, append nothing and do not mention offers, partner alternatives, or why none appeared.
Standard line:
***<Offer>** has an exclusive offer via AWS Activate — <value>, <eligibility>. [Redeem →](<source_url>?source=ide-startupAdvisor-<host>)*Caps and control: at most one offer per response and often none; no more than one per five messages and two per session; show a given offer at most once per session and never one already shown, claimed, or dismissed; if the founder has muted offers, skip this step entirely. These per-five-messages, per-session, and already-shown caps are session-state limits; in a fresh session with no prior offers they are non-binding, so do not withhold an otherwise-qualifying offer merely because you cannot verify session history. See ../contextual-offers-for-startups/SKILL.md for the full rules — but perform the check inline; it must not depend on that skill being loaded.
Files
- ATTRIBUTION.mdAdded by AutoGineer907 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md19.2 KiB
- references/decision-refs/agentcore.md5.4 KiB
- references/decision-refs/batch.md2.3 KiB
- references/decision-refs/cost-levers.md1.8 KiB
- references/decision-refs/ecs.md1.4 KiB
- references/decision-refs/eks.md1.1 KiB
- references/decision-refs/freshness.md10.7 KiB
- references/decision-refs/lambda-microvms.md1.9 KiB
- references/decision-refs/lambda.md1.1 KiB
- references/decision-refs/managed-alternatives.md1.9 KiB
- references/decision-refs/maturity-readiness.md2.8 KiB
- references/decision-refs/model-selection.md4.2 KiB
- references/decision-refs/poc-shapes.md15.5 KiB
- references/decision-refs/temporal.md17.5 KiB
- references/decision-refs/workload-classes.md2.2 KiB
- references/diagram/build-diagram.md5.1 KiB
- references/handoff/handoff-migration.md2.1 KiB
- references/output-templates/recommendation-doc.md5.1 KiB
- references/phases/add-capabilities/add-capabilities-assemble.md951 B
- references/phases/add-capabilities/add-capabilities.md4.6 KiB
- references/phases/clarify/clarify-assemble.md1.4 KiB
- references/phases/clarify/clarify-business.md3.3 KiB
- references/phases/clarify/clarify-technical.md2.7 KiB
- references/phases/clarify/clarify.md26.5 KiB
- references/phases/confirm/confirm-assemble.md1019 B
- references/phases/confirm/confirm.md15.1 KiB
- references/phases/design/design-assemble.md1.7 KiB
- references/phases/design/design.md26.9 KiB
- references/phases/discover/discover-assemble.md1.2 KiB
- references/phases/discover/discover.md10.0 KiB
- references/phases/estimate/estimate-assemble.md780 B
- references/phases/estimate/estimate.md19.0 KiB
- references/phases/generate/generate-assemble.md1.0 KiB
- references/phases/generate/generate-report.md45.6 KiB
- references/phases/generate/generate.md15.7 KiB
- references/phases/intake/intake-assemble.md991 B
- references/phases/intake/intake.md5.6 KiB
- references/phases/migration-plan/migration-plan-assemble.md1.2 KiB
- references/phases/migration-plan/migration-plan-gcp-constraints.md3.9 KiB
- references/phases/migration-plan/migration-plan.md32.1 KiB
- references/phases/model-recommend/model-recommend-assemble.md937 B
- references/phases/model-recommend/model-recommend.md17.2 KiB
- references/phases/poc/poc-assemble.md1.0 KiB
- references/phases/poc/poc-report.md12.6 KiB
- references/phases/poc/poc.md44.8 KiB
- references/report-help-banner.md6.0 KiB
- references/report-shell.md12.3 KiB
- references/runtimes/agentcore.json3.1 KiB
- references/runtimes/ecs.json1.5 KiB
- references/runtimes/eks.json1.4 KiB
- references/runtimes/lambda.json2.4 KiB
- references/runtimes/lambda_microvms.json3.3 KiB
- references/vendored/README.md2.0 KiB
- references/vendored/ai/bedrock-pricing-cache.md57.2 KiB
- references/vendored/ai/models/anthropic-bedrock.json8.6 KiB
- references/vendored/ai/models/openai-bedrock.json28.0 KiB
- references/vendored/dsl/INTERPRETER.md51.8 KiB
- scripts/anthropic_model_recommendation.pyScript35.0 KiB
- scripts/build_diagram.pyScript21.2 KiB
- scripts/model_recommendation.pyScript8.8 KiB
- scripts/openai_model_recommendation.pyScript58.1 KiB
- scripts/pyproject.toml170 B
- scripts/schemas/current-run-verifications.json1.1 KiB
- scripts/schemas/model-recommendation-input.json5.4 KiB
- scripts/schemas/model-recommendation.json13.1 KiB
- scripts/schemas/model-verification.json2.5 KiB
- scripts/schemas/scoring-result.json3.5 KiB
- scripts/schemas/seed.json5.6 KiB
- scripts/score_units.pyScript2.9 KiB
- scripts/scoring.pyScript16.5 KiB
- scripts/test_build_diagram.pyScript21.8 KiB
- scripts/test_collapse_invariant.pyScript2.0 KiB
- scripts/test_cost_levers.pyScript1.7 KiB
- scripts/test_model_recommendation.pyScript13.9 KiB
- scripts/test_openai_model_recommendation.pyScript46.5 KiB
- scripts/test_opus55_generation_contracts.pyScript20.8 KiB
- scripts/test_opus55_integration.pyScript21.5 KiB
- scripts/test_poc_shapes.pyScript14.2 KiB
- scripts/test_scoring.pyScript35.3 KiB
- scripts/test_temporal_decision_refs.pyScript7.4 KiB
- scripts/test_unit_grouping.pyScript71.7 KiB
- scripts/test_verify_model_path.pyScript25.8 KiB
- scripts/test_workload_classes.pyScript5.2 KiB
- scripts/uv.lock97.8 KiB
- scripts/verify_model_path.pyScript10.9 KiB
references/decision-refs/poc-shapes.md
POC Shapes — Per-Runtime Deploy Artifacts
Single source of truth for what a generated POC looks like per winning
runtime. Loaded by poc.md Step 3 (non-AgentCore verdicts) and by its
temporal_worker_poll dispatch (whose base shape follows the unit's
effective_runtime — ecs or eks — see the Temporal worker POC section).
Content locked by scripts/test_poc_shapes.py — changing a allowlist, auth
mode, or fallback rule requires updating that test in the same commit.
Common contract (every runtime)
plan.mdprecedes artifacts (staged deployment plan).Bedrock wiring is CONDITIONAL on the unit's
model_recommendation != null. An agent unit (model-bearing) carries the minimal Bedrock-calling logic; the entrypoint file name and contract are runtime-specific:agent.py(HTTP/invocations+/ping) for AgentCore/ECS/EKS,handler.py(Lambda handler) for Lambda; Harness has no code file; a plan-backed 3-F POC ships the user's migrated app instead. A model-less unit (a plainservice/batch/light_iounit in a MIXED system —model_recommendation: null) carries NO Bedrock code, NO model env var (BEDROCK_MODEL_ID), NObedrock:InvokeModelIAM permission, NO model-access prerequisite, and NO Bedrock smoke check — its POC is the runtime shape alone (container/job/function + its trigger). Every runtime shape below (ECS/EKS/Lambda/Batch/Fargate) applies its Bedrock-specific artifacts, env, IAM, and smoke ONLY when the unit is model-bearing.deploy.shguardrails (all runtimes): cost warning at top; typedread -p "Type 'deploy' to continue"confirmation before any resource-creating call; region via env var, and model via env var ONLY for a model-bearing unit; NO credentials embedded; volatile CLI flags carryTODO: verifyunless MCP-verified.README.md: prerequisites, deploy, test-after-deploy, teardown, cost note (no dollar figures — point to the recommendation doc).Mode A generates files only — nothing is executed. Mode B follows poc.md Step 4's safety contract unchanged.
agentcore
Unchanged — poc.md sections 3-H (Harness) / 3-F (plan-backed framework) / 3a–3e (code path) remain the authority. This file adds nothing for AgentCore.
ecs
Also serves fargate verdicts (W5/W6). ECS-on-Fargate is this shape's launch type, so a
fargate verdict (a light_io/service unit under workload-classes W5/W6) uses this exact
shape — same artifacts, same create-allowlist, same smoke path. There is no separate
## fargate shape; ecs-poc.tf already provisions Fargate tasks (no EC2 launch type).
Scope limit for W5 (fargate — Fargate behind ALB): this POC deliberately does NOT
provision an ALB (see never-create list below) — provisioning one drags in VPC/subnet/target-group
wiring the POC's never-list exists to avoid. So for a W5 webhook/HTTP-ingress workload, this POC
validates the container via the localhost smoke path (plus Bedrock connectivity ONLY for a
model-bearing unit), not the public ALB ingress. State this in the generated README.md: for
a model-bearing unit, "POC validates the task and its Bedrock calls; the production W5 design puts
this Fargate service behind an ALB — add the ALB and its target group when you promote beyond the
POC." For a model-less unit, drop the "and its Bedrock calls" clause. Do not claim the POC
exercised the real HTTP entry point, and do not claim Bedrock calls for a model-less unit.
Artifacts: Dockerfile, ecs-poc.tf, agent.py, deploy.sh, README.md.
Model-less variant (a
service/batch/light_ioSECONDARY unit withmodel_recommendation: null): the entrypoint is a plainapp.py(the container's real work, no Bedrock call), the task role gets NObedrock:InvokeModel, there is noBEDROCK_MODEL_IDenv var or model-access prerequisite, and the smoke path checks the container is healthy (not a Bedrock round-trip). Everything below aboutagent.py/ model env / InvokeModel applies ONLY when the unit is model-bearing.
No ALB. The smoke path is: deploy.sh finishes by running a one-off
aws ecs run-task(oraws ecs execute-command) that curls the container's localhost endpoint, then prints theaws logs tail /agent-advisor/poc/<run_id> --followcommand. A service that deploys but cannot be invoked is not a POC.Terraform may create ONLY: ECS cluster (reuse-or-create by name), ECR repo, CloudWatch log group
/agent-advisor/poc/<run_id>, IAM roles and policies, security group (egress-only), task definition, service (desired_count 1, Fargate, 0.25–0.5 vCPU).Terraform must NEVER create: VPC, subnets, NAT gateway, internet gateway, ALB/NLB.
Networking:
VPC_ID/SUBNET_IDSenv vars → if unset, data-source the default VPC → if no default VPC exists, FAIL with a clear message; never create one. Public IP = ENABLED when in the default VPC (no NAT assumption).IAM: task execution role attaches the managed
AmazonECSTaskExecutionRolePolicy; task role getsbedrock:InvokeModelscoped to the resolved model ARN only.Image tag:
poc-<run_id>. deploy.sh creates the ECR repo if missing (inside the typed-confirm section), builds, pushes.Teardown:
terraform destroy; note that the ECR repo (if Terraform-created) goes with it.
eks
Model-less variant (a non-agent SECONDARY unit,
model_recommendation: null): plainapp.py(no Bedrock call), nobedrock:InvokeModelin the IRSA/node-role prerequisite, no model env var, health-check smoke only. The Bedrock-related items below apply ONLY when the unit is model-bearing (per the common-contract conditional).
Artifacts: Dockerfile, k8s/namespace.yaml, k8s/deployment.yaml,
k8s/service.yaml, deploy.sh, README.md.
Never creates an EKS cluster. Requires an existing cluster; without one, emit the manifests plus "point kubectl at your cluster".
Namespace is
agent-advisor-poc-<run_id>— unique per run, created bynamespace.yaml. Never a fixed name likepoc(teardown of a fixed name could delete a user's pre-existing namespace).Service type
ClusterIP; the README test path iskubectl port-forward+ local curl. No LoadBalancer (billable cloud resource).Bedrock auth: manifests include a commented IRSA
serviceAccountNameblock; README states the prerequisite "your node role or an IRSA service account must allow bedrock:InvokeModel". The EKS POC creates no IAM resources.deploy.sh: build/push to ECR, then
kubectl apply -f k8s/.Teardown:
kubectl delete -f k8s/— deletes exactly what it created.
lambda
Artifacts: handler.py, lambda-poc.tf, deploy.sh, README.md.
Model-less variant (a non-agent SECONDARY unit,
model_recommendation: null):handler.pydoes the function's real work with no Bedrock call, the role omitsbedrock:InvokeModel, there is noBEDROCK_MODEL_IDenv var, and the smoke is a plain invoke (no model round-trip). The Bedrock items below apply ONLY when the unit is model-bearing.
Function URL auth mode
AWS_IAM— neverNONE(a public Bedrock-invoking endpoint is an open cost hole). README test usescurl --aws-sigv4oraws lambda invoke.Terraform locks: timeout 60s, memory 512 MB,
source_code_hashon the package, CloudWatch log group, env varsAWS_REGION+BEDROCK_MODEL_ID, role withbedrock:InvokeModelscoped to the resolved model ARN.Packaging: zip via pip target-dir; if deps exceed zip limits, container image packaging (note it in README).
Teardown:
terraform destroy.
lambda_microvms
Artifacts: the full lambda shape above, PLUS microvms.tf.disabled.
Fallback rule: every MicroVMs-specific flag or config key MUST be MCP-verified this run. If verification fails, the file stays
.disabledwith this header: "MicroVMs config pending verification — POC deploys as standard Lambda; rename after verifying against AWS docs." No deployable claim is made for unverified MicroVMs config.If verified: rename guidance in README; config keys cite the verification in the freshness footer.
batch
Artifacts: Dockerfile, batch-poc.tf, job.py, deploy.sh, README.md.
Model-less variant (common for
batch— a job that calls no model,model_recommendation: null):job.pydoes its compute with no Bedrock call, the job role omitsbedrock:InvokeModel(keeping only its data-access policies, e.g. S3), noBEDROCK_MODEL_IDenv var, and the smoke is job SUCCEEDED (no model round-trip). Thebedrock:InvokeModelgrant below applies ONLY when the job actually calls a model.
Terraform may create ONLY:
aws_batch_compute_environment(Fargate compute environment),aws_batch_job_queue,aws_batch_job_definition,aws_ecr_repository, CloudWatch log group, IAM execution role and job role. Job role getsbedrock:InvokeModelscoped to the resolved model ARN when the job calls a model, plus least-privilege policies for whatever the job reads/writes (e.g. S3 GetObject/PutObject for bucket-scoped data).Terraform must NEVER create: VPC, subnets, NAT gateway, internet gateway, always-on compute resources.
Networking:
VPC_ID/SUBNET_IDSenv vars → if unset, data-source the default VPC → if no default VPC exists, FAIL with a clear message; never create one. Fargate jobs run in the specified subnets with public IP assignment when in the default VPC (no NAT assumption).Image tag:
poc-<run_id>. deploy.sh creates the ECR repo if missing (inside the typed-confirm section), builds, pushes.Smoke path: deploy.sh finishes by running
aws batch submit-jobwith the POC job definition, then pollsaws batch describe-jobsuntil the job reachesSUCCEEDEDstatus, and prints the CloudWatch Logs command to read the job's output. A job definition that cannot be invoked is not a POC.Teardown:
terraform destroyderegisters the job definition, deletes the queue and compute environment, and deletes the ECR repository. Note that resources that are not deletable while jobs are running — drain the queue first beforeterraform destroyif jobs are in-flight.deploy.sh guardrails: cost warning at top; typed
read -p "Type 'deploy' to continue"confirmation before any resource-creating call; region and model id (when the job calls a model) via env varsAWS_REGIONandBEDROCK_MODEL_ID; NO credentials embedded; volatile CLI flags carryTODO: verifyunless MCP-verified this run.Secrets: API keys, tokens, or sensitive configuration go in SSM Parameter Store (SecureString) or Secrets Manager, referenced in the job definition via
secrets— never inline in the job definition or Terraform.
Composite (multi-unit) layout
With >1 unit in design.json, nest per-unit POCs under poc/<unit-id>/, each applying
its own runtime shape. A top-level poc/README.md orchestrates: deploy ORDER, per-unit
deploy.sh pointers, env-var interconnects only. Single unit collapses to today's flat
layout. See poc.md Step 3 UNIT DISPATCH as the authority.
Temporal worker POC (used by poc.md Step 3 unit dispatch for temporal_worker_poll units)
Base shape follows the unit's effective_runtime, NOT always ECS:
effective_runtime == "ecs"(orserverless_workers, which is Public Preview and smoke-deploys on ecs) → reuse the ecs shape's Terraform allowlist/never-list and guardrails, with the Temporal deltas below.effective_runtime == "eks"→ reuse the eks shape's cluster model (kubectl + existing cluster, NO Terraform, uniqueagent-advisor-poc-<run_id>namespace) but OVERRIDE its artifacts for a worker (NOT the generic HTTP shape — a Temporal worker exposes NO HTTP endpoint, so there is NOservice.yaml, NOClusterIP, and NOkubectl port-forward+ curl smoke):Artifacts:
Dockerfile(COPYssmoke_worker.py),smoke_worker.py,k8s/namespace.yaml,k8s/deployment.yaml(runssmoke_worker.py worker, long-poll),k8s/smoke-job.yaml(the one-shot starterJobrunningsmoke_worker.py start),deploy.sh,README.md. NOservice.yaml.Smoke: apply
k8s/smoke-job.yaml(a one-shotJob, NOT an ECSrun-task); the proof is the starter's printed result, verified viakubectl logs job/<name>, NOT an HTTP curl.Secrets: the API key/cert material is loaded into a Kubernetes Secret created by
deploy.shfrom env/files (kubectl create secret) — do NOT commit connection material into a generatedsecret.yaml. Scalar values (e.g.TEMPORAL_API_KEY) are injected as env vars viasecretKeyRef. But theTEMPORAL_TLS_CA_PATH/TEMPORAL_TLS_CERT_PATH/TEMPORAL_TLS_KEY_PATHvars are FILE PATHS — mount the cert Secret keys as a volume (volumeMountsat, e.g.,/tmp/temporal-tls/) and set those*_PATHenv vars to the mounted file paths; do NOTsecretKeyRefcert contents into the path variables (that puts PEM bytes wheresmoke_worker.pyexpects a filename, and it fails opening the path).Teardown:
kubectl delete -f k8s/(+ the one-shot starter pod/Job) — NEVERterraform destroy(this base creates no Terraform). The task queue is stillpoc-smoke-<run_id>and the connection env contract is identical. An EKS-selected worker therefore gets a Kubernetes worker POC, not an ECS Fargate one.
Temporal deltas (apply on whichever base shape the effective_runtime selected):
The container runs
smoke_worker.py worker(long-poll worker); the smoke is a SEPARATE one-off starter ofsmoke_worker.py start— on the ECS base anaws ecs run-task(or local run), on the EKS base a one-shotJob(k8s/smoke-job.yaml). Deploy succeeding proves nothing by itself — the starter's printed result is the proof.Task queue:
poc-smoke-<run_id>— never the user's real queues.Connection env contract (explicit — never inferred):
Connection via the full env contract —
TEMPORAL_ADDRESS,TEMPORAL_NAMESPACE,TEMPORAL_TLS,TEMPORAL_API_KEY,TEMPORAL_TLS_SERVER_NAME,TEMPORAL_TLS_CA_PATH,TEMPORAL_TLS_CERT_PATH,TEMPORAL_TLS_KEY_PATH— mapped EXPLICITLY toClient.connect(tls=TLSConfig(...));TEMPORAL_TLSis never inferred from other vars.
| Env | Meaning |
|---|---|
TEMPORAL_ADDRESS, TEMPORAL_NAMESPACE | always required |
TEMPORAL_TLS | off / tls / mtls |
TEMPORAL_API_KEY | Cloud API-key auth (with tls) |
TEMPORAL_TLS_SERVER_NAME | SNI override (self-hosted behind LB) |
TEMPORAL_TLS_CA_PATH | custom root CA (self-hosted TLS) |
TEMPORAL_TLS_CERT_PATH / TEMPORAL_TLS_KEY_PATH | client cert/key (mtls) |
Secrets material (API key, cert/key) is never inline: on ECS it comes from SSM Parameter Store (SecureString) or Secrets Manager via task-definition
secrets; on EKS it comes from a Kubernetes Secret mounted into the pod.run_local.shreads local file paths.Teardown wording follows the base: on ECS,
terraform destroystops the worker; on EKS,kubectl delete -f k8s/(plus the one-shot starter pod/Job) — neverterraform destroyon the EKS base. Either way, Temporal task queues are not deletable resources — thepoc-smoke-<run_id>queue metadata ages out on its own and never touches production queues.
Requirements and compatibility
Written for: Claude Code
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Names Claude Code tools, Needs Python
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- AWS
- Publisher
- AWS (Official)
- Source
- aws/agent-toolkit-for-aws · plugins/aws-startup-advisor/skills/agent-advisor · commit 0a218f8
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- NOTICE (added by AutoGineer from NOTICE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by AWS.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download agent-advisor.zip