AWS + Kubernetes operations dashboard with real-time monitoring, a private CloudFront/Fargate edge, Aurora Serverless v2 state, and AI-powered diagnosis via Amazon Bedrock AgentCore. | ๋น๊ณต๊ฐ CloudFront/Fargate ์ฃ์ง, Aurora Serverless v2 ์ํ ์ ์ฅ, Amazon Bedrock AgentCore ๊ธฐ๋ฐ AI ์ง๋จ์ ๊ฐ์ถ ์ค์๊ฐ ๋ชจ๋ํฐ๋ง AWS + Kubernetes ์ด์ ๋์๋ณด๋์ ๋๋ค.
AWSops v2 is a single-pane operations dashboard for AWS and Kubernetes, rebuilt as a Terraform-based MSA: a private edge (CloudFront VPC Origin โ internal ALB โ ECS Fargate), Cognito + Lambda@Edge auth, Aurora Serverless v2 persistent state, AgentCore section agents for live AWS queries, and an OOM-safe async worker tier. The previous v1 architecture (single EC2, CDK, embedded Steampipe) is being decommissioned per ADR-016 โ per ADR-016 (decision records are maintained in the private upstream repository).
Internet -> CloudFront (TLS, Lambda@Edge Cognito auth) -> VPC Origin (https-only) -> internal ALB (HTTPS)
-> ECS Fargate: Next.js 15 thin-BFF :3000 (arm64, no basePath) -> Aurora Serverless v2 (PG 17.9, node-pg)
-> Amazon Bedrock AgentCore: Runtime (Strands) + 9 section Gateways + Memory + Code Interpreter
-> async workers: POST /api/jobs -> SQS -> Step Functions -> Lambda or Fargate worker
Stats: 41 pages, 99 API routes, 110 components (web/), 21 consolidated ADRs, Terraform-managed (terraform/foundation, no CDK).
No public ALB. The edge is fully private โ CloudFront reaches the ALB only through a VPC Origin, and the ALB only accepts traffic from CloudFront's managed security group. v2's posture is a read-only ops dashboard + AI diagnosis: AWS-resource mutation and autonomous remediation are FROZEN by design (ADR-005) โ infra changes stay with the operator's own IaC/Change Manager, with one narrowly-scoped exception for self-healing service restarts (ADR-015). (ADR-019's SG-rules Athena role is a separate, ordinary GATED feature โ ADR-019 concludes it sits inside the existing read-only invariant and is not an ADR-005 exception.)
- Resource inventory -- EC2, EKS, Lambda, ECS clusters/tasks, ECR, storage/DB, network, and security groupings, derived from Aurora-persisted inventory snapshots (with an optional flag-gated Steampipe sync layer).
- AI assistant -- Bedrock AgentCore Runtime (Strands agent) routes each question to 1-3 of 9 section gateways in parallel and synthesizes the result, with SSE streaming, AgentCore Memory (conversation history), and a Python Code Interpreter.
- CIS compliance -- Powerpipe benchmark runs with history (
compliance_runs/compliance_results), flag-gated. - Cost and FinOps -- Cost Explorer, Bedrock usage/spend tracking, and 14-day resource-trend charts on the dashboard.
- Async diagnosis and jobs -- long-running work (AI diagnosis reports via
POST /api/diagnosis, compliance scans viaPOST /api/compliance/run) is enqueued to the same SQS + Step Functions + Lambda/Fargate worker tier as the genericPOST /api/jobsroute โ the web tier never blocks on OOM-risk work./api/jobsitself only acceptsnoop/noop-heavyjob types (diagnosis/compliance computerequestedByserver-side and reject attacker-controlled report/run ids);GET /api/jobsandGET /api/jobs/[id]enforce owner-or-admin visibility. - EKS onboarding --
configure.mjsprovides host-account Terraform onboarding. Enabled member clusters register through the web UI using the registered member role for discovery and default Kubernetes authentication; that role needs its own Access Entry/read policy. Explicit SA-token and same-member AssumeRole authentication are supported.
9 section gateways are defined in Terraform (ai.tf); each is provisioned idempotently and routes to Lambda-backed MCP tools. All 9 gateways hold READY MCP targets โ the fleet (local.agent_lambdas, 30 slices: 21 gated on agentcore_enabled, 9 on integrations_enabled) is deployed; the table below reflects the live shape.
| Gateway | Capabilities | Status |
|---|---|---|
| network | VPC, ENI, reachability, flow logs, TGW, VPN, firewall | โ live |
| security | IAM users/roles/policies + policy simulation (14 tools, iam-mcp) | โ live |
| container | EKS, ECS, Istio, Kubernetes | โ live |
| data | DynamoDB, RDS/Aurora, ElastiCache, MSK, OpenSearch | โ live |
| cost | Cost Explorer, forecast, budgets, container cost | โ live |
| monitoring | CloudWatch, CloudTrail | โ live |
| iac | CloudFormation, CDK, Terraform | โ live |
| ops | Aurora-backed inventory/topology reads + AWS docs/CLI suggestions (no live Steampipe) | โ live |
| external-obs | External observability & integrations (Prometheus, ClickHouse, Notion) | โ live |
All 9 rows are gated behind agentcore_enabled/integrations_enabled (default false in a fresh clone/deploy โ plan = No changes, $0); "live" here describes this project's actual running deployment, which has both flags on.
Models: Claude Sonnet 5 (default), Opus 4.8 (deep analysis), Haiku 4.5 (fast/low-cost).
- Terraform >= 1.15 (S3 native state locking via
use_lockfile) - Node.js >= 18 (configurator TUI, migration scripts)
- Docker with buildx (arm64 image builds)
- AWS CLI configured with credentials for the target account
- kubectl and a kubeconfig, if onboarding EKS clusters
# Clone the repository
git clone https://github.com/Atom-oh/awsops.git
cd awsops
# Interactive TUI: choose new/existing VPC, domain, bucket, EKS clusters
make configure # -> terraform.tfvars + backend.hcl
# Provision the foundation stack
terraform -chdir=terraform/foundation init -backend-config=backend.hcl
terraform -chdir=terraform/foundation plan -out tfplan
terraform -chdir=terraform/foundation apply tfplan
# New, verified-empty DB only, from an approved host with private Aurora connectivity:
INITIALIZE_EMPTY_DB=1 make migrate
# For an existing ledger use make migrate; INTEGER ledgers need the separate BOOTSTRAP gate.
# See terraform/foundation/migrations/README.md for runtime image/env/IAM/TLS and recovery.
# Build + push web, roll ECS and wait for /api/health (reruns migrate first; any failure blocks deploy)
make deploy
# After migrations: build/push the agent image and run the idempotent provisioner.
# make agentcore does not create the reader role or sync its password.
# See docs/runbooks/agent-sql-reader.md.
make agentcore
# After apply with workers_enabled=true: build/push the worker image
make workersmake help # list all available targets
make migrate-status # offline: app version + each on-disk migration's release
make backfill-owner-sub # PLAN the legacy email-keyed requested_by -> Cognito sub rewrite (changes
# nothing). Review the plan, delete entries you cannot vouch for, then
# `node scripts/v2/backfill-owner-sub.mjs --apply <plan.json>`. Quiesce the
# schedule dispatcher first โ the plan output prints the exact commands. Step 2
# of ADR-009's Ownership Amendment; step 3 is legacy_email_owner_match=false.
DRY_RUN=1 make migrate # preview pending DB migrations before applying
make upgrade # safe release upgrade: RDS snapshot -> migrate -> deployRuntime configuration is flag-gated in the Terraform foundation root (variables.tf, ai.tf, and ci-migrations.tf). The feature gates below all default false, so their gated resources are absent from a fresh plan. Four operational switches deliberately do NOT: legacy_email_owner_match (default true โ accepts the legacy email-keyed ownership match at every matchesIdentity() gate โ reads and report PATCH/DELETE via canMutateReport(), not reads alone; flip to false only after a successful --apply leaves zero legacy email-keyed rows, or a plan that finds none at all โ a clean plan over rows that still need rewriting is not enough, make backfill-owner-sub only plans; see ADR-009's Ownership Amendment), the pre-existing create_network / allow_vpc_db_access, and publish_service_dns:
publish_service_dns defaults to true; false removes service A aliases from the desired
configuration, but does not disable certificate validation CNAMEs. The nullable
existing_cf_certificate_arn / existing_alb_certificate_arn inputs default to null
(Terraform-managed certificates). External certificates must already be issued and trusted;
CloudFront's must be in us-east-1, and the ALB's in the stack Region.
For DNS-free deployment, an explicit dispatch preserves existing managed certificate ownership
and service aliases. External certificates require operator-selected ARNs or already-attached
external certificates; CI never scans the account to choose one. allow_dns_changes is a
dispatch input (default false), separate from publish_service_dns; it prohibits private
Cloud Map changes too. Routine CI cannot externalize a managed certificate or retire/replace
its validation CNAMEs even when DNS is allowed. PR/push plans are advisory and cannot
be applied; dev preserves ownership from state without live certificate/SAN checks.
Dev repo variables override domain/zone consistently in console and plan, with
CERTIFICATE_MODE_DEV=preserve|managed. Explicit domain_rollout=true on each dev/full
domain-stage plan pins scoped DNS checks in saved metadata; its default false retains
ordinary DNS behavior only with explicit permission. Apply cannot toggle that saved scope.
See the unpublished/same-domain rollout runbook,
edge reference
and deployment runbook ยง5.
| Flag | Gates |
|---|---|
agentcore_enabled |
21 of the AgentCore Lambda slices |
ci_readiness_enabled |
Default-off bounded billed deployment probe. Dedicated CI_READINESS_ENABLED_DEV=true/false overrides the dev value; unset preserves explicit tfvars/default false. The runtime profile alone does not enable it. Before the mandatory dev Deploy Web gate, apply steampipe_enabled=true, agentcore_enabled=true, workers_enabled=true and readiness, deploy the inventory/worker images, ensure worker dispatch is enabled, and provision AgentCore as described in runtime activation, which requires post-marker success with known counts and zero unknown attributes for every current catalog type plus runtime and worker proof; health-only verification cannot bypass it. Public CI permits enabled readiness only on dev. Apply requires AgentCore for the verifier group and create_demo_user=true for managed-demo membership. Each activated dev release invokes collection, a billed model probe and two real worker jobs. No admin/IAM grant. |
integrations_enabled |
remaining 6 AgentCore Lambda slices |
workers_enabled |
the async worker tier (SQS/SFN/Lambda/Fargate) |
ci_migrations_enabled |
Default-off operator capability: private migration task template, exact-secret task role/policy and 14-day logs. Private dev CI migration: manual dispatch or the guarded current-source Deploy Web path; no service or scheduler. Disabling deletes the log group/history. |
steampipe_enabled |
the Steampipe inventory-sync data layer |
inventory_host_only |
Default-off collector scope: require exactly one enabled host and omit collector AssumeRole. Agent MCP grants stay unchanged; dev requires profile-bound host verification. See runtime activation and ADR-011 onboarding. |
finops_baseline_enabled |
the FinOps baseline-recommendations engine (ADR-020): a daily Fargate rule batch (unattached EBS volumes; EC2/RDS rightsizing via Compute Optimizer) writing to finops_findings, read-only, rendered on /cost. Requires workers_enabled only at the Terraform level โ but the EBS rule additionally needs a fresh steampipe_enabled=true inventory sync at runtime; without it, that rule honestly reports partial (EC2/RDS rightsizing still work) |
official_mcp_enabled |
ADR-017 curated official-vendor MCP presets โ the 3 vendor-hosted ones (DatadogยทDynatraceยทNew Relic) as external-obs mcpServer targets. (The runtime fail-closed tool allowlist is NOT gated by this flag โ it is written on every provisioner run and enforced unconditionally; that unconditionality is the fail-closed property.) Operator notes: Dynatrace ships with a deliberately EMPTY allowlist (zero tools until its hosted tool list is transcribed into catalog.py); make agentcore waits for runtime READY (default 300s, AGENTCORE_RUNTIME_READY_TIMEOUT) and a failed/slow rollout temporarily retires eligible live targets until the next successful run. |
graph_querygen_enabled |
LLM fallback for the ONE ClickHouse trace_spans graph query (ADR-018). Note it does NOT carry the diag-signal path's identifier sanitising, relevance gate, weekly budget or read-side gate โ ADR-018 ยงC |
diag_signal_querygen_enabled |
LLM fallback for ONE Explore diag-signal chip, only when a kind's deterministic catalog yields zero ready rows (a partial match is not topped up), and only for the chips โ the diagnosis report never uses generated rows, and a flag-off read excludes them too. Separate from graph_querygen_enabled; both need datasource_diagnosis_enabled; graph_querygen_enabled ALSO requires agentcore_enabled (it provisions the Code Interpreter session IAM) |
sg_rule_activity_enabled |
the SG Rules Athena-based traffic-evidence pipeline (/network/security-groups/rules) โ the Athena/Glue broker Lambda, the daily sg_rule_scan worker job, and their Terraform (sg-rules.tf) |
network_path_check_enabled |
the Network Path Check page/worker (network-path.tf) โ fetch_live_topology() is now real (cache-only, from Aurora's synced topology), but a full live AWS/Kubernetes re-read at run time is still deliberately unimplemented, so POST .../runs still 503s unimplemented even with this flag on; see the Network Path Check changelog entry. A pod/node source's live identity confirmation additionally needs an EKS Access Entry โ for the worker task role on a host-account cluster (this feature's _default_k8s_get() uses that role's own credentials directly when the source's account is the host account), or for the target account's AWSopsReadOnlyRole on a member-account cluster (the K8s GET is authenticated via that assumed session instead, so registering the worker task role there is a no-op and every GET 403s) โ see docs/runbooks/network-path-eks-access.md + scripts/v2/eks/register-network-path-access.sh (ROLE_ARN=... overrides the principal for the member-account case) |
Runtime IAM narrowing is independent of these opt-in flags: the next apply changes permissions on already-enabled stacks, including main (three web SSM parameters, runtime discovery/token actions, own-cluster task control and Claude-only models). Known regions include future opt-ins; this is not live-access proof.
One more ADR-017 gate is not a terraform flag: CLICKHOUSE_OFFICIAL_MCP is an AgentCore runtime env recorded by the provisioner (CLICKHOUSE_OFFICIAL_MCP=true make agentcore) that embeds the official mcp-clickhouse as a stdio subprocess in the runtime container. It is FROZEN / do-not-enable: the stdio path has no replacement for the in-house lambda's table-function SSRF guard, so unfreezing requires both the technical precondition and a new ADR + multi-AI panel + dated owner-override (ADR-017 ยงStatus, BASELINE ยง2).
Two companion maps (not booleans, both default {}) configure ADR-017 per preset โ official_mcp_endpoints (map(string), preset_key -> https:// endpoint) and official_mcp_read_only_ack (map(string), preset_key -> the exact endpoint URL the operator reviewed, echoed verbatim โ not true). A preset provisions only when its ack equals its current endpoint; anything else is a fail-closed SKIP that retires any live target:
official_mcp_endpoints = { datadog = "https://mcp.datadoghq.com/v1/mcp" }
official_mcp_read_only_ack = { datadog = "https://mcp.datadoghq.com/v1/mcp" }AgentCore's own config (runtime ARN, Memory ID, Code Interpreter ID) is written to SSM (/ops/awsops-v2/agentcore/*) by the provisioner and read by the web BFF at runtime โ never passed via task-def valueFrom (avoids a startup race).
awsops/
web/ # Next.js 15 thin-BFF: 41 pages, 99 API routes, 110 components
agent/ # Strands Agent (Runtime source) + MCP Lambda tool sources
terraform/foundation/ # single Terraform root: network, edge, auth, data, workload, ai, workers, eks
scripts/v2/ # configure/deploy/migrate/agentcore/workers tooling (all Node.js/Python)
tests/ # repo-wide hook/structure tests + PR-review/Steampipe/ExternalId wiring checks
docs/ # guides, runbooks, implementation references (ADR bodies remain private)
docs-site/ # Docusaurus user guide (deployed separately)
Install the dependencies listed in merge verification.
Docker and prepared AWSOPS_REVIEW_CODEC_STATE are also required; use the sandbox setup.
Image fixtures, including the panel-prompt structure check in tests/run-all.sh, require
Python 3.12 on Linux ARM64/x86-64 and a separate hash-pinned Pillow install:
python3 -m pip install --require-hashes --only-binary=:all: -r scripts/pr-review/image-requirements.txt.
Do not combine this command with the unhashed requirements install.
Private migration tests require npm ci --prefix scripts/v2 --ignore-scripts --no-audit --no-fund
(pg + AWS SDK), OpenSSL and a reachable Docker daemon for postgres:17.
The required migration, web connection-phase and agent tool-policy history PostgreSQL suites fail if Docker is missing;
they use bare docker on PATH (the documented exceptions to optional legacy itests).
The web connection and policy suites also require npm ci --prefix web for the locked driver and TypeScript.
These suites and their offline companion use no AWS credentials.
Authenticated deployment smoke tests require curl, OpenSSL, Python 3 with PyYAML and Terraform 1.15.7;
their offline variable fixture needs no providers. Terraform mock tests require 1.15.7 and installed/cached
providers; the helper copies only tracked working-tree files, runs init -backend=false, validates
and tests without a real backend. Missing deployment-suite prerequisites fail the shared runner;
only its final fmt/validate diagnostics are informational.
The required test_ci_web_read.py and test_ci_web_deploy.py suites use Python 3.12 on Linux with /proc, POSIX process groups and os.geteuid; provider boundaries are simulated and those two suites do not invoke AWS CLI, gh, curl or jq. The required test_ci_web_workflow.py suite additionally needs PyYAML and Bash. Deploy Web uses the controller and forces automatic SQL admission for web-driven migrations; see docs/runbooks/release-safety-primitives.md.
The offline web image provenance helper tests also require jq, Linux /proc, and curl on /usr/local/bin:/usr/bin:/bin.
Deploy Web proves the image before private migrations, calls guarded promotion for that digest, then requires exact ECS/image verification and the full dev runtime gate including login/DB; the guide defines receipts and recovery. The release safety primitives describe the controller and migration policy.
See web release for standalone bootstrap or unsupported SQL โ successful migration/reader sync โ fresh web dispatch, and legacy image recovery for images without receipts.
bash scripts/v2/merge-verify.sh # required Python, web and deployment tests
node --test scripts/v2/ci/*.test.mjs # offline private migration runtime fixtures (CI required)
node --test scripts/v2/ci/migration.itest.mjs scripts/v2/ci/web-db-connection.itest.mjs scripts/v2/ci/agent-tool-policy.itest.mjs # real PG migration + web connections + agent policy regressions (CI required)
bash scripts/v2/terraform-test.sh # isolated, backend-disabled Terraform mock tests (also required in CI)
# Also CI-required when docs-site/ or .github/workflows/merge-verify.yml changes:
(cd docs-site && npm ci && npm run typecheck && npm run build &&
bash scripts/verify-deck.sh static/presentation/awsops-intro/awsops-intro.pptx)
node --test scripts/v2/deployment-smoke.test.mjs # offline health/auth/credential preparation and workflow checks
bash tests/run-all.sh # repo-wide hook/structure tests + agent Python unittests
(cd web && npx vitest run) # web unit tests onlyThe private migration fixture command includes runtime, controller, workflow and mocked-plan
checks. Controller/workflow checks also require Python 3 with PyYAML, boto3/botocore (pip install -r agent/requirements.txt) and Terraform 1.15.7.
See merge verification for the complete CI scope,
including the conditional documentation build and full presentation archive check.
The 99 API routes live under web/app/api/. Key routes: health (public), stream (SSE chat), db (Aurora ping), jobs (+/[id], async job submission/status), security, compliance, auth/login. See the docs site for user-facing guidance.
- Fork the repository
- Create your branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
Target dev. Fork contributions are integrated through a maintainer-owned internal PR
after patch inspection and full AI/CI review; fork tests alone do not satisfy the AI gate.
See the contribution branch flow.
Licensed under the MIT License. See LICENSE for details.
- Maintainer: Atom-oh
- Issues: github.com/Atom-oh/awsops/issues
AWSops v2๋ AWS์ Kubernetes๋ฅผ ์ํ ๋จ์ผ ํ๋ฉด ์ด์ ๋์๋ณด๋๋ก, Terraform ๊ธฐ๋ฐ MSA๋ก ์ฌ๊ตฌ์ถ๋์์ต๋๋ค: ๋น๊ณต๊ฐ ์ฃ์ง(CloudFront VPC Origin โ ๋ด๋ถ ALB โ ECS Fargate), Cognito + Lambda@Edge ์ธ์ฆ, Aurora Serverless v2 ์์ ์ํ, ๋ผ์ด๋ธ AWS ์กฐํ๋ฅผ ์ํํ๋ AgentCore ์น์ ์์ด์ ํธ, OOM-์์ ๋น๋๊ธฐ ์์ปค ๊ณ์ธต์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด์ v1 ์ํคํ ์ฒ(๋จ์ผ EC2, CDK, ๋ด์ฅ Steampipe)๋ ADR-016์ ๋ฐ๋ผ ํ๊ธฐ ์งํ ์ค์ ๋๋ค โ (๊ฒฐ์ ๊ธฐ๋ก์ ๋น๊ณต๊ฐ upstream ๋ฆฌํฌ์งํ ๋ฆฌ์์ ๊ด๋ฆฌ๋ฉ๋๋ค).
Internet -> CloudFront (TLS, Lambda@Edge Cognito ์ธ์ฆ) -> VPC Origin (https-only) -> ๋ด๋ถ ALB (HTTPS)
-> ECS Fargate: Next.js 15 thin-BFF :3000 (arm64, basePath ์์) -> Aurora Serverless v2 (PG 17.9, node-pg)
-> Amazon Bedrock AgentCore: Runtime (Strands) + 9 ์น์
Gateway + Memory + Code Interpreter
-> ๋น๋๊ธฐ ์์ปค: POST /api/jobs -> SQS -> Step Functions -> Lambda ๋๋ Fargate ์์ปค
ํํฉ: 41 ํ์ด์ง, 99 API ๋ผ์ฐํธ, 110 ์ปดํฌ๋ํธ(web/), 21๊ฐ ํตํฉ ADR, Terraform ๊ด๋ฆฌ(terraform/foundation, CDK ์์).
๊ณต๊ฐ ALB ์์. ์ฃ์ง๋ ์์ ํ ๋น๊ณต๊ฐ์ ๋๋ค โ CloudFront๋ VPC Origin์ ํตํด์๋ง ALB์ ๋๋ฌํ๊ณ , ALB๋ CloudFront ๊ด๋ฆฌํ ๋ณด์ ๊ทธ๋ฃน์ ํธ๋ํฝ๋ง ํ์ฉํฉ๋๋ค. v2์ ์์ธ๋ read-only ์ด์ ๋์๋ณด๋ + AI ์ง๋จ์ ๋๋ค: AWS ๋ฆฌ์์ค ๋ณ๊ฒฝยท์์จ ์กฐ์น๋ ์ค๊ณ์ FROZEN(ADR-005) โ ์ธํ๋ผ ๋ณ๊ฒฝ์ ์ด์์ ์์ ์ IaC/Change Manager๊ฐ ๋ด๋นํ๋ฉฐ, ์๊ฐ์น์ ์๋น์ค ์ฌ์์ ํ๋๋ง ์ข๊ฒ ์์ธ ํ์ฉ๋ฉ๋๋ค(ADR-015). (ADR-019์ SG-rules Athena role์ ๋ณ๊ฐ์ ์ผ๋ฐ GATED ๊ธฐ๋ฅ์ ๋๋ค โ ADR-019๋ ์ด๊ฒ์ด ๊ธฐ์กด read-only ๋ถ๋ณ์ ๋ด๋ถ์ ์๋ค๊ณ ๊ฒฐ๋ก ๋ด๋ฆฌ๋ฉฐ, ADR-005 ์์ธ๊ฐ ์๋๋๋ค.)
- ๋ฆฌ์์ค ์ธ๋ฒคํ ๋ฆฌ -- EC2, EKS, Lambda, ECS ํด๋ฌ์คํฐ/ํ์คํฌ, ECR, ์คํ ๋ฆฌ์ง/DB, ๋คํธ์ํฌ, ๋ณด์ ๊ทธ๋ฃนํ์ Aurora์ ์ ์ฅ๋ ์ธ๋ฒคํ ๋ฆฌ ์ค๋ ์ท ๊ธฐ๋ฐ์ผ๋ก ์ ๊ณต(์ ํ์ flag-gated Steampipe sync ๊ณ์ธต ํฌํจ).
- AI ์ด์์คํดํธ -- Bedrock AgentCore Runtime(Strands ์์ด์ ํธ)์ด ๊ฐ ์ง๋ฌธ์ 9๊ฐ ์น์ ๊ฒ์ดํธ์จ์ด ์ค 1~3๊ฐ๋ก ๋ณ๋ ฌ ๋ผ์ฐํ ํ ๋ค ๊ฒฐ๊ณผ๋ฅผ ํตํฉํ๋ฉฐ, SSE ์คํธ๋ฆฌ๋ฐยทAgentCore Memory(๋ํ ํ์คํ ๋ฆฌ)ยทPython Code Interpreter๋ฅผ ์ง์ํฉ๋๋ค.
- CIS ์ปดํ๋ผ์ด์ธ์ค -- Powerpipe ๋ฒค์น๋งํฌ ์คํ ์ด๋ ฅ ๊ด๋ฆฌ(
compliance_runs/compliance_results), flag-gated. - ๋น์ฉ ๋ฐ FinOps -- Cost Explorer, Bedrock ์ฌ์ฉ๋/๋น์ฉ ์ถ์ , ๋์๋ณด๋์ 14์ผ ๋ฆฌ์์ค ํธ๋ ๋ ์ฐจํธ.
- ๋น๋๊ธฐ ์ง๋จยท์์
-- AI ์ง๋จ ๋ฆฌํฌํธ(
POST /api/diagnosis)ยท์ปดํ๋ผ์ด์ธ์ค ์ค์บ(POST /api/compliance/run) ๋ฑ ์ฅ์๊ฐ ์์ ์ ๋ฒ์ฉPOST /api/jobs์ ๋์ผํ SQS + Step Functions + Lambda/Fargate ์์ปค ๊ณ์ธต์ ํ์ โ ์น ํฐ์ด๋ OOM ์ํ ์์ ์ ์ ๋ ์ง์ ์คํํ์ง ์์ต๋๋ค./api/jobs์์ฒด๋noop/noop-heavyํ์ ๋ง ํ์ฉํ๋ฉฐ(์ง๋จ/์ปดํ๋ผ์ด์ธ์ค๋requestedBy๋ฅผ ์๋ฒ ์ธก์์ ๊ณ์ฐํด report/run id ์์กฐ๋ฅผ ๋ง์),GET /api/jobsยทGET /api/jobs/[id]๋ ์์ ์-๋๋-๊ด๋ฆฌ์ ๊ฐ์์ฑ์ ๊ฐ์ ํฉ๋๋ค. - EKS ์จ๋ณด๋ฉ --
configure.mjs๋ ํธ์คํธ ๊ณ์ ์ Terraform ์จ๋ณด๋ฉ์ ์ ๊ณตํฉ๋๋ค. ํ์ฑํ๋ ๋ฉค๋ฒ ํด๋ฌ์คํฐ๋ ์น UI์์ ๋ฑ๋กํ๋ฉฐ ๋ฉํ๋ฐ์ดํฐ ์กฐํ์ ๊ธฐ๋ณธ Kubernetes ์ธ์ฆ์ ๋ฑ๋ก๋ ๋ฉค๋ฒ ์ญํ ์ ์ฌ์ฉํฉ๋๋ค. ํด๋น ์ญํ ์ Access Entryยท์ฝ๊ธฐ ์ ์ฑ ์ด ํ์ํ๊ณ , ๋ช ์์ SA ํ ํฐ๊ณผ ๋์ผ ๋ฉค๋ฒ ๊ณ์ ์ AssumeRole ์ธ์ฆ๋ ์ง์ํฉ๋๋ค.
Terraform(ai.tf)์ 9๊ฐ ์น์
๊ฒ์ดํธ์จ์ด๊ฐ ์ ์๋์ด ์์ผ๋ฉฐ, ๊ฐ๊ฐ ๋ฉฑ๋ฑํ๊ฒ ํ๋ก๋น์ ๋๋์ด Lambda ๊ธฐ๋ฐ MCP ๋๊ตฌ๋ก ๋ผ์ฐํ
๋ฉ๋๋ค. 9๊ฐ ๊ฒ์ดํธ์จ์ด ์ ๋ถ READY MCP ํ๊น์ ๋ณด์ ํฉ๋๋ค โ ํจ๋(local.agent_lambdas, ์ฌ๋ผ์ด์ค 30๊ฐ: 21๊ฐ agentcore_enabled + 9๊ฐ integrations_enabled ๊ฒ์ดํธ)๊ฐ ๋ฐฐํฌ๋์ด ์์ผ๋ฉฐ, ์๋ ํ๋ ์ค์ live ์ํ๋ฅผ ๋ฐ์ํฉ๋๋ค.
| Gateway | ์ฃผ์ ๊ธฐ๋ฅ | ์ํ |
|---|---|---|
| network | VPC, ENI, reachability, flow logs, TGW, VPN, firewall | โ live |
| security | IAM ์ฌ์ฉ์/์ญํ /์ ์ฑ + ์ ์ฑ ์๋ฎฌ๋ ์ด์ (14๊ฐ ๋๊ตฌ, iam-mcp) | โ live |
| container | EKS, ECS, Istio, Kubernetes | โ live |
| data | DynamoDB, RDS/Aurora, ElastiCache, MSK, OpenSearch | โ live |
| cost | Cost Explorer, forecast, budgets, ์ปจํ ์ด๋ ๋น์ฉ | โ live |
| monitoring | CloudWatch, CloudTrail | โ live |
| iac | CloudFormation, CDK, Terraform | โ live |
| ops | Aurora ๊ธฐ๋ฐ ์ธ๋ฒคํ ๋ฆฌ/ํ ํด๋ก์ง ์กฐํ + AWS ๋ฌธ์/CLI ์ ์(๋ผ์ด๋ธ Steampipe ์์) | โ live |
| external-obs | ์ธ๋ถ ์ต์ ๋ฒ๋น๋ฆฌํฐ & ์ฐ๋(Prometheus, ClickHouse, Notion) | โ live |
9๊ฐ ํ ๋ชจ๋ agentcore_enabled/integrations_enabled ๋ค์ ๊ฒ์ดํธ๋์ด ์์ต๋๋ค(์๋ก ํด๋ก ยท๋ฐฐํฌ ์ ๊ธฐ๋ณธ๊ฐ์ false โ plan = No changes, $0). ์ฌ๊ธฐ์ "live"๋ ์ด ํ๋ก์ ํธ์ ์ค์ ์ด์ ๋ฐฐํฌ ๊ธฐ์ค์ด๋ฉฐ, ๊ทธ ๋ฐฐํฌ๋ ๋ ํ๋๊ทธ ๋ชจ๋ ์ผ์ ธ ์์ต๋๋ค.
๋ชจ๋ธ: Claude Sonnet 5(๊ธฐ๋ณธ), Opus 4.8(์ฌ์ธต ๋ถ์), Haiku 4.5(๋น ๋ฅด๊ณ ์ ๋ ด).
- Terraform >= 1.15 (S3 native state locking,
use_lockfile) - Node.js >= 18 (๊ตฌ์ฑ TUI, ๋ง์ด๊ทธ๋ ์ด์ ์คํฌ๋ฆฝํธ)
- Docker with buildx (arm64 ์ด๋ฏธ์ง ๋น๋)
- ๋์ ๊ณ์ ์๊ฒฉ ์ฆ๋ช ์ด ์ค์ ๋ AWS CLI
- EKS ํด๋ฌ์คํฐ๋ฅผ ์จ๋ณด๋ฉํ๋ค๋ฉด kubectl ๋ฐ kubeconfig
# ์ ์ฅ์ ๋ณต์
git clone https://github.com/Atom-oh/awsops.git
cd awsops
# ๋ํํ TUI: VPC/๋๋ฉ์ธ/๋ฒํท/EKS ํด๋ฌ์คํฐ ์ ํ
make configure # -> terraform.tfvars + backend.hcl
# foundation ์คํ ํ๋ก๋น์ ๋
terraform -chdir=terraform/foundation init -backend-config=backend.hcl
terraform -chdir=terraform/foundation plan -out tfplan
terraform -chdir=terraform/foundation apply tfplan
# Aurora ์ฌ์ค ์ฐ๊ฒฐ์ด ๊ฐ๋ฅํ ์น์ธ๋ ํธ์คํธ์์ ์ ๋น DB์ ํํด์๋ง:
INITIALIZE_EMPTY_DB=1 make migrate
# ๊ธฐ์กด ์์ฅ์ด ์์ผ๋ฉด make migrate; INTEGER ์์ฅ์ ๋ณ๋ BOOTSTRAP gate ํ์.
# runtime ์ด๋ฏธ์ง/env/IAM/TLS/๋ณต๊ตฌ: terraform/foundation/migrations/README.md
# web ๋น๋+ํธ์, ECS ๋กค๋ง, /api/health ๋๊ธฐ (migrate ์ฌ์คํ, ์คํจ ์ deploy ์ค๋จ)
make deploy
# ๋ง์ด๊ทธ๋ ์ด์
์ดํ agent ์ด๋ฏธ์ง ๋น๋+ํธ์, ๋ฉฑ๋ฑ provisioner ์คํ.
# make agentcore๋ reader ๋กค ์์ฑ/๋น๋ฐ๋ฒํธ ๋๊ธฐํ๋ฅผ ํ์ง ์๋๋ค.
# docs/runbooks/agent-sql-reader.md ์ฐธ์กฐ.
make agentcore
# workers_enabled=true๋ก apply ์ดํ: worker ์ด๋ฏธ์ง ๋น๋+ํธ์
make workersmake help # ์ฌ์ฉ ๊ฐ๋ฅํ ์ ์ฒด ํ๊ฒ ๋ชฉ๋ก
make migrate-status # ์คํ๋ผ์ธ: ์ฑ ๋ฒ์ + ๋์คํฌ์ ์๋ ๋ง์ด๊ทธ๋ ์ด์
๋ณ release
make backfill-owner-sub # legacy email-keyed requested_by -> Cognito sub ์ฌ์์ฑ '๊ณํ'๋ง ์์ฑ(๋ณ๊ฒฝ ์์).
# ๊ณํ์ ๊ฒํ ํด ํ์ ๋ชป ํ๋ ํญ๋ชฉ์ ์ง์ด ๋ค
# `node scripts/v2/backfill-owner-sub.mjs --apply <plan.json>`.
# apply ์ ์ schedule dispatcher ๋ฅผ ์ ์งํ๋ค(๋ช
๋ น์ plan ์ถ๋ ฅ์ ์์).
# ADR-009 ์์ ๊ถ Amendment 2๋จ๊ณ; 3๋จ๊ณ๋ legacy_email_owner_match=false.
DRY_RUN=1 make migrate # DB ๋ง์ด๊ทธ๋ ์ด์
์ ์ฉ ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
make upgrade # ์์ ํ ๋ฆด๋ฆฌ์ค ์
๊ทธ๋ ์ด๋: RDS ์ค๋
์ท -> migrate -> deploy๋ฐํ์ ์ค์ ์ Terraform foundation ๋ฃจํธ์์ flag-gated(variables.tf, ai.tf, ci-migrations.tf)์
๋๋ค. ์๋ ํ์ feature gate ๋ ๋ชจ๋ ๊ธฐ๋ณธ๊ฐ false๋ผ ์ ๊ณํ์์ ํด๋น ๋ฆฌ์์ค๋ฅผ ์์ฑํ์ง ์์ต๋๋ค. ๋ค๋ง ์๋์ ์ผ๋ก ๊ทธ๋ ์ง ์์ ์ด์ ์ค์์น๊ฐ ๋ท ์์ต๋๋ค: legacy_email_owner_match(๊ธฐ๋ณธ true โ legacy email-keyed ์์ ๊ถ ๋งค์นญ์ matchesIdentity() ๋ฅผ ๊ฑฐ์น๋ ๋ชจ๋ ๊ฒ์ดํธ์์ ๊ณ์ ์์ฉํฉ๋๋ค โ ์ฝ๊ธฐ๋ฟ ์๋๋ผ canMutateReport()(๋ฆฌํฌํธ PATCH/DELETE)๋ ํฌํจ์
๋๋ค. make backfill-owner-sub ๋ ๊ณํ๋ง ๋ง๋ค๋ฏ๋ก ์ฌ์์ฑ์ด ๋จ์ ์ํ์ clean plan ๋ง์ผ๋ก๋ ๋ถ์กฑํฉ๋๋ค โ --apply ๊ฐ ์ฑ๊ณตํ๊ณ ์์ฌ legacy row ๊ฐ 0 ์ธ ๊ฒ์ ํ์ธํ ๋ค(๋๋ ์ ์ด์ legacy ํ์ด ์์ด plan ์ด zero-row ์ธ ๊ฒฝ์ฐ)์๋ง false ๋ก ๋ด๋ฆฌ์ธ์. ADR-009 ์์ ๊ถ Amendment ์ฐธ์กฐ)์, ๊ธฐ์กด๋ถํฐ ์๋ create_network / allow_vpc_db_access, ๊ทธ๋ฆฌ๊ณ publish_service_dns์
๋๋ค.
publish_service_dns๋ ๊ธฐ๋ณธ true์ด๋ฉฐ false๋ ์๋น์ค A ๋ณ์นญ์ ์ํ๋ ๊ตฌ์ฑ์์ ์ ์ธํ์ง๋ง
์ธ์ฆ์ ๊ฒ์ฆ CNAME๊น์ง ๊ธ์งํ์ง ์์ต๋๋ค. existing_cf_certificate_arn /
existing_alb_certificate_arn์ ๊ธฐ๋ณธ null(Terraform ๊ด๋ฆฌ ์ธ์ฆ์)์
๋๋ค. ์ธ๋ถ ์ธ์ฆ์๋
์ด๋ฏธ ๋ฐ๊ธ๋๊ณ ์ ๋ขฐํ ์ ์์ด์ผ ํ๋ฉฐ CloudFront์ฉ์ us-east-1, ALB์ฉ์ ์คํ ๋ฆฌ์ ์ ์์ด์ผ ํฉ๋๋ค.
DNS ๊ธ์ง ๋ฐฐํฌ๋ ๋ช
์์ dispatch์์ ๊ธฐ์กด ๊ด๋ฆฌ ์ธ์ฆ์ ์์ ๊ถ๊ณผ ์๋น์ค ๋ณ์นญ์ ๋ณด์กดํฉ๋๋ค.
์ธ๋ถ ์ธ์ฆ์๋ ์ด์์๊ฐ ARN์ ์ง์ ํ๊ฑฐ๋ ์ด๋ฏธ ์ฐ๊ฒฐ๋ ์ธ๋ถ ์ธ์ฆ์๋ง ์ฌ์ฌ์ฉํ๋ฉฐ ๊ณ์ ์ ์ฒด ๊ฒ์์ ํ์ง ์์ต๋๋ค.
๋ณ๋ dispatch ์
๋ ฅ์ธ allow_dns_changes๋ ๊ธฐ๋ณธ false๋ก ์ฌ์ค Cloud Map DNS๋ ๊ธ์งํฉ๋๋ค.
DNS๋ฅผ ํ์ฉํด๋ ์ผ๋ฐ CI์์ ๊ด๋ฆฌ ์ธ์ฆ์๋ฅผ ์ธ๋ถํํ๊ฑฐ๋ ๊ฒ์ฆ CNAME์ ์ญ์ ยท๊ต์ฒดํ ์ ์์ต๋๋ค.
PR/push ๊ณํ์ ์ฐธ๊ณ ์ฉ์ด๋ฉฐ ์ ์ฉํ ์ ์๊ณ dev๋ ์ค์๊ฐ ์ธ์ฆ์/SAN ๊ฒ์ฆ ์์ด ์ํ ์์ ๊ถ์ ๋ณด์กดํฉ๋๋ค.
dev ์ ์ฅ์ ์ด๋ฆ/์กด ๋ณ์์ CERTIFICATE_MODE_DEV=preserve|managed๋ console๊ณผ plan์ ์ผ๊ด๋๊ฒ ๋ฐ์๋ฉ๋๋ค.
๋ชจ๋ dev/full ๋๋ฉ์ธ ๋จ๊ณ plan์ domain_rollout=true๋ ์ ์ฅ ๋ฉํ๋ฐ์ดํฐ๋ก DNS ๋ฒ์๋ฅผ ์ ํํ๋ฉฐ
apply์์ ๋ฐ๊ฟ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ false์ธ ์ผ๋ฐ full ๊ณํ๋ DNS ๋ณ๊ฒฝ์๋ ๋ช
์์ ์น์ธ์ด ํ์ํฉ๋๋ค.
๋ฏธ๊ฒ์/๋์ผ ๋๋ฉ์ธ ์ ํ ๋ฐ๋ถ, ์ฃ์ง ์ฐธ์กฐ์
๋ฐฐํฌ ๋ฐ๋ถ ยง5๋ฅผ ์ฐธ๊ณ ํ์ธ์.
| Flag | ๊ฒ์ดํธ ๋์ |
|---|---|
agentcore_enabled |
AgentCore Lambda ์ฌ๋ผ์ด์ค 21๊ฐ |
ci_readiness_enabled |
๊ธฐ๋ณธ ๋นํ์ฑ ์ ๋ฃ ๋ฐฐํฌ ๊ฒ์ฆ. ์ ์ฉ CI_READINESS_ENABLED_DEV=true/false๊ฐ dev ๊ฐ์ ๋ฎ์ด์ฐ๋ฉฐ ๋ฏธ์ค์ ์ ๋ช
์์ tfvarsยท๊ธฐ๋ณธ false๋ฅผ ์ ์งํ๋ค. ๋ฐํ์ ํ๋กํ๋ง์ผ๋ก ํ์ฑํํ์ง ์๋๋ค. ํ์ dev Deploy Web ๊ฒ์ฆ ์ ์ steampipe_enabled=true, agentcore_enabled=true, workers_enabled=true์ readiness๋ฅผ ์ ์ฉํ๊ณ ์์งยท์์ปค ์ด๋ฏธ์ง๋ฅผ ๋ฐฐํฌํ๋ฉฐ dispatch ํ์ฑ ์ํ๋ฅผ ํ์ธํ ๋ค AgentCore๋ฅผ ํ๋ก๋น์ ๋ํด์ผ ํ๋ค. ๋ฐํ์ ํ์ฑํ ์ ์ฐจ๋ฅผ ๋ฐ๋ฅธ๋ค. ๋ชจ๋ ํ์ฌ ์นดํ๋ก๊ทธ ํ์
์ ๊ธฐ์ค ์๊ฐ ์ดํ ์ฑ๊ณตยทํ์ธ๋ ๊ฐ์ยท๋ฏธํ์ธ ์์ฑ 0๊ฐ์ ๋ฐํ์ยท์์ปค ์ฆ๊ฑฐ๋ฅผ ์๊ตฌํ๋ฉฐ health ๊ฒ์ฌ๋ง์ผ๋ก ์ฐํํ์ง ์๋๋ค. ๊ณต๊ฐ CI์์๋ dev๋ง ํ์ฉํ๋ค. ์ ์ฉ ์ verifier ๊ทธ๋ฃน์๋ AgentCore๊ฐ, ๊ด๋ฆฌ demo ๋ฉค๋ฒ์ญ์๋ create_demo_user=true๋ ํ์ํ๋ค. ํ์ฑํ๋ ๊ฐ dev ๋ฐฐํฌ๋ ์์งยท์ ๋ฃ ๋ชจ๋ธ ๊ฒ์ฆยท์ค์ ์์ปค ์์
๋ ๊ฐ๋ฅผ ์คํํ๋ค. ๊ด๋ฆฌ์ยทIAM ๊ถํ์ ๋ถ์ฌํ์ง ์๋๋ค. |
integrations_enabled |
๋๋จธ์ง AgentCore Lambda ์ฌ๋ผ์ด์ค 6๊ฐ |
workers_enabled |
๋น๋๊ธฐ ์์ปค ๊ณ์ธต(SQS/SFN/Lambda/Fargate) |
ci_migrations_enabled |
๊ธฐ๋ณธ ๋นํ์ฑ ์ด์ ๊ธฐ๋ฅ: ์ฌ์ค migration ํ์คํฌ ํ ํ๋ฆฟยท์ ํํ ์ํฌ๋ฆฟ ์ฝ๊ธฐ ์ญํ /์ ์ฑ ยท14์ผ ๋ก๊ทธ. dev ์๋ ์คํ ๋๋ ํ์ฌ ์์ค Deploy Web์ ๋ณดํธ๋ migration ๊ฒฝ๋ก์์ ์ฌ์ฉํ๋ฉฐ ์๋น์คยท์ค์ผ์ค๋ฌ๋ ์๋ค. ๋นํ์ฑํํ๋ฉด ๋ก๊ทธ ๊ทธ๋ฃน/์ด๋ ฅ์ด ์ญ์ ๋๋ค. |
steampipe_enabled |
Steampipe ์ธ๋ฒคํ ๋ฆฌ sync ๋ฐ์ดํฐ ๊ณ์ธต |
inventory_host_only |
๊ธฐ๋ณธ ๋นํ์ฑ: ํ์ฑ ํธ์คํธ ํ๋๋ง ํ์ฉํ๊ณ ์์ง๊ธฐ AssumeRole์ ์ ์ธํฉ๋๋ค. Agent MCP ๊ถํ์ ์ ์งํ๋ฉฐ dev ํ์ฑํ์๋ ํ๋กํ ๊ธฐ๋ฐ ํธ์คํธ ๊ฒ์ฆ์ด ํ์ํฉ๋๋ค. ๋ฐํ์ ์ ์ฐจ์ ADR-011 ์ฐธ๊ณ . |
finops_baseline_enabled |
FinOps ๊ธฐ๋ณธ ๊ถ์ฅ ์์ง(ADR-020): ์ผ๋ณ Fargate ๋ฃฐ ๋ฐฐ์น(๋ฏธ์ฌ์ฉ EBS ๋ณผ๋ฅจ; Compute Optimizer ๊ธฐ๋ฐ EC2/RDS rightsizing)๊ฐ finops_findings์ ์ ์ฌ, read-only, /cost์ ๋ ๋. terraform ๋ ๋ฒจ๋ก๋ workers_enabled๋ง ์ ํ โ ๋จ EBS ๋ฃฐ์ ๋ฐํ์์ steampipe_enabled=true์ ์ต์ ๋๊ธฐํ๊ฐ ์์ด์ผ ๋์ํ๊ณ , ์์ผ๋ฉด ๊ทธ ๋ฃฐ๋ง ์ ์งํ๊ฒ partial๋ก ํ๋ฉดํ(EC2/RDS๋ ๋ฌด๊ดํ๊ฒ ๋์) |
official_mcp_enabled |
ADR-017 ํ๋ ์ด์
๊ณต์ ๋ฒค๋ MCP ํ๋ฆฌ์
โ ๋ฒค๋ ํธ์คํ
3์ข
(DatadogยทDynatraceยทNew Relic)์ external-obs mcpServer target์ผ๋ก ๋ฑ๋ก. (๋ฐํ์ fail-closed ํด allowlist๋ ์ด ํ๋๊ทธ์ ๋ฌด๊ดํ๊ฒ ๋งค provisioner run์ ๊ธฐ๋กยท๋ฌด์กฐ๊ฑด ๊ฐ์ ๋๋ค โ ๊ทธ ๋ฌด์กฐ๊ฑด์ฑ์ด fail-closed์ ๋ณธ์ฒด) ์ด์ ์ฃผ์: Dynatrace๋ hosted ํด ๋ชฉ๋ก ์ ์ฌ ์ ๊น์ง ์๋์ ์ผ๋ก ํด 0๊ฐ; make agentcore๋ ๋ฐํ์ READY๋ฅผ ๋๊ธฐ(๊ธฐ๋ณธ 300s, AGENTCORE_RUNTIME_READY_TIMEOUT)ํ๋ฉฐ ๋กค์์ ์คํจ/์ง์ฐ ์ ์๊ฒฉ์ ๊ฐ์ถ live target์ ๋ค์ ์ฑ๊ณต run๊น์ง ์ผ์ ํ์ํ๋ค |
graph_querygen_enabled |
ClickHouse trace_spans ๊ทธ๋ํ ์ฟผ๋ฆฌ 1๊ฑด์ ๋ํ LLM ํด๋ฐฑ (ADR-018). diag-signal ๊ฒฝ๋ก์ ์๋ณ์ ์ ํยท๊ด๋ จ์ฑ ๊ฒ์ดํธยท์ฃผ๊ฐ ์์ฐยท์ฝ๊ธฐ ๊ฒ์ดํธ๋ ์๋ค โ ADR-018 ยงC |
diag_signal_querygen_enabled |
Explore diag-signal ์นฉ 1๊ฐ์ LLM ํด๋ฐฑ โ ๊ทธ kind์ ๊ฒฐ์ ๋ก ์นดํ๋ก๊ทธ๊ฐ ready 0ํ์ผ ๋๋ง ๋ฐ๋(๋ถ๋ถ ๋งค์นญ์ ๋ณด์ถฉํ์ง ์์), ์์ฑ ํ์ ์นฉ ์ ์ฉ(์ง๋จ ๋ฆฌํฌํธ ๋ฏธ์ฌ์ฉ, ํ๋๊ทธ OFF ๋ฉด ์ฝ๊ธฐ์์๋ ์ ์ธ). graph_querygen_enabled์ ๋ณ๊ฐ, ๋ ๋ค datasource_diagnosis_enabled ์ ํ. graph_querygen_enabled๋ ์ถ๊ฐ๋ก agentcore_enabled๋ ์ ํ(Code Interpreter ์ธ์
IAM ํ๋ก๋น์ ๋ ๋๋ฌธ) |
sg_rule_activity_enabled |
SG Rules Athena ๊ธฐ๋ฐ ํธ๋ํฝ ๊ทผ๊ฑฐ ํ์ดํ๋ผ์ธ(/network/security-groups/rules) โ Athena/Glue ๋ธ๋ก์ปค Lambda, ์ผ์ผ sg_rule_scan ์์ปค job, ๊ด๋ จ Terraform(sg-rules.tf) |
network_path_check_enabled |
Network Path Check ํ์ด์ง/์์ปค(network-path.tf) โ fetch_live_topology()๋ ์ด์ ์ค์ ๊ตฌํ์ด๋ค(์บ์๋ Aurora ํ ํด๋ก์ง ๊ธฐ๋ฐ), ๋ค๋ง run ์์ ์ ์ค์๊ฐ AWS/Kubernetes ์ฌ์กฐํ๋ ์ฌ์ ํ ์๋์ ์ผ๋ก ๋ฏธ๊ตฌํ์ด๋ผ ์ด ํ๋๊ทธ๊ฐ ์ผ์ ธ ์์ด๋ POST .../runs๋ ์ฌ์ ํ 503 unimplemented๋ฅผ ๋ฐํํ๋ค; Network Path Check CHANGELOG ํญ๋ชฉ ์ฐธ๊ณ . pod/node ์์ค์ live identity ํ์ธ์๋ EKS Access Entry๊ฐ ์ถ๊ฐ๋ก ํ์ํ๋ค โ ์์ค ๊ณ์ ์ด ํธ์คํธ ๊ณ์ ์ด๋ฉด ์์ปค task role์ฉ(์ด ๊ฒฝ์ฐ _default_k8s_get()์ด ๊ทธ role ์์ ์ ์๊ฒฉ์ฆ๋ช
์ ์ง์ ์ฌ์ฉ), ๋ฉค๋ฒ ๊ณ์ ์ด๋ฉด ๋์ ๊ณ์ ์ **AWSopsReadOnlyRole**์ฉ(๊ทธ assume๋ ์ธ์
์ผ๋ก K8s GET์ ์ธ์ฆํ๋ฏ๋ก, ์์ปค task role์ ๋ฑ๋กํด๋ ์๋ฌด ํจ๊ณผ๊ฐ ์๊ณ ๋ชจ๋ GET์ด 403๋๋ค) โ docs/runbooks/network-path-eks-access.md + scripts/v2/eks/register-network-path-access.sh(๋ฉค๋ฒ ๊ณ์ ์ ๊ฒฝ์ฐ ROLE_ARN=...๋ก principal ์ค๋ฒ๋ผ์ด๋) ์ฐธ๊ณ |
๋ฐํ์ IAM ์ถ์๋ ์ ์ ํ ํ๋๊ทธ์ ๋ฌด๊ดํ๋ฉฐ main ๋ฑ ๊ธฐ์กด ํ์ฑ ์คํ์ ๋ค์ apply์ ์ ์ฉ๋ฉ๋๋ค(์น SSM ์ธ ํ๋ผ๋ฏธํฐยท๋ฐํ์ ์กฐํ/ํ ํฐ ๋์ยท์์ฒด ํด๋ฌ์คํฐ ํ์คํฌ ์ ์ดยทClaude ๋ชจ๋ธ). ์๋ ค์ง ๋ฆฌ์ ์๋ ์ดํ opt-in ๋ฆฌ์ ๋ ํฌํจ๋๋ฉฐ ์ค์ ์ ๊ทผ ์ฑ๊ณต์ ์ฆ๊ฑฐ๋ ์๋๋๋ค.
ADR-017์๋ terraform flag๊ฐ ์๋ ๊ฒ์ดํธ๊ฐ ํ๋ ๋ ์์ต๋๋ค: CLICKHOUSE_OFFICIAL_MCP โ provisioner๊ฐ ๊ธฐ๋กํ๋ AgentCore ๋ฐํ์ env(CLICKHOUSE_OFFICIAL_MCP=true make agentcore)๋ก, ๊ณต์ mcp-clickhouse๋ฅผ ๋ฐํ์ ์ปจํ
์ด๋์ stdio ์๋ธํ๋ก์ธ์ค๋ก ๋ด์ฅํฉ๋๋ค. FROZEN / do-not-enable์
๋๋ค: ์์ฒด ๋๋ค์ ํ
์ด๋ธ ํจ์ SSRF ๊ฐ๋์ ๋์ํ๋ ๋ฐฉ์ด๊ฐ stdio ๊ฒฝ๋ก์ ์์ด, ํด์ ์๋ ๊ธฐ์ ์ ๊ฒฐ์กฐ๊ฑด๊ณผ ์ ADR + ๋ฉํฐ-AI ํจ๋ + ๋ ์ง๋ฐํ owner-override๊ฐ ๋ชจ๋ ํ์ํฉ๋๋ค(ADR-017 ยงStatus, BASELINE ยง2).
ADR-017์ ํ๋ฆฌ์
๋ณ ์ค์ ์ฉ ๋งต ๋ณ์ 2๊ฐ(๋ถ๋ฆฌ์ธ ์๋, ๋ ๋ค ๊ธฐ๋ณธ {})๋ฅผ ํจ๊ป ์๋๋ค โ official_mcp_endpoints(map(string), preset_key -> https:// ์๋ํฌ์ธํธ)์ official_mcp_read_only_ack(map(string), preset_key -> ์ด์์๊ฐ ๊ฒํ ํ ์๋ํฌ์ธํธ URL ๊ทธ๋๋ก. true๊ฐ ์๋๋๋ค). ack ๊ฐ์ด ํ์ฌ ์๋ํฌ์ธํธ์ ์ ํํ ๊ฐ์ ๋๋ง provisioning๋๊ณ , ๊ทธ ๋ฐ์ ๋ชจ๋ ๊ฒฝ์ฐ๋ fail-closed SKIP(๊ธฐ์กด target ํ์)์
๋๋ค:
official_mcp_endpoints = { datadog = "https://mcp.datadoghq.com/v1/mcp" }
official_mcp_read_only_ack = { datadog = "https://mcp.datadoghq.com/v1/mcp" }AgentCore ์์ฒด ์ค์ (runtime ARN, Memory ID, Code Interpreter ID)์ provisioner๊ฐ SSM(/ops/awsops-v2/agentcore/*)์ ๊ธฐ๋กํ๊ณ web BFF๊ฐ ๋ฐํ์์ ์ฝ์ต๋๋ค โ ์์ ์ ๋ ์ด์ค๋ฅผ ํผํ๊ธฐ ์ํด task-def valueFrom์ผ๋ก๋ ์ ๋ ์ ๋ฌํ์ง ์์ต๋๋ค.
awsops/
web/ # Next.js 15 thin-BFF: 41 ํ์ด์ง, 99 API ๋ผ์ฐํธ, 110 ์ปดํฌ๋ํธ
agent/ # Strands Agent(Runtime ์์ค) + MCP Lambda ๋๊ตฌ ์์ค
terraform/foundation/ # ๋จ์ผ Terraform ๋ฃจํธ: network, edge, auth, data, workload, ai, workers, eks
scripts/v2/ # configure/deploy/migrate/agentcore/workers ๋๊ตฌ(์ ๋ถ Node.js/Python)
tests/ # repo ์ ๋ฐ์ hook/structure ํ
์คํธ + PR-review/Steampipe/ExternalId ๋ฐฐ์ ์ฒดํฌ
docs/ # ๊ฐ์ด๋, ๋ฐ๋ถ, ๊ตฌํ ์ฐธ์กฐ ๋ฌธ์(ADR ๋ณธ๋ฌธ์ ๋น๊ณต๊ฐ upstream์์ ๊ด๋ฆฌ)
docs-site/ # Docusaurus ์ฌ์ฉ์ ๊ฐ์ด๋(๋ณ๋ ๋ฐฐํฌ)
๋จธ์ง ๊ฒ์ฆ์ ์์กด์ฑ์ ๋จผ์ ์ค์นํ์ธ์.
Docker์ ์ค๋น๋ AWSOPS_REVIEW_CODEC_STATE๋ ํ์ํฉ๋๋ค. ์๋๋ฐ์ค ์ค๋น ์ ์ฐจ๋ฅผ ๋ฐ๋ฅด์ธ์.
tests/run-all.sh์ panel-prompt ๊ตฌ์กฐ ๊ฒ์ฌ๋ฅผ ํฌํจํ ์ด๋ฏธ์ง fixture์๋ Linux ARM64/x86-64์
Python 3.12์ ํด์๊ฐ ๊ณ ์ ๋ Pillow๊ฐ ํ์ํฉ๋๋ค. ๋ค์ ๋ช
๋ น์ ํด์ ์๋ requirements ์ค์น์
ํฉ์น์ง ๋ง๊ณ ๋ณ๋๋ก ์คํํ์ธ์:
python3 -m pip install --require-hashes --only-binary=:all: -r scripts/pr-review/image-requirements.txt.
Private migration ํ
์คํธ๋ npm ci --prefix scripts/v2 --ignore-scripts --no-audit --no-fund๋ก
pgยทAWS SDK๋ฅผ ์ค์นํ๋ฉฐ PostgreSQL ํ
์คํธ์๋ OpenSSLยท์ ๊ทผ ๊ฐ๋ฅํ Dockerยทpostgres:17์ด
ํ์ํฉ๋๋ค. ํ์ migrationยท์น ์ฐ๊ฒฐ ๋จ๊ณยท์์ด์ ํธ ๋๊ตฌ ์ ์ฑ
์ด๋ ฅ PostgreSQL ํ
์คํธ๋ ๋ ๊ฑฐ์ ์ ํ์ itest์ ๋ฌ๋ฆฌ
Docker ๋ถ์ฌ ์ gate๊ฐ ์คํจํ๊ณ PATH์ docker๋ฅผ ์ง์ ์ฌ์ฉํฉ๋๋ค. ์น ์ฐ๊ฒฐยท์ ์ฑ
ํ
์คํธ๋ ์ ๊ธด ๋๋ผ์ด๋ฒ์
TypeScript๋ฅผ ์ํด npm ci --prefix web๋ ํ์ํฉ๋๋ค. ์ด ํ
์คํธ๋ค๊ณผ ์คํ๋ผ์ธ companion์
AWS ์๊ฒฉ์ฆ๋ช
์ ์ฌ์ฉํ์ง ์์ต๋๋ค.
์ธ์ฆ ๋ฐฐํฌ smoke ํ
์คํธ๋ curlยทOpenSSLยทPython 3ยทPyYAMLยทTerraform 1.15.7์ ํ์๋ก ์๊ตฌํ๋ฉฐ,
๋๋ฝ ์ ๊ณตํต ๋ฌ๋๋ ์คํจํฉ๋๋ค. ์คํ๋ผ์ธ ๋ณ์ fixture์๋ provider๊ฐ ํ์ํ์ง ์์ต๋๋ค.
๋ง์ง๋ง fmt/validate ์ง๋จ๋ง ์ฐธ๊ณ ์ฉ์
๋๋ค. Terraform mock ํ
์คํธ์๋ 1.15.7๊ณผ
์ค์น/์บ์๋ provider๊ฐ ํ์ํฉ๋๋ค. ๋์ฐ๋ฏธ๋ ์ถ์ ๋
์์
ํ์ผ๋ง ๋ณต์ฌํด init -backend=false, validate, test๋ฅผ ์คํํ๋ฉฐ ์ค์ backend๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค.
ํ์ test_ci_web_read.pyยทtest_ci_web_deploy.py ํ
์คํธ๋ Python 3.12์ Linux /proc, POSIX ํ๋ก์ธ์ค ๊ทธ๋ฃน, os.geteuid๊ฐ ํ์ํ๋ฉฐ ์ธ๋ถ provider๋ฅผ ๋ชจ์ํ๋ฏ๋ก AWS CLIยทghยทcurlยทjq๋ฅผ ์คํํ์ง ์์ต๋๋ค. ํ์ test_ci_web_workflow.py ํ
์คํธ์๋ PyYAML๊ณผ Bash๋ ํ์ํฉ๋๋ค. Deploy Web์ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฌ์ฉํ๊ณ ์น ๋ฐฐํฌ๊ฐ ํธ์ถํ๋ ๋ง์ด๊ทธ๋ ์ด์
์ ์๋ SQL ๊ฒ์ฌ๋ฅผ ๊ฐ์ ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ docs/runbooks/release-safety-primitives.md๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์คํ๋ผ์ธ ์น ์ด๋ฏธ์ง ์ถ์ฒ ๊ฒ์ฆ ๋์ฐ๋ฏธ ํ
์คํธ์๋ jq, Linux /proc, /usr/local/bin:/usr/bin:/bin์ curl๋ ํ์ํฉ๋๋ค.
Deploy Web์ ์ฌ์ค ๋ง์ด๊ทธ๋ ์ด์
์ ์ ์ด๋ฏธ์ง๋ฅผ ๊ฒ์ฆํ๊ณ ํด๋น ๋ค์ด์ ์คํธ๋ฅผ ๋ณดํธ๋ ์ง์
์ ์ผ๋ก ์น๊ฒฉํ ๋ค, ์ ํํ ECSยท์ด๋ฏธ์ง์ ๋ก๊ทธ์ธยทDB๋ฅผ ํฌํจํ ์ ์ฒด dev ๋ฐํ์ ๊ฒ์ฆ์ ํ์๋ก ์ํํ๋ฉฐ ๊ฐ์ด๋์์ ์์์ฆยท๋ณต๊ตฌ ๊ณ์ฝ์ ์ ์ํฉ๋๋ค. ๋ฐฐํฌ ์์ ๋๊ตฌ์์ ์ปจํธ๋กค๋ฌ์ ๋ง์ด๊ทธ๋ ์ด์
์ ์ฑ
์ ์ค๋ช
ํฉ๋๋ค.
์น ๋ฐฐํฌ์์ ์ด๊ธฐํยท์๋ ๊ฒ์ฌ ๋ฏธ์ง์ SQL์ ์๋ migration/reader ๋๊ธฐํ ์ฑ๊ณต ํ ์ ์น ๋ฐฐํฌ๋ฅผ ์คํํ๋ ์ ์ฐจ๋ฅผ, ๋ ๊ฑฐ์ ์ด๋ฏธ์ง ๋ณต๊ตฌ์์ ์์์ฆ ์๋ ์ด๋ฏธ์ง ๋ณต๊ตฌ๋ฅผ ํ์ธํ์ธ์.
bash scripts/v2/merge-verify.sh # ํ์ Pythonยท์นยท๋ฐฐํฌ ํ
์คํธ
node --test scripts/v2/ci/*.test.mjs # private migration runtime ์คํ๋ผ์ธ fixture (CI ํ์)
node --test scripts/v2/ci/migration.itest.mjs scripts/v2/ci/web-db-connection.itest.mjs scripts/v2/ci/agent-tool-policy.itest.mjs # ์ค์ PG migrationยท์น ์ฐ๊ฒฐยท์์ด์ ํธ ์ ์ฑ
ํ๊ท ํ
์คํธ (CI ํ์)
bash scripts/v2/terraform-test.sh # ๋ณ๋ ๋ณต์ฌ๋ณธยทbackend ๋นํ์ฑ Terraform mock ํ
์คํธ (CI ํ์)
# docs-site/ ๋๋ .github/workflows/merge-verify.yml ๋ณ๊ฒฝ ์ ์๋๋ CI ํ์:
(cd docs-site && npm ci && npm run typecheck && npm run build &&
bash scripts/verify-deck.sh static/presentation/awsops-intro/awsops-intro.pptx)
node --test scripts/v2/deployment-smoke.test.mjs # ์คํ๋ผ์ธ healthยท์ธ์ฆยท์๊ฒฉ์ฆ๋ช
์ค๋นยท์ํฌํ๋ก ๊ฒ์ฌ
bash tests/run-all.sh # repo ์ ๋ฐ hook/structure ํ
์คํธ + agent Python unittest
(cd web && npx vitest run) # web ์ ๋ ํ
์คํธ๋ง์ private migration fixture ๋ช
๋ น์ runtimeยทcontrollerยทworkflowยท๋ชจ์ ๊ณํ ๊ฒ์ฌ๋ฅผ ํฌํจํฉ๋๋ค.
controller/workflow ๊ฒ์ฌ์๋ Python 3ยทPyYAMLยทboto3/botocore (pip install -r agent/requirements.txt)ยทTerraform 1.15.7๋ ํ์ํฉ๋๋ค.
์กฐ๊ฑด๋ถ ๋ฌธ์ ๋น๋์ ํ๋ ์ ํ
์ด์
์ ์ฒด ์์นด์ด๋ธ ๊ฒ์ฆ์ ํฌํจํ CI ๋ฒ์๋
๋จธ์ง ๊ฒ์ฆ ๊ฐ์ด๋๋ฅผ ์ฐธ๊ณ ํ์ธ์.
99๊ฐ API ๋ผ์ฐํธ๊ฐ web/app/api/์ ์์ต๋๋ค. ์ฃผ์ ๋ผ์ฐํธ: health(๊ณต๊ฐ), stream(SSE ์ฑํ
), db(Aurora ping), jobs(+/[id], ๋น๋๊ธฐ ์์
์ ์ถ/์ํ), security, compliance, auth/login. ์ฌ์ฉ์ ๊ฐ์ด๋๋ docs site๋ฅผ ์ฐธ๊ณ ํ์ธ์.
- ์ ์ฅ์๋ฅผ Fork ํฉ๋๋ค
- ๋ธ๋์น๋ฅผ ์์ฑํฉ๋๋ค (
git checkout -b feat/amazing-feature) - ๋ณ๊ฒฝ ์ฌํญ์ ์ปค๋ฐํฉ๋๋ค (
git commit -m 'feat: add amazing feature') - ๋ธ๋์น์ Push ํฉ๋๋ค (
git push origin feat/amazing-feature) - Pull Request๋ฅผ ์ฝ๋๋ค
๋์ ๋ธ๋์น๋ dev์
๋๋ค. Fork ๊ธฐ์ฌ๋ ์ ์ง๊ด๋ฆฌ์๊ฐ ํจ์น๋ฅผ ํ์ธํ ๋ค ๋ด๋ถ PR๋ก
๊ฐ์ ธ์ ์ ์ฒด AIยทCI ๊ฒ์ฌ๋ฅผ ๊ฑฐ์ณ ํตํฉํฉ๋๋ค. Fork ํ
์คํธ ํต๊ณผ๋ง์ผ๋ก AI ๊ฒ์ฌ๋ฅผ ๋์ ํ์ง
์์ต๋๋ค. ๊ธฐ์ฌ ๋ธ๋์น ํ๋ฆ์ ์ฐธ๊ณ ํ์ธ์.
MIT License๋ก ๋ฐฐํฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ LICENSE๋ฅผ ์ฐธ๊ณ ํ์ธ์.
- ๋ฉ์ธํ ์ด๋: Atom-oh
- ์ด์: github.com/Atom-oh/awsops/issues
