claudient 0.1.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/.claude-plugin/plugin.json +42 -0
- package/CONTEXT.md +58 -0
- package/README.md +165 -0
- package/agents/build-resolvers/de/python-resolver.md +64 -0
- package/agents/build-resolvers/de/typescript-resolver.md +65 -0
- package/agents/build-resolvers/es/python-resolver.md +64 -0
- package/agents/build-resolvers/es/typescript-resolver.md +65 -0
- package/agents/build-resolvers/fr/python-resolver.md +64 -0
- package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
- package/agents/build-resolvers/nl/python-resolver.md +64 -0
- package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
- package/agents/build-resolvers/python-resolver.md +62 -0
- package/agents/build-resolvers/typescript-resolver.md +63 -0
- package/agents/core/architect.md +64 -0
- package/agents/core/code-reviewer.md +78 -0
- package/agents/core/de/architect.md +66 -0
- package/agents/core/de/code-reviewer.md +80 -0
- package/agents/core/de/planner.md +63 -0
- package/agents/core/de/security-reviewer.md +93 -0
- package/agents/core/es/architect.md +66 -0
- package/agents/core/es/code-reviewer.md +80 -0
- package/agents/core/es/planner.md +63 -0
- package/agents/core/es/security-reviewer.md +93 -0
- package/agents/core/fr/architect.md +66 -0
- package/agents/core/fr/code-reviewer.md +80 -0
- package/agents/core/fr/planner.md +63 -0
- package/agents/core/fr/security-reviewer.md +93 -0
- package/agents/core/nl/architect.md +66 -0
- package/agents/core/nl/code-reviewer.md +80 -0
- package/agents/core/nl/planner.md +63 -0
- package/agents/core/nl/security-reviewer.md +93 -0
- package/agents/core/planner.md +61 -0
- package/agents/core/security-reviewer.md +91 -0
- package/guides/agent-orchestration.md +231 -0
- package/guides/de/agent-orchestration.md +174 -0
- package/guides/de/getting-started.md +164 -0
- package/guides/de/hooks-cookbook.md +160 -0
- package/guides/de/memory-management.md +153 -0
- package/guides/de/security.md +180 -0
- package/guides/de/skill-authoring.md +214 -0
- package/guides/de/token-optimization.md +156 -0
- package/guides/es/agent-orchestration.md +174 -0
- package/guides/es/getting-started.md +164 -0
- package/guides/es/hooks-cookbook.md +160 -0
- package/guides/es/memory-management.md +153 -0
- package/guides/es/security.md +180 -0
- package/guides/es/skill-authoring.md +214 -0
- package/guides/es/token-optimization.md +156 -0
- package/guides/fr/agent-orchestration.md +174 -0
- package/guides/fr/getting-started.md +164 -0
- package/guides/fr/hooks-cookbook.md +227 -0
- package/guides/fr/memory-management.md +169 -0
- package/guides/fr/security.md +180 -0
- package/guides/fr/skill-authoring.md +214 -0
- package/guides/fr/token-optimization.md +158 -0
- package/guides/getting-started.md +164 -0
- package/guides/hooks-cookbook.md +423 -0
- package/guides/memory-management.md +192 -0
- package/guides/nl/agent-orchestration.md +174 -0
- package/guides/nl/getting-started.md +164 -0
- package/guides/nl/hooks-cookbook.md +160 -0
- package/guides/nl/memory-management.md +153 -0
- package/guides/nl/security.md +180 -0
- package/guides/nl/skill-authoring.md +214 -0
- package/guides/nl/token-optimization.md +156 -0
- package/guides/security.md +229 -0
- package/guides/skill-authoring.md +226 -0
- package/guides/token-optimization.md +169 -0
- package/hooks/lifecycle/cost-tracker.md +49 -0
- package/hooks/lifecycle/cost-tracker.sh +59 -0
- package/hooks/lifecycle/pre-compact-save.md +56 -0
- package/hooks/lifecycle/pre-compact-save.sh +37 -0
- package/hooks/lifecycle/session-start.md +50 -0
- package/hooks/lifecycle/session-start.sh +47 -0
- package/hooks/post-tool-use/audit-log.md +53 -0
- package/hooks/post-tool-use/audit-log.sh +53 -0
- package/hooks/post-tool-use/prettier.md +53 -0
- package/hooks/post-tool-use/prettier.sh +49 -0
- package/hooks/pre-tool-use/block-dangerous.md +48 -0
- package/hooks/pre-tool-use/block-dangerous.sh +76 -0
- package/hooks/pre-tool-use/git-push-confirm.md +46 -0
- package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
- package/mcp/configs/github.json +11 -0
- package/mcp/configs/postgres.json +11 -0
- package/mcp/de/recommended-servers.md +170 -0
- package/mcp/es/recommended-servers.md +170 -0
- package/mcp/fr/recommended-servers.md +170 -0
- package/mcp/nl/recommended-servers.md +170 -0
- package/mcp/recommended-servers.md +168 -0
- package/package.json +45 -0
- package/prompts/project-starters/de/fastapi-project.md +62 -0
- package/prompts/project-starters/de/nextjs-project.md +82 -0
- package/prompts/project-starters/es/fastapi-project.md +62 -0
- package/prompts/project-starters/es/nextjs-project.md +82 -0
- package/prompts/project-starters/fastapi-project.md +60 -0
- package/prompts/project-starters/fr/fastapi-project.md +62 -0
- package/prompts/project-starters/fr/nextjs-project.md +82 -0
- package/prompts/project-starters/nextjs-project.md +80 -0
- package/prompts/project-starters/nl/fastapi-project.md +62 -0
- package/prompts/project-starters/nl/nextjs-project.md +82 -0
- package/prompts/system-prompts/ai-product.md +80 -0
- package/prompts/system-prompts/data-pipeline.md +76 -0
- package/prompts/system-prompts/de/ai-product.md +82 -0
- package/prompts/system-prompts/de/data-pipeline.md +78 -0
- package/prompts/system-prompts/de/saas-backend.md +71 -0
- package/prompts/system-prompts/es/ai-product.md +82 -0
- package/prompts/system-prompts/es/data-pipeline.md +78 -0
- package/prompts/system-prompts/es/saas-backend.md +71 -0
- package/prompts/system-prompts/fr/ai-product.md +82 -0
- package/prompts/system-prompts/fr/data-pipeline.md +78 -0
- package/prompts/system-prompts/fr/saas-backend.md +71 -0
- package/prompts/system-prompts/nl/ai-product.md +82 -0
- package/prompts/system-prompts/nl/data-pipeline.md +78 -0
- package/prompts/system-prompts/nl/saas-backend.md +71 -0
- package/prompts/system-prompts/saas-backend.md +69 -0
- package/prompts/task-specific/changelog.md +81 -0
- package/prompts/task-specific/de/changelog.md +83 -0
- package/prompts/task-specific/de/debugging.md +78 -0
- package/prompts/task-specific/de/pr-description.md +69 -0
- package/prompts/task-specific/debugging.md +76 -0
- package/prompts/task-specific/es/changelog.md +83 -0
- package/prompts/task-specific/es/debugging.md +78 -0
- package/prompts/task-specific/es/pr-description.md +69 -0
- package/prompts/task-specific/fr/changelog.md +83 -0
- package/prompts/task-specific/fr/debugging.md +78 -0
- package/prompts/task-specific/fr/pr-description.md +69 -0
- package/prompts/task-specific/nl/changelog.md +83 -0
- package/prompts/task-specific/nl/debugging.md +78 -0
- package/prompts/task-specific/nl/pr-description.md +69 -0
- package/prompts/task-specific/pr-description.md +67 -0
- package/rules/common/coding-style.md +45 -0
- package/rules/common/de/coding-style.md +47 -0
- package/rules/common/de/git.md +48 -0
- package/rules/common/de/performance.md +40 -0
- package/rules/common/de/security.md +45 -0
- package/rules/common/de/testing.md +45 -0
- package/rules/common/es/coding-style.md +47 -0
- package/rules/common/es/git.md +48 -0
- package/rules/common/es/performance.md +40 -0
- package/rules/common/es/security.md +45 -0
- package/rules/common/es/testing.md +45 -0
- package/rules/common/fr/coding-style.md +47 -0
- package/rules/common/fr/git.md +48 -0
- package/rules/common/fr/performance.md +40 -0
- package/rules/common/fr/security.md +45 -0
- package/rules/common/fr/testing.md +45 -0
- package/rules/common/git.md +46 -0
- package/rules/common/nl/coding-style.md +47 -0
- package/rules/common/nl/git.md +48 -0
- package/rules/common/nl/performance.md +40 -0
- package/rules/common/nl/security.md +45 -0
- package/rules/common/nl/testing.md +45 -0
- package/rules/common/performance.md +38 -0
- package/rules/common/security.md +43 -0
- package/rules/common/testing.md +43 -0
- package/rules/language-specific/de/go.md +48 -0
- package/rules/language-specific/de/python.md +38 -0
- package/rules/language-specific/de/typescript.md +51 -0
- package/rules/language-specific/es/go.md +48 -0
- package/rules/language-specific/es/python.md +38 -0
- package/rules/language-specific/es/typescript.md +51 -0
- package/rules/language-specific/fr/go.md +48 -0
- package/rules/language-specific/fr/python.md +38 -0
- package/rules/language-specific/fr/typescript.md +51 -0
- package/rules/language-specific/go.md +46 -0
- package/rules/language-specific/nl/go.md +48 -0
- package/rules/language-specific/nl/python.md +38 -0
- package/rules/language-specific/nl/typescript.md +51 -0
- package/rules/language-specific/python.md +36 -0
- package/rules/language-specific/typescript.md +49 -0
- package/scripts/cli.js +161 -0
- package/scripts/link-skills.sh +35 -0
- package/scripts/list-skills.sh +34 -0
- package/skills/ai-engineering/agent-construction.md +285 -0
- package/skills/ai-engineering/claude-api.md +248 -0
- package/skills/ai-engineering/de/agent-construction.md +287 -0
- package/skills/ai-engineering/de/claude-api.md +250 -0
- package/skills/ai-engineering/es/agent-construction.md +287 -0
- package/skills/ai-engineering/es/claude-api.md +250 -0
- package/skills/ai-engineering/fr/agent-construction.md +287 -0
- package/skills/ai-engineering/fr/claude-api.md +250 -0
- package/skills/ai-engineering/nl/agent-construction.md +287 -0
- package/skills/ai-engineering/nl/claude-api.md +250 -0
- package/skills/backend/dotnet/csharp.md +304 -0
- package/skills/backend/dotnet/de/csharp.md +306 -0
- package/skills/backend/dotnet/es/csharp.md +306 -0
- package/skills/backend/dotnet/fr/csharp.md +306 -0
- package/skills/backend/dotnet/nl/csharp.md +306 -0
- package/skills/backend/go/de/go.md +307 -0
- package/skills/backend/go/es/go.md +307 -0
- package/skills/backend/go/fr/go.md +307 -0
- package/skills/backend/go/go.md +305 -0
- package/skills/backend/go/nl/go.md +307 -0
- package/skills/backend/nodejs/de/nestjs.md +274 -0
- package/skills/backend/nodejs/de/nextjs.md +222 -0
- package/skills/backend/nodejs/es/nestjs.md +274 -0
- package/skills/backend/nodejs/es/nextjs.md +222 -0
- package/skills/backend/nodejs/fr/nestjs.md +274 -0
- package/skills/backend/nodejs/fr/nextjs.md +222 -0
- package/skills/backend/nodejs/nestjs.md +272 -0
- package/skills/backend/nodejs/nextjs.md +220 -0
- package/skills/backend/nodejs/nl/nestjs.md +274 -0
- package/skills/backend/nodejs/nl/nextjs.md +222 -0
- package/skills/backend/python/de/django.md +285 -0
- package/skills/backend/python/de/fastapi.md +244 -0
- package/skills/backend/python/django.md +283 -0
- package/skills/backend/python/es/django.md +285 -0
- package/skills/backend/python/es/fastapi.md +244 -0
- package/skills/backend/python/fastapi.md +242 -0
- package/skills/backend/python/fr/django.md +285 -0
- package/skills/backend/python/fr/fastapi.md +244 -0
- package/skills/backend/python/nl/django.md +285 -0
- package/skills/backend/python/nl/fastapi.md +244 -0
- package/skills/data-ml/dbt-data-pipelines.md +155 -0
- package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/de/pandas-polars.md +147 -0
- package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/es/pandas-polars.md +147 -0
- package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/fr/pandas-polars.md +147 -0
- package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/nl/pandas-polars.md +147 -0
- package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/pandas-polars.md +145 -0
- package/skills/data-ml/pytorch-tensorflow.md +169 -0
- package/skills/database/de/graphql.md +181 -0
- package/skills/database/es/graphql.md +181 -0
- package/skills/database/fr/graphql.md +181 -0
- package/skills/database/graphql.md +179 -0
- package/skills/database/nl/graphql.md +181 -0
- package/skills/devops-infra/de/docker.md +133 -0
- package/skills/devops-infra/de/github-actions.md +179 -0
- package/skills/devops-infra/de/kubernetes.md +129 -0
- package/skills/devops-infra/de/terraform.md +130 -0
- package/skills/devops-infra/docker.md +131 -0
- package/skills/devops-infra/es/docker.md +133 -0
- package/skills/devops-infra/es/github-actions.md +179 -0
- package/skills/devops-infra/es/kubernetes.md +129 -0
- package/skills/devops-infra/es/terraform.md +130 -0
- package/skills/devops-infra/fr/docker.md +133 -0
- package/skills/devops-infra/fr/github-actions.md +179 -0
- package/skills/devops-infra/fr/kubernetes.md +129 -0
- package/skills/devops-infra/fr/terraform.md +130 -0
- package/skills/devops-infra/github-actions.md +177 -0
- package/skills/devops-infra/kubernetes.md +127 -0
- package/skills/devops-infra/nl/docker.md +133 -0
- package/skills/devops-infra/nl/github-actions.md +179 -0
- package/skills/devops-infra/nl/kubernetes.md +129 -0
- package/skills/devops-infra/nl/terraform.md +130 -0
- package/skills/devops-infra/terraform.md +128 -0
- package/skills/finance-payments/de/stripe.md +187 -0
- package/skills/finance-payments/es/stripe.md +187 -0
- package/skills/finance-payments/fr/stripe.md +187 -0
- package/skills/finance-payments/nl/stripe.md +187 -0
- package/skills/finance-payments/stripe.md +185 -0
- package/workflows/code-review.md +151 -0
- package/workflows/de/code-review.md +153 -0
- package/workflows/de/debugging-session.md +146 -0
- package/workflows/de/feature-development.md +155 -0
- package/workflows/de/new-project-bootstrap.md +175 -0
- package/workflows/de/refactor-safely.md +150 -0
- package/workflows/debugging-session.md +144 -0
- package/workflows/es/code-review.md +153 -0
- package/workflows/es/debugging-session.md +146 -0
- package/workflows/es/feature-development.md +155 -0
- package/workflows/es/new-project-bootstrap.md +175 -0
- package/workflows/es/refactor-safely.md +150 -0
- package/workflows/feature-development.md +153 -0
- package/workflows/fr/code-review.md +153 -0
- package/workflows/fr/debugging-session.md +146 -0
- package/workflows/fr/feature-development.md +155 -0
- package/workflows/fr/new-project-bootstrap.md +175 -0
- package/workflows/fr/refactor-safely.md +150 -0
- package/workflows/new-project-bootstrap.md +173 -0
- package/workflows/nl/code-review.md +153 -0
- package/workflows/nl/debugging-session.md +146 -0
- package/workflows/nl/feature-development.md +155 -0
- package/workflows/nl/new-project-bootstrap.md +175 -0
- package/workflows/nl/refactor-safely.md +150 -0
- package/workflows/refactor-safely.md +148 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../github-actions.md).
|
|
2
|
+
|
|
3
|
+
# GitHub Actions Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- CI/CD-pipelines schrijven voor testen, linting, bouwen en deployen
|
|
7
|
+
- Matrix-builds instellen voor meerdere besturingssystemen of taalversies
|
|
8
|
+
- Omgevingsbeschermingsregels en deployment-gates configureren
|
|
9
|
+
- Herbruikbare workflows of composite actions schrijven
|
|
10
|
+
- Docker build instellen en naar een containerregister pushen
|
|
11
|
+
- OIDC-authenticatie naar cloudproviders configureren (geen langlevende secrets)
|
|
12
|
+
- Falende workflows debuggen of workflowsyntaxfouten begrijpen
|
|
13
|
+
- Caching instellen voor afhankelijkheden (npm, pip, Go modules)
|
|
14
|
+
|
|
15
|
+
## Wanneer NIET te gebruiken
|
|
16
|
+
- GitLab CI, CircleCI, Jenkins — andere pipeline-systemen
|
|
17
|
+
- Lokale ontwikkelingsautomatisering (gebruik Makefile of scripts)
|
|
18
|
+
- Cron-jobs die niet aan een repository zijn gekoppeld (gebruik cloud scheduler)
|
|
19
|
+
|
|
20
|
+
## Instructies
|
|
21
|
+
|
|
22
|
+
### Workflow-bestandsstructuur
|
|
23
|
+
```yaml
|
|
24
|
+
name: CI
|
|
25
|
+
|
|
26
|
+
on:
|
|
27
|
+
push:
|
|
28
|
+
branches: [main]
|
|
29
|
+
pull_request:
|
|
30
|
+
branches: [main]
|
|
31
|
+
|
|
32
|
+
# Expliciete rechten — gebruik nooit de standaard write-all
|
|
33
|
+
permissions:
|
|
34
|
+
contents: read
|
|
35
|
+
pull-requests: write # Alleen als nodig (bijv. voor het plaatsen van opmerkingen)
|
|
36
|
+
|
|
37
|
+
jobs:
|
|
38
|
+
test:
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- name: Set up Node.js
|
|
43
|
+
uses: actions/setup-node@v4
|
|
44
|
+
with:
|
|
45
|
+
node-version: '20'
|
|
46
|
+
cache: 'npm'
|
|
47
|
+
- run: npm ci
|
|
48
|
+
- run: npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Rechten — altijd expliciet
|
|
52
|
+
Gebruik nooit de standaard `permissions: write-all`. Declareer altijd minimaal vereiste rechten:
|
|
53
|
+
```yaml
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read # Repository lezen
|
|
56
|
+
packages: write # Pushen naar GitHub Container Registry
|
|
57
|
+
id-token: write # OIDC voor cloud-authenticatie
|
|
58
|
+
pull-requests: write # Opmerkingen op PR's plaatsen
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Secrets — OIDC boven langlevende credentials
|
|
62
|
+
Gebruik OIDC (OpenID Connect) voor cloud-authenticatie — geen opgeslagen secrets:
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
# AWS OIDC — geen AWS_ACCESS_KEY_ID nodig
|
|
66
|
+
- name: Configure AWS credentials
|
|
67
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
68
|
+
with:
|
|
69
|
+
role-to-assume: arn:aws:iam::123456789:role/github-actions-role
|
|
70
|
+
aws-region: eu-west-1
|
|
71
|
+
|
|
72
|
+
# GCP OIDC
|
|
73
|
+
- name: Authenticate to GCP
|
|
74
|
+
uses: google-github-actions/auth@v2
|
|
75
|
+
with:
|
|
76
|
+
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/pool/providers/github
|
|
77
|
+
service_account: deploy@project.iam.gserviceaccount.com
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Afhankelijkheidscaching
|
|
81
|
+
Cache altijd afhankelijkheden om bouwtijd te verkorten:
|
|
82
|
+
```yaml
|
|
83
|
+
# Node.js
|
|
84
|
+
- uses: actions/setup-node@v4
|
|
85
|
+
with:
|
|
86
|
+
node-version: '20'
|
|
87
|
+
cache: 'npm' # Ingebouwde cache — geen handmatige cache-stap nodig
|
|
88
|
+
|
|
89
|
+
# Python
|
|
90
|
+
- uses: actions/setup-python@v5
|
|
91
|
+
with:
|
|
92
|
+
python-version: '3.12'
|
|
93
|
+
cache: 'pip'
|
|
94
|
+
|
|
95
|
+
# Go
|
|
96
|
+
- uses: actions/setup-go@v5
|
|
97
|
+
with:
|
|
98
|
+
go-version: '1.22'
|
|
99
|
+
cache: true
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Omgevingsgates voor productie-deployments
|
|
103
|
+
```yaml
|
|
104
|
+
jobs:
|
|
105
|
+
deploy-production:
|
|
106
|
+
environment: production # Verwijst naar GitHub Environment met beschermingsregels
|
|
107
|
+
needs: [test, build]
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
steps:
|
|
110
|
+
- name: Deploy
|
|
111
|
+
run: ./scripts/deploy.sh
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Stel omgevingsbeschermingsregels in via GitHub-instellingen:
|
|
115
|
+
- Vereiste reviewers voor productie-deployments
|
|
116
|
+
- Wachttimer tussen staging en productie
|
|
117
|
+
- Beperken tot specifieke branches (alleen `main`)
|
|
118
|
+
|
|
119
|
+
### Matrix-builds
|
|
120
|
+
```yaml
|
|
121
|
+
jobs:
|
|
122
|
+
test:
|
|
123
|
+
strategy:
|
|
124
|
+
matrix:
|
|
125
|
+
node-version: [18, 20, 22]
|
|
126
|
+
os: [ubuntu-latest, windows-latest]
|
|
127
|
+
fail-fast: false # Niet alles annuleren bij eerste fout
|
|
128
|
+
runs-on: ${{ matrix.os }}
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@v4
|
|
131
|
+
- uses: actions/setup-node@v4
|
|
132
|
+
with:
|
|
133
|
+
node-version: ${{ matrix.node-version }}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Herbruikbare workflows
|
|
137
|
+
```yaml
|
|
138
|
+
# .github/workflows/deploy.yml — herbruikbaar
|
|
139
|
+
on:
|
|
140
|
+
workflow_call:
|
|
141
|
+
inputs:
|
|
142
|
+
environment:
|
|
143
|
+
required: true
|
|
144
|
+
type: string
|
|
145
|
+
secrets:
|
|
146
|
+
deploy-token:
|
|
147
|
+
required: true
|
|
148
|
+
|
|
149
|
+
# Aanroeper
|
|
150
|
+
jobs:
|
|
151
|
+
deploy:
|
|
152
|
+
uses: ./.github/workflows/deploy.yml
|
|
153
|
+
with:
|
|
154
|
+
environment: production
|
|
155
|
+
secrets:
|
|
156
|
+
deploy-token: ${{ secrets.DEPLOY_TOKEN }}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Veelvoorkomende fouten
|
|
160
|
+
- `actions/checkout@v4` ontbreekt — altijd de eerste stap
|
|
161
|
+
- Secrets niet toegankelijk in forks — gebruik `pull_request_target` voorzichtig (beveiligingsrisico)
|
|
162
|
+
- Cache niet getroffen — sleutel moet exact overeenkomen; gebruik `restore-keys` als fallback
|
|
163
|
+
- OIDC mislukt — controleer vertrouwensbeleid aan de cloudprovider-kant dat de repo en branch toestaat
|
|
164
|
+
|
|
165
|
+
## Voorbeeld
|
|
166
|
+
|
|
167
|
+
**Gebruiker:** Schrijf een CI/CD-pipeline voor een Node.js-app: voer tests uit op PR's, bouw en push Docker image bij merge naar main, deploy naar productie met een handmatige goedkeuringsgate.
|
|
168
|
+
|
|
169
|
+
**Verwachte output:**
|
|
170
|
+
- `on: push/pull_request`-triggers
|
|
171
|
+
- `test`-job: checkout, setup-node met cache, `npm ci`, `npm test`
|
|
172
|
+
- `build`-job (bij push naar main, heeft test nodig): Docker build + push naar GHCR via OIDC
|
|
173
|
+
- `deploy`-job: `environment: production` (vereist goedkeuring), roept deploy-script aan
|
|
174
|
+
- Expliciet `permissions:`-blok — minimaal vereist
|
|
175
|
+
- Geen hardcoded secrets — OIDC voor registry-authenticatie
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. CI/CD bouwen voor AI-producten of cloud-deployments? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../kubernetes.md).
|
|
2
|
+
|
|
3
|
+
# Kubernetes Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- Kubernetes manifests schrijven (Deployments, Services, ConfigMaps, Secrets, Ingress)
|
|
7
|
+
- Helm charts of values-bestanden configureren voor een applicatie
|
|
8
|
+
- Een falende Pod, CrashLoopBackOff, of OOMKilled container debuggen
|
|
9
|
+
- Horizontal pod autoscaling (HPA) of vertical pod autoscaling (VPA) instellen
|
|
10
|
+
- Resource requests en limits definiëren voor containers
|
|
11
|
+
- RBAC-beleid schrijven of reviewen (Roles, ClusterRoles, RoleBindings)
|
|
12
|
+
- Liveness-, readiness- en startup-probes instellen
|
|
13
|
+
- Persistent volumes en persistent volume claims configureren
|
|
14
|
+
- Network policies schrijven om pod-naar-pod-verkeer te beheren
|
|
15
|
+
- Namespaces en multi-tenant isolatie instellen
|
|
16
|
+
|
|
17
|
+
## Wanneer NIET te gebruiken
|
|
18
|
+
- Docker Compose-setups die niet naar Kubernetes worden gemigreerd
|
|
19
|
+
- Serverless (Cloud Run, Lambda, Fargate) — ander deployment-model
|
|
20
|
+
- Eenvoudige single-container apps die geen orkestratie nodig hebben
|
|
21
|
+
- Lokale ontwikkelomgevingen waar Docker alleen voldoende is
|
|
22
|
+
- Nomad, Mesos, of andere niet-Kubernetes orchestrators
|
|
23
|
+
|
|
24
|
+
## Instructies
|
|
25
|
+
|
|
26
|
+
### Manifest-structuur
|
|
27
|
+
Stel deze velden altijd in voor elke Deployment:
|
|
28
|
+
```yaml
|
|
29
|
+
apiVersion: apps/v1
|
|
30
|
+
kind: Deployment
|
|
31
|
+
metadata:
|
|
32
|
+
name: app-name
|
|
33
|
+
namespace: production # Altijd expliciet — nooit vertrouwen op de default namespace
|
|
34
|
+
labels:
|
|
35
|
+
app: app-name
|
|
36
|
+
version: "1.0.0"
|
|
37
|
+
spec:
|
|
38
|
+
replicas: 3
|
|
39
|
+
selector:
|
|
40
|
+
matchLabels:
|
|
41
|
+
app: app-name
|
|
42
|
+
template:
|
|
43
|
+
metadata:
|
|
44
|
+
labels:
|
|
45
|
+
app: app-name
|
|
46
|
+
version: "1.0.0"
|
|
47
|
+
spec:
|
|
48
|
+
containers:
|
|
49
|
+
- name: app-name
|
|
50
|
+
image: registry/app-name:tag # Gebruik nooit :latest in productie
|
|
51
|
+
resources:
|
|
52
|
+
requests:
|
|
53
|
+
cpu: "100m"
|
|
54
|
+
memory: "128Mi"
|
|
55
|
+
limits:
|
|
56
|
+
cpu: "500m"
|
|
57
|
+
memory: "512Mi"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Resource requests en limits
|
|
61
|
+
- Stel altijd zowel `requests` als `limits` in — nooit weglaten
|
|
62
|
+
- `requests` = gegarandeerde resources (gebruikt voor scheduling)
|
|
63
|
+
- `limits` = maximaal toegestaan (OOMKilled als geheugen wordt overschreden)
|
|
64
|
+
- CPU-limits zijn optioneel in clusters met CPU-throttling uitgeschakeld — maar geheugenlimieten zijn verplicht
|
|
65
|
+
- Begin conservatief: requests op ~25% van verwacht, limits op 2x verwacht, dan bijstellen met werkelijke metrieken
|
|
66
|
+
|
|
67
|
+
### Health probes
|
|
68
|
+
Alle productiecontainers moeten probes hebben:
|
|
69
|
+
```yaml
|
|
70
|
+
livenessProbe:
|
|
71
|
+
httpGet:
|
|
72
|
+
path: /healthz
|
|
73
|
+
port: 8080
|
|
74
|
+
initialDelaySeconds: 15
|
|
75
|
+
periodSeconds: 20
|
|
76
|
+
failureThreshold: 3
|
|
77
|
+
|
|
78
|
+
readinessProbe:
|
|
79
|
+
httpGet:
|
|
80
|
+
path: /ready
|
|
81
|
+
port: 8080
|
|
82
|
+
initialDelaySeconds: 5
|
|
83
|
+
periodSeconds: 10
|
|
84
|
+
failureThreshold: 3
|
|
85
|
+
```
|
|
86
|
+
- `livenessProbe`-fout → container herstart
|
|
87
|
+
- `readinessProbe`-fout → verwijderd uit Service load balancer (geen verkeer, geen herstart)
|
|
88
|
+
- Wijs beide nooit naar hetzelfde endpoint — readiness moet afhankelijkheden controleren, liveness niet
|
|
89
|
+
|
|
90
|
+
### Secrets-beheer
|
|
91
|
+
- Zet nooit secrets in ConfigMaps — gebruik Secrets
|
|
92
|
+
- Commit nooit Secret-manifests met echte waarden — gebruik sealed-secrets, external-secrets-operator, of Vault
|
|
93
|
+
- Verwijs naar secrets als omgevingsvariabelen, niet als volumes, tenzij de app specifiek bestandsgebaseerde secrets vereist:
|
|
94
|
+
```yaml
|
|
95
|
+
env:
|
|
96
|
+
- name: DATABASE_URL
|
|
97
|
+
valueFrom:
|
|
98
|
+
secretKeyRef:
|
|
99
|
+
name: app-secrets
|
|
100
|
+
key: database-url
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Namespace-conventies
|
|
104
|
+
- `default` namespace: alleen voor dev/testing
|
|
105
|
+
- Productie-workloads altijd in benoemde namespaces
|
|
106
|
+
- Gebruik `ResourceQuota` en `LimitRange` op elke productie-namespace
|
|
107
|
+
- RBAC: ontwikkelaars krijgen edit in dev-namespaces, view in productie
|
|
108
|
+
|
|
109
|
+
### Veelvoorkomende CrashLoopBackOff-oorzaken en oplossingen
|
|
110
|
+
1. Ontbrekende omgevingsvariabele → controleer de sectie Events van `kubectl describe pod`
|
|
111
|
+
2. Mislukte healthcheck → logs tonen de werkelijke fout, probe detecteert alleen
|
|
112
|
+
3. OOMKilled → verhoog de geheugenlimiet of los geheugenlek op
|
|
113
|
+
4. Image pull-fout → controleer imagePullPolicy en registrygegevens
|
|
114
|
+
5. Init container-fout → `kubectl logs pod-name -c init-container-name`
|
|
115
|
+
|
|
116
|
+
## Voorbeeld
|
|
117
|
+
|
|
118
|
+
**Gebruiker:** Implementeer een FastAPI-app met PostgreSQL-verbinding, 3 replica's, resource-limieten en health checks.
|
|
119
|
+
|
|
120
|
+
**Verwachte outputstructuur:**
|
|
121
|
+
- Namespace-manifest
|
|
122
|
+
- Secret voor `DATABASE_URL`
|
|
123
|
+
- Deployment met 3 replica's, resource requests/limits, liveness + readiness probes die verwijzen naar `/healthz` en `/ready`
|
|
124
|
+
- Service (ClusterIP) die port 80 blootstelt → container port 8080
|
|
125
|
+
- HorizontalPodAutoscaler gericht op 70% CPU-gebruik, min 3 / max 10 replica's
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. Kubernetes-infrastructuur of cloud-native AI-producten bouwen? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../terraform.md).
|
|
2
|
+
|
|
3
|
+
# Terraform Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- Terraform-modules schrijven voor AWS-, GCP- of Azure-infrastructuur
|
|
7
|
+
- VPC's, subnets, security groups en netwerkresources definiëren
|
|
8
|
+
- Compute-resources inrichten (EC2, GKE, AKS, ECS, Lambda)
|
|
9
|
+
- Database-infrastructuur beheren (RDS, Cloud SQL, Aurora)
|
|
10
|
+
- IAM-rollen, -beleid en serviceaccounts instellen
|
|
11
|
+
- Remote state-configuratie schrijven (S3 backend, GCS, Terraform Cloud)
|
|
12
|
+
- Bestaande Terraform refactoren om modules te gebruiken
|
|
13
|
+
- CI/CD-pipelines schrijven voor `terraform plan` en `terraform apply`
|
|
14
|
+
- Bestaande infrastructuur importeren in de Terraform-state
|
|
15
|
+
|
|
16
|
+
## Wanneer NIET te gebruiken
|
|
17
|
+
- Pulumi, CDK, of Crossplane — andere IaC-tools, andere patronen
|
|
18
|
+
- Helm chart-configuratie (gebruik in plaats daarvan de Kubernetes skill)
|
|
19
|
+
- Configuratie op applicatieniveau (Kubernetes ConfigMaps, app-omgevingsvariabelen)
|
|
20
|
+
- Eenmalige CLI-operaties die niet herhaald worden
|
|
21
|
+
|
|
22
|
+
## Instructies
|
|
23
|
+
|
|
24
|
+
### Module-structuur
|
|
25
|
+
Elk Terraform-project moet deze structuur volgen:
|
|
26
|
+
```
|
|
27
|
+
infrastructure/
|
|
28
|
+
├── modules/
|
|
29
|
+
│ ├── networking/
|
|
30
|
+
│ │ ├── main.tf
|
|
31
|
+
│ │ ├── variables.tf
|
|
32
|
+
│ │ ├── outputs.tf
|
|
33
|
+
│ │ └── versions.tf
|
|
34
|
+
│ └── compute/
|
|
35
|
+
│ ├── main.tf
|
|
36
|
+
│ ├── variables.tf
|
|
37
|
+
│ └── outputs.tf
|
|
38
|
+
├── environments/
|
|
39
|
+
│ ├── production/
|
|
40
|
+
│ │ ├── main.tf ← roept modules aan
|
|
41
|
+
│ │ ├── variables.tf
|
|
42
|
+
│ │ ├── terraform.tfvars
|
|
43
|
+
│ │ └── backend.tf
|
|
44
|
+
│ └── staging/
|
|
45
|
+
│ └── ...
|
|
46
|
+
└── versions.tf ← root provider-versies
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### State-beheer — altijd remote
|
|
50
|
+
```hcl
|
|
51
|
+
# backend.tf
|
|
52
|
+
terraform {
|
|
53
|
+
backend "s3" {
|
|
54
|
+
bucket = "company-terraform-state"
|
|
55
|
+
key = "production/networking/terraform.tfstate"
|
|
56
|
+
region = "eu-west-1"
|
|
57
|
+
encrypt = true
|
|
58
|
+
dynamodb_table = "terraform-state-lock"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
- Gebruik nooit lokale state voor gedeelde zaken
|
|
63
|
+
- Schakel encryptie en state-locking in (DynamoDB voor S3 backend)
|
|
64
|
+
- Aparte state-bestanden per omgeving en per module (niet één grote state)
|
|
65
|
+
|
|
66
|
+
### Variabelen en outputs discipline
|
|
67
|
+
```hcl
|
|
68
|
+
# variables.tf — altijd description en type opnemen
|
|
69
|
+
variable "environment" {
|
|
70
|
+
description = "Deployment environment (production, staging, development)"
|
|
71
|
+
type = string
|
|
72
|
+
validation {
|
|
73
|
+
condition = contains(["production", "staging", "development"], var.environment)
|
|
74
|
+
error_message = "Environment must be production, staging, or development."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# outputs.tf — alles outputten wat een gebruikende module nodig kan hebben
|
|
79
|
+
output "vpc_id" {
|
|
80
|
+
description = "The ID of the VPC"
|
|
81
|
+
value = aws_vpc.main.id
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Secrets — nooit in state of code
|
|
86
|
+
- Zet nooit secrets in `terraform.tfvars` of hardcode ze in `.tf`-bestanden
|
|
87
|
+
- Gebruik `data "aws_secretsmanager_secret_version"` of `data "google_secret_manager_secret_version"` om secrets te lezen bij apply
|
|
88
|
+
- Gevoelige outputs: markeer met `sensitive = true` om te onderdrukken in plan-output
|
|
89
|
+
- `.gitignore` moet bevatten: `*.tfvars`, `*.tfstate`, `*.tfstate.backup`, `.terraform/`
|
|
90
|
+
|
|
91
|
+
### Naamconventies voor resources
|
|
92
|
+
```hcl
|
|
93
|
+
# Consistente naamgeving: {project}-{environment}-{resource}-{suffix}
|
|
94
|
+
resource "aws_vpc" "main" {
|
|
95
|
+
cidr_block = var.vpc_cidr
|
|
96
|
+
tags = {
|
|
97
|
+
Name = "${var.project}-${var.environment}-vpc"
|
|
98
|
+
Environment = var.environment
|
|
99
|
+
ManagedBy = "terraform"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
Tag elke resource altijd met `Environment` en `ManagedBy = "terraform"`.
|
|
104
|
+
|
|
105
|
+
### Plan voor apply — altijd
|
|
106
|
+
- CI/CD-pipeline: `terraform plan -out=tfplan` bij PR, `terraform apply tfplan` bij merge
|
|
107
|
+
- Voer nooit `terraform apply` uit zonder een opgeslagen plan in productie
|
|
108
|
+
- Gebruik `-target` spaarzaam — het creëert drift tussen werkelijke state en plan
|
|
109
|
+
|
|
110
|
+
### Veelvoorkomende valkuilen
|
|
111
|
+
- `terraform destroy` zonder `-target` vernietigt alles — bevestig altijd de reikwijdte
|
|
112
|
+
- Een resource-attribuut wijzigen dat vervanging forceert (bijv. VPC CIDR) verwijdert en herschept — controleer plan zorgvuldig
|
|
113
|
+
- Provider versie-pinning is verplicht: gebruik `~> 5.0` niet `>= 5.0`
|
|
114
|
+
- `count` vs `for_each`: gebruik `for_each` met maps — `count` veroorzaakt index-drift wanneer items worden verwijderd
|
|
115
|
+
|
|
116
|
+
## Voorbeeld
|
|
117
|
+
|
|
118
|
+
**Gebruiker:** Maak een Terraform-module voor een private RDS PostgreSQL-instantie op AWS met Multi-AZ, versleutelde opslag en een toegewijd security group.
|
|
119
|
+
|
|
120
|
+
**Verwachte outputstructuur:**
|
|
121
|
+
- `modules/rds/main.tf` — `aws_db_instance`, `aws_db_subnet_group`, `aws_security_group`
|
|
122
|
+
- `modules/rds/variables.tf` — instantieklasse, engine-versie, db-naam, VPC/subnet-ID's, ingress CIDR
|
|
123
|
+
- `modules/rds/outputs.tf` — endpoint, port, security group ID
|
|
124
|
+
- Security group: staat PostgreSQL (5432) alleen toe vanuit app security group, geen publieke toegang
|
|
125
|
+
- `storage_encrypted = true`, `multi_az = true`, `deletion_protection = true` voor productie
|
|
126
|
+
- Wachtwoord via `aws_secretsmanager_secret`-referentie, nooit hardcoded
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. Cloud-infrastructuur of IaC-pipelines bouwen? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Terraform Skill
|
|
2
|
+
|
|
3
|
+
## When to activate
|
|
4
|
+
- Writing Terraform modules for AWS, GCP, or Azure infrastructure
|
|
5
|
+
- Defining VPCs, subnets, security groups, and networking resources
|
|
6
|
+
- Provisioning compute resources (EC2, GKE, AKS, ECS, Lambda)
|
|
7
|
+
- Managing database infrastructure (RDS, Cloud SQL, Aurora)
|
|
8
|
+
- Setting up IAM roles, policies, and service accounts
|
|
9
|
+
- Writing remote state configuration (S3 backend, GCS, Terraform Cloud)
|
|
10
|
+
- Refactoring existing Terraform to use modules
|
|
11
|
+
- Writing CI/CD pipelines for `terraform plan` and `terraform apply`
|
|
12
|
+
- Importing existing infrastructure into Terraform state
|
|
13
|
+
|
|
14
|
+
## When NOT to use
|
|
15
|
+
- Pulumi, CDK, or Crossplane — different IaC tools, different patterns
|
|
16
|
+
- Helm chart configuration (use the Kubernetes skill instead)
|
|
17
|
+
- Application-level config (Kubernetes ConfigMaps, app env vars)
|
|
18
|
+
- One-off CLI operations that won't be repeated
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
### Module structure
|
|
23
|
+
Every Terraform project must follow this structure:
|
|
24
|
+
```
|
|
25
|
+
infrastructure/
|
|
26
|
+
├── modules/
|
|
27
|
+
│ ├── networking/
|
|
28
|
+
│ │ ├── main.tf
|
|
29
|
+
│ │ ├── variables.tf
|
|
30
|
+
│ │ ├── outputs.tf
|
|
31
|
+
│ │ └── versions.tf
|
|
32
|
+
│ └── compute/
|
|
33
|
+
│ ├── main.tf
|
|
34
|
+
│ ├── variables.tf
|
|
35
|
+
│ └── outputs.tf
|
|
36
|
+
├── environments/
|
|
37
|
+
│ ├── production/
|
|
38
|
+
│ │ ├── main.tf ← calls modules
|
|
39
|
+
│ │ ├── variables.tf
|
|
40
|
+
│ │ ├── terraform.tfvars
|
|
41
|
+
│ │ └── backend.tf
|
|
42
|
+
│ └── staging/
|
|
43
|
+
│ └── ...
|
|
44
|
+
└── versions.tf ← root provider versions
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### State management — always remote
|
|
48
|
+
```hcl
|
|
49
|
+
# backend.tf
|
|
50
|
+
terraform {
|
|
51
|
+
backend "s3" {
|
|
52
|
+
bucket = "company-terraform-state"
|
|
53
|
+
key = "production/networking/terraform.tfstate"
|
|
54
|
+
region = "eu-west-1"
|
|
55
|
+
encrypt = true
|
|
56
|
+
dynamodb_table = "terraform-state-lock"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
- Never use local state for anything shared
|
|
61
|
+
- Enable encryption and state locking (DynamoDB for S3 backend)
|
|
62
|
+
- Separate state files per environment and per module (not one giant state)
|
|
63
|
+
|
|
64
|
+
### Variable and output discipline
|
|
65
|
+
```hcl
|
|
66
|
+
# variables.tf — always include description and type
|
|
67
|
+
variable "environment" {
|
|
68
|
+
description = "Deployment environment (production, staging, development)"
|
|
69
|
+
type = string
|
|
70
|
+
validation {
|
|
71
|
+
condition = contains(["production", "staging", "development"], var.environment)
|
|
72
|
+
error_message = "Environment must be production, staging, or development."
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# outputs.tf — output everything a consuming module might need
|
|
77
|
+
output "vpc_id" {
|
|
78
|
+
description = "The ID of the VPC"
|
|
79
|
+
value = aws_vpc.main.id
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Secrets — never in state or code
|
|
84
|
+
- Never put secrets in `terraform.tfvars` or hardcode them in `.tf` files
|
|
85
|
+
- Use `data "aws_secretsmanager_secret_version"` or `data "google_secret_manager_secret_version"` to read secrets at apply time
|
|
86
|
+
- Sensitive outputs: mark with `sensitive = true` to suppress in plan output
|
|
87
|
+
- `.gitignore` must include: `*.tfvars`, `*.tfstate`, `*.tfstate.backup`, `.terraform/`
|
|
88
|
+
|
|
89
|
+
### Resource naming conventions
|
|
90
|
+
```hcl
|
|
91
|
+
# Consistent naming: {project}-{environment}-{resource}-{suffix}
|
|
92
|
+
resource "aws_vpc" "main" {
|
|
93
|
+
cidr_block = var.vpc_cidr
|
|
94
|
+
tags = {
|
|
95
|
+
Name = "${var.project}-${var.environment}-vpc"
|
|
96
|
+
Environment = var.environment
|
|
97
|
+
ManagedBy = "terraform"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
Always tag every resource with `Environment` and `ManagedBy = "terraform"`.
|
|
102
|
+
|
|
103
|
+
### Plan before apply — always
|
|
104
|
+
- CI/CD pipeline: `terraform plan -out=tfplan` on PR, `terraform apply tfplan` on merge
|
|
105
|
+
- Never run `terraform apply` without a saved plan in production
|
|
106
|
+
- Use `-target` sparingly — it creates drift between real state and plan
|
|
107
|
+
|
|
108
|
+
### Common pitfalls
|
|
109
|
+
- `terraform destroy` with no `-target` destroys everything — always confirm scope
|
|
110
|
+
- Changing a resource attribute that forces replacement (e.g., VPC CIDR) deletes and recreates — check plan carefully
|
|
111
|
+
- Provider version pinning is mandatory: use `~> 5.0` not `>= 5.0`
|
|
112
|
+
- `count` vs `for_each`: use `for_each` with maps — `count` causes index drift when items are removed
|
|
113
|
+
|
|
114
|
+
## Example
|
|
115
|
+
|
|
116
|
+
**User:** Create a Terraform module for a private RDS PostgreSQL instance on AWS with Multi-AZ, encrypted storage, and a dedicated security group.
|
|
117
|
+
|
|
118
|
+
**Expected output structure:**
|
|
119
|
+
- `modules/rds/main.tf` — `aws_db_instance`, `aws_db_subnet_group`, `aws_security_group`
|
|
120
|
+
- `modules/rds/variables.tf` — instance class, engine version, db name, VPC/subnet IDs, ingress CIDR
|
|
121
|
+
- `modules/rds/outputs.tf` — endpoint, port, security group ID
|
|
122
|
+
- Security group: allows PostgreSQL (5432) only from app security group, no public access
|
|
123
|
+
- `storage_encrypted = true`, `multi_az = true`, `deletion_protection = true` for production
|
|
124
|
+
- Password via `aws_secretsmanager_secret` reference, never hardcoded
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Building cloud infrastructure or IaC pipelines? [uitbreiden.com](https://uitbreiden.com/)
|