cfsa-antigravity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terraform
|
|
3
|
+
description: "Comprehensive Terraform infrastructure-as-code guide covering HCL syntax, resource and data blocks, variables, outputs, state management, modules, providers, workspaces, lifecycle rules, dynamic blocks, loops, conditional resources, import, Terragrunt, testing, CI/CD integration, state locking, and secret management. Use when provisioning cloud infrastructure, designing IaC modules, or managing Terraform state and workflows."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Terraform
|
|
8
|
+
|
|
9
|
+
## 1. Philosophy
|
|
10
|
+
|
|
11
|
+
Terraform manages infrastructure through **declarative configuration files** that describe the desired end state. You do not write scripts that create resources step by step. You declare what should exist, and Terraform figures out how to get there.
|
|
12
|
+
|
|
13
|
+
**Key principles**:
|
|
14
|
+
- Infrastructure is code. It lives in version control, gets reviewed, and is tested.
|
|
15
|
+
- State is the source of truth. Terraform tracks what it has created and diffs against your configuration.
|
|
16
|
+
- Plan before apply. Always review the execution plan before making changes.
|
|
17
|
+
- Modules are the unit of reuse. Never copy-paste resource blocks across projects.
|
|
18
|
+
- Immutable when possible. Replace resources rather than mutating them in place.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. HCL Syntax Fundamentals
|
|
23
|
+
|
|
24
|
+
### Resource Blocks
|
|
25
|
+
|
|
26
|
+
Resources are the core building block. Each resource block declares one infrastructure object.
|
|
27
|
+
|
|
28
|
+
```hcl
|
|
29
|
+
# resource "<provider>_<type>" "<local_name>" { ... }
|
|
30
|
+
resource "aws_instance" "web_server" {
|
|
31
|
+
ami = "ami-0c55b159cbfafe1f0"
|
|
32
|
+
instance_type = "t3.micro"
|
|
33
|
+
subnet_id = aws_subnet.public.id
|
|
34
|
+
|
|
35
|
+
tags = {
|
|
36
|
+
Name = "web-server"
|
|
37
|
+
Environment = var.environment
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Data Blocks
|
|
43
|
+
|
|
44
|
+
Data sources read existing infrastructure that Terraform does not manage.
|
|
45
|
+
|
|
46
|
+
```hcl
|
|
47
|
+
data "aws_ami" "ubuntu" {
|
|
48
|
+
most_recent = true
|
|
49
|
+
owners = ["099720109477"] # Canonical
|
|
50
|
+
|
|
51
|
+
filter {
|
|
52
|
+
name = "name"
|
|
53
|
+
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
resource "aws_instance" "web" {
|
|
58
|
+
ami = data.aws_ami.ubuntu.id
|
|
59
|
+
instance_type = "t3.micro"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Variables
|
|
64
|
+
|
|
65
|
+
```hcl
|
|
66
|
+
# variables.tf
|
|
67
|
+
variable "environment" {
|
|
68
|
+
description = "Deployment environment (dev, staging, prod)"
|
|
69
|
+
type = string
|
|
70
|
+
default = "dev"
|
|
71
|
+
|
|
72
|
+
validation {
|
|
73
|
+
condition = contains(["dev", "staging", "prod"], var.environment)
|
|
74
|
+
error_message = "Environment must be dev, staging, or prod."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
variable "instance_count" {
|
|
79
|
+
description = "Number of web server instances"
|
|
80
|
+
type = number
|
|
81
|
+
default = 2
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
variable "tags" {
|
|
85
|
+
description = "Common tags applied to all resources"
|
|
86
|
+
type = map(string)
|
|
87
|
+
default = {}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
variable "allowed_cidrs" {
|
|
91
|
+
description = "CIDR blocks allowed to access the load balancer"
|
|
92
|
+
type = list(string)
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Outputs
|
|
97
|
+
|
|
98
|
+
```hcl
|
|
99
|
+
# outputs.tf
|
|
100
|
+
output "instance_public_ip" {
|
|
101
|
+
description = "Public IP address of the web server"
|
|
102
|
+
value = aws_instance.web_server.public_ip
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
output "database_endpoint" {
|
|
106
|
+
description = "RDS endpoint for the database"
|
|
107
|
+
value = aws_db_instance.main.endpoint
|
|
108
|
+
sensitive = true
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 3. State Management
|
|
115
|
+
|
|
116
|
+
### Remote Backends
|
|
117
|
+
|
|
118
|
+
Never use local state in team environments. Use a remote backend with locking.
|
|
119
|
+
|
|
120
|
+
```hcl
|
|
121
|
+
# S3 Backend (AWS)
|
|
122
|
+
terraform {
|
|
123
|
+
backend "s3" {
|
|
124
|
+
bucket = "my-terraform-state"
|
|
125
|
+
key = "prod/network/terraform.tfstate"
|
|
126
|
+
region = "us-east-1"
|
|
127
|
+
dynamodb_table = "terraform-locks"
|
|
128
|
+
encrypt = true
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```hcl
|
|
134
|
+
# Terraform Cloud Backend
|
|
135
|
+
terraform {
|
|
136
|
+
cloud {
|
|
137
|
+
organization = "my-org"
|
|
138
|
+
|
|
139
|
+
workspaces {
|
|
140
|
+
name = "my-app-prod"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### State Locking
|
|
147
|
+
|
|
148
|
+
State locking prevents concurrent modifications. With S3 backend, use DynamoDB for locking.
|
|
149
|
+
|
|
150
|
+
```hcl
|
|
151
|
+
# Create the lock table
|
|
152
|
+
resource "aws_dynamodb_table" "terraform_locks" {
|
|
153
|
+
name = "terraform-locks"
|
|
154
|
+
billing_mode = "PAY_PER_REQUEST"
|
|
155
|
+
hash_key = "LockID"
|
|
156
|
+
|
|
157
|
+
attribute {
|
|
158
|
+
name = "LockID"
|
|
159
|
+
type = "S"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### State Operations
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# List resources in state
|
|
168
|
+
terraform state list
|
|
169
|
+
|
|
170
|
+
# Show details of a specific resource
|
|
171
|
+
terraform state show aws_instance.web_server
|
|
172
|
+
|
|
173
|
+
# Move a resource (rename without destroying)
|
|
174
|
+
terraform state mv aws_instance.old_name aws_instance.new_name
|
|
175
|
+
|
|
176
|
+
# Remove a resource from state (does not destroy it)
|
|
177
|
+
terraform state rm aws_instance.legacy
|
|
178
|
+
|
|
179
|
+
# Import existing infrastructure into state
|
|
180
|
+
terraform import aws_instance.web_server i-1234567890abcdef0
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 4. Modules
|
|
186
|
+
|
|
187
|
+
### Module Structure
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
modules/
|
|
191
|
+
vpc/
|
|
192
|
+
main.tf # Resource definitions
|
|
193
|
+
variables.tf # Input variables
|
|
194
|
+
outputs.tf # Output values
|
|
195
|
+
versions.tf # Required providers and versions
|
|
196
|
+
README.md # Usage documentation
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Writing a Module
|
|
200
|
+
|
|
201
|
+
```hcl
|
|
202
|
+
# modules/vpc/main.tf
|
|
203
|
+
resource "aws_vpc" "this" {
|
|
204
|
+
cidr_block = var.cidr_block
|
|
205
|
+
enable_dns_support = true
|
|
206
|
+
enable_dns_hostnames = true
|
|
207
|
+
|
|
208
|
+
tags = merge(var.tags, {
|
|
209
|
+
Name = "${var.name_prefix}-vpc"
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
resource "aws_subnet" "public" {
|
|
214
|
+
count = length(var.public_subnet_cidrs)
|
|
215
|
+
|
|
216
|
+
vpc_id = aws_vpc.this.id
|
|
217
|
+
cidr_block = var.public_subnet_cidrs[count.index]
|
|
218
|
+
availability_zone = var.availability_zones[count.index]
|
|
219
|
+
map_public_ip_on_launch = true
|
|
220
|
+
|
|
221
|
+
tags = merge(var.tags, {
|
|
222
|
+
Name = "${var.name_prefix}-public-${count.index}"
|
|
223
|
+
Tier = "public"
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
# modules/vpc/variables.tf
|
|
228
|
+
variable "name_prefix" {
|
|
229
|
+
description = "Prefix for resource names"
|
|
230
|
+
type = string
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
variable "cidr_block" {
|
|
234
|
+
description = "VPC CIDR block"
|
|
235
|
+
type = string
|
|
236
|
+
default = "10.0.0.0/16"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
variable "public_subnet_cidrs" {
|
|
240
|
+
description = "CIDR blocks for public subnets"
|
|
241
|
+
type = list(string)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
variable "availability_zones" {
|
|
245
|
+
description = "Availability zones for subnets"
|
|
246
|
+
type = list(string)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
variable "tags" {
|
|
250
|
+
description = "Tags to apply to all resources"
|
|
251
|
+
type = map(string)
|
|
252
|
+
default = {}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# modules/vpc/outputs.tf
|
|
256
|
+
output "vpc_id" {
|
|
257
|
+
description = "ID of the created VPC"
|
|
258
|
+
value = aws_vpc.this.id
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
output "public_subnet_ids" {
|
|
262
|
+
description = "IDs of the public subnets"
|
|
263
|
+
value = aws_subnet.public[*].id
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Using a Module
|
|
268
|
+
|
|
269
|
+
```hcl
|
|
270
|
+
module "vpc" {
|
|
271
|
+
source = "./modules/vpc"
|
|
272
|
+
|
|
273
|
+
name_prefix = "myapp"
|
|
274
|
+
cidr_block = "10.0.0.0/16"
|
|
275
|
+
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
|
|
276
|
+
availability_zones = ["us-east-1a", "us-east-1b"]
|
|
277
|
+
tags = local.common_tags
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# Reference module outputs
|
|
281
|
+
resource "aws_instance" "web" {
|
|
282
|
+
subnet_id = module.vpc.public_subnet_ids[0]
|
|
283
|
+
# ...
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Versioned Modules
|
|
288
|
+
|
|
289
|
+
```hcl
|
|
290
|
+
# From a Git repository
|
|
291
|
+
module "vpc" {
|
|
292
|
+
source = "git::https://github.com/myorg/terraform-modules.git//vpc?ref=v1.2.0"
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
# From Terraform Registry
|
|
296
|
+
module "vpc" {
|
|
297
|
+
source = "terraform-aws-modules/vpc/aws"
|
|
298
|
+
version = "~> 5.0"
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 5. Provider Configuration
|
|
305
|
+
|
|
306
|
+
```hcl
|
|
307
|
+
# versions.tf
|
|
308
|
+
terraform {
|
|
309
|
+
required_version = ">= 1.5"
|
|
310
|
+
|
|
311
|
+
required_providers {
|
|
312
|
+
aws = {
|
|
313
|
+
source = "hashicorp/aws"
|
|
314
|
+
version = "~> 5.0"
|
|
315
|
+
}
|
|
316
|
+
cloudflare = {
|
|
317
|
+
source = "cloudflare/cloudflare"
|
|
318
|
+
version = "~> 4.0"
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
# providers.tf
|
|
324
|
+
provider "aws" {
|
|
325
|
+
region = var.aws_region
|
|
326
|
+
|
|
327
|
+
default_tags {
|
|
328
|
+
tags = {
|
|
329
|
+
ManagedBy = "terraform"
|
|
330
|
+
Project = var.project_name
|
|
331
|
+
Environment = var.environment
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
# Multiple provider configurations (aliased)
|
|
337
|
+
provider "aws" {
|
|
338
|
+
alias = "us_west"
|
|
339
|
+
region = "us-west-2"
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
resource "aws_s3_bucket" "replica" {
|
|
343
|
+
provider = aws.us_west
|
|
344
|
+
bucket = "my-bucket-replica"
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 6. Workspaces
|
|
351
|
+
|
|
352
|
+
Workspaces let you manage multiple environments with the same configuration.
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
# Create and switch to a workspace
|
|
356
|
+
terraform workspace new staging
|
|
357
|
+
terraform workspace new production
|
|
358
|
+
|
|
359
|
+
# List workspaces
|
|
360
|
+
terraform workspace list
|
|
361
|
+
|
|
362
|
+
# Switch workspace
|
|
363
|
+
terraform workspace select staging
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
```hcl
|
|
367
|
+
# Use workspace name in configuration
|
|
368
|
+
locals {
|
|
369
|
+
environment = terraform.workspace
|
|
370
|
+
|
|
371
|
+
instance_type = {
|
|
372
|
+
dev = "t3.micro"
|
|
373
|
+
staging = "t3.small"
|
|
374
|
+
prod = "t3.medium"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
resource "aws_instance" "web" {
|
|
379
|
+
instance_type = local.instance_type[local.environment]
|
|
380
|
+
# ...
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## 7. Lifecycle Rules
|
|
387
|
+
|
|
388
|
+
```hcl
|
|
389
|
+
resource "aws_instance" "web" {
|
|
390
|
+
ami = data.aws_ami.ubuntu.id
|
|
391
|
+
instance_type = var.instance_type
|
|
392
|
+
|
|
393
|
+
lifecycle {
|
|
394
|
+
# Create the replacement before destroying the original
|
|
395
|
+
create_before_destroy = true
|
|
396
|
+
|
|
397
|
+
# Prevent accidental destruction (e.g., databases)
|
|
398
|
+
prevent_destroy = true
|
|
399
|
+
|
|
400
|
+
# Ignore changes made outside Terraform
|
|
401
|
+
ignore_changes = [
|
|
402
|
+
tags["LastModifiedBy"],
|
|
403
|
+
user_data,
|
|
404
|
+
]
|
|
405
|
+
|
|
406
|
+
# Replace the resource when any of these change
|
|
407
|
+
replace_triggered_by = [
|
|
408
|
+
aws_security_group.web.id,
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 8. Dynamic Blocks
|
|
417
|
+
|
|
418
|
+
Dynamic blocks generate repeated nested blocks programmatically.
|
|
419
|
+
|
|
420
|
+
```hcl
|
|
421
|
+
variable "ingress_rules" {
|
|
422
|
+
description = "Security group ingress rules"
|
|
423
|
+
type = list(object({
|
|
424
|
+
port = number
|
|
425
|
+
protocol = string
|
|
426
|
+
cidr_blocks = list(string)
|
|
427
|
+
description = string
|
|
428
|
+
}))
|
|
429
|
+
default = [
|
|
430
|
+
{ port = 80, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"], description = "HTTP" },
|
|
431
|
+
{ port = 443, protocol = "tcp", cidr_blocks = ["0.0.0.0/0"], description = "HTTPS" },
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
resource "aws_security_group" "web" {
|
|
436
|
+
name = "web-sg"
|
|
437
|
+
vpc_id = module.vpc.vpc_id
|
|
438
|
+
|
|
439
|
+
dynamic "ingress" {
|
|
440
|
+
for_each = var.ingress_rules
|
|
441
|
+
content {
|
|
442
|
+
from_port = ingress.value.port
|
|
443
|
+
to_port = ingress.value.port
|
|
444
|
+
protocol = ingress.value.protocol
|
|
445
|
+
cidr_blocks = ingress.value.cidr_blocks
|
|
446
|
+
description = ingress.value.description
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
egress {
|
|
451
|
+
from_port = 0
|
|
452
|
+
to_port = 0
|
|
453
|
+
protocol = "-1"
|
|
454
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## 9. for_each vs count
|
|
462
|
+
|
|
463
|
+
### Use for_each for Named Resources
|
|
464
|
+
|
|
465
|
+
```hcl
|
|
466
|
+
# GOOD: Each resource has a meaningful key
|
|
467
|
+
variable "buckets" {
|
|
468
|
+
type = map(object({
|
|
469
|
+
versioning = bool
|
|
470
|
+
acl = string
|
|
471
|
+
}))
|
|
472
|
+
default = {
|
|
473
|
+
logs = { versioning = false, acl = "log-delivery-write" }
|
|
474
|
+
assets = { versioning = true, acl = "private" }
|
|
475
|
+
backups = { versioning = true, acl = "private" }
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
resource "aws_s3_bucket" "this" {
|
|
480
|
+
for_each = var.buckets
|
|
481
|
+
bucket = "${var.project_name}-${each.key}"
|
|
482
|
+
|
|
483
|
+
tags = { Purpose = each.key }
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
# Removing "logs" from the map only destroys that one bucket
|
|
487
|
+
# Adding "uploads" only creates that one bucket
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Use count for Conditional Resources
|
|
491
|
+
|
|
492
|
+
```hcl
|
|
493
|
+
# Create the resource only if the variable is true
|
|
494
|
+
resource "aws_cloudwatch_log_group" "app" {
|
|
495
|
+
count = var.enable_logging ? 1 : 0
|
|
496
|
+
name = "/app/${var.environment}"
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
# Reference conditional resources carefully
|
|
500
|
+
output "log_group_arn" {
|
|
501
|
+
value = var.enable_logging ? aws_cloudwatch_log_group.app[0].arn : null
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### When NOT to Use count for Lists
|
|
506
|
+
|
|
507
|
+
```hcl
|
|
508
|
+
# BAD: count with a list -- removing item 0 forces recreation of all subsequent items
|
|
509
|
+
resource "aws_subnet" "public" {
|
|
510
|
+
count = length(var.subnet_cidrs)
|
|
511
|
+
cidr_block = var.subnet_cidrs[count.index]
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
# GOOD: for_each with a map -- each subnet is independently addressable
|
|
515
|
+
resource "aws_subnet" "public" {
|
|
516
|
+
for_each = { for i, cidr in var.subnet_cidrs : "subnet-${i}" => cidr }
|
|
517
|
+
cidr_block = each.value
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## 10. Importing Existing Infrastructure
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
# CLI import (Terraform 1.5+)
|
|
527
|
+
terraform import aws_instance.web i-1234567890abcdef0
|
|
528
|
+
|
|
529
|
+
# Import block (declarative, recommended for Terraform 1.5+)
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
```hcl
|
|
533
|
+
import {
|
|
534
|
+
to = aws_instance.web
|
|
535
|
+
id = "i-1234567890abcdef0"
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
resource "aws_instance" "web" {
|
|
539
|
+
ami = "ami-0c55b159cbfafe1f0"
|
|
540
|
+
instance_type = "t3.micro"
|
|
541
|
+
# Fill in all attributes to match the existing resource
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
# Generate configuration from imported resources
|
|
547
|
+
terraform plan -generate-config-out=generated.tf
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## 11. Terragrunt for DRY Patterns
|
|
553
|
+
|
|
554
|
+
Terragrunt is a wrapper that keeps Terraform configurations DRY across environments.
|
|
555
|
+
|
|
556
|
+
```
|
|
557
|
+
# Directory structure
|
|
558
|
+
infrastructure/
|
|
559
|
+
terragrunt.hcl # Root config (backend, providers)
|
|
560
|
+
dev/
|
|
561
|
+
terragrunt.hcl # Dev overrides
|
|
562
|
+
vpc/
|
|
563
|
+
terragrunt.hcl # Module instance
|
|
564
|
+
app/
|
|
565
|
+
terragrunt.hcl
|
|
566
|
+
prod/
|
|
567
|
+
terragrunt.hcl # Prod overrides
|
|
568
|
+
vpc/
|
|
569
|
+
terragrunt.hcl
|
|
570
|
+
app/
|
|
571
|
+
terragrunt.hcl
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
```hcl
|
|
575
|
+
# infrastructure/terragrunt.hcl (root)
|
|
576
|
+
remote_state {
|
|
577
|
+
backend = "s3"
|
|
578
|
+
generate = {
|
|
579
|
+
path = "backend.tf"
|
|
580
|
+
if_exists = "overwrite_terragrunt"
|
|
581
|
+
}
|
|
582
|
+
config = {
|
|
583
|
+
bucket = "my-terraform-state"
|
|
584
|
+
key = "${path_relative_to_include()}/terraform.tfstate"
|
|
585
|
+
region = "us-east-1"
|
|
586
|
+
encrypt = true
|
|
587
|
+
dynamodb_table = "terraform-locks"
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
# infrastructure/dev/vpc/terragrunt.hcl
|
|
592
|
+
terraform {
|
|
593
|
+
source = "../../../modules/vpc"
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
include "root" {
|
|
597
|
+
path = find_in_parent_folders()
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
inputs = {
|
|
601
|
+
environment = "dev"
|
|
602
|
+
cidr_block = "10.0.0.0/16"
|
|
603
|
+
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
## 12. Testing
|
|
610
|
+
|
|
611
|
+
### terraform validate and plan
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
# Syntax and configuration validation
|
|
615
|
+
terraform validate
|
|
616
|
+
|
|
617
|
+
# Dry-run -- shows what would change without applying
|
|
618
|
+
terraform plan -out=tfplan
|
|
619
|
+
|
|
620
|
+
# Apply a saved plan (no confirmation prompt)
|
|
621
|
+
terraform apply tfplan
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Terratest (Go-based Integration Tests)
|
|
625
|
+
|
|
626
|
+
```go
|
|
627
|
+
package test
|
|
628
|
+
|
|
629
|
+
import (
|
|
630
|
+
"testing"
|
|
631
|
+
"github.com/gruntwork-io/terratest/modules/terraform"
|
|
632
|
+
"github.com/stretchr/testify/assert"
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
func TestVpcModule(t *testing.T) {
|
|
636
|
+
t.Parallel()
|
|
637
|
+
|
|
638
|
+
terraformOptions := &terraform.Options{
|
|
639
|
+
TerraformDir: "../modules/vpc",
|
|
640
|
+
Vars: map[string]interface{}{
|
|
641
|
+
"name_prefix": "test",
|
|
642
|
+
"cidr_block": "10.0.0.0/16",
|
|
643
|
+
"public_subnet_cidrs": []string{"10.0.1.0/24"},
|
|
644
|
+
"availability_zones": []string{"us-east-1a"},
|
|
645
|
+
},
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Clean up after test
|
|
649
|
+
defer terraform.Destroy(t, terraformOptions)
|
|
650
|
+
|
|
651
|
+
// Deploy
|
|
652
|
+
terraform.InitAndApply(t, terraformOptions)
|
|
653
|
+
|
|
654
|
+
// Validate outputs
|
|
655
|
+
vpcId := terraform.Output(t, terraformOptions, "vpc_id")
|
|
656
|
+
assert.NotEmpty(t, vpcId)
|
|
657
|
+
assert.Contains(t, vpcId, "vpc-")
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### terraform test (Native, Terraform 1.6+)
|
|
662
|
+
|
|
663
|
+
```hcl
|
|
664
|
+
# tests/vpc.tftest.hcl
|
|
665
|
+
run "create_vpc" {
|
|
666
|
+
command = apply
|
|
667
|
+
|
|
668
|
+
variables {
|
|
669
|
+
name_prefix = "test"
|
|
670
|
+
cidr_block = "10.0.0.0/16"
|
|
671
|
+
public_subnet_cidrs = ["10.0.1.0/24"]
|
|
672
|
+
availability_zones = ["us-east-1a"]
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
assert {
|
|
676
|
+
condition = aws_vpc.this.cidr_block == "10.0.0.0/16"
|
|
677
|
+
error_message = "VPC CIDR block did not match"
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
assert {
|
|
681
|
+
condition = length(aws_subnet.public) == 1
|
|
682
|
+
error_message = "Expected exactly 1 public subnet"
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## 13. CI/CD Integration
|
|
690
|
+
|
|
691
|
+
```yaml
|
|
692
|
+
# .github/workflows/terraform.yml
|
|
693
|
+
name: Terraform
|
|
694
|
+
|
|
695
|
+
on:
|
|
696
|
+
pull_request:
|
|
697
|
+
paths: ["infrastructure/**"]
|
|
698
|
+
push:
|
|
699
|
+
branches: [main]
|
|
700
|
+
paths: ["infrastructure/**"]
|
|
701
|
+
|
|
702
|
+
jobs:
|
|
703
|
+
plan:
|
|
704
|
+
runs-on: ubuntu-latest
|
|
705
|
+
steps:
|
|
706
|
+
- uses: actions/checkout@v4
|
|
707
|
+
|
|
708
|
+
- uses: hashicorp/setup-terraform@v3
|
|
709
|
+
with:
|
|
710
|
+
terraform_version: "1.7.0"
|
|
711
|
+
|
|
712
|
+
- name: Terraform Init
|
|
713
|
+
run: terraform init
|
|
714
|
+
working-directory: infrastructure
|
|
715
|
+
|
|
716
|
+
- name: Terraform Validate
|
|
717
|
+
run: terraform validate
|
|
718
|
+
working-directory: infrastructure
|
|
719
|
+
|
|
720
|
+
- name: Terraform Plan
|
|
721
|
+
run: terraform plan -no-color -out=tfplan
|
|
722
|
+
working-directory: infrastructure
|
|
723
|
+
env:
|
|
724
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
725
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
726
|
+
|
|
727
|
+
# Post plan output as PR comment
|
|
728
|
+
- uses: actions/github-script@v7
|
|
729
|
+
if: github.event_name == 'pull_request'
|
|
730
|
+
with:
|
|
731
|
+
script: |
|
|
732
|
+
// Post plan summary to PR
|
|
733
|
+
|
|
734
|
+
apply:
|
|
735
|
+
needs: plan
|
|
736
|
+
if: github.ref == 'refs/heads/main'
|
|
737
|
+
runs-on: ubuntu-latest
|
|
738
|
+
environment: production
|
|
739
|
+
steps:
|
|
740
|
+
- uses: actions/checkout@v4
|
|
741
|
+
- uses: hashicorp/setup-terraform@v3
|
|
742
|
+
- run: terraform init && terraform apply -auto-approve
|
|
743
|
+
working-directory: infrastructure
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
## 14. Secret Management
|
|
749
|
+
|
|
750
|
+
```hcl
|
|
751
|
+
# NEVER hardcode secrets
|
|
752
|
+
# BAD
|
|
753
|
+
resource "aws_db_instance" "main" {
|
|
754
|
+
password = "my-secret-password" # NEVER DO THIS
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
# GOOD: Use variables marked as sensitive
|
|
758
|
+
variable "db_password" {
|
|
759
|
+
description = "Database master password"
|
|
760
|
+
type = string
|
|
761
|
+
sensitive = true
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
resource "aws_db_instance" "main" {
|
|
765
|
+
password = var.db_password
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
# GOOD: Read from AWS Secrets Manager
|
|
769
|
+
data "aws_secretsmanager_secret_version" "db_password" {
|
|
770
|
+
secret_id = "prod/database/password"
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
resource "aws_db_instance" "main" {
|
|
774
|
+
password = data.aws_secretsmanager_secret_version.db_password.secret_string
|
|
775
|
+
}
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
```bash
|
|
779
|
+
# Pass secrets via environment variables
|
|
780
|
+
export TF_VAR_db_password="$(aws secretsmanager get-secret-value \
|
|
781
|
+
--secret-id prod/database/password \
|
|
782
|
+
--query SecretString --output text)"
|
|
783
|
+
|
|
784
|
+
terraform apply
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
## 15. Anti-Patterns
|
|
790
|
+
|
|
791
|
+
### NEVER
|
|
792
|
+
|
|
793
|
+
- Store state locally in a team project -- always use a remote backend with locking
|
|
794
|
+
- Hardcode secrets in `.tf` files -- use variables, environment variables, or secret managers
|
|
795
|
+
- Use `count` for resources identified by name -- use `for_each` with meaningful keys
|
|
796
|
+
- Skip `terraform plan` and go straight to `apply`
|
|
797
|
+
- Commit `.terraform/` or `*.tfstate` files to version control
|
|
798
|
+
- Use `terraform taint` (deprecated) -- use `-replace` flag instead
|
|
799
|
+
- Create monolithic configurations with hundreds of resources -- break into modules
|
|
800
|
+
- Ignore provider version constraints -- pin major versions with `~>`
|
|
801
|
+
- Use `terraform destroy` in production without a plan review
|
|
802
|
+
- Share a single state file across unrelated projects
|
|
803
|
+
|
|
804
|
+
### ALWAYS
|
|
805
|
+
|
|
806
|
+
- Pin provider versions (`~> 5.0`) and Terraform version (`>= 1.5`)
|
|
807
|
+
- Use `terraform fmt` to format all files before committing
|
|
808
|
+
- Tag all resources with at least `ManagedBy`, `Environment`, and `Project`
|
|
809
|
+
- Use `sensitive = true` on variables and outputs containing secrets
|
|
810
|
+
- Write module README files with usage examples
|
|
811
|
+
- Use `terraform plan -out=tfplan` and `terraform apply tfplan` in CI/CD
|
|
812
|
+
- Review the plan output before every apply
|
|
813
|
+
- Use separate state files per environment (or workspaces)
|
|
814
|
+
- Run `terraform validate` in pre-commit hooks
|
|
815
|
+
- Keep modules small and focused -- one logical concern per module
|
|
816
|
+
|
|
817
|
+
---
|
|
818
|
+
|
|
819
|
+
## 16. Quick Reference
|
|
820
|
+
|
|
821
|
+
```bash
|
|
822
|
+
# Initialize a working directory
|
|
823
|
+
terraform init
|
|
824
|
+
|
|
825
|
+
# Format configuration files
|
|
826
|
+
terraform fmt -recursive
|
|
827
|
+
|
|
828
|
+
# Validate configuration
|
|
829
|
+
terraform validate
|
|
830
|
+
|
|
831
|
+
# Preview changes
|
|
832
|
+
terraform plan
|
|
833
|
+
|
|
834
|
+
# Apply changes
|
|
835
|
+
terraform apply
|
|
836
|
+
|
|
837
|
+
# Destroy all managed resources
|
|
838
|
+
terraform destroy
|
|
839
|
+
|
|
840
|
+
# Show current state
|
|
841
|
+
terraform show
|
|
842
|
+
|
|
843
|
+
# List resources in state
|
|
844
|
+
terraform state list
|
|
845
|
+
|
|
846
|
+
# Import existing resource
|
|
847
|
+
terraform import <resource_address> <resource_id>
|
|
848
|
+
|
|
849
|
+
# Force replacement of a resource
|
|
850
|
+
terraform apply -replace="aws_instance.web"
|
|
851
|
+
|
|
852
|
+
# Refresh state from real infrastructure
|
|
853
|
+
terraform refresh
|
|
854
|
+
|
|
855
|
+
# Output a specific value
|
|
856
|
+
terraform output database_endpoint
|
|
857
|
+
|
|
858
|
+
# Generate dependency graph
|
|
859
|
+
terraform graph | dot -Tpng > graph.png
|
|
860
|
+
```
|