pangea-aws 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/flake.lock +3 -3
- data/flake.nix +7 -41
- data/lib/pangea/architectures/aws/web_application_architecture/README.md +375 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/component_creation.rb +146 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/cost_estimation.rb +71 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/fallback_resources.rb +63 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/helpers.rb +50 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/outputs.rb +73 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture/resource_creation.rb +54 -0
- data/lib/pangea/architectures/aws/web_application_architecture/architecture.rb +75 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types/cost_estimation.rb +88 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types/defaults.rb +90 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types/input_schema.rb +91 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types/output_schema.rb +49 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types/validation.rb +81 -0
- data/lib/pangea/architectures/aws/web_application_architecture/types.rb +70 -0
- data/lib/pangea/components/aws/public_private_subnets/README.md +293 -0
- data/lib/pangea/components/aws/public_private_subnets/component/outputs.rb +49 -0
- data/lib/pangea/components/aws/public_private_subnets/component/routing/nat_gateways.rb +89 -0
- data/lib/pangea/components/aws/public_private_subnets/component/routing.rb +145 -0
- data/lib/pangea/components/aws/public_private_subnets/component/subnets.rb +70 -0
- data/lib/pangea/components/aws/public_private_subnets/component.rb +92 -0
- data/lib/pangea/components/aws/public_private_subnets/types.rb +152 -0
- data/lib/pangea/components/aws/secure_vpc/README.md +187 -0
- data/lib/pangea/components/aws/secure_vpc/component.rb +88 -0
- data/lib/pangea/components/aws/secure_vpc/types.rb +141 -0
- data/lib/pangea/components/aws/vpc_with_subnets/component.rb +175 -0
- data/lib/pangea/components/aws/vpc_with_subnets/types.rb +61 -0
- data/lib/pangea/components/capabilities.rb +93 -0
- data/lib/pangea/components/types.rb +198 -0
- data/lib/pangea/resources/aws/composition/auto_scaling_web_tier.rb +179 -0
- data/lib/pangea/resources/aws/composition/composite_auto_scaling_reference.rb +63 -0
- data/lib/pangea/resources/aws/composition/composite_vpc_reference.rb +73 -0
- data/lib/pangea/resources/aws/composition/composite_web_server_reference.rb +46 -0
- data/lib/pangea/resources/aws/composition/helpers.rb +75 -0
- data/lib/pangea/resources/aws/composition/vpc_with_subnets.rb +143 -0
- data/lib/pangea/resources/aws/composition/web_server.rb +72 -0
- data/lib/pangea/resources/aws/composition.rb +38 -0
- data/lib/pangea/resources/aws/examples/event_driven/dynamodb_tables.rb +103 -0
- data/lib/pangea/resources/aws/examples/event_driven/eventbridge_buses.rb +68 -0
- data/lib/pangea/resources/aws/examples/event_driven/eventbridge_rules.rb +94 -0
- data/lib/pangea/resources/aws/examples/event_driven/eventbridge_targets.rb +123 -0
- data/lib/pangea/resources/types/aws/core.rb +0 -28
- data/lib/pangea/resources/validators/aws_validators.rb +66 -0
- data/lib/pangea/types/aws_types.rb +65 -0
- data/lib/pangea/types/computed_types.rb +23 -0
- data/lib/pangea/utilities/aws/pricing.rb +102 -0
- data/lib/pangea-aws/version.rb +1 -1
- data/lib/pangea-aws.rb +22 -0
- data/pangea-aws.gemspec +1 -1
- metadata +54 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 171b953acda35d607e7f18e2dd248e2535ffb11966cd85389288130bfaab807d
|
|
4
|
+
data.tar.gz: d1140dcd5eb37444b0ce9a34577e825bd3eba4421af2e32c90f8966dd80c2a6f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 992c3aadad1f441386c8fba09cdbe6fadcd11e4bfbaf741622ee670a692c525af6d9202a4095fe5232f4e03a5cc751d2070f844f618f38db89692ad45b95118a
|
|
7
|
+
data.tar.gz: f6b08dd54ca87b02c9a7f2cb7aa35f0d1b0e3451f7c00fdad34845117e352bcb39527f3a25209d1dc0c962b77a3fe9697f06141732381ac7c2a6855e5f37be7b
|
data/flake.lock
CHANGED
|
@@ -771,11 +771,11 @@
|
|
|
771
771
|
]
|
|
772
772
|
},
|
|
773
773
|
"locked": {
|
|
774
|
-
"lastModified":
|
|
775
|
-
"narHash": "sha256-
|
|
774
|
+
"lastModified": 1771861648,
|
|
775
|
+
"narHash": "sha256-XjYnA7XQUFTg/XrgQL35oojiX/oddmuqHSsLbQg+X44=",
|
|
776
776
|
"owner": "pleme-io",
|
|
777
777
|
"repo": "substrate",
|
|
778
|
-
"rev": "
|
|
778
|
+
"rev": "0f97a626e8141f4ffa2a4e143f96df2689a82b6b",
|
|
779
779
|
"type": "github"
|
|
780
780
|
},
|
|
781
781
|
"original": {
|
data/flake.nix
CHANGED
|
@@ -16,45 +16,11 @@
|
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
outputs = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
...
|
|
27
|
-
}:
|
|
28
|
-
flake-utils.lib.eachSystem ["x86_64-linux" "aarch64-linux" "aarch64-darwin"] (system: let
|
|
29
|
-
pkgs = import nixpkgs {
|
|
30
|
-
inherit system;
|
|
31
|
-
overlays = [ruby-nix.overlays.ruby];
|
|
32
|
-
};
|
|
33
|
-
rnix = ruby-nix.lib pkgs;
|
|
34
|
-
rnix-env = rnix {
|
|
35
|
-
name = "pangea-aws";
|
|
36
|
-
gemset = ./gemset.nix;
|
|
37
|
-
};
|
|
38
|
-
env = rnix-env.env;
|
|
39
|
-
ruby = rnix-env.ruby;
|
|
40
|
-
|
|
41
|
-
rubyBuild = import "${substrate}/lib/ruby-build.nix" {
|
|
42
|
-
inherit pkgs;
|
|
43
|
-
forgeCmd = "${forge.packages.${system}.default}/bin/forge";
|
|
44
|
-
defaultGhcrToken = "";
|
|
45
|
-
};
|
|
46
|
-
in {
|
|
47
|
-
devShells.default = pkgs.mkShell {
|
|
48
|
-
buildInputs = [env ruby];
|
|
49
|
-
shellHook = ''
|
|
50
|
-
export RUBYLIB=$PWD/lib:$RUBYLIB
|
|
51
|
-
export DRY_TYPES_WARNINGS=false
|
|
52
|
-
'';
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
apps = rubyBuild.mkRubyGemApps {
|
|
56
|
-
srcDir = self;
|
|
57
|
-
name = "pangea-aws";
|
|
58
|
-
};
|
|
59
|
-
});
|
|
19
|
+
outputs = { self, nixpkgs, ruby-nix, flake-utils, substrate, forge, ... }:
|
|
20
|
+
(import "${substrate}/lib/ruby-gem-flake.nix" {
|
|
21
|
+
inherit nixpkgs ruby-nix flake-utils substrate forge;
|
|
22
|
+
}) {
|
|
23
|
+
inherit self;
|
|
24
|
+
name = "pangea-aws";
|
|
25
|
+
};
|
|
60
26
|
}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# Web Application Architecture
|
|
2
|
+
|
|
3
|
+
Production-ready 3-tier web application architecture with load balancing, auto-scaling, database, monitoring, and optional caching/CDN capabilities.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Web Application Architecture creates a complete, production-ready infrastructure for web applications. It automatically configures networking, security, compute resources, database, monitoring, and optional performance enhancements based on environment and requirements.
|
|
8
|
+
|
|
9
|
+
## Architecture Components
|
|
10
|
+
|
|
11
|
+
### Core Infrastructure
|
|
12
|
+
- **VPC with Public/Private Subnets**: Multi-AZ network foundation with proper isolation
|
|
13
|
+
- **Application Load Balancer**: SSL termination, health checks, and traffic distribution
|
|
14
|
+
- **Auto Scaling Group**: Elastic compute capacity with configurable scaling policies
|
|
15
|
+
- **RDS Database**: Managed database with backups, encryption, and multi-AZ support
|
|
16
|
+
- **Security Groups**: Least-privilege security rules for each tier
|
|
17
|
+
|
|
18
|
+
### Optional Components
|
|
19
|
+
- **ElastiCache Redis**: In-memory caching for improved performance
|
|
20
|
+
- **CloudFront CDN**: Global content delivery network
|
|
21
|
+
- **Route53 DNS**: Custom domain management
|
|
22
|
+
- **ACM SSL Certificate**: Automatic SSL certificate provisioning
|
|
23
|
+
- **CloudWatch Monitoring**: Comprehensive monitoring, logging, and alerting
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Basic Web Application
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
web_app = web_application_architecture(:myapp, {
|
|
31
|
+
domain_name: "myapp.com",
|
|
32
|
+
environment: "production"
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
# Architecture automatically configures:
|
|
36
|
+
# - Multi-AZ VPC with public/private subnets
|
|
37
|
+
# - Application Load Balancer with SSL termination
|
|
38
|
+
# - Auto Scaling Group (min: 2, max: 10)
|
|
39
|
+
# - MySQL RDS database with Multi-AZ
|
|
40
|
+
# - CloudWatch monitoring and alarms
|
|
41
|
+
# - Security groups with proper isolation
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Development Environment
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
dev_app = web_application_architecture(:myapp_dev, {
|
|
48
|
+
domain_name: "dev.myapp.com",
|
|
49
|
+
environment: "development",
|
|
50
|
+
auto_scaling: { min: 1, max: 2 },
|
|
51
|
+
instance_type: "t3.micro",
|
|
52
|
+
database_instance_class: "db.t3.micro",
|
|
53
|
+
high_availability: false
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Production with Performance Features
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
prod_app = web_application_architecture(:myapp_prod, {
|
|
61
|
+
domain_name: "myapp.com",
|
|
62
|
+
environment: "production",
|
|
63
|
+
|
|
64
|
+
# High performance configuration
|
|
65
|
+
instance_type: "c5.large",
|
|
66
|
+
auto_scaling: { min: 3, max: 20, desired: 5 },
|
|
67
|
+
|
|
68
|
+
# Database optimization
|
|
69
|
+
database_engine: "aurora-mysql",
|
|
70
|
+
database_instance_class: "db.r5.xlarge",
|
|
71
|
+
|
|
72
|
+
# Performance features
|
|
73
|
+
enable_caching: true,
|
|
74
|
+
enable_cdn: true,
|
|
75
|
+
|
|
76
|
+
# Security enhancements
|
|
77
|
+
security: {
|
|
78
|
+
enable_waf: true,
|
|
79
|
+
enable_ddos_protection: true,
|
|
80
|
+
compliance_standards: ["PCI-DSS"]
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Configuration Parameters
|
|
86
|
+
|
|
87
|
+
### Required Parameters
|
|
88
|
+
|
|
89
|
+
- **domain_name**: Primary domain for the application
|
|
90
|
+
- **environment**: Deployment environment (`development`, `staging`, `production`)
|
|
91
|
+
|
|
92
|
+
### Network Configuration
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# Network settings
|
|
96
|
+
region: "us-east-1",
|
|
97
|
+
vpc_cidr: "10.0.0.0/16",
|
|
98
|
+
availability_zones: ["us-east-1a", "us-east-1b", "us-east-1c"]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Compute Configuration
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
# Instance and scaling settings
|
|
105
|
+
instance_type: "t3.medium",
|
|
106
|
+
auto_scaling: {
|
|
107
|
+
min: 2,
|
|
108
|
+
max: 10,
|
|
109
|
+
desired: 3
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Database Configuration
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
# Database settings
|
|
117
|
+
database_enabled: true,
|
|
118
|
+
database_engine: "mysql", # mysql, postgresql, aurora
|
|
119
|
+
database_instance_class: "db.t3.small",
|
|
120
|
+
database_allocated_storage: 100,
|
|
121
|
+
high_availability: true # Enables Multi-AZ
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Performance Features
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
# Performance optimization
|
|
128
|
+
enable_caching: true, # ElastiCache Redis cluster
|
|
129
|
+
enable_cdn: true, # CloudFront distribution
|
|
130
|
+
ssl_certificate_arn: "...", # Custom SSL cert (optional)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Security Configuration
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
security: {
|
|
137
|
+
encryption_at_rest: true,
|
|
138
|
+
encryption_in_transit: true,
|
|
139
|
+
enable_waf: true,
|
|
140
|
+
enable_ddos_protection: true,
|
|
141
|
+
compliance_standards: ["SOC2", "PCI-DSS"]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Monitoring Configuration
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
monitoring: {
|
|
149
|
+
detailed_monitoring: true,
|
|
150
|
+
enable_logging: true,
|
|
151
|
+
log_retention_days: 30,
|
|
152
|
+
enable_alerting: true,
|
|
153
|
+
enable_tracing: false
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Backup Configuration
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
backup: {
|
|
161
|
+
backup_schedule: "daily",
|
|
162
|
+
retention_days: 30,
|
|
163
|
+
cross_region_backup: true,
|
|
164
|
+
point_in_time_recovery: true
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Environment Defaults
|
|
169
|
+
|
|
170
|
+
The architecture automatically applies environment-appropriate defaults:
|
|
171
|
+
|
|
172
|
+
### Development
|
|
173
|
+
- **Instance Type**: t3.micro
|
|
174
|
+
- **Auto Scaling**: min=1, max=2
|
|
175
|
+
- **Database**: db.t3.micro
|
|
176
|
+
- **High Availability**: false
|
|
177
|
+
- **Caching**: disabled
|
|
178
|
+
- **CDN**: disabled
|
|
179
|
+
- **Backup Retention**: 1 day
|
|
180
|
+
|
|
181
|
+
### Staging
|
|
182
|
+
- **Instance Type**: t3.small
|
|
183
|
+
- **Auto Scaling**: min=1, max=4
|
|
184
|
+
- **Database**: db.t3.small
|
|
185
|
+
- **High Availability**: true
|
|
186
|
+
- **Caching**: enabled
|
|
187
|
+
- **CDN**: disabled
|
|
188
|
+
- **Backup Retention**: 3 days
|
|
189
|
+
|
|
190
|
+
### Production
|
|
191
|
+
- **Instance Type**: t3.medium
|
|
192
|
+
- **Auto Scaling**: min=2, max=10
|
|
193
|
+
- **Database**: db.r5.large
|
|
194
|
+
- **High Availability**: true
|
|
195
|
+
- **Caching**: enabled
|
|
196
|
+
- **CDN**: enabled
|
|
197
|
+
- **Backup Retention**: 30 days
|
|
198
|
+
- **WAF & DDoS Protection**: enabled
|
|
199
|
+
|
|
200
|
+
## Architecture Outputs
|
|
201
|
+
|
|
202
|
+
### Primary Outputs
|
|
203
|
+
```ruby
|
|
204
|
+
web_app.application_url # https://myapp.com
|
|
205
|
+
web_app.load_balancer_dns # myapp-alb-123.us-east-1.elb.amazonaws.com
|
|
206
|
+
web_app.database_endpoint # myapp-db.cluster-xyz.rds.amazonaws.com
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Optional Outputs
|
|
210
|
+
```ruby
|
|
211
|
+
web_app.cdn_domain # d1234567890.cloudfront.net
|
|
212
|
+
web_app.monitoring_dashboard_url # CloudWatch dashboard URL
|
|
213
|
+
web_app.estimated_monthly_cost # $247.50
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Architecture Capabilities
|
|
217
|
+
```ruby
|
|
218
|
+
web_app.capabilities = {
|
|
219
|
+
high_availability: true,
|
|
220
|
+
auto_scaling: true,
|
|
221
|
+
caching: true,
|
|
222
|
+
cdn: true,
|
|
223
|
+
ssl_termination: true,
|
|
224
|
+
monitoring: true,
|
|
225
|
+
backup: true
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Architecture Validation
|
|
230
|
+
|
|
231
|
+
### Security Compliance Score
|
|
232
|
+
```ruby
|
|
233
|
+
web_app.security_compliance_score # 95.2
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### High Availability Score
|
|
237
|
+
```ruby
|
|
238
|
+
web_app.high_availability_score # 88.0
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Performance Score
|
|
242
|
+
```ruby
|
|
243
|
+
web_app.performance_score # 92.5
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Cost Estimation
|
|
247
|
+
|
|
248
|
+
### Monthly Cost Breakdown
|
|
249
|
+
```ruby
|
|
250
|
+
web_app.cost_breakdown = {
|
|
251
|
+
components: {
|
|
252
|
+
load_balancer: 22.0,
|
|
253
|
+
web_servers: 204.0, # 3 x t3.medium
|
|
254
|
+
database: 180.0, # db.r5.large Multi-AZ
|
|
255
|
+
cache: 15.0, # ElastiCache
|
|
256
|
+
cdn: 10.0 # CloudFront
|
|
257
|
+
},
|
|
258
|
+
total: 431.0
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Customization and Overrides
|
|
263
|
+
|
|
264
|
+
### Override Database with Aurora Serverless
|
|
265
|
+
```ruby
|
|
266
|
+
web_app.override(:database) do |arch_ref|
|
|
267
|
+
aurora_serverless_cluster(:"#{arch_ref.name}_db", {
|
|
268
|
+
engine: "aurora-mysql",
|
|
269
|
+
vpc_ref: arch_ref.network.vpc,
|
|
270
|
+
scaling: { min_capacity: 2, max_capacity: 16 }
|
|
271
|
+
})
|
|
272
|
+
end
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Extend with Additional Components
|
|
276
|
+
```ruby
|
|
277
|
+
web_app.extend_with({
|
|
278
|
+
api_gateway: aws_api_gateway_rest_api(:"#{web_app.name}_api", {
|
|
279
|
+
description: "API Gateway for #{web_app.name}"
|
|
280
|
+
}),
|
|
281
|
+
|
|
282
|
+
lambda_functions: aws_lambda_function(:"#{web_app.name}_processor", {
|
|
283
|
+
runtime: "python3.9",
|
|
284
|
+
handler: "lambda_function.lambda_handler"
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Compose with Other Architectures
|
|
290
|
+
```ruby
|
|
291
|
+
web_app.compose_with do |arch_ref|
|
|
292
|
+
# Add data analytics pipeline
|
|
293
|
+
arch_ref.analytics = data_lake_architecture(:"#{arch_ref.name}_analytics", {
|
|
294
|
+
vpc_ref: arch_ref.network.vpc,
|
|
295
|
+
source_database: arch_ref.database
|
|
296
|
+
})
|
|
297
|
+
end
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Template Integration
|
|
301
|
+
|
|
302
|
+
### Basic Template Usage
|
|
303
|
+
```ruby
|
|
304
|
+
template :web_application do
|
|
305
|
+
include Pangea::Architectures
|
|
306
|
+
|
|
307
|
+
web_app = web_application_architecture(:myapp, {
|
|
308
|
+
domain_name: "myapp.com",
|
|
309
|
+
environment: "production"
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
output :application_url do
|
|
313
|
+
value web_app.application_url
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
output :monthly_cost do
|
|
317
|
+
value web_app.estimated_monthly_cost
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Multi-Environment Deployment
|
|
323
|
+
```ruby
|
|
324
|
+
template :multi_environment_web_app do
|
|
325
|
+
include Pangea::Architectures
|
|
326
|
+
|
|
327
|
+
environments = ["development", "staging", "production"]
|
|
328
|
+
|
|
329
|
+
environments.each do |env|
|
|
330
|
+
web_app = web_application_architecture(:"myapp_#{env}", {
|
|
331
|
+
domain_name: "#{env == 'production' ? '' : env + '.'}myapp.com",
|
|
332
|
+
environment: env
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
output :"#{env}_url" do
|
|
336
|
+
value web_app.application_url
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Best Practices
|
|
343
|
+
|
|
344
|
+
1. **Environment Separation**: Use separate architectures per environment
|
|
345
|
+
2. **Domain Strategy**: Use subdomains for non-production environments
|
|
346
|
+
3. **Scaling Configuration**: Set appropriate min/max based on traffic patterns
|
|
347
|
+
4. **Database Sizing**: Choose instance classes based on performance requirements
|
|
348
|
+
5. **Security**: Enable WAF and DDoS protection for production
|
|
349
|
+
6. **Monitoring**: Always enable detailed monitoring and alerting
|
|
350
|
+
7. **Backup Strategy**: Configure appropriate retention for your RPO requirements
|
|
351
|
+
8. **Cost Optimization**: Use spot instances for development environments
|
|
352
|
+
9. **SSL Certificates**: Let the architecture manage ACM certificates automatically
|
|
353
|
+
10. **Tags**: Use consistent tagging for cost allocation and management
|
|
354
|
+
|
|
355
|
+
## Troubleshooting
|
|
356
|
+
|
|
357
|
+
### High Costs
|
|
358
|
+
- Review instance types and auto scaling settings
|
|
359
|
+
- Consider using spot instances for non-production
|
|
360
|
+
- Optimize database instance class selection
|
|
361
|
+
|
|
362
|
+
### Performance Issues
|
|
363
|
+
- Enable caching with ElastiCache
|
|
364
|
+
- Add CloudFront CDN for static content
|
|
365
|
+
- Consider upgrading instance types
|
|
366
|
+
|
|
367
|
+
### Security Compliance
|
|
368
|
+
- Enable WAF and DDoS protection
|
|
369
|
+
- Ensure encryption at rest and in transit
|
|
370
|
+
- Review security group rules
|
|
371
|
+
|
|
372
|
+
### High Availability Issues
|
|
373
|
+
- Verify Multi-AZ database configuration
|
|
374
|
+
- Ensure auto scaling spans multiple availability zones
|
|
375
|
+
- Check load balancer health check configuration
|
data/lib/pangea/architectures/aws/web_application_architecture/architecture/component_creation.rb
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2025 The Pangea Authors
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
module Pangea
|
|
18
|
+
module Architectures
|
|
19
|
+
module WebApplicationArchitecture
|
|
20
|
+
class Architecture
|
|
21
|
+
# Component creation methods
|
|
22
|
+
module ComponentCreation
|
|
23
|
+
def create_components(name, attributes)
|
|
24
|
+
extend Pangea::Components if defined?(Pangea::Components)
|
|
25
|
+
|
|
26
|
+
components = {}
|
|
27
|
+
components[:network] = create_network_component(name, attributes)
|
|
28
|
+
components[:security_groups] = create_security_groups(name, attributes, components[:network])
|
|
29
|
+
components[:load_balancer] = create_load_balancer(name, attributes, components[:network], components[:security_groups])
|
|
30
|
+
components[:web_servers] = create_web_servers(name, attributes, components[:network], components[:security_groups], components[:load_balancer])
|
|
31
|
+
components[:database] = create_database(name, attributes, components[:network], components[:security_groups]) if attributes[:database_enabled] != false
|
|
32
|
+
components[:monitoring] = create_monitoring(name, attributes, components)
|
|
33
|
+
components[:cache] = create_cache_component(name, attributes, components[:network], components[:security_groups]) if attributes[:enable_caching]
|
|
34
|
+
components[:cdn] = create_cdn_component(name, attributes, components[:load_balancer]) if attributes[:enable_cdn]
|
|
35
|
+
components
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_network_component(name, attributes)
|
|
39
|
+
if defined?(Pangea::Components) && respond_to?(:secure_vpc)
|
|
40
|
+
secure_vpc(:"#{name}_network", {
|
|
41
|
+
cidr_block: attributes[:vpc_cidr] || '10.0.0.0/16',
|
|
42
|
+
availability_zones: attributes[:availability_zones] || %w[us-east-1a us-east-1b us-east-1c],
|
|
43
|
+
enable_flow_logs: attributes[:environment] == 'production',
|
|
44
|
+
tags: architecture_tags(attributes)
|
|
45
|
+
})
|
|
46
|
+
else
|
|
47
|
+
create_vpc_directly(name, attributes)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def create_security_groups(name, attributes, network)
|
|
52
|
+
if defined?(Pangea::Components) && respond_to?(:web_security_group)
|
|
53
|
+
web_security_group(:"#{name}_web_sg", {
|
|
54
|
+
vpc_ref: network.respond_to?(:vpc) ? network.vpc : network,
|
|
55
|
+
allowed_cidr_blocks: attributes[:allowed_cidr_blocks] || ['0.0.0.0/0'],
|
|
56
|
+
tags: architecture_tags(attributes)
|
|
57
|
+
})
|
|
58
|
+
else
|
|
59
|
+
create_security_groups_directly(name, attributes, network)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def create_load_balancer(name, attributes, network, security_groups)
|
|
64
|
+
if defined?(Pangea::Components) && respond_to?(:application_load_balancer)
|
|
65
|
+
subnets = network.respond_to?(:public_subnets) ? network.public_subnets : []
|
|
66
|
+
sg_refs = security_groups.respond_to?(:security_groups) ? security_groups.security_groups : [security_groups]
|
|
67
|
+
|
|
68
|
+
application_load_balancer(:"#{name}_alb", {
|
|
69
|
+
subnet_refs: subnets, security_group_refs: sg_refs,
|
|
70
|
+
enable_deletion_protection: attributes[:environment] == 'production',
|
|
71
|
+
certificate_arn: attributes[:ssl_certificate_arn],
|
|
72
|
+
tags: architecture_tags(attributes)
|
|
73
|
+
})
|
|
74
|
+
else
|
|
75
|
+
create_load_balancer_directly(name, attributes, network, security_groups)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def create_web_servers(name, attributes, network, security_groups, load_balancer)
|
|
80
|
+
if defined?(Pangea::Components) && respond_to?(:auto_scaling_web_servers)
|
|
81
|
+
subnets = network.respond_to?(:private_subnets) ? network.private_subnets : []
|
|
82
|
+
auto_scaling_web_servers(:"#{name}_web", {
|
|
83
|
+
subnet_refs: subnets,
|
|
84
|
+
target_group_ref: load_balancer.respond_to?(:target_group) ? load_balancer.target_group : nil,
|
|
85
|
+
min_size: attributes[:auto_scaling][:min], max_size: attributes[:auto_scaling][:max],
|
|
86
|
+
desired_capacity: attributes[:auto_scaling][:desired] || attributes[:auto_scaling][:min],
|
|
87
|
+
instance_type: attributes[:instance_type] || 't3.medium',
|
|
88
|
+
tags: architecture_tags(attributes)
|
|
89
|
+
})
|
|
90
|
+
else
|
|
91
|
+
create_web_servers_directly(name, attributes, network, security_groups, load_balancer)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def create_database(name, attributes, network, security_groups)
|
|
96
|
+
engine = attributes[:database_engine] || 'mysql'
|
|
97
|
+
|
|
98
|
+
if defined?(Pangea::Components)
|
|
99
|
+
component_method = engine == 'postgresql' ? :postgresql_database : :mysql_database
|
|
100
|
+
return create_database_directly(name, attributes, network, security_groups) unless respond_to?(component_method)
|
|
101
|
+
|
|
102
|
+
subnets = network.respond_to?(:private_subnets) ? network.private_subnets : []
|
|
103
|
+
vpc = network.respond_to?(:vpc) ? network.vpc : network
|
|
104
|
+
|
|
105
|
+
send(component_method, :"#{name}_db", {
|
|
106
|
+
subnet_refs: subnets, vpc_ref: vpc,
|
|
107
|
+
instance_class: attributes[:database_instance_class] || 'db.t3.micro',
|
|
108
|
+
allocated_storage: attributes[:database_allocated_storage] || 20,
|
|
109
|
+
storage_encrypted: attributes[:environment] == 'production',
|
|
110
|
+
backup_retention_days: attributes.dig(:backup, :retention_days) || (attributes[:environment] == 'production' ? 7 : 1),
|
|
111
|
+
multi_az: attributes[:high_availability] && attributes[:environment] == 'production',
|
|
112
|
+
tags: architecture_tags(attributes)
|
|
113
|
+
})
|
|
114
|
+
else
|
|
115
|
+
create_database_directly(name, attributes, network, security_groups)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def create_monitoring(name, attributes, components)
|
|
120
|
+
monitoring_resources = {}
|
|
121
|
+
monitoring_resources[:alarms] = create_cloudwatch_alarms(name, attributes, components) if attributes[:monitoring][:enable_alerting]
|
|
122
|
+
monitoring_resources[:dashboard] = create_cloudwatch_dashboard(name, attributes, components) if attributes[:monitoring][:detailed_monitoring]
|
|
123
|
+
monitoring_resources
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def create_cache_component(name, attributes, network, security_groups)
|
|
127
|
+
if defined?(Pangea::Components) && respond_to?(:elasticache_redis)
|
|
128
|
+
subnets = network.respond_to?(:private_subnets) ? network.private_subnets : []
|
|
129
|
+
elasticache_redis(:"#{name}_cache", { subnet_refs: subnets, node_type: 'cache.t3.micro', num_cache_nodes: 1, port: 6379, tags: architecture_tags(attributes) })
|
|
130
|
+
else
|
|
131
|
+
create_cache_directly(name, attributes, network, security_groups)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def create_cdn_component(name, attributes, load_balancer)
|
|
136
|
+
if defined?(Pangea::Components) && respond_to?(:cloudfront_distribution)
|
|
137
|
+
cloudfront_distribution(:"#{name}_cdn", { origin_domain_name: load_balancer.respond_to?(:dns_name) ? load_balancer.dns_name : '', price_class: 'PriceClass_100', tags: architecture_tags(attributes) })
|
|
138
|
+
else
|
|
139
|
+
create_cdn_directly(name, attributes, load_balancer)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
data/lib/pangea/architectures/aws/web_application_architecture/architecture/cost_estimation.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2025 The Pangea Authors
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
module Pangea
|
|
18
|
+
module Architectures
|
|
19
|
+
module WebApplicationArchitecture
|
|
20
|
+
class Architecture
|
|
21
|
+
# Cost estimation methods
|
|
22
|
+
module CostEstimation
|
|
23
|
+
def calculate_monthly_cost(components, _resources)
|
|
24
|
+
cost = 0.0
|
|
25
|
+
cost += 22.0 if components[:load_balancer]
|
|
26
|
+
cost += calculate_instance_costs(components[:web_servers])
|
|
27
|
+
cost += calculate_database_costs(components[:database])
|
|
28
|
+
cost += 15.0 if components[:cache]
|
|
29
|
+
cost += 10.0 if components[:cdn]
|
|
30
|
+
cost.round(2)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def calculate_instance_costs(web_servers)
|
|
36
|
+
return 0.0 unless web_servers&.[](:min_size)
|
|
37
|
+
|
|
38
|
+
instance_cost = estimate_instance_cost(web_servers[:instance_type] || 't3.medium')
|
|
39
|
+
instance_cost * web_servers[:min_size]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def calculate_database_costs(database)
|
|
43
|
+
return 0.0 unless database
|
|
44
|
+
|
|
45
|
+
estimate_database_cost(database[:instance_class] || 'db.t3.micro')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def estimate_instance_cost(instance_type)
|
|
49
|
+
case instance_type
|
|
50
|
+
when /t3\.micro/ then 8.5
|
|
51
|
+
when /t3\.small/ then 17.0
|
|
52
|
+
when /t3\.medium/ then 34.0
|
|
53
|
+
when /t3\.large/ then 67.0
|
|
54
|
+
when /c5\.large/ then 72.0
|
|
55
|
+
else 50.0
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def estimate_database_cost(instance_class)
|
|
60
|
+
case instance_class
|
|
61
|
+
when /db\.t3\.micro/ then 16.0
|
|
62
|
+
when /db\.t3\.small/ then 32.0
|
|
63
|
+
when /db\.r5\.large/ then 180.0
|
|
64
|
+
else 80.0
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|