env-secrets 0.2.0 → 0.3.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/.devcontainer/devcontainer.json +10 -6
- package/.dockerignore +9 -0
- package/.eslintignore +4 -2
- package/.github/dependabot.yml +4 -0
- package/.github/workflows/build-main.yml +6 -2
- package/.github/workflows/deploy-docs.yml +50 -0
- package/.github/workflows/e2e-tests.yaml +54 -0
- package/.github/workflows/lint.yaml +6 -2
- package/.github/workflows/release.yml +2 -2
- package/.github/workflows/snyk.yaml +5 -1
- package/.github/workflows/unittests.yaml +9 -66
- package/.lintstagedrc +2 -7
- package/.prettierignore +6 -0
- package/AGENTS.md +149 -0
- package/Dockerfile +14 -0
- package/README.md +331 -13
- package/__e2e__/README.md +160 -0
- package/__e2e__/index.test.ts +334 -32
- package/__e2e__/setup.ts +58 -0
- package/__e2e__/utils/debug-logger.ts +45 -0
- package/__e2e__/utils/test-utils.ts +645 -0
- package/__tests__/index.test.ts +266 -9
- package/__tests__/vaults/secretsmanager.test.ts +460 -0
- package/__tests__/vaults/utils.test.ts +9 -9
- package/dist/index.js +36 -10
- package/dist/vaults/secretsmanager.js +17 -5
- package/dist/vaults/utils.js +2 -2
- package/docker-compose.yaml +29 -0
- package/docs/AWS.md +257 -0
- package/jest.config.js +3 -1
- package/jest.e2e.config.js +8 -0
- package/package.json +10 -7
- package/src/index.ts +44 -10
- package/src/vaults/secretsmanager.ts +16 -5
- package/src/vaults/utils.ts +6 -4
- package/website/docs/advanced-usage.mdx +399 -0
- package/website/docs/best-practices.mdx +416 -0
- package/website/docs/cli-reference.mdx +204 -0
- package/website/docs/examples.mdx +960 -0
- package/website/docs/faq.mdx +302 -0
- package/website/docs/index.mdx +56 -0
- package/website/docs/installation.mdx +30 -0
- package/website/docs/overview.mdx +17 -0
- package/website/docs/production-deployment.mdx +622 -0
- package/website/docs/providers/aws-secrets-manager.mdx +28 -0
- package/website/docs/security.mdx +122 -0
- package/website/docs/troubleshooting.mdx +236 -0
- package/website/docs/tutorials/local-dev/devcontainer-localstack.mdx +31 -0
- package/website/docs/tutorials/local-dev/docker-compose.mdx +22 -0
- package/website/docs/tutorials/local-dev/nextjs.mdx +18 -0
- package/website/docs/tutorials/local-dev/node-python-go.mdx +39 -0
- package/website/docs/tutorials/local-dev/quickstart.mdx +23 -0
- package/website/docusaurus.config.ts +89 -0
- package/website/package.json +21 -0
- package/website/sidebars.ts +33 -0
- package/website/src/css/custom.css +1 -0
- package/website/static/img/env-secrets.png +0 -0
- package/website/static/img/favicon.ico +0 -0
- package/website/static/img/logo.svg +4 -0
- package/website/yarn.lock +8764 -0
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Examples
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Examples
|
|
6
|
+
|
|
7
|
+
This page provides comprehensive examples of how to use `env-secrets` in various scenarios.
|
|
8
|
+
|
|
9
|
+
## Basic Examples
|
|
10
|
+
|
|
11
|
+
### Simple Node.js Application
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Create a secret
|
|
15
|
+
aws secretsmanager create-secret \
|
|
16
|
+
--name myapp/config \
|
|
17
|
+
--secret-string '{
|
|
18
|
+
"DATABASE_URL": "postgres://user:pass@localhost:5432/myapp",
|
|
19
|
+
"API_KEY": "abc123",
|
|
20
|
+
"REDIS_URL": "redis://localhost:6379"
|
|
21
|
+
}'
|
|
22
|
+
|
|
23
|
+
# Run your application
|
|
24
|
+
env-secrets aws -s myapp/config -r us-east-1 -- node app.js
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// app.js
|
|
29
|
+
const express = require('express');
|
|
30
|
+
const app = express();
|
|
31
|
+
|
|
32
|
+
const port = process.env.PORT || 3000;
|
|
33
|
+
const dbUrl = process.env.DATABASE_URL;
|
|
34
|
+
const apiKey = process.env.API_KEY;
|
|
35
|
+
|
|
36
|
+
app.get('/', (req, res) => {
|
|
37
|
+
res.json({
|
|
38
|
+
message: 'Hello from env-secrets!',
|
|
39
|
+
database: dbUrl ? 'Connected' : 'Not configured',
|
|
40
|
+
apiKey: apiKey ? 'Set' : 'Missing'
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
app.listen(port, () => {
|
|
45
|
+
console.log(`Server running on port ${port}`);
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Python Application
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Create a secret for Python app
|
|
53
|
+
aws secretsmanager create-secret \
|
|
54
|
+
--name python-app/config \
|
|
55
|
+
--secret-string '{
|
|
56
|
+
"DATABASE_URL": "postgresql://user:pass@localhost:5432/pyapp",
|
|
57
|
+
"SECRET_KEY": "your-secret-key-here",
|
|
58
|
+
"DEBUG": "False"
|
|
59
|
+
}'
|
|
60
|
+
|
|
61
|
+
# Run Python application
|
|
62
|
+
env-secrets aws -s python-app/config -r us-east-1 -- python app.py
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# app.py
|
|
67
|
+
import os
|
|
68
|
+
from flask import Flask
|
|
69
|
+
|
|
70
|
+
app = Flask(__name__)
|
|
71
|
+
|
|
72
|
+
@app.route('/')
|
|
73
|
+
def hello():
|
|
74
|
+
return {
|
|
75
|
+
'message': 'Hello from Python!',
|
|
76
|
+
'database': os.getenv('DATABASE_URL', 'Not set'),
|
|
77
|
+
'debug': os.getenv('DEBUG', 'Not set')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if __name__ == '__main__':
|
|
81
|
+
app.run(host='0.0.0.0', port=5000)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Go Application
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Create a secret for Go app
|
|
88
|
+
aws secretsmanager create-secret \
|
|
89
|
+
--name go-app/config \
|
|
90
|
+
--secret-string '{
|
|
91
|
+
"DB_HOST": "localhost",
|
|
92
|
+
"DB_PORT": "5432",
|
|
93
|
+
"DB_NAME": "goapp",
|
|
94
|
+
"API_KEY": "go-api-key-123"
|
|
95
|
+
}'
|
|
96
|
+
|
|
97
|
+
# Run Go application
|
|
98
|
+
env-secrets aws -s go-app/config -r us-east-1 -- go run main.go
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```go
|
|
102
|
+
// main.go
|
|
103
|
+
package main
|
|
104
|
+
|
|
105
|
+
import (
|
|
106
|
+
"fmt"
|
|
107
|
+
"net/http"
|
|
108
|
+
"os"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
func main() {
|
|
112
|
+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
113
|
+
fmt.Fprintf(w, "Hello from Go!\n")
|
|
114
|
+
fmt.Fprintf(w, "DB Host: %s\n", os.Getenv("DB_HOST"))
|
|
115
|
+
fmt.Fprintf(w, "API Key: %s\n", os.Getenv("API_KEY"))
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
http.ListenAndServe(":8080", nil)
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Docker Examples
|
|
123
|
+
|
|
124
|
+
### Basic Docker Container
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Run container with secrets
|
|
128
|
+
env-secrets aws -s docker-app/config -r us-east-1 -- docker run \
|
|
129
|
+
-e DATABASE_URL \
|
|
130
|
+
-e API_KEY \
|
|
131
|
+
-e REDIS_URL \
|
|
132
|
+
-p 3000:3000 \
|
|
133
|
+
myapp:latest
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Docker Compose
|
|
137
|
+
|
|
138
|
+
```yaml
|
|
139
|
+
# docker-compose.yml
|
|
140
|
+
version: '3.8'
|
|
141
|
+
services:
|
|
142
|
+
app:
|
|
143
|
+
build: .
|
|
144
|
+
environment:
|
|
145
|
+
- DATABASE_URL
|
|
146
|
+
- API_KEY
|
|
147
|
+
- REDIS_URL
|
|
148
|
+
ports:
|
|
149
|
+
- '3000:3000'
|
|
150
|
+
depends_on:
|
|
151
|
+
- redis
|
|
152
|
+
- postgres
|
|
153
|
+
|
|
154
|
+
redis:
|
|
155
|
+
image: redis:alpine
|
|
156
|
+
ports:
|
|
157
|
+
- '6379:6379'
|
|
158
|
+
|
|
159
|
+
postgres:
|
|
160
|
+
image: postgres:13
|
|
161
|
+
environment:
|
|
162
|
+
POSTGRES_DB: myapp
|
|
163
|
+
POSTGRES_USER: user
|
|
164
|
+
POSTGRES_PASSWORD: password
|
|
165
|
+
ports:
|
|
166
|
+
- '5432:5432'
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Run with secrets
|
|
171
|
+
env-secrets aws -s docker-app/config -r us-east-1 -- docker-compose up
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Multi-Stage Dockerfile
|
|
175
|
+
|
|
176
|
+
```dockerfile
|
|
177
|
+
# Dockerfile
|
|
178
|
+
FROM node:18-alpine AS builder
|
|
179
|
+
WORKDIR /app
|
|
180
|
+
COPY package*.json ./
|
|
181
|
+
RUN npm ci --only=production
|
|
182
|
+
|
|
183
|
+
FROM node:18-alpine
|
|
184
|
+
WORKDIR /app
|
|
185
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
186
|
+
COPY . .
|
|
187
|
+
|
|
188
|
+
# Install env-secrets
|
|
189
|
+
RUN npm install -g env-secrets
|
|
190
|
+
|
|
191
|
+
# Use env-secrets as entrypoint
|
|
192
|
+
ENTRYPOINT ["env-secrets", "aws", "-s", "docker/app", "-r", "us-east-1", "--"]
|
|
193
|
+
CMD ["node", "app.js"]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Kubernetes Examples
|
|
197
|
+
|
|
198
|
+
### Basic Deployment
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
# deployment.yaml
|
|
202
|
+
apiVersion: apps/v1
|
|
203
|
+
kind: Deployment
|
|
204
|
+
metadata:
|
|
205
|
+
name: myapp
|
|
206
|
+
spec:
|
|
207
|
+
replicas: 3
|
|
208
|
+
selector:
|
|
209
|
+
matchLabels:
|
|
210
|
+
app: myapp
|
|
211
|
+
template:
|
|
212
|
+
metadata:
|
|
213
|
+
labels:
|
|
214
|
+
app: myapp
|
|
215
|
+
spec:
|
|
216
|
+
serviceAccountName: myapp-sa
|
|
217
|
+
containers:
|
|
218
|
+
- name: app
|
|
219
|
+
image: myapp:latest
|
|
220
|
+
command: ['env-secrets']
|
|
221
|
+
args:
|
|
222
|
+
[
|
|
223
|
+
'aws',
|
|
224
|
+
'-s',
|
|
225
|
+
'k8s/myapp',
|
|
226
|
+
'-r',
|
|
227
|
+
'us-east-1',
|
|
228
|
+
'--',
|
|
229
|
+
'node',
|
|
230
|
+
'app.js'
|
|
231
|
+
]
|
|
232
|
+
ports:
|
|
233
|
+
- containerPort: 3000
|
|
234
|
+
env:
|
|
235
|
+
- name: AWS_REGION
|
|
236
|
+
value: 'us-east-1'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Service Account
|
|
240
|
+
|
|
241
|
+
```yaml
|
|
242
|
+
# service-account.yaml
|
|
243
|
+
apiVersion: v1
|
|
244
|
+
kind: ServiceAccount
|
|
245
|
+
metadata:
|
|
246
|
+
name: myapp-sa
|
|
247
|
+
annotations:
|
|
248
|
+
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/myapp-role
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### ConfigMap for Configuration
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
# configmap.yaml
|
|
255
|
+
apiVersion: v1
|
|
256
|
+
kind: ConfigMap
|
|
257
|
+
metadata:
|
|
258
|
+
name: myapp-config
|
|
259
|
+
data:
|
|
260
|
+
AWS_REGION: 'us-east-1'
|
|
261
|
+
SECRET_NAME: 'k8s/myapp'
|
|
262
|
+
NODE_ENV: 'production'
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## CI/CD Examples
|
|
266
|
+
|
|
267
|
+
### GitHub Actions
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
# .github/workflows/deploy.yml
|
|
271
|
+
name: Deploy to Production
|
|
272
|
+
|
|
273
|
+
on:
|
|
274
|
+
push:
|
|
275
|
+
branches: [main]
|
|
276
|
+
|
|
277
|
+
jobs:
|
|
278
|
+
test:
|
|
279
|
+
runs-on: ubuntu-latest
|
|
280
|
+
steps:
|
|
281
|
+
- uses: actions/checkout@v3
|
|
282
|
+
|
|
283
|
+
- name: Setup Node.js
|
|
284
|
+
uses: actions/setup-node@v3
|
|
285
|
+
with:
|
|
286
|
+
node-version: '18'
|
|
287
|
+
|
|
288
|
+
- name: Configure AWS credentials
|
|
289
|
+
uses: aws-actions/configure-aws-credentials@v2
|
|
290
|
+
with:
|
|
291
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
292
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
293
|
+
aws-region: us-east-1
|
|
294
|
+
|
|
295
|
+
- name: Install env-secrets
|
|
296
|
+
run: npm install -g env-secrets
|
|
297
|
+
|
|
298
|
+
- name: Run tests with secrets
|
|
299
|
+
run: env-secrets aws -s test/myapp -r us-east-1 -- npm test
|
|
300
|
+
|
|
301
|
+
deploy:
|
|
302
|
+
needs: test
|
|
303
|
+
runs-on: ubuntu-latest
|
|
304
|
+
steps:
|
|
305
|
+
- uses: actions/checkout@v3
|
|
306
|
+
|
|
307
|
+
- name: Setup Node.js
|
|
308
|
+
uses: actions/setup-node@v3
|
|
309
|
+
with:
|
|
310
|
+
node-version: '18'
|
|
311
|
+
|
|
312
|
+
- name: Configure AWS credentials
|
|
313
|
+
uses: aws-actions/configure-aws-credentials@v2
|
|
314
|
+
with:
|
|
315
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
316
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
317
|
+
aws-region: us-east-1
|
|
318
|
+
|
|
319
|
+
- name: Install env-secrets
|
|
320
|
+
run: npm install -g env-secrets
|
|
321
|
+
|
|
322
|
+
- name: Deploy with secrets
|
|
323
|
+
run: env-secrets aws -s prod/myapp -r us-east-1 -- npm run deploy
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### GitLab CI
|
|
327
|
+
|
|
328
|
+
```yaml
|
|
329
|
+
# .gitlab-ci.yml
|
|
330
|
+
stages:
|
|
331
|
+
- test
|
|
332
|
+
- deploy
|
|
333
|
+
|
|
334
|
+
variables:
|
|
335
|
+
AWS_REGION: us-east-1
|
|
336
|
+
|
|
337
|
+
test:
|
|
338
|
+
stage: test
|
|
339
|
+
image: node:18
|
|
340
|
+
before_script:
|
|
341
|
+
- npm install -g env-secrets
|
|
342
|
+
script:
|
|
343
|
+
- env-secrets aws -s test/myapp -r $AWS_REGION -- npm test
|
|
344
|
+
environment:
|
|
345
|
+
name: test
|
|
346
|
+
|
|
347
|
+
deploy:
|
|
348
|
+
stage: deploy
|
|
349
|
+
image: node:18
|
|
350
|
+
before_script:
|
|
351
|
+
- npm install -g env-secrets
|
|
352
|
+
script:
|
|
353
|
+
- env-secrets aws -s prod/myapp -r $AWS_REGION -- npm run deploy
|
|
354
|
+
environment:
|
|
355
|
+
name: production
|
|
356
|
+
only:
|
|
357
|
+
- main
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Database Examples
|
|
361
|
+
|
|
362
|
+
### PostgreSQL with Prisma
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# Create database secret
|
|
366
|
+
aws secretsmanager create-secret \
|
|
367
|
+
--name myapp/database \
|
|
368
|
+
--secret-string '{
|
|
369
|
+
"DATABASE_URL": "postgresql://user:password@localhost:5432/myapp?schema=public",
|
|
370
|
+
"DB_HOST": "localhost",
|
|
371
|
+
"DB_PORT": "5432",
|
|
372
|
+
"DB_NAME": "myapp",
|
|
373
|
+
"DB_USER": "user",
|
|
374
|
+
"DB_PASSWORD": "password"
|
|
375
|
+
}'
|
|
376
|
+
|
|
377
|
+
# Run with Prisma
|
|
378
|
+
env-secrets aws -s myapp/database -r us-east-1 -- npx prisma migrate deploy
|
|
379
|
+
env-secrets aws -s myapp/database -r us-east-1 -- npm start
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
// prisma/schema.prisma
|
|
384
|
+
generator client {
|
|
385
|
+
provider = "prisma-client-js"
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
datasource db {
|
|
389
|
+
provider = "postgresql"
|
|
390
|
+
url = env("DATABASE_URL")
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
model User {
|
|
394
|
+
id Int @id @default(autoincrement())
|
|
395
|
+
email String @unique
|
|
396
|
+
name String?
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### MongoDB with Mongoose
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Create MongoDB secret
|
|
404
|
+
aws secretsmanager create-secret \
|
|
405
|
+
--name myapp/mongodb \
|
|
406
|
+
--secret-string '{
|
|
407
|
+
"MONGODB_URI": "mongodb://user:password@localhost:27017/myapp",
|
|
408
|
+
"DB_NAME": "myapp"
|
|
409
|
+
}'
|
|
410
|
+
|
|
411
|
+
# Run application
|
|
412
|
+
env-secrets aws -s myapp/mongodb -r us-east-1 -- node app.js
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
```javascript
|
|
416
|
+
// app.js
|
|
417
|
+
const mongoose = require('mongoose');
|
|
418
|
+
|
|
419
|
+
mongoose.connect(process.env.MONGODB_URI, {
|
|
420
|
+
useNewUrlParser: true,
|
|
421
|
+
useUnifiedTopology: true
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
const db = mongoose.connection;
|
|
425
|
+
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
|
|
426
|
+
db.once('open', () => {
|
|
427
|
+
console.log('Connected to MongoDB');
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
## API Examples
|
|
432
|
+
|
|
433
|
+
### Express.js with External APIs
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# Create API secret
|
|
437
|
+
aws secretsmanager create-secret \
|
|
438
|
+
--name myapp/apis \
|
|
439
|
+
--secret-string '{
|
|
440
|
+
"STRIPE_SECRET_KEY": "sk_test_...",
|
|
441
|
+
"SENDGRID_API_KEY": "SG...",
|
|
442
|
+
"TWILIO_AUTH_TOKEN": "your-twilio-token",
|
|
443
|
+
"JWT_SECRET": "your-jwt-secret"
|
|
444
|
+
}'
|
|
445
|
+
|
|
446
|
+
# Run API server
|
|
447
|
+
env-secrets aws -s myapp/apis -r us-east-1 -- node server.js
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// server.js
|
|
452
|
+
const express = require('express');
|
|
453
|
+
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
|
|
454
|
+
const sgMail = require('@sendgrid/mail');
|
|
455
|
+
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
|
|
456
|
+
|
|
457
|
+
const app = express();
|
|
458
|
+
|
|
459
|
+
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
|
|
460
|
+
const sig = req.headers['stripe-signature'];
|
|
461
|
+
const event = stripe.webhooks.constructEvent(
|
|
462
|
+
req.body,
|
|
463
|
+
sig,
|
|
464
|
+
process.env.STRIPE_WEBHOOK_SECRET
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
// Handle webhook
|
|
468
|
+
res.json({ received: true });
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
app.listen(3000, () => {
|
|
472
|
+
console.log('API server running on port 3000');
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## Environment-Specific Examples
|
|
477
|
+
|
|
478
|
+
### Development Environment
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
# Development secrets
|
|
482
|
+
aws secretsmanager create-secret \
|
|
483
|
+
--name dev/myapp \
|
|
484
|
+
--secret-string '{
|
|
485
|
+
"DATABASE_URL": "postgresql://dev:dev@localhost:5432/dev",
|
|
486
|
+
"API_KEY": "dev-key-123",
|
|
487
|
+
"DEBUG": "true",
|
|
488
|
+
"LOG_LEVEL": "debug"
|
|
489
|
+
}'
|
|
490
|
+
|
|
491
|
+
# Run in development
|
|
492
|
+
env-secrets aws -s dev/myapp -r us-east-1 -- npm run dev
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Staging Environment
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
# Staging secrets
|
|
499
|
+
aws secretsmanager create-secret \
|
|
500
|
+
--name staging/myapp \
|
|
501
|
+
--secret-string '{
|
|
502
|
+
"DATABASE_URL": "postgresql://staging:staging@staging-db:5432/staging",
|
|
503
|
+
"API_KEY": "staging-key-456",
|
|
504
|
+
"DEBUG": "false",
|
|
505
|
+
"LOG_LEVEL": "info"
|
|
506
|
+
}'
|
|
507
|
+
|
|
508
|
+
# Run in staging
|
|
509
|
+
env-secrets aws -s staging/myapp -r us-east-1 -- npm start
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Production Environment
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
# Production secrets
|
|
516
|
+
aws secretsmanager create-secret \
|
|
517
|
+
--name prod/myapp \
|
|
518
|
+
--secret-string '{
|
|
519
|
+
"DATABASE_URL": "postgresql://prod:prod@prod-db:5432/prod",
|
|
520
|
+
"API_KEY": "prod-key-789",
|
|
521
|
+
"DEBUG": "false",
|
|
522
|
+
"LOG_LEVEL": "warn"
|
|
523
|
+
}'
|
|
524
|
+
|
|
525
|
+
# Run in production
|
|
526
|
+
env-secrets aws -s prod/myapp -r us-east-1 -- npm start
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Monitoring Examples
|
|
530
|
+
|
|
531
|
+
### Health Check Script
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
#!/bin/bash
|
|
535
|
+
# health-check.sh
|
|
536
|
+
|
|
537
|
+
SECRET_NAME="prod/myapp"
|
|
538
|
+
REGION="us-east-1"
|
|
539
|
+
|
|
540
|
+
# Check if secrets are accessible
|
|
541
|
+
if env-secrets aws -s "$SECRET_NAME" -r "$REGION" -- echo "OK" 2>/dev/null; then
|
|
542
|
+
echo "✓ Secrets accessible"
|
|
543
|
+
|
|
544
|
+
# Check if application is healthy
|
|
545
|
+
if env-secrets aws -s "$SECRET_NAME" -r "$REGION" -- curl -f http://localhost:3000/health; then
|
|
546
|
+
echo "✓ Application healthy"
|
|
547
|
+
exit 0
|
|
548
|
+
else
|
|
549
|
+
echo "✗ Application unhealthy"
|
|
550
|
+
exit 1
|
|
551
|
+
fi
|
|
552
|
+
else
|
|
553
|
+
echo "✗ Secrets not accessible"
|
|
554
|
+
exit 1
|
|
555
|
+
fi
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Application Health Endpoint
|
|
559
|
+
|
|
560
|
+
```javascript
|
|
561
|
+
// health.js
|
|
562
|
+
app.get('/health', (req, res) => {
|
|
563
|
+
const requiredVars = ['DATABASE_URL', 'API_KEY'];
|
|
564
|
+
const missing = requiredVars.filter(var => !process.env[var]);
|
|
565
|
+
|
|
566
|
+
if (missing.length > 0) {
|
|
567
|
+
res.status(503).json({
|
|
568
|
+
status: 'unhealthy',
|
|
569
|
+
missing: missing,
|
|
570
|
+
timestamp: new Date().toISOString()
|
|
571
|
+
});
|
|
572
|
+
} else {
|
|
573
|
+
res.json({
|
|
574
|
+
status: 'healthy',
|
|
575
|
+
timestamp: new Date().toISOString(),
|
|
576
|
+
environment: process.env.NODE_ENV || 'development'
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
## Creating Local secrets.env Files
|
|
583
|
+
|
|
584
|
+
The `-o` option allows you to write secrets to a local file instead of injecting them directly into environment variables. This is particularly useful for development workflows, CI/CD pipelines, and scenarios where you need to share environment variables across multiple processes.
|
|
585
|
+
|
|
586
|
+
### Prerequisites
|
|
587
|
+
|
|
588
|
+
To use the generated `.env` files, you'll need to install [`dotenv-cli`](https://www.npmjs.com/package/dotenv-cli) or [`dotenv`](https://www.npmjs.com/package/dotenv):
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# Install dotenv-cli globally
|
|
592
|
+
npm install -g dotenv-cli
|
|
593
|
+
|
|
594
|
+
# Or install dotenv locally
|
|
595
|
+
npm install --save-dev dotenv
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Basic File Output
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
# Output secrets to a file
|
|
602
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
603
|
+
|
|
604
|
+
# File content (secrets.env):
|
|
605
|
+
# DATABASE_URL=postgres://user:pass@localhost:5432/myapp
|
|
606
|
+
# API_KEY=abc123
|
|
607
|
+
# REDIS_URL=redis://localhost:6379
|
|
608
|
+
|
|
609
|
+
# Use the file with dotenv-cli
|
|
610
|
+
dotenv -- node app.js
|
|
611
|
+
|
|
612
|
+
# Use the file with dotenv
|
|
613
|
+
node -r dotenv/config app.js
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Creating secrets.env for Local Development
|
|
617
|
+
|
|
618
|
+
This is one of the most common use cases - creating a local `secrets.env` file for development:
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
# Create a development secrets file
|
|
622
|
+
env-secrets aws -s dev/myapp -r us-east-1 -o secrets.env
|
|
623
|
+
|
|
624
|
+
# The file will contain your development secrets:
|
|
625
|
+
# DATABASE_URL=postgresql://dev:dev@localhost:5432/dev
|
|
626
|
+
# API_KEY=dev-key-123
|
|
627
|
+
# DEBUG=true
|
|
628
|
+
# LOG_LEVEL=debug
|
|
629
|
+
|
|
630
|
+
# Source the file and run your application
|
|
631
|
+
dotenv -- npm run dev
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### File Security Features
|
|
635
|
+
|
|
636
|
+
The `-o` option includes several security features:
|
|
637
|
+
|
|
638
|
+
```bash
|
|
639
|
+
# Files are created with 0400 permissions (read-only for owner)
|
|
640
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
641
|
+
ls -la secrets.env
|
|
642
|
+
# -r-------- 1 user user 123 Jan 1 12:00 secrets.env
|
|
643
|
+
|
|
644
|
+
# Existing files are never overwritten for safety
|
|
645
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
646
|
+
# Error: File secrets.env already exists and will not be overwritten
|
|
647
|
+
|
|
648
|
+
# To update an existing file, delete it first
|
|
649
|
+
rm secrets.env
|
|
650
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Integration with Different Environments
|
|
654
|
+
|
|
655
|
+
#### Node.js Applications
|
|
656
|
+
|
|
657
|
+
```bash
|
|
658
|
+
# Create .env for Node.js
|
|
659
|
+
env-secrets aws -s node-app/config -r us-east-1 -o .env
|
|
660
|
+
|
|
661
|
+
# Use with dotenv-cli
|
|
662
|
+
dotenv -- node app.js
|
|
663
|
+
|
|
664
|
+
# Alternative: Use Node.js built-in dotenv support
|
|
665
|
+
node -r dotenv/config app.js
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
```javascript
|
|
669
|
+
// app.js
|
|
670
|
+
console.log('Database URL:', process.env.DATABASE_URL);
|
|
671
|
+
console.log('API Key:', process.env.API_KEY);
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
#### Python Applications
|
|
675
|
+
|
|
676
|
+
```bash
|
|
677
|
+
# Create .env for Python
|
|
678
|
+
env-secrets aws -s python-app/config -r us-east-1 -o .env
|
|
679
|
+
|
|
680
|
+
# load_dotenv
|
|
681
|
+
pip install python-dotenv
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
```python
|
|
685
|
+
# app.py
|
|
686
|
+
import os
|
|
687
|
+
from dotenv import load_dotenv
|
|
688
|
+
|
|
689
|
+
load_dotenv()
|
|
690
|
+
|
|
691
|
+
# load_env automatically loads the secrets.env file
|
|
692
|
+
print(f"Database URL: {os.getenv('DATABASE_URL')}")
|
|
693
|
+
print(f"API Key: {os.getenv('API_KEY')}")
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
#### Docker Development
|
|
697
|
+
|
|
698
|
+
```bash
|
|
699
|
+
# Create .env file for Docker
|
|
700
|
+
env-secrets aws -s docker-app/config -r us-east-1 -o .env
|
|
701
|
+
|
|
702
|
+
# Use with Docker
|
|
703
|
+
docker run --env-file .env -p 3000:3000 myapp:latest
|
|
704
|
+
|
|
705
|
+
# Or with docker-compose
|
|
706
|
+
docker-compose up
|
|
707
|
+
|
|
708
|
+
# Or use dotenv-cli for local development
|
|
709
|
+
dotenv -- docker-compose up
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
```yaml
|
|
713
|
+
# docker-compose.yml
|
|
714
|
+
version: '3.8'
|
|
715
|
+
services:
|
|
716
|
+
app:
|
|
717
|
+
build: .
|
|
718
|
+
env_file:
|
|
719
|
+
- .env
|
|
720
|
+
ports:
|
|
721
|
+
- '3000:3000'
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
### CI/CD Pipeline Integration
|
|
725
|
+
|
|
726
|
+
#### GitHub Actions
|
|
727
|
+
|
|
728
|
+
```yaml
|
|
729
|
+
# .github/workflows/deploy.yml
|
|
730
|
+
name: Deploy with Secrets
|
|
731
|
+
|
|
732
|
+
on:
|
|
733
|
+
push:
|
|
734
|
+
branches: [main]
|
|
735
|
+
|
|
736
|
+
jobs:
|
|
737
|
+
deploy:
|
|
738
|
+
runs-on: ubuntu-latest
|
|
739
|
+
steps:
|
|
740
|
+
- uses: actions/checkout@v3
|
|
741
|
+
|
|
742
|
+
- name: Configure AWS credentials
|
|
743
|
+
uses: aws-actions/configure-aws-credentials@v2
|
|
744
|
+
with:
|
|
745
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
746
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
747
|
+
aws-region: us-east-1
|
|
748
|
+
|
|
749
|
+
- name: Install env-secrets
|
|
750
|
+
run: npm install -g env-secrets dotenv-cli
|
|
751
|
+
|
|
752
|
+
- name: Generate secrets file
|
|
753
|
+
run: env-secrets aws -s prod/myapp -r us-east-1 -o .env
|
|
754
|
+
|
|
755
|
+
- name: Deploy with secrets
|
|
756
|
+
run: |
|
|
757
|
+
dotenv -- npm run deploy
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
#### GitLab CI
|
|
761
|
+
|
|
762
|
+
```yaml
|
|
763
|
+
# .gitlab-ci.yml
|
|
764
|
+
deploy:
|
|
765
|
+
stage: deploy
|
|
766
|
+
image: node:18
|
|
767
|
+
before_script:
|
|
768
|
+
- npm install -g env-secrets dotenv-cli
|
|
769
|
+
script:
|
|
770
|
+
- env-secrets aws -s prod/myapp -r us-east-1 -o .env
|
|
771
|
+
- dotenv -- npm run deploy
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### Advanced File Output Examples
|
|
775
|
+
|
|
776
|
+
#### Multiple Environment Files
|
|
777
|
+
|
|
778
|
+
```bash
|
|
779
|
+
# Create environment-specific files
|
|
780
|
+
env-secrets aws -s dev/myapp -r us-east-1 -o dev.env
|
|
781
|
+
env-secrets aws -s staging/myapp -r us-east-1 -o staging.env
|
|
782
|
+
env-secrets aws -s prod/myapp -r us-east-1 -o prod.env
|
|
783
|
+
|
|
784
|
+
# Use the appropriate file for your environment
|
|
785
|
+
if [ "$NODE_ENV" = "production" ]; then
|
|
786
|
+
dotenv -e prod.env -- node app.js
|
|
787
|
+
elif [ "$NODE_ENV" = "staging" ]; then
|
|
788
|
+
dotenv -e staging.env -- node app.js
|
|
789
|
+
else
|
|
790
|
+
dotenv -e dev.env -- node app.js
|
|
791
|
+
fi
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
#### Shared Secrets Across Services
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
# Create a shared secrets file for microservices
|
|
798
|
+
env-secrets aws -s shared/config -r us-east-1 -o shared-secrets.env
|
|
799
|
+
|
|
800
|
+
# Use in multiple services
|
|
801
|
+
dotenv -e shared-secrets.env -- node service-a.js &
|
|
802
|
+
dotenv -e shared-secrets.env -- node service-b.js &
|
|
803
|
+
dotenv -e shared-secrets.env -- node service-c.js &
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
#### Kubernetes Init Container Pattern
|
|
807
|
+
|
|
808
|
+
```bash
|
|
809
|
+
# Generate secrets file in init container
|
|
810
|
+
env-secrets aws -s k8s/myapp -r us-east-1 -o /shared/secrets.env
|
|
811
|
+
|
|
812
|
+
# Use in main container
|
|
813
|
+
dotenv -e /shared/secrets.env -- node app.js
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Troubleshooting File Output
|
|
817
|
+
|
|
818
|
+
#### Common Issues
|
|
819
|
+
|
|
820
|
+
```bash
|
|
821
|
+
# Check if file was created successfully
|
|
822
|
+
ls -la secrets.env
|
|
823
|
+
|
|
824
|
+
# Verify file permissions
|
|
825
|
+
stat secrets.env
|
|
826
|
+
|
|
827
|
+
# Check file contents
|
|
828
|
+
cat secrets.env
|
|
829
|
+
|
|
830
|
+
# Test loading the file
|
|
831
|
+
dotenv -e secrets.env -- echo $DATABASE_URL
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
#### File Permission Issues
|
|
835
|
+
|
|
836
|
+
```bash
|
|
837
|
+
# If you need to modify permissions later
|
|
838
|
+
chmod 600 secrets.env # Read/write for owner only
|
|
839
|
+
chmod 644 secrets.env # Read for owner and group
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
#### File Not Found Errors
|
|
843
|
+
|
|
844
|
+
```bash
|
|
845
|
+
# Make sure the file exists before using
|
|
846
|
+
if [ -f "secrets.env" ]; then
|
|
847
|
+
dotenv -e secrets.env -- node app.js
|
|
848
|
+
else
|
|
849
|
+
echo "Error: secrets.env not found"
|
|
850
|
+
exit 1
|
|
851
|
+
fi
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
## File Output Examples
|
|
855
|
+
|
|
856
|
+
### Basic File Output
|
|
857
|
+
|
|
858
|
+
```bash
|
|
859
|
+
# Output secrets to a file
|
|
860
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
861
|
+
|
|
862
|
+
# File content (secrets.env):
|
|
863
|
+
# DATABASE_URL=postgres://user:pass@localhost:5432/myapp
|
|
864
|
+
# API_KEY=abc123
|
|
865
|
+
# REDIS_URL=redis://localhost:6379
|
|
866
|
+
|
|
867
|
+
# Use the file with dotenv-cli
|
|
868
|
+
dotenv -- node app.js
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
### Docker with File Output
|
|
872
|
+
|
|
873
|
+
```bash
|
|
874
|
+
# Generate environment file for Docker
|
|
875
|
+
env-secrets aws -s docker-app/config -r us-east-1 -o .env
|
|
876
|
+
|
|
877
|
+
# Use with Docker
|
|
878
|
+
docker run --env-file .env -p 3000:3000 myapp:latest
|
|
879
|
+
|
|
880
|
+
# Or with docker-compose
|
|
881
|
+
docker-compose up
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
### CI/CD with File Output
|
|
885
|
+
|
|
886
|
+
```bash
|
|
887
|
+
# GitHub Actions example
|
|
888
|
+
- name: Generate secrets file
|
|
889
|
+
run: env-secrets aws -s prod/myapp -r us-east-1 -o .env
|
|
890
|
+
|
|
891
|
+
- name: Deploy with secrets
|
|
892
|
+
run: |
|
|
893
|
+
source .env
|
|
894
|
+
npm run deploy
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
### Kubernetes with File Output
|
|
898
|
+
|
|
899
|
+
```bash
|
|
900
|
+
# Generate secrets file in init container
|
|
901
|
+
env-secrets aws -s k8s/myapp -r us-east-1 -o /shared/secrets.env
|
|
902
|
+
|
|
903
|
+
# Use in main container
|
|
904
|
+
dotenv -e /shared/secrets.env -- node app.js
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
### File Security Features
|
|
908
|
+
|
|
909
|
+
```bash
|
|
910
|
+
# File permissions are automatically set to 0400 (read-only for owner)
|
|
911
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
912
|
+
ls -la secrets.env
|
|
913
|
+
# -r-------- 1 user user 123 Jan 1 12:00 secrets.env
|
|
914
|
+
|
|
915
|
+
# Existing files are never overwritten
|
|
916
|
+
env-secrets aws -s myapp/config -r us-east-1 -o secrets.env
|
|
917
|
+
# Error: File secrets.env already exists and will not be overwritten
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
## Debug Examples
|
|
921
|
+
|
|
922
|
+
### Debug Mode
|
|
923
|
+
|
|
924
|
+
```bash
|
|
925
|
+
# Basic debug
|
|
926
|
+
DEBUG=env-secrets env-secrets aws -s myapp/config -r us-east-1 -- node app.js
|
|
927
|
+
|
|
928
|
+
# Detailed debug
|
|
929
|
+
DEBUG=env-secrets,env-secrets:secretsmanager env-secrets aws -s myapp/config -r us-east-1 -- node app.js
|
|
930
|
+
|
|
931
|
+
# AWS SDK debug
|
|
932
|
+
DEBUG=env-secrets,aws-sdk:* env-secrets aws -s myapp/config -r us-east-1 -- node app.js
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
### Environment Variable Inspection
|
|
936
|
+
|
|
937
|
+
```bash
|
|
938
|
+
# Check what variables are injected
|
|
939
|
+
env-secrets aws -s myapp/config -r us-east-1 -- env | grep -E "(DATABASE|API|SECRET)"
|
|
940
|
+
|
|
941
|
+
# Check specific variables
|
|
942
|
+
env-secrets aws -s myapp/config -r us-east-1 -- bash -c '
|
|
943
|
+
echo "Database URL: $DATABASE_URL"
|
|
944
|
+
echo "API Key: $API_KEY"
|
|
945
|
+
echo "Redis URL: $REDIS_URL"
|
|
946
|
+
'
|
|
947
|
+
|
|
948
|
+
# Validate required variables
|
|
949
|
+
env-secrets aws -s myapp/config -r us-east-1 -- bash -c '
|
|
950
|
+
required=("DATABASE_URL" "API_KEY")
|
|
951
|
+
for var in "${required[@]}"; do
|
|
952
|
+
if [ -z "${!var}" ]; then
|
|
953
|
+
echo "ERROR: Missing $var"
|
|
954
|
+
exit 1
|
|
955
|
+
fi
|
|
956
|
+
echo "✓ $var is set"
|
|
957
|
+
done
|
|
958
|
+
echo "All required variables are present"
|
|
959
|
+
'
|
|
960
|
+
```
|