envilder 0.8.0 → 0.9.1
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/README.md +2 -1
- package/ROADMAP.md +77 -18
- package/docs/CHANGELOG.md +0 -102
- package/lib/iac/bin/main.d.ts +28 -0
- package/lib/iac/bin/main.d.ts.map +1 -0
- package/lib/iac/bin/main.js +201 -0
- package/lib/iac/bin/main.js.map +1 -0
- package/lib/iac/lib/core/types.d.ts +5 -0
- package/lib/iac/lib/core/types.d.ts.map +1 -0
- package/lib/iac/lib/core/types.js +9 -0
- package/lib/iac/lib/core/types.js.map +1 -0
- package/lib/iac/lib/stacks/customStack.d.ts +23 -0
- package/lib/iac/lib/stacks/customStack.d.ts.map +1 -0
- package/lib/iac/lib/stacks/customStack.js +34 -0
- package/lib/iac/lib/stacks/customStack.js.map +1 -0
- package/lib/iac/lib/stacks/staticWebsiteStack.d.ts +10 -0
- package/lib/iac/lib/stacks/staticWebsiteStack.d.ts.map +1 -0
- package/lib/iac/lib/stacks/staticWebsiteStack.js +163 -0
- package/lib/iac/lib/stacks/staticWebsiteStack.js.map +1 -0
- package/lib/iac/lib/stacks/utils.d.ts +6 -0
- package/lib/iac/lib/stacks/utils.d.ts.map +1 -0
- package/lib/iac/lib/stacks/utils.js +18 -0
- package/lib/iac/lib/stacks/utils.js.map +1 -0
- package/package.json +24 -23
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 🗝️ Envilder ☁️
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="https://github.com/user-attachments/assets/
|
|
4
|
+
<img src="https://github.com/user-attachments/assets/8a7188ef-9d8d-45fb-8c37-3af718fb5103" alt="Envilder">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
@@ -246,6 +246,7 @@ Envilder is designed for automation, onboarding, and secure cloud-native workflo
|
|
|
246
246
|
|
|
247
247
|
### 📚 Quick Links
|
|
248
248
|
|
|
249
|
+
- [📖 Full Documentation](https://envilder.com) — Visit envilder.com for the complete guide
|
|
249
250
|
- [Requirements & Installation](docs/requirements-installation.md)
|
|
250
251
|
- [Push Command Guide](docs/push-command.md)
|
|
251
252
|
- [Pull Command Guide](docs/pull-command.md)
|
package/ROADMAP.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# 🛣️ Envilder Roadmap
|
|
2
2
|
|
|
3
|
-
Envilder
|
|
4
|
-
|
|
3
|
+
Envilder is evolving from a CLI tool into a **multi-runtime secret management platform**.
|
|
4
|
+
The goal: one declarative map-file format becomes the universal standard for resolving
|
|
5
|
+
environment variables from cloud secret stores (AWS SSM Parameter Store, AWS Secrets Manager,
|
|
6
|
+
Azure Key Vault, GCP Secret Manager) — whether in local development, CI/CD pipelines,
|
|
7
|
+
or directly inside application code at runtime.
|
|
5
8
|
|
|
9
|
+
> **Vision:** One map-file. Every cloud. Every language. Every runtime.
|
|
10
|
+
>
|
|
6
11
|
> **Note:** This roadmap contains ideas and potential features based on initial vision and community feedback.
|
|
7
12
|
> Not all features are guaranteed to be implemented. Priorities may change based on user needs, feedback,
|
|
8
13
|
> and real-world usage patterns. Your input matters—feel free to share your thoughts and suggestions!
|
|
@@ -13,27 +18,81 @@ Envilder aims to be the simplest, most reliable way to generate `.env` files fro
|
|
|
13
18
|
|
|
14
19
|
<!-- markdownlint-disable MD013 -->
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
20
|
-
| **
|
|
21
|
-
|
|
|
22
|
-
| **
|
|
23
|
-
| **
|
|
24
|
-
| **
|
|
25
|
-
| **
|
|
26
|
-
| **
|
|
27
|
-
| **Documentation website** |
|
|
28
|
-
| **
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
### ✅ Shipped
|
|
22
|
+
|
|
23
|
+
| Feature | Notes |
|
|
24
|
+
|---------|-------|
|
|
25
|
+
| **Mapping-based resolution** | Core functionality |
|
|
26
|
+
| **`.env` file generation** | Core functionality |
|
|
27
|
+
| **AWS SSM Parameter Store** | Default provider |
|
|
28
|
+
| **AWS profile support** | `--profile` flag |
|
|
29
|
+
| **Push mode** (`--push`) | [Guide](./docs/push-command.md) |
|
|
30
|
+
| **GitHub Action** | [Documentation](./github-action/README.md) |
|
|
31
|
+
| **Azure Key Vault** | Multi-backend via `$config` map-file section ([#90](https://github.com/macalbert/envilder/pull/90)) |
|
|
32
|
+
| **Documentation website** | [envilder.com](https://envilder.com) |
|
|
33
|
+
| **Onboarding documentation** | [Setup guide](./docs/requirements-installation.md) |
|
|
34
|
+
|
|
35
|
+
### 🔥 Up Next
|
|
36
|
+
|
|
37
|
+
| Feature | Priority | Notes |
|
|
38
|
+
|---------|----------|-------|
|
|
39
|
+
| **Exec mode** (`--exec`) | 🔴 High | Inject secrets into a child process env without writing to disk (`envilder exec -- node server.js`) |
|
|
40
|
+
| **TypeScript SDK** (`@envilder/sdk`) | 🔴 High | Native runtime library — load secrets directly into `process.env` from a map-file. No `.env` file needed. Published to npm |
|
|
41
|
+
| **GCP Secret Manager** | 🔴 High | Third cloud provider — similar DX to AWS SSM. Completes the multi-cloud trident (AWS + Azure + GCP) |
|
|
42
|
+
| **Map-file JSON Schema** | 🔴 High | Formal spec for the map-file format at `spec/` — serves as the contract between all SDKs and tools |
|
|
43
|
+
| **AWS Secrets Manager** | 🟡 Medium | Support AWS Secrets Manager alongside SSM Parameter Store for teams using JSON-structured secrets |
|
|
44
|
+
| **Python SDK** (`envilder`) | 🟡 Medium | Runtime library for Python — Django/FastAPI/data pipelines. Published to PyPI |
|
|
45
|
+
| **Check/sync mode** (`--check`) | 🟡 Medium | Validate cloud secrets vs local `.env`, fail CI if out-of-sync |
|
|
46
|
+
|
|
47
|
+
### 💡 Planned
|
|
48
|
+
|
|
49
|
+
| Feature | Priority | Notes |
|
|
50
|
+
|---------|----------|-------|
|
|
51
|
+
| **Go SDK** (`envilder`) | Medium | Runtime library for Go — cloud-native apps, Kubernetes tooling. Published as Go module |
|
|
52
|
+
| **.NET SDK** (`Envilder`) | Medium | Runtime library for .NET — enterprise apps, Azure-native shops. Published to NuGet |
|
|
53
|
+
| **Java SDK** (`envilder`) | Medium | Runtime library for Java/Kotlin — Spring Boot, Android backends. Published to Maven Central |
|
|
54
|
+
| **SDK conformance tests** | Medium | Language-agnostic test fixtures (JSON input → expected output) that all SDKs must pass |
|
|
55
|
+
| **Auto-discovery mode** (`--auto`) | Medium | Fetch all parameters matching a given prefix (e.g., `/my-app/prod/*`) |
|
|
56
|
+
| **Exec with refresh** (`--refresh-interval`) | Low | Kill & restart child process periodically with fresh secrets (requires `--exec`) |
|
|
57
|
+
| **Hierarchical mapping** | Low | Per-environment `param-map.json` with inheritance/overrides |
|
|
32
58
|
|
|
33
59
|
<!-- markdownlint-enable MD013 -->
|
|
34
60
|
|
|
35
61
|
---
|
|
36
62
|
|
|
63
|
+
## 🏗️ Platform Architecture
|
|
64
|
+
|
|
65
|
+
All tools and SDKs live in a single monorepo and share the same map-file format:
|
|
66
|
+
|
|
67
|
+
```txt
|
|
68
|
+
param-map.json (universal contract)
|
|
69
|
+
│
|
|
70
|
+
├── envilder CLI → generates .env files
|
|
71
|
+
├── envilder GitHub Action → CI/CD secret injection
|
|
72
|
+
├── @envilder/sdk (npm) → Node.js / TypeScript runtime
|
|
73
|
+
├── envilder (PyPI) → Python runtime
|
|
74
|
+
├── Envilder (NuGet) → .NET runtime
|
|
75
|
+
├── envilder (Go module) → Go runtime
|
|
76
|
+
└── envilder (Maven) → Java / Kotlin runtime
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### SDK Rollout Phases
|
|
80
|
+
|
|
81
|
+
| Phase | Scope | Rationale |
|
|
82
|
+
|-------|-------|-----------|
|
|
83
|
+
| **Phase 1** | TypeScript SDK | Core already exists in TypeScript — refactor + package |
|
|
84
|
+
| **Phase 2** | Python SDK | Massive adoption in data engineering, ML, and scripting where secrets are critical |
|
|
85
|
+
| **Phase 3** | Go, .NET, Java SDKs | Enterprise reach and cloud-native coverage, prioritized by community demand |
|
|
86
|
+
|
|
87
|
+
### Monorepo Principles
|
|
88
|
+
|
|
89
|
+
- **One map-file spec** — formal JSON Schema at `spec/` is the source of truth for all SDKs
|
|
90
|
+
- **Conformance tests** — language-agnostic fixtures that every SDK must pass
|
|
91
|
+
- **Independent versioning** — each SDK has its own semver (`sdk-ts@1.2.0`, `sdk-py@0.3.0`)
|
|
92
|
+
- **Shared test infrastructure** — LocalStack (AWS) and Lowkey Vault (Azure) via Docker Compose serve all SDKs
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
37
96
|
## 🙌 Contribute or Suggest Ideas
|
|
38
97
|
|
|
39
98
|
If you've faced similar problems or want to help improve this tool, feel free to:
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
<!-- markdownlint-disable MD024 -->
|
|
2
|
-
# Changelog
|
|
3
|
-
|
|
4
1
|
## [0.8.0] - 2026-03-22
|
|
5
2
|
|
|
6
3
|
### Added
|
|
@@ -163,13 +160,6 @@ prints a warning. It will be removed in a future release.
|
|
|
163
160
|
|
|
164
161
|
---
|
|
165
162
|
|
|
166
|
-
## Changelog
|
|
167
|
-
|
|
168
|
-
All notable changes to this project will be documented in this file.
|
|
169
|
-
|
|
170
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
171
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
172
|
-
|
|
173
163
|
## [0.6.6] - 2025-11-02
|
|
174
164
|
|
|
175
165
|
### Changed
|
|
@@ -393,95 +383,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
393
383
|
## [0.1.4] - 2024-10-01
|
|
394
384
|
|
|
395
385
|
Initial public release of Envilder.
|
|
396
|
-
|
|
397
|
-
---
|
|
398
|
-
|
|
399
|
-
## How to Update This Changelog
|
|
400
|
-
|
|
401
|
-
This changelog follows [Conventional Commits](https://www.conventionalcommits.org/) specification.
|
|
402
|
-
|
|
403
|
-
### Commit Message Format
|
|
404
|
-
|
|
405
|
-
```txt
|
|
406
|
-
<type>[optional scope]: <description>
|
|
407
|
-
|
|
408
|
-
[optional body]
|
|
409
|
-
|
|
410
|
-
[optional footer(s)]
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
### Types
|
|
414
|
-
|
|
415
|
-
* `feat`: A new feature (triggers MINOR version bump)
|
|
416
|
-
* `fix`: A bug fix (triggers PATCH version bump)
|
|
417
|
-
* `docs`: Documentation-only changes
|
|
418
|
-
* `style`: Changes that don't affect code meaning (formatting, etc.)
|
|
419
|
-
* `refactor`: Code change that neither fixes a bug nor adds a feature
|
|
420
|
-
* `perf`: Performance improvements
|
|
421
|
-
* `test`: Adding or correcting tests
|
|
422
|
-
* `chore`: Changes to build process or auxiliary tools
|
|
423
|
-
* `ci`: Changes to CI configuration files and scripts
|
|
424
|
-
|
|
425
|
-
### Breaking Changes
|
|
426
|
-
|
|
427
|
-
Add `BREAKING CHANGE:` in the footer or append `!` after type/scope:
|
|
428
|
-
|
|
429
|
-
```txt
|
|
430
|
-
feat!: remove AWS profile auto-detection
|
|
431
|
-
|
|
432
|
-
BREAKING CHANGE: Users must now explicitly specify --profile flag
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
This triggers a MAJOR version bump.
|
|
436
|
-
|
|
437
|
-
### Examples
|
|
438
|
-
|
|
439
|
-
```bash
|
|
440
|
-
# Feature addition (0.7.0 -> 0.8.0)
|
|
441
|
-
git commit -m "feat(gha): add GitHub Action support"
|
|
442
|
-
|
|
443
|
-
# Bug fix (0.7.0 -> 0.7.1)
|
|
444
|
-
git commit -m "fix(cli): handle empty environment files"
|
|
445
|
-
|
|
446
|
-
# Breaking change (0.7.0 -> 1.0.0)
|
|
447
|
-
git commit -m "feat!: redesign CLI interface"
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
## Maintenance
|
|
453
|
-
|
|
454
|
-
This project follows [Conventional Commits](https://www.conventionalcommits.org/) for commit messages.
|
|
455
|
-
|
|
456
|
-
**To update this changelog**:
|
|
457
|
-
|
|
458
|
-
1. Edit this file following the format above
|
|
459
|
-
2. Add entries under `[Unreleased]` section
|
|
460
|
-
3. Run `pnpm version [patch|minor|major]` to create a new release
|
|
461
|
-
4. Move `[Unreleased]` entries to the new version section
|
|
462
|
-
|
|
463
|
-
**Alternative**: Use [GitHub Releases](https://github.com/macalbert/envilder/releases) to auto-generate release notes
|
|
464
|
-
from commit messages.
|
|
465
|
-
|
|
466
|
-
[0.7.6]: https://github.com/macalbert/envilder/compare/v0.7.5...v0.7.6
|
|
467
|
-
[0.7.5]: https://github.com/macalbert/envilder/compare/v0.7.4...v0.7.5
|
|
468
|
-
[0.7.4]: https://github.com/macalbert/envilder/compare/v0.7.3...v0.7.4
|
|
469
|
-
[0.7.3]: https://github.com/macalbert/envilder/compare/v0.7.2...v0.7.3
|
|
470
|
-
[0.7.2]: https://github.com/macalbert/envilder/compare/v0.7.1...v0.7.2
|
|
471
|
-
[0.7.1]: https://github.com/macalbert/envilder/compare/v0.6.6...v0.7.1
|
|
472
|
-
[0.6.6]: https://github.com/macalbert/envilder/compare/v0.6.5...v0.6.6
|
|
473
|
-
[0.6.5]: https://github.com/macalbert/envilder/compare/v0.6.4...v0.6.5
|
|
474
|
-
[0.6.4]: https://github.com/macalbert/envilder/compare/v0.6.3...v0.6.4
|
|
475
|
-
[0.6.3]: https://github.com/macalbert/envilder/compare/v0.6.1...v0.6.3
|
|
476
|
-
[0.6.1]: https://github.com/macalbert/envilder/compare/v0.5.6...v0.6.1
|
|
477
|
-
[0.5.6]: https://github.com/macalbert/envilder/compare/v0.5.5...v0.5.6
|
|
478
|
-
[0.5.5]: https://github.com/macalbert/envilder/compare/v0.5.4...v0.5.5
|
|
479
|
-
[0.5.4]: https://github.com/macalbert/envilder/compare/v0.5.3...v0.5.4
|
|
480
|
-
[0.5.3]: https://github.com/macalbert/envilder/compare/v0.5.2...v0.5.3
|
|
481
|
-
[0.5.2]: https://github.com/macalbert/envilder/compare/v0.5.1...v0.5.2
|
|
482
|
-
[0.5.1]: https://github.com/macalbert/envilder/compare/v0.3.0...v0.5.1
|
|
483
|
-
[0.3.0]: https://github.com/macalbert/envilder/compare/v0.2.3...v0.3.0
|
|
484
|
-
[0.2.3]: https://github.com/macalbert/envilder/compare/v0.2.1...v0.2.3
|
|
485
|
-
[0.2.1]: https://github.com/macalbert/envilder/compare/v0.1.4...v0.2.1
|
|
486
|
-
[0.1.4]: https://github.com/macalbert/envilder/releases/tag/v0.1.4
|
|
487
|
-
<!-- markdownlint-enable MD024 -->
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import type { Stack } from "aws-cdk-lib";
|
|
3
|
+
import { AppEnvironment } from "../lib/core/types";
|
|
4
|
+
interface StaticWebsiteConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
projectPath: string;
|
|
7
|
+
subdomain?: string;
|
|
8
|
+
}
|
|
9
|
+
interface DeploymentConfig {
|
|
10
|
+
repoName: string;
|
|
11
|
+
branch: string;
|
|
12
|
+
environment: AppEnvironment;
|
|
13
|
+
domain: {
|
|
14
|
+
name: string;
|
|
15
|
+
certificateId: string;
|
|
16
|
+
hostedZoneId: string;
|
|
17
|
+
};
|
|
18
|
+
stacks: {
|
|
19
|
+
frontend: {
|
|
20
|
+
staticWebsites: readonly StaticWebsiteConfig[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
rootPath?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function validateConfig(config: DeploymentConfig): void;
|
|
26
|
+
export declare function deploy(configOverride?: DeploymentConfig): Stack[];
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/iac/bin/main.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAe,KAAK,EAAE,MAAM,aAAa,CAAC;AAKtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD,UAAU,mBAAmB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,gBAAgB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACP,QAAQ,EAAE;YACT,cAAc,EAAE,SAAS,mBAAmB,EAAE,CAAC;SAC/C,CAAC;KACF,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAmFD,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA8D7D;AAMD,wBAAgB,MAAM,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,KAAK,EAAE,CA+EjE"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateConfig = validateConfig;
|
|
8
|
+
exports.deploy = deploy;
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* CDK Infrastructure Deployment Entry Point
|
|
12
|
+
*/
|
|
13
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
14
|
+
const types_1 = require("../lib/core/types");
|
|
15
|
+
const staticWebsiteStack_1 = require("../lib/stacks/staticWebsiteStack");
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Configuration
|
|
18
|
+
// ============================================================================
|
|
19
|
+
const config = {
|
|
20
|
+
repoName: "envilder",
|
|
21
|
+
branch: "main",
|
|
22
|
+
environment: types_1.AppEnvironment.Production,
|
|
23
|
+
domain: {
|
|
24
|
+
name: "envilder.com",
|
|
25
|
+
certificateId: "e04983fe-1561-4ebe-9166-83f77789964a",
|
|
26
|
+
hostedZoneId: "Z0718467FEEOZ35UNCTO",
|
|
27
|
+
},
|
|
28
|
+
stacks: {
|
|
29
|
+
frontend: {
|
|
30
|
+
staticWebsites: [
|
|
31
|
+
{
|
|
32
|
+
name: "Website",
|
|
33
|
+
projectPath: "envilder/src/apps/website/dist",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Utils
|
|
41
|
+
// ============================================================================
|
|
42
|
+
function getRootPath(rootPath) {
|
|
43
|
+
return rootPath !== null && rootPath !== void 0 ? rootPath : node_path_1.default.join(process.cwd(), "../../../");
|
|
44
|
+
}
|
|
45
|
+
function resolveFullPath(rootPath, relativePath) {
|
|
46
|
+
return node_path_1.default.join(rootPath, relativePath);
|
|
47
|
+
}
|
|
48
|
+
function logInfo(message) {
|
|
49
|
+
process.stderr.write(`${message}\x1b[E\n`);
|
|
50
|
+
}
|
|
51
|
+
function logError(error) {
|
|
52
|
+
process.stderr.write(`\x1b[31m❌ Error: ${error.message}\x1b[0m\x1b[E\n`);
|
|
53
|
+
if (error.stack) {
|
|
54
|
+
process.stderr.write(`${error.stack}\x1b[E\n`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function logTable(entries) {
|
|
58
|
+
const MAX_VALUE_WIDTH = 40;
|
|
59
|
+
const truncate = (s) => s.length > MAX_VALUE_WIDTH ? `…${s.slice(-(MAX_VALUE_WIDTH - 1))}` : s;
|
|
60
|
+
const rows = entries.map(({ label, value }) => ({
|
|
61
|
+
label,
|
|
62
|
+
value: truncate(value),
|
|
63
|
+
}));
|
|
64
|
+
const maxLabel = Math.max(...rows.map((e) => e.label.length));
|
|
65
|
+
const maxValue = Math.max(...rows.map((e) => e.value.length));
|
|
66
|
+
const header = " 📁 Deployment Info ";
|
|
67
|
+
const innerWidth = maxLabel + maxValue + 4;
|
|
68
|
+
const padding = Math.max(0, innerWidth - header.length);
|
|
69
|
+
const nl = "\x1b[E\n";
|
|
70
|
+
process.stderr.write(nl);
|
|
71
|
+
process.stderr.write(`╭─${header}${"─".repeat(padding)}╮${nl}`);
|
|
72
|
+
for (const { label, value } of rows) {
|
|
73
|
+
process.stderr.write(`│ ${label.padEnd(maxLabel)} │ ${value.padEnd(maxValue)} │${nl}`);
|
|
74
|
+
}
|
|
75
|
+
process.stderr.write(`╰${"─".repeat(maxLabel + 2)}┴${"─".repeat(maxValue + 2)}╯${nl}`);
|
|
76
|
+
process.stderr.write(nl);
|
|
77
|
+
}
|
|
78
|
+
function validateConfig(config) {
|
|
79
|
+
const errors = [];
|
|
80
|
+
if (!config.repoName || config.repoName.trim() === "") {
|
|
81
|
+
errors.push("repoName is required and cannot be empty");
|
|
82
|
+
}
|
|
83
|
+
if (!config.branch || config.branch.trim() === "") {
|
|
84
|
+
errors.push("branch is required and cannot be empty");
|
|
85
|
+
}
|
|
86
|
+
if (config.environment === undefined || config.environment === null) {
|
|
87
|
+
errors.push("environment is required and cannot be empty");
|
|
88
|
+
}
|
|
89
|
+
if (!config.domain) {
|
|
90
|
+
errors.push("domain configuration is required");
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (!config.domain.name || config.domain.name.trim() === "") {
|
|
94
|
+
errors.push("domain.name is required and cannot be empty");
|
|
95
|
+
}
|
|
96
|
+
if (!config.domain.certificateId ||
|
|
97
|
+
config.domain.certificateId.trim() === "") {
|
|
98
|
+
errors.push("domain.certificateId is required and cannot be empty");
|
|
99
|
+
}
|
|
100
|
+
if (!config.domain.hostedZoneId ||
|
|
101
|
+
config.domain.hostedZoneId.trim() === "") {
|
|
102
|
+
errors.push("domain.hostedZoneId is required and cannot be empty");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!config.stacks) {
|
|
106
|
+
errors.push("stacks configuration is required");
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
if (!config.stacks.frontend) {
|
|
110
|
+
errors.push("stacks.frontend is required");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const { staticWebsites } = config.stacks.frontend;
|
|
114
|
+
if (staticWebsites) {
|
|
115
|
+
for (const [index, website] of staticWebsites.entries()) {
|
|
116
|
+
if (!website.name || website.name.trim() === "") {
|
|
117
|
+
errors.push(`frontend.staticWebsites[${index}].name is required`);
|
|
118
|
+
}
|
|
119
|
+
if (!website.projectPath || website.projectPath.trim() === "") {
|
|
120
|
+
errors.push(`frontend.staticWebsites[${index}].projectPath is required`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (errors.length > 0) {
|
|
127
|
+
throw new Error(`Configuration validation failed with ${errors.length} error(s):\n${errors.join("\n")}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// Deployment
|
|
132
|
+
// ============================================================================
|
|
133
|
+
function deploy(configOverride) {
|
|
134
|
+
const effectiveConfig = configOverride !== null && configOverride !== void 0 ? configOverride : config;
|
|
135
|
+
const rootPath = getRootPath(effectiveConfig.rootPath);
|
|
136
|
+
try {
|
|
137
|
+
validateConfig(effectiveConfig);
|
|
138
|
+
// Log deployment info
|
|
139
|
+
const entries = [
|
|
140
|
+
{ label: "Repository", value: effectiveConfig.repoName },
|
|
141
|
+
{ label: "Branch", value: effectiveConfig.branch },
|
|
142
|
+
{ label: "Environment", value: String(effectiveConfig.environment) },
|
|
143
|
+
];
|
|
144
|
+
if (process.env.CDK_DEFAULT_REGION) {
|
|
145
|
+
entries.push({ label: "Region", value: process.env.CDK_DEFAULT_REGION });
|
|
146
|
+
}
|
|
147
|
+
if (process.env.CDK_DEFAULT_ACCOUNT) {
|
|
148
|
+
entries.push({
|
|
149
|
+
label: "Account",
|
|
150
|
+
value: `***${process.env.CDK_DEFAULT_ACCOUNT.slice(-4)}`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
entries.push({ label: "Root Path", value: rootPath });
|
|
154
|
+
for (const ws of effectiveConfig.stacks.frontend.staticWebsites) {
|
|
155
|
+
entries.push({
|
|
156
|
+
label: ws.name,
|
|
157
|
+
value: resolveFullPath(rootPath, ws.projectPath),
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
logTable(entries);
|
|
161
|
+
logInfo("🎯 Requested stacks:");
|
|
162
|
+
const app = new aws_cdk_lib_1.App();
|
|
163
|
+
const envFromCli = {
|
|
164
|
+
account: process.env.CDK_DEFAULT_ACCOUNT,
|
|
165
|
+
region: process.env.CDK_DEFAULT_REGION,
|
|
166
|
+
};
|
|
167
|
+
const stacks = [];
|
|
168
|
+
for (const websiteConfig of effectiveConfig.stacks.frontend
|
|
169
|
+
.staticWebsites) {
|
|
170
|
+
const distFolderPath = resolveFullPath(rootPath, websiteConfig.projectPath);
|
|
171
|
+
const stack = new staticWebsiteStack_1.StaticWebsiteStack(app, {
|
|
172
|
+
env: envFromCli,
|
|
173
|
+
name: websiteConfig.name,
|
|
174
|
+
domains: [
|
|
175
|
+
{
|
|
176
|
+
subdomain: websiteConfig.subdomain,
|
|
177
|
+
domainName: effectiveConfig.domain.name,
|
|
178
|
+
certificateId: effectiveConfig.domain.certificateId,
|
|
179
|
+
hostedZoneId: effectiveConfig.domain.hostedZoneId,
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
distFolderPath,
|
|
183
|
+
envName: effectiveConfig.environment,
|
|
184
|
+
githubRepo: effectiveConfig.repoName,
|
|
185
|
+
stackName: `${effectiveConfig.repoName}-${websiteConfig.name}`,
|
|
186
|
+
});
|
|
187
|
+
stacks.push(stack);
|
|
188
|
+
}
|
|
189
|
+
return stacks;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (error instanceof Error) {
|
|
193
|
+
logError(error);
|
|
194
|
+
}
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (!process.env.VITEST) {
|
|
199
|
+
deploy();
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/iac/bin/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/iac/lib/core/types.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc;IACzB,UAAU,eAAe;IACzB,WAAW,gBAAgB;CAC3B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppEnvironment = void 0;
|
|
4
|
+
var AppEnvironment;
|
|
5
|
+
(function (AppEnvironment) {
|
|
6
|
+
AppEnvironment["Production"] = "Production";
|
|
7
|
+
AppEnvironment["Development"] = "Development";
|
|
8
|
+
})(AppEnvironment || (exports.AppEnvironment = AppEnvironment = {}));
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/iac/lib/core/types.ts"],"names":[],"mappings":";;;AAAA,IAAY,cAGX;AAHD,WAAY,cAAc;IACzB,2CAAyB,CAAA;IACzB,6CAA2B,CAAA;AAC5B,CAAC,EAHW,cAAc,8BAAd,cAAc,QAGzB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Stack, type StackProps } from "aws-cdk-lib";
|
|
2
|
+
import type { Construct } from "constructs";
|
|
3
|
+
import type { AppEnvironment } from "../core/types";
|
|
4
|
+
export interface DomainConfig {
|
|
5
|
+
subdomain?: string;
|
|
6
|
+
domainName: string;
|
|
7
|
+
hostedZoneId: string;
|
|
8
|
+
certificateId: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CustomStackProps extends StackProps {
|
|
11
|
+
githubRepo: string;
|
|
12
|
+
envName: AppEnvironment;
|
|
13
|
+
name: string;
|
|
14
|
+
stackName: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class CustomStack extends Stack {
|
|
17
|
+
props: CustomStackProps;
|
|
18
|
+
constructor(scope: Construct, props: CustomStackProps);
|
|
19
|
+
getStackId(): string;
|
|
20
|
+
private addProjectTags;
|
|
21
|
+
getCloudFormationRepoName(): string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=customStack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customStack.d.ts","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/customStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAQ,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,WAAY,SAAQ,KAAK;IACrC,KAAK,EAAE,gBAAgB,CAAC;gBAEZ,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB;IAQrD,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,cAAc;IAcf,yBAAyB,IAAI,MAAM;CAG1C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomStack = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
class CustomStack extends aws_cdk_lib_1.Stack {
|
|
7
|
+
constructor(scope, props) {
|
|
8
|
+
super(scope, getStackName(props), props);
|
|
9
|
+
this.props = props;
|
|
10
|
+
this.addProjectTags();
|
|
11
|
+
}
|
|
12
|
+
getStackId() {
|
|
13
|
+
return getStackName(this.props);
|
|
14
|
+
}
|
|
15
|
+
addProjectTags() {
|
|
16
|
+
aws_cdk_lib_1.Tags.of(this).add("StackId", getStackName(this.props), {
|
|
17
|
+
priority: 300,
|
|
18
|
+
});
|
|
19
|
+
aws_cdk_lib_1.Tags.of(this).add("Environment", this.props.envName.valueOf(), {
|
|
20
|
+
priority: 300,
|
|
21
|
+
});
|
|
22
|
+
aws_cdk_lib_1.Tags.of(this).add("Project", this.props.githubRepo, {
|
|
23
|
+
priority: 300,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
getCloudFormationRepoName() {
|
|
27
|
+
return (0, utils_1.formatRepoNameForCloudFormation)(this.props.githubRepo);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.CustomStack = CustomStack;
|
|
31
|
+
function getStackName(props) {
|
|
32
|
+
return `macalbert-${(0, utils_1.formatRepoNameForCloudFormation)(props.githubRepo)}-${props.name}-${props.envName}-stack`.toLowerCase();
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=customStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customStack.js","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/customStack.ts"],"names":[],"mappings":";;;AAAA,6CAA2D;AAG3D,mCAA0D;AAgB1D,MAAa,WAAY,SAAQ,mBAAK;IAGrC,YAAY,KAAgB,EAAE,KAAuB;QACpD,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAEzC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAED,UAAU;QACT,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAEO,cAAc;QACrB,kBAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YACtD,QAAQ,EAAE,GAAG;SACb,CAAC,CAAC;QAEH,kBAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE;YAC9D,QAAQ,EAAE,GAAG;SACb,CAAC,CAAC;QAEH,kBAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;YACnD,QAAQ,EAAE,GAAG;SACb,CAAC,CAAC;IACJ,CAAC;IAEM,yBAAyB;QAC/B,OAAO,IAAA,uCAA+B,EAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/D,CAAC;CACD;AAhCD,kCAgCC;AAED,SAAS,YAAY,CAAC,KAAuB;IAC5C,OAAO,aAAa,IAAA,uCAA+B,EAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;AAC5H,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Construct } from "constructs";
|
|
2
|
+
import { CustomStack, type CustomStackProps, type DomainConfig } from "./customStack";
|
|
3
|
+
export interface StaticWebsiteStackProps extends CustomStackProps {
|
|
4
|
+
domains: DomainConfig[];
|
|
5
|
+
distFolderPath: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class StaticWebsiteStack extends CustomStack {
|
|
8
|
+
constructor(scope: Construct, props: StaticWebsiteStackProps);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=staticWebsiteStack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticWebsiteStack.d.ts","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/staticWebsiteStack.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACN,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAChE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,kBAAmB,SAAQ,WAAW;gBACtC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB;CAmM5D"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StaticWebsiteStack = void 0;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
6
|
+
const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
|
|
7
|
+
const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront");
|
|
8
|
+
const aws_cloudfront_origins_1 = require("aws-cdk-lib/aws-cloudfront-origins");
|
|
9
|
+
const aws_route53_1 = require("aws-cdk-lib/aws-route53");
|
|
10
|
+
const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets");
|
|
11
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
12
|
+
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
13
|
+
const customStack_1 = require("./customStack");
|
|
14
|
+
class StaticWebsiteStack extends customStack_1.CustomStack {
|
|
15
|
+
constructor(scope, props) {
|
|
16
|
+
var _a;
|
|
17
|
+
super(scope, props);
|
|
18
|
+
if (!props.domains || props.domains.length === 0) {
|
|
19
|
+
throw new Error("At least one domain configuration is required");
|
|
20
|
+
}
|
|
21
|
+
const primaryDomain = props.domains[0];
|
|
22
|
+
const primaryFullDomainName = primaryDomain.subdomain && primaryDomain.subdomain.length > 0
|
|
23
|
+
? [primaryDomain.subdomain, primaryDomain.domainName]
|
|
24
|
+
.join(".")
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
: primaryDomain.domainName.toLowerCase();
|
|
27
|
+
const allDomainNames = props.domains.map((domain) => domain.subdomain && domain.subdomain.length > 0
|
|
28
|
+
? `${domain.subdomain}.${domain.domainName}`.toLowerCase()
|
|
29
|
+
: domain.domainName.toLowerCase());
|
|
30
|
+
const certificateMap = new Map();
|
|
31
|
+
for (const domain of props.domains) {
|
|
32
|
+
if (!certificateMap.has(domain.certificateId)) {
|
|
33
|
+
const certificateArn = `arn:aws:acm:us-east-1:${(_a = props.env) === null || _a === void 0 ? void 0 : _a.account}:certificate/${domain.certificateId}`;
|
|
34
|
+
certificateMap.set(domain.certificateId, aws_certificatemanager_1.Certificate.fromCertificateArn(this, `certificate-${domain.certificateId}`, certificateArn));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const primaryCertificate = certificateMap.get(primaryDomain.certificateId);
|
|
38
|
+
if (!primaryCertificate) {
|
|
39
|
+
throw new Error(`Certificate not found for ${primaryDomain.certificateId}`);
|
|
40
|
+
}
|
|
41
|
+
const loggingBucket = new aws_s3_1.Bucket(this, "logging-bucket", {
|
|
42
|
+
accessControl: aws_s3_1.BucketAccessControl.LOG_DELIVERY_WRITE,
|
|
43
|
+
publicReadAccess: false,
|
|
44
|
+
versioned: false,
|
|
45
|
+
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
46
|
+
bucketName: `${primaryFullDomainName}-logs`,
|
|
47
|
+
autoDeleteObjects: true,
|
|
48
|
+
blockPublicAccess: aws_s3_1.BlockPublicAccess.BLOCK_ALL,
|
|
49
|
+
encryption: aws_s3_1.BucketEncryption.S3_MANAGED,
|
|
50
|
+
enforceSSL: true,
|
|
51
|
+
lifecycleRules: [
|
|
52
|
+
{
|
|
53
|
+
id: "DeleteOldLogs",
|
|
54
|
+
expiration: aws_cdk_lib_1.Duration.days(90),
|
|
55
|
+
enabled: true,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
const bucketWebsite = new aws_s3_1.Bucket(this, "static-website-bucket", {
|
|
60
|
+
accessControl: aws_s3_1.BucketAccessControl.PRIVATE,
|
|
61
|
+
publicReadAccess: false,
|
|
62
|
+
versioned: false,
|
|
63
|
+
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
64
|
+
bucketName: primaryFullDomainName,
|
|
65
|
+
autoDeleteObjects: true,
|
|
66
|
+
blockPublicAccess: aws_s3_1.BlockPublicAccess.BLOCK_ALL,
|
|
67
|
+
encryption: aws_s3_1.BucketEncryption.S3_MANAGED,
|
|
68
|
+
cors: [
|
|
69
|
+
{
|
|
70
|
+
allowedMethods: [aws_s3_1.HttpMethods.GET, aws_s3_1.HttpMethods.HEAD],
|
|
71
|
+
allowedOrigins: ["*"],
|
|
72
|
+
allowedHeaders: ["*"],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
enforceSSL: true,
|
|
76
|
+
serverAccessLogsBucket: loggingBucket,
|
|
77
|
+
serverAccessLogsPrefix: "s3-access-logs/",
|
|
78
|
+
});
|
|
79
|
+
const originAccessIdentity = new aws_cloudfront_1.OriginAccessIdentity(this, "originAccessIdentity", {
|
|
80
|
+
comment: `Setup access from CloudFront to the bucket ${primaryFullDomainName} (read)`,
|
|
81
|
+
});
|
|
82
|
+
bucketWebsite.grantRead(originAccessIdentity);
|
|
83
|
+
const errorResponses = [];
|
|
84
|
+
const errorResponse403 = {
|
|
85
|
+
httpStatus: 403,
|
|
86
|
+
responseHttpStatus: 200,
|
|
87
|
+
responsePagePath: "/index.html",
|
|
88
|
+
ttl: aws_cdk_lib_1.Duration.seconds(10),
|
|
89
|
+
};
|
|
90
|
+
const errorResponse404 = {
|
|
91
|
+
httpStatus: 404,
|
|
92
|
+
responseHttpStatus: 200,
|
|
93
|
+
responsePagePath: "/index.html",
|
|
94
|
+
ttl: aws_cdk_lib_1.Duration.seconds(10),
|
|
95
|
+
};
|
|
96
|
+
errorResponses.push(errorResponse403, errorResponse404);
|
|
97
|
+
const distribution = new aws_cloudfront_1.Distribution(this, "distribution", {
|
|
98
|
+
domainNames: allDomainNames,
|
|
99
|
+
defaultBehavior: {
|
|
100
|
+
origin: aws_cloudfront_origins_1.S3BucketOrigin.withOriginAccessIdentity(bucketWebsite, {
|
|
101
|
+
originAccessIdentity: originAccessIdentity,
|
|
102
|
+
}),
|
|
103
|
+
viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
104
|
+
functionAssociations: [
|
|
105
|
+
{
|
|
106
|
+
eventType: aws_cloudfront_1.FunctionEventType.VIEWER_REQUEST,
|
|
107
|
+
function: new aws_cloudfront_1.Function(this, `${primaryFullDomainName}-url-rewrite`.toLowerCase(), {
|
|
108
|
+
code: aws_cloudfront_1.FunctionCode.fromFile({
|
|
109
|
+
filePath: (0, node_path_1.join)(__dirname, "cloudfront-url-rewrite.js"),
|
|
110
|
+
}),
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
defaultRootObject: "index.html",
|
|
116
|
+
certificate: primaryCertificate,
|
|
117
|
+
errorResponses: errorResponses,
|
|
118
|
+
enableLogging: true,
|
|
119
|
+
logBucket: loggingBucket,
|
|
120
|
+
logFilePrefix: "cloudfront-logs/",
|
|
121
|
+
});
|
|
122
|
+
new aws_s3_deployment_1.BucketDeployment(this, "deploy-static-website", {
|
|
123
|
+
sources: [aws_s3_deployment_1.Source.asset(props.distFolderPath)],
|
|
124
|
+
destinationBucket: bucketWebsite,
|
|
125
|
+
distribution,
|
|
126
|
+
distributionPaths: ["/*"],
|
|
127
|
+
});
|
|
128
|
+
const aliasRecords = [];
|
|
129
|
+
for (const [index, domainConfig] of props.domains.entries()) {
|
|
130
|
+
const fullDomainName = domainConfig.subdomain && domainConfig.subdomain.length > 0
|
|
131
|
+
? `${domainConfig.subdomain}.${domainConfig.domainName}`.toLowerCase()
|
|
132
|
+
: domainConfig.domainName.toLowerCase();
|
|
133
|
+
const zoneLogicalId = index === 0
|
|
134
|
+
? "publicHostedZone-0"
|
|
135
|
+
: `hostedZone-${fullDomainName.replace(/[.-]/g, "")}`;
|
|
136
|
+
const zoneFromAttributes = aws_route53_1.HostedZone.fromHostedZoneAttributes(this, zoneLogicalId, {
|
|
137
|
+
zoneName: domainConfig.domainName,
|
|
138
|
+
hostedZoneId: domainConfig.hostedZoneId,
|
|
139
|
+
});
|
|
140
|
+
const recordLogicalId = index === 0
|
|
141
|
+
? "webDomainRecord-0"
|
|
142
|
+
: `webDomainRecord-${fullDomainName.replace(/[.-]/g, "")}`;
|
|
143
|
+
const aliasRecord = new aws_route53_1.ARecord(this, recordLogicalId, {
|
|
144
|
+
zone: zoneFromAttributes,
|
|
145
|
+
recordName: fullDomainName,
|
|
146
|
+
target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.CloudFrontTarget(distribution)),
|
|
147
|
+
});
|
|
148
|
+
aliasRecords.push(aliasRecord);
|
|
149
|
+
}
|
|
150
|
+
new aws_cdk_lib_1.CfnOutput(this, "CloudFrontDistributionDomainName", {
|
|
151
|
+
value: distribution.distributionDomainName,
|
|
152
|
+
description: "CloudFront distribution domain",
|
|
153
|
+
exportName: `${this.getCloudFormationRepoName()}-${props.envName}-CdnDomainName`,
|
|
154
|
+
});
|
|
155
|
+
new aws_cdk_lib_1.CfnOutput(this, "DnsRecordName", {
|
|
156
|
+
value: aliasRecords[0].domainName || allDomainNames[0],
|
|
157
|
+
description: "The DNS record name (primary)",
|
|
158
|
+
exportName: `${this.getCloudFormationRepoName()}-${props.envName}-AliasRecord`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.StaticWebsiteStack = StaticWebsiteStack;
|
|
163
|
+
//# sourceMappingURL=staticWebsiteStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticWebsiteStack.js","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/staticWebsiteStack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a formatted repository name that complies with AWS CloudFormation stack naming requirements.
|
|
3
|
+
* Stack names must match the regular expression: /^[A-Za-z][A-Za-z0-9-]*$/
|
|
4
|
+
*/
|
|
5
|
+
export declare function formatRepoNameForCloudFormation(repoName: string): string;
|
|
6
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYxE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatRepoNameForCloudFormation = formatRepoNameForCloudFormation;
|
|
4
|
+
/**
|
|
5
|
+
* Returns a formatted repository name that complies with AWS CloudFormation stack naming requirements.
|
|
6
|
+
* Stack names must match the regular expression: /^[A-Za-z][A-Za-z0-9-]*$/
|
|
7
|
+
*/
|
|
8
|
+
function formatRepoNameForCloudFormation(repoName) {
|
|
9
|
+
let formattedName = repoName.toLowerCase();
|
|
10
|
+
formattedName = formattedName.replace(/[^A-Za-z0-9]/g, "-");
|
|
11
|
+
formattedName = formattedName.replace(/-+/g, "-");
|
|
12
|
+
formattedName = formattedName.replace(/^-|-$/g, "");
|
|
13
|
+
if (!/^[A-Za-z]/.test(formattedName)) {
|
|
14
|
+
formattedName = `r-${formattedName}`;
|
|
15
|
+
}
|
|
16
|
+
return formattedName;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/iac/lib/stacks/utils.ts"],"names":[],"mappings":";;AAIA,0EAYC;AAhBD;;;GAGG;AACH,SAAgB,+BAA+B,CAAC,QAAgB;IAC/D,IAAI,aAAa,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE3C,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IAC5D,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClD,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEpD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QACtC,aAAa,GAAG,KAAK,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,OAAO,aAAa,CAAC;AACtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envilder",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A CLI that securely centralizes your environment variables from AWS SSM or Azure Key Vault as a single source of truth",
|
|
3
|
+
"version": "0.9.1",
|
|
4
|
+
"description": "A CLI and GitHub Action that securely centralizes your environment variables from AWS SSM or Azure Key Vault as a single source of truth",
|
|
5
|
+
"homepage": "https://envilder.com",
|
|
5
6
|
"author": {
|
|
6
7
|
"name": "Marçal Albert Castellví",
|
|
7
8
|
"email": "mac.albert@gmail.com",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"cli",
|
|
50
51
|
"environment",
|
|
51
52
|
"secrets",
|
|
53
|
+
"secret-management",
|
|
52
54
|
"automation",
|
|
53
55
|
"config",
|
|
54
56
|
"aws-cli",
|
|
@@ -61,7 +63,8 @@
|
|
|
61
63
|
"actions",
|
|
62
64
|
"azure",
|
|
63
65
|
"key-vault",
|
|
64
|
-
"azure-key-vault"
|
|
66
|
+
"azure-key-vault",
|
|
67
|
+
"multi-cloud"
|
|
65
68
|
],
|
|
66
69
|
"bugs": {
|
|
67
70
|
"url": "https://github.com/macalbert/envilder/issues"
|
|
@@ -80,47 +83,45 @@
|
|
|
80
83
|
],
|
|
81
84
|
"type": "module",
|
|
82
85
|
"dependencies": {
|
|
83
|
-
"@aws-sdk/client-ssm": "^3.
|
|
84
|
-
"@aws-sdk/credential-providers": "^3.
|
|
85
|
-
"@azure/core-rest-pipeline": "^1.
|
|
86
|
-
"@azure/identity": "^4.13.
|
|
86
|
+
"@aws-sdk/client-ssm": "^3.1019.0",
|
|
87
|
+
"@aws-sdk/credential-providers": "^3.1019.0",
|
|
88
|
+
"@azure/core-rest-pipeline": "^1.23.0",
|
|
89
|
+
"@azure/identity": "^4.13.1",
|
|
87
90
|
"@azure/keyvault-secrets": "^4.10.0",
|
|
88
|
-
"@types/node": "^25.3.3",
|
|
89
91
|
"commander": "^14.0.3",
|
|
90
92
|
"dotenv": "^17.3.1",
|
|
91
|
-
"inversify": "^
|
|
93
|
+
"inversify": "^8.1.0",
|
|
92
94
|
"picocolors": "^1.1.1",
|
|
93
95
|
"reflect-metadata": "^0.2.2"
|
|
94
96
|
},
|
|
95
97
|
"devDependencies": {
|
|
96
|
-
"@biomejs/biome": "
|
|
97
|
-
"@commitlint/cli": "^20.
|
|
98
|
-
"@commitlint/config-conventional": "^20.
|
|
99
|
-
"@secretlint/secretlint-rule-preset-recommend": "^11.
|
|
100
|
-
"@testcontainers/localstack": "^11.
|
|
98
|
+
"@biomejs/biome": "catalog:",
|
|
99
|
+
"@commitlint/cli": "^20.5.0",
|
|
100
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
101
|
+
"@secretlint/secretlint-rule-preset-recommend": "^11.4.0",
|
|
102
|
+
"@testcontainers/localstack": "^11.13.0",
|
|
103
|
+
"@types/node": "catalog:",
|
|
101
104
|
"@vercel/ncc": "^0.38.4",
|
|
102
|
-
"@vitest/coverage-v8": "
|
|
105
|
+
"@vitest/coverage-v8": "catalog:",
|
|
103
106
|
"glob": "^13.0.6",
|
|
104
107
|
"lefthook": "^2.1.4",
|
|
105
|
-
"secretlint": "^11.
|
|
106
|
-
"testcontainers": "^11.
|
|
107
|
-
"ts-node": "
|
|
108
|
+
"secretlint": "^11.4.0",
|
|
109
|
+
"testcontainers": "^11.13.0",
|
|
110
|
+
"ts-node": "catalog:",
|
|
108
111
|
"tsx": "^4.21.0",
|
|
109
|
-
"typescript": "
|
|
110
|
-
"vitest": "
|
|
112
|
+
"typescript": "catalog:",
|
|
113
|
+
"vitest": "catalog:"
|
|
111
114
|
},
|
|
112
115
|
"engines": {
|
|
113
116
|
"node": ">=20.0.0"
|
|
114
117
|
},
|
|
115
118
|
"pnpm": {
|
|
116
|
-
"overrides": {
|
|
117
|
-
"minimatch": "^10.2.2"
|
|
118
|
-
},
|
|
119
119
|
"onlyBuiltDependencies": [
|
|
120
120
|
"cpu-features",
|
|
121
121
|
"esbuild",
|
|
122
122
|
"lefthook",
|
|
123
123
|
"protobufjs",
|
|
124
|
+
"sharp",
|
|
124
125
|
"ssh2"
|
|
125
126
|
]
|
|
126
127
|
}
|