-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.py
More file actions
106 lines (87 loc) · 5.41 KB
/
Copy pathapp.py
File metadata and controls
106 lines (87 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python3
"""CDK application entry point.
Synthesizes a :class:`AppStage` per target region and deployment
environment. Each Stage groups the five stacks that make up one regional
deployment (data, WAF, backend, frontend, audit) so ``cdk deploy`` treats them
as a single unit:
ServerlessAppWaf-{region} — WAF WebACL, physically in us-east-1
(CloudFront constraint), but named per region
so each Stage is fully independent and can
be destroyed separately.
ServerlessAppData-{region} — stateful layer: DynamoDB idempotency table and
its dedicated CMK, isolated so its lifecycle is
independent of the stateless compute stack
(RETAIN/protection togglable via retain_data).
ServerlessAppBackend-{region} — Lambda, API Gateway, SSM, AppConfig
ServerlessAppFrontend-{region} — S3, CloudFront (references WAF ARN cross-region
via SSM when target region differs from us-east-1)
ServerlessAppAudit-{region} — stateful audit layer: the CloudTrail object-level
S3 data-event trail, its log bucket, and a
dedicated CMK. Audits the frontend buckets
one-way (RETAIN/protection togglable via
retain_data).
The target region is controlled by the ``region`` CDK context key.
Defaults to us-east-1 if not specified.
The stateful stacks' retention posture is controlled by the ``retain_data`` CDK
context key (``-c retain_data=true``). It defaults to ``false`` so the template
tears down cleanly; production forks set it true to flip the data and audit
stacks (tables, buckets, CMKs) to RETAIN with deletion/termination protection.
The AppConfig feature-flag rollout posture is controlled by the
``appconfig_monitor`` CDK context key (``-c appconfig_monitor=true``). It defaults
to ``false`` (all-at-once flag deployment, no monitor) so the cold/first deploy
always succeeds; enable it only after a first deploy to get a gradual rollout with
alarm-driven auto-rollback for ongoing flag changes (see README "Deployment safety").
The deployment environment is controlled by the ``env`` CDK context key,
falling back to the ``ENVIRONMENT`` variable, defaulting to ``prod``.
``prod`` keeps the un-suffixed stack names above (so the long-lived
deployment is unaffected) and routes alarms to the SNS topic. Any other
value namespaces every stack (``ServerlessAppBackend-{env}-{region}``), which makes
ephemeral per-developer or per-branch deployments collision-free in a
shared account, and disables alarm paging for them.
Usage:
cdk deploy --all # prod stage in us-east-1 (default)
cdk deploy --all -c region=ap-southeast-1 # separate Singapore Stage
cdk deploy --all -c env=alice-feature-x # ephemeral developer stage
make deploy ENV=alice-feature-x # same, via the Makefile
Each Stage is fully independent — destroying one does not affect any other.
All five stacks for a given region+environment are destroyed together:
cdk destroy --all -c region=ap-southeast-1
cdk destroy --all -c env=alice-feature-x
"""
import os
import aws_cdk as cdk
from infrastructure.app_stage import DEFAULT_ENV_NAME, AppStage, stage_id
app = cdk.App()
# Target region for the backend and frontend stacks. Defaults to us-east-1
# when no context value is provided. WAF is always pinned to us-east-1
# inside the Stage regardless of this value.
target_region: str = app.node.try_get_context("region") or "us-east-1"
# Deployment environment. Context key wins (explicit per-invocation intent);
# the ENVIRONMENT variable serves pipelines that export it once per job;
# the default keeps `cdk deploy` pointing at the long-lived prod stacks.
env_name: str = app.node.try_get_context("env") or os.environ.get("ENVIRONMENT") or DEFAULT_ENV_NAME
# Retention switch for the stateful data stack. Context values arrive as
# strings on the CLI (`-c retain_data=true`) or as a native bool from
# cdk.json, so normalise both. Default False keeps the template destroy-friendly.
_retain_ctx = app.node.try_get_context("retain_data")
retain_data: bool = _retain_ctx if isinstance(_retain_ctx, bool) else str(_retain_ctx).lower() == "true"
# Opt-in AppConfig gradual rollout + alarm rollback monitor (`-c appconfig_monitor=true`).
# Default False so the cold/first deploy always succeeds: a CFN-managed AppConfig
# deployment with a monitor rolls back when its alarm is INSUFFICIENT_DATA, which a
# fresh stack's metric always is — see backend_app._attach_appconfig_rollback_monitor
# and README "Deployment safety". Turn it on only AFTER a first all-at-once deploy has
# produced metric data, to protect ongoing flag changes.
_monitor_ctx = app.node.try_get_context("appconfig_monitor")
appconfig_monitor: bool = _monitor_ctx if isinstance(_monitor_ctx, bool) else str(_monitor_ctx).lower() == "true"
# Stage id composition lives next to the Stage (app_stage.stage_id):
# prod keeps the legacy id so existing cdk.out assembly paths and tooling
# keyed on the stage name stay stable; other envs get their own id.
AppStage(
app,
stage_id(env_name, target_region),
region=target_region,
env_name=env_name,
retain_data=retain_data,
appconfig_monitor=appconfig_monitor,
)
app.synth()