@intentius/chant-lexicon-aws 0.41.18 → 0.41.20
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/dist/composites/index.d.ts +2 -0
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/landing-zone.d.ts +65 -0
- package/dist/composites/landing-zone.d.ts.map +1 -0
- package/dist/governance.d.ts +92 -0
- package/dist/governance.d.ts.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +2 -2
- package/src/composites/index.ts +7 -0
- package/src/composites/landing-zone.test.ts +53 -0
- package/src/composites/landing-zone.ts +150 -0
- package/src/governance.test.ts +54 -0
- package/src/governance.ts +198 -0
- package/src/index.ts +7 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail } from "./landing-zone.js";
|
|
2
|
+
export type { OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps, } from "./landing-zone.js";
|
|
1
3
|
export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda } from "./lambda-function.js";
|
|
2
4
|
export type { LambdaFunctionProps } from "./lambda-function.js";
|
|
3
5
|
export { LambdaApi } from "./lambda-api.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvG,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,IAAI,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Landing-zone bootstrap composites (#791, epic #787 C1).
|
|
3
|
+
*
|
|
4
|
+
* Fixed-shape resources for greenfield creation of the recommended
|
|
5
|
+
* governance foundation through a management-account stack. The evaluability
|
|
6
|
+
* rules (EVL002/004) require composites to declare a fixed set of resources,
|
|
7
|
+
* so these carry the foundation only; arbitrary OU/account trees are
|
|
8
|
+
* authored as config with `landingZoneConfig()` (../governance.ts) and
|
|
9
|
+
* reconciled by the AWS cloud warden (#792), and further OUs/accounts are
|
|
10
|
+
* declared as ordinary resources referencing these members' ids.
|
|
11
|
+
*
|
|
12
|
+
* The pieces compose:
|
|
13
|
+
* const org = OrganizationRoot({}); // greenfield only
|
|
14
|
+
* const lz = GovernanceFoundation({ parentRootId: org.organization.RootId });
|
|
15
|
+
* const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: [org.organization.RootId] });
|
|
16
|
+
* const at = OrganizationTrail({ bucket: "acme-org-audit" });
|
|
17
|
+
* Brownfield skips OrganizationRoot and passes the existing root id
|
|
18
|
+
* ("r-...") to GovernanceFoundation.
|
|
19
|
+
*/
|
|
20
|
+
import { Organization, OrganizationalUnit, OrganizationsPolicy, Trail } from "../generated/index.js";
|
|
21
|
+
export interface OrganizationRootProps {
|
|
22
|
+
featureSet?: "ALL" | "CONSOLIDATED_BILLING";
|
|
23
|
+
}
|
|
24
|
+
export type OrganizationRootResult = {
|
|
25
|
+
organization: InstanceType<typeof Organization>;
|
|
26
|
+
};
|
|
27
|
+
/** Creates the organization itself. Control Tower / existing orgs skip this. */
|
|
28
|
+
export declare const OrganizationRoot: import("@intentius/chant").CompositeDefinition<OrganizationRootProps, OrganizationRootResult>;
|
|
29
|
+
export interface GovernanceFoundationProps {
|
|
30
|
+
/** The organization root to hang the foundation off ("r-..." or `OrganizationRoot(...).organization.RootId`). */
|
|
31
|
+
parentRootId: string;
|
|
32
|
+
}
|
|
33
|
+
export type GovernanceFoundationResult = {
|
|
34
|
+
ouSecurity: InstanceType<typeof OrganizationalUnit>;
|
|
35
|
+
ouInfrastructure: InstanceType<typeof OrganizationalUnit>;
|
|
36
|
+
ouSandbox: InstanceType<typeof OrganizationalUnit>;
|
|
37
|
+
ouWorkloads: InstanceType<typeof OrganizationalUnit>;
|
|
38
|
+
scpDenyLeaveOrganization: InstanceType<typeof OrganizationsPolicy>;
|
|
39
|
+
scpDenyAuditTamper: InstanceType<typeof OrganizationsPolicy>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Security / Infrastructure / Sandbox / Workloads OUs,
|
|
43
|
+
* `deny-leave-organization` attached at the root and `deny-audit-tamper`
|
|
44
|
+
* on the Security OU — the same baseline `landingZoneConfig()` declares.
|
|
45
|
+
*/
|
|
46
|
+
export declare const GovernanceFoundation: import("@intentius/chant").CompositeDefinition<GovernanceFoundationProps, GovernanceFoundationResult>;
|
|
47
|
+
export interface RegionRestrictionProps {
|
|
48
|
+
/** The only regions requests may target (global services excepted). */
|
|
49
|
+
regions: string[];
|
|
50
|
+
/** Root/OU ids the SCP attaches to. */
|
|
51
|
+
targetIds: string[];
|
|
52
|
+
}
|
|
53
|
+
export type RegionRestrictionResult = {
|
|
54
|
+
scpRegionRestriction: InstanceType<typeof OrganizationsPolicy>;
|
|
55
|
+
};
|
|
56
|
+
export declare const RegionRestriction: import("@intentius/chant").CompositeDefinition<RegionRestrictionProps, RegionRestrictionResult>;
|
|
57
|
+
export interface OrganizationTrailProps {
|
|
58
|
+
/** S3 bucket the organization trail delivers into. */
|
|
59
|
+
bucket: string;
|
|
60
|
+
}
|
|
61
|
+
export type OrganizationTrailResult = {
|
|
62
|
+
trail: InstanceType<typeof Trail>;
|
|
63
|
+
};
|
|
64
|
+
export declare const OrganizationTrail: import("@intentius/chant").CompositeDefinition<OrganizationTrailProps, OrganizationTrailResult>;
|
|
65
|
+
//# sourceMappingURL=landing-zone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"landing-zone.d.ts","sourceRoot":"","sources":["../../src/composites/landing-zone.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,EACN,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,KAAK,GAAG,sBAAsB,CAAC;CAC7C;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,+FAGP,CAAC;AAMvB,MAAM,WAAW,yBAAyB;IACxC,iHAAiH;IACjH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACpD,gBAAgB,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC1D,SAAS,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACnD,WAAW,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACrD,wBAAwB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;IACnE,kBAAkB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;CAC9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,uGA6BP,CAAC;AAM3B,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,oBAAoB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,iBAAiB,iGAUP,CAAC;AAMxB,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,iGAQP,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS governance authoring (#791, epic #787 C1): the desired-state config
|
|
3
|
+
* shape the AWS cloud warden (#792) reconciles, and `landingZoneConfig()` —
|
|
4
|
+
* the typed authoring layer that emits it.
|
|
5
|
+
*
|
|
6
|
+
* This is deliberately NOT a composite. The evaluability rules (EVL002/004,
|
|
7
|
+
* #916/#952) require composites to declare a fixed set of resources, so a
|
|
8
|
+
* data-driven OU tree walker cannot be one. The split mirrors the SCM
|
|
9
|
+
* wardens: authoring emits config (this module, arbitrary cardinality);
|
|
10
|
+
* resources for greenfield bootstrap are the fixed-shape composites in
|
|
11
|
+
* `composites/landing-zone.ts`; the warden consumes only the config.
|
|
12
|
+
*
|
|
13
|
+
* GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
|
|
14
|
+
* counterparts are tracked as #791 follow-ups.
|
|
15
|
+
*/
|
|
16
|
+
/** An SCP definition, keyed by name in `AwsGovernanceConfig.scps`. */
|
|
17
|
+
export interface ScpConfig {
|
|
18
|
+
description?: string;
|
|
19
|
+
/** The policy document (SCP JSON). */
|
|
20
|
+
document: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
/** A member account declared inside an OU. */
|
|
23
|
+
export interface AccountConfig {
|
|
24
|
+
name: string;
|
|
25
|
+
email: string;
|
|
26
|
+
}
|
|
27
|
+
/** One OU: its guardrails, accounts, and child OUs, keyed by OU name. */
|
|
28
|
+
export interface OuConfig {
|
|
29
|
+
/** Names of SCPs (from `scps`) attached to this OU. */
|
|
30
|
+
scps?: string[];
|
|
31
|
+
accounts?: AccountConfig[];
|
|
32
|
+
children?: Record<string, OuConfig>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The desired-state governance tree for one AWS organization. This is the
|
|
36
|
+
* shape `wardens/aws` (#792) loads as config — the AWS counterpart of the
|
|
37
|
+
* SCM wardens' GovernanceConfig. Cycles map onto the governance verbs
|
|
38
|
+
* (#790): the OU/account tree is `org-unit`, SCPs are `policy-guardrail`,
|
|
39
|
+
* audit sinks are `audit-sink`.
|
|
40
|
+
*/
|
|
41
|
+
export interface AwsGovernanceConfig {
|
|
42
|
+
organization: {
|
|
43
|
+
/** SCP names attached at the organization root. */
|
|
44
|
+
scps?: string[];
|
|
45
|
+
};
|
|
46
|
+
/** Top-level OUs under the root, keyed by OU name. */
|
|
47
|
+
ous: Record<string, OuConfig>;
|
|
48
|
+
/** SCP definitions, keyed by the names the tree attaches. */
|
|
49
|
+
scps: Record<string, ScpConfig>;
|
|
50
|
+
/** Where audit evidence flows. */
|
|
51
|
+
auditSinks?: {
|
|
52
|
+
cloudtrail?: {
|
|
53
|
+
bucket: string;
|
|
54
|
+
multiRegion: boolean;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export declare const DENY_LEAVE_ORGANIZATION: ScpConfig;
|
|
59
|
+
export declare const DENY_AUDIT_TAMPER: ScpConfig;
|
|
60
|
+
/** Deny requests outside `regions`, excepting global services. */
|
|
61
|
+
export declare function regionRestriction(regions: readonly string[]): ScpConfig;
|
|
62
|
+
/**
|
|
63
|
+
* The recommended foundation OU structure. Exported so callers can extend it
|
|
64
|
+
* rather than restate it.
|
|
65
|
+
*/
|
|
66
|
+
export declare const FOUNDATION_OUS: Record<string, OuConfig>;
|
|
67
|
+
export interface LandingZoneConfigProps {
|
|
68
|
+
/**
|
|
69
|
+
* Start from the recommended foundation: Security / Infrastructure /
|
|
70
|
+
* Sandbox / Workloads OUs, `deny-leave-organization` at the root, and
|
|
71
|
+
* `deny-audit-tamper` on Security. Default true; your `ous`/`scps` merge
|
|
72
|
+
* over it (same-name keys win).
|
|
73
|
+
*/
|
|
74
|
+
foundation?: boolean;
|
|
75
|
+
/** Adds a region-restriction SCP at the root allowing only these regions. */
|
|
76
|
+
allowedRegions?: string[];
|
|
77
|
+
/** OU tree, merged over the foundation's. Greenfield (full tree) and brownfield (partial subtree) are both just this map. */
|
|
78
|
+
ous?: Record<string, OuConfig>;
|
|
79
|
+
/** SCP definitions, merged over the foundation's. */
|
|
80
|
+
scps?: Record<string, ScpConfig>;
|
|
81
|
+
/** Extra SCP names to attach at the organization root. */
|
|
82
|
+
rootScps?: string[];
|
|
83
|
+
/** Declare an organization CloudTrail flowing into this bucket. */
|
|
84
|
+
cloudtrailBucket?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Author the desired-state tree the AWS cloud warden (#792) reconciles.
|
|
88
|
+
* Pure. Throws when the tree attaches an SCP name with no definition; only
|
|
89
|
+
* SCPs the tree actually attaches are included in the output.
|
|
90
|
+
*/
|
|
91
|
+
export declare function landingZoneConfig(props?: LandingZoneConfigProps): AwsGovernanceConfig;
|
|
92
|
+
//# sourceMappingURL=governance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance.d.ts","sourceRoot":"","sources":["../src/governance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE;QACZ,mDAAmD;QACnD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,kCAAkC;IAClC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,OAAO,CAAA;SAAE,CAAC;KACvD,CAAC;CACH;AAMD,eAAO,MAAM,uBAAuB,EAAE,SAMrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,SAkB/B,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAuBvE;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAKnD,CAAC;AAMF,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,6HAA6H;IAC7H,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,sBAA2B,GAAG,mBAAmB,CAoCzF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -23,10 +23,12 @@ export type { CFNSchema, SchemaProperty, SchemaDefinition } from "./spec/fetch.j
|
|
|
23
23
|
export { parseCFNSchema, cfnShortName, cfnServiceName } from "./spec/parse.js";
|
|
24
24
|
export type { SchemaParseResult, ParsedResource, ParsedProperty, ParsedAttribute, ParsedPropertyType, ParsedEnum, PropertyConstraints } from "./spec/parse.js";
|
|
25
25
|
export { S3Actions, LambdaActions, DynamoDBActions, SQSActions, SNSActions, IAMActions, ECRActions, LogsActions, ECSActions } from "./actions/index.js";
|
|
26
|
-
export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda, LambdaApi, LambdaScheduled, ScheduledLambda, LambdaSqs, LambdaEventBridge, LambdaDynamoDB, LambdaS3, LambdaSns, VpcDefault, FargateAlb, AlbShared, FargateService, RdsInstance, RdsPostgres, EfsWithAccessPoint, Ec2InstanceRole, MinimalVpc, EksCluster, SolrFargateService, MicrovmApp, MICROVM_LIMITS, AgentCoreAgent, } from "./composites/index.js";
|
|
27
|
-
export type { LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps, LambdaSqsProps, LambdaEventBridgeProps, LambdaDynamoDBProps, LambdaS3Props, LambdaSnsProps, VpcDefaultProps, FargateAlbProps, AlbSharedProps, FargateServiceProps, RdsInstanceProps, RdsPostgresProps, EfsWithAccessPointProps, Ec2InstanceRoleProps, MinimalVpcProps, EksClusterProps, SolrFargateServiceProps, MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB, AgentCoreAgentProps, AgentCoreAgentResult, } from "./composites/index.js";
|
|
26
|
+
export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda, LambdaApi, LambdaScheduled, ScheduledLambda, LambdaSqs, LambdaEventBridge, LambdaDynamoDB, LambdaS3, LambdaSns, VpcDefault, FargateAlb, AlbShared, FargateService, RdsInstance, RdsPostgres, EfsWithAccessPoint, Ec2InstanceRole, MinimalVpc, EksCluster, SolrFargateService, MicrovmApp, MICROVM_LIMITS, AgentCoreAgent, OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail, } from "./composites/index.js";
|
|
27
|
+
export type { LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps, LambdaSqsProps, LambdaEventBridgeProps, LambdaDynamoDBProps, LambdaS3Props, LambdaSnsProps, VpcDefaultProps, FargateAlbProps, AlbSharedProps, FargateServiceProps, RdsInstanceProps, RdsPostgresProps, EfsWithAccessPointProps, Ec2InstanceRoleProps, MinimalVpcProps, EksClusterProps, SolrFargateServiceProps, MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB, AgentCoreAgentProps, AgentCoreAgentResult, OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps, } from "./composites/index.js";
|
|
28
28
|
export { generate, writeGeneratedFiles } from "./codegen/generate.js";
|
|
29
29
|
export { packageLexicon } from "./codegen/package.js";
|
|
30
30
|
export type { PackageOptions, PackageResult } from "./codegen/package.js";
|
|
31
31
|
export { awsCapabilityPlugin } from "./components/capability-plugin.js";
|
|
32
|
+
export { landingZoneConfig, regionRestriction, DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, FOUNDATION_OUS } from "./governance.js";
|
|
33
|
+
export type { AwsGovernanceConfig, LandingZoneConfigProps, OuConfig, ScpConfig, AccountConfig } from "./governance.js";
|
|
32
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "34e5cc07ea3f4ee6dc9f368d1439bbc43e8c5ef6a012ec0f7d03ce53816e08f6",
|
|
5
5
|
"meta.json": "2e4cae67cbc2eb2962c3dd0aa57008ae96fb725dd0118af7b04b2b44eab7722a",
|
|
6
6
|
"types/index.d.ts": "6d6b37bd14a9b40fb3ff5c66e1cb49be1ae1032de47a4e167cf5f411c943b7f5",
|
|
7
7
|
"rules/hardcoded-region.ts": "5a0eaf7ab391231fe6cd51426ece29539cb4b36f31c8dd060956638fed55722a",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"skills/chant-aws-eks.md": "8789255709ff004ad0a875fd5999edcdc66fc6e33d710db058d9f42703bcfdfe",
|
|
60
60
|
"skills/chant-aws-carve-terraform.md": "f4c6fe1c702250665f90d82b3bdaba5ea50ae75e380a8ae321dad6eb1c39683e"
|
|
61
61
|
},
|
|
62
|
-
"composite": "
|
|
62
|
+
"composite": "e0f1e5822bf0c7d39fa16c05f7e259344432b4eb815d7cc005714857a8d833b6"
|
|
63
63
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-aws",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.20",
|
|
4
4
|
"description": "AWS CloudFormation lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"typescript": "^5.9.3"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
|
-
"@intentius/chant": "^0.41.
|
|
83
|
+
"@intentius/chant": "^0.41.20",
|
|
84
84
|
"typescript": "^5.9.3"
|
|
85
85
|
}
|
|
86
86
|
}
|
package/src/composites/index.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export { OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail } from "./landing-zone";
|
|
2
|
+
export type {
|
|
3
|
+
OrganizationRootProps,
|
|
4
|
+
GovernanceFoundationProps,
|
|
5
|
+
RegionRestrictionProps,
|
|
6
|
+
OrganizationTrailProps,
|
|
7
|
+
} from "./landing-zone";
|
|
1
8
|
export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda } from "./lambda-function";
|
|
2
9
|
export type { LambdaFunctionProps } from "./lambda-function";
|
|
3
10
|
export { LambdaApi } from "./lambda-api";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { expandComposite } from "@intentius/chant";
|
|
3
|
+
import { AttrRef } from "@intentius/chant/attrref";
|
|
4
|
+
import { GovernanceFoundation, OrganizationRoot, OrganizationTrail, RegionRestriction } from "./landing-zone";
|
|
5
|
+
|
|
6
|
+
describe("GovernanceFoundation (#791)", () => {
|
|
7
|
+
test("declares the foundation OUs and baseline SCPs", () => {
|
|
8
|
+
const lz = GovernanceFoundation({ parentRootId: "r-abc1" });
|
|
9
|
+
expect(Object.keys(lz.members)).toEqual([
|
|
10
|
+
"ouSecurity",
|
|
11
|
+
"ouInfrastructure",
|
|
12
|
+
"ouSandbox",
|
|
13
|
+
"ouWorkloads",
|
|
14
|
+
"scpDenyLeaveOrganization",
|
|
15
|
+
"scpDenyAuditTamper",
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("deny-leave-organization targets the root; deny-audit-tamper targets the Security OU", () => {
|
|
20
|
+
const lz = GovernanceFoundation({ parentRootId: "r-abc1" });
|
|
21
|
+
expect((lz.scpDenyLeaveOrganization as any).props.TargetIds).toEqual(["r-abc1"]);
|
|
22
|
+
const tamperTargets = (lz.scpDenyAuditTamper as any).props.TargetIds;
|
|
23
|
+
expect(tamperTargets).toHaveLength(1);
|
|
24
|
+
expect(tamperTargets[0]).toBeInstanceOf(AttrRef);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("brownfield and greenfield wire the same way", () => {
|
|
28
|
+
const org = OrganizationRoot({});
|
|
29
|
+
const green = GovernanceFoundation({ parentRootId: org.organization.RootId });
|
|
30
|
+
expect((green.ouSecurity as any).props.ParentId).toBeInstanceOf(AttrRef);
|
|
31
|
+
const brown = GovernanceFoundation({ parentRootId: "r-live" });
|
|
32
|
+
expect((brown.ouSecurity as any).props.ParentId).toBe("r-live");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("expandComposite produces prefixed logical names", () => {
|
|
36
|
+
const expanded = expandComposite("lz", GovernanceFoundation({ parentRootId: "r-abc1" }));
|
|
37
|
+
expect([...expanded.keys()]).toContain("lzOuSecurity");
|
|
38
|
+
expect([...expanded.keys()]).toContain("lzScpDenyAuditTamper");
|
|
39
|
+
expect(expanded.size).toBe(6);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("RegionRestriction and OrganizationTrail carry the optional guardrails", () => {
|
|
43
|
+
const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: ["r-abc1"] });
|
|
44
|
+
const doc = (rr.scpRegionRestriction as any).props.Content;
|
|
45
|
+
expect(JSON.stringify(doc)).toContain("eu-west-1");
|
|
46
|
+
const trail = OrganizationTrail({ bucket: "acme-audit" });
|
|
47
|
+
expect((trail.trail as any).props).toMatchObject({
|
|
48
|
+
S3BucketName: "acme-audit",
|
|
49
|
+
IsOrganizationTrail: true,
|
|
50
|
+
IsLogging: true,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Landing-zone bootstrap composites (#791, epic #787 C1).
|
|
3
|
+
*
|
|
4
|
+
* Fixed-shape resources for greenfield creation of the recommended
|
|
5
|
+
* governance foundation through a management-account stack. The evaluability
|
|
6
|
+
* rules (EVL002/004) require composites to declare a fixed set of resources,
|
|
7
|
+
* so these carry the foundation only; arbitrary OU/account trees are
|
|
8
|
+
* authored as config with `landingZoneConfig()` (../governance.ts) and
|
|
9
|
+
* reconciled by the AWS cloud warden (#792), and further OUs/accounts are
|
|
10
|
+
* declared as ordinary resources referencing these members' ids.
|
|
11
|
+
*
|
|
12
|
+
* The pieces compose:
|
|
13
|
+
* const org = OrganizationRoot({}); // greenfield only
|
|
14
|
+
* const lz = GovernanceFoundation({ parentRootId: org.organization.RootId });
|
|
15
|
+
* const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: [org.organization.RootId] });
|
|
16
|
+
* const at = OrganizationTrail({ bucket: "acme-org-audit" });
|
|
17
|
+
* Brownfield skips OrganizationRoot and passes the existing root id
|
|
18
|
+
* ("r-...") to GovernanceFoundation.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { Composite } from "@intentius/chant";
|
|
22
|
+
import {
|
|
23
|
+
Organization,
|
|
24
|
+
OrganizationalUnit,
|
|
25
|
+
OrganizationsPolicy,
|
|
26
|
+
Trail,
|
|
27
|
+
} from "../generated";
|
|
28
|
+
import { DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, regionRestriction } from "../governance";
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// OrganizationRoot — greenfield only
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
export interface OrganizationRootProps {
|
|
35
|
+
featureSet?: "ALL" | "CONSOLIDATED_BILLING";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type OrganizationRootResult = {
|
|
39
|
+
organization: InstanceType<typeof Organization>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Creates the organization itself. Control Tower / existing orgs skip this. */
|
|
43
|
+
export const OrganizationRoot = Composite<OrganizationRootProps, OrganizationRootResult>((props) => {
|
|
44
|
+
const organization = new Organization({ FeatureSet: props.featureSet ?? "ALL" });
|
|
45
|
+
return { organization };
|
|
46
|
+
}, "OrganizationRoot");
|
|
47
|
+
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// GovernanceFoundation — the recommended foundation
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
export interface GovernanceFoundationProps {
|
|
53
|
+
/** The organization root to hang the foundation off ("r-..." or `OrganizationRoot(...).organization.RootId`). */
|
|
54
|
+
parentRootId: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type GovernanceFoundationResult = {
|
|
58
|
+
ouSecurity: InstanceType<typeof OrganizationalUnit>;
|
|
59
|
+
ouInfrastructure: InstanceType<typeof OrganizationalUnit>;
|
|
60
|
+
ouSandbox: InstanceType<typeof OrganizationalUnit>;
|
|
61
|
+
ouWorkloads: InstanceType<typeof OrganizationalUnit>;
|
|
62
|
+
scpDenyLeaveOrganization: InstanceType<typeof OrganizationsPolicy>;
|
|
63
|
+
scpDenyAuditTamper: InstanceType<typeof OrganizationsPolicy>;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Security / Infrastructure / Sandbox / Workloads OUs,
|
|
68
|
+
* `deny-leave-organization` attached at the root and `deny-audit-tamper`
|
|
69
|
+
* on the Security OU — the same baseline `landingZoneConfig()` declares.
|
|
70
|
+
*/
|
|
71
|
+
export const GovernanceFoundation = Composite<GovernanceFoundationProps, GovernanceFoundationResult>((props) => {
|
|
72
|
+
const ouSecurity = new OrganizationalUnit({ Name: "Security", ParentId: props.parentRootId });
|
|
73
|
+
const ouInfrastructure = new OrganizationalUnit({ Name: "Infrastructure", ParentId: props.parentRootId });
|
|
74
|
+
const ouSandbox = new OrganizationalUnit({ Name: "Sandbox", ParentId: props.parentRootId });
|
|
75
|
+
const ouWorkloads = new OrganizationalUnit({ Name: "Workloads", ParentId: props.parentRootId });
|
|
76
|
+
|
|
77
|
+
const scpDenyLeaveOrganization = new OrganizationsPolicy({
|
|
78
|
+
Name: "deny-leave-organization",
|
|
79
|
+
Type: "SERVICE_CONTROL_POLICY",
|
|
80
|
+
Content: DENY_LEAVE_ORGANIZATION.document,
|
|
81
|
+
Description: DENY_LEAVE_ORGANIZATION.description,
|
|
82
|
+
TargetIds: [props.parentRootId],
|
|
83
|
+
});
|
|
84
|
+
const scpDenyAuditTamper = new OrganizationsPolicy({
|
|
85
|
+
Name: "deny-audit-tamper",
|
|
86
|
+
Type: "SERVICE_CONTROL_POLICY",
|
|
87
|
+
Content: DENY_AUDIT_TAMPER.document,
|
|
88
|
+
Description: DENY_AUDIT_TAMPER.description,
|
|
89
|
+
TargetIds: [ouSecurity.Id],
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
ouSecurity,
|
|
94
|
+
ouInfrastructure,
|
|
95
|
+
ouSandbox,
|
|
96
|
+
ouWorkloads,
|
|
97
|
+
scpDenyLeaveOrganization,
|
|
98
|
+
scpDenyAuditTamper,
|
|
99
|
+
};
|
|
100
|
+
}, "GovernanceFoundation");
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// RegionRestriction — optional root guardrail
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
export interface RegionRestrictionProps {
|
|
107
|
+
/** The only regions requests may target (global services excepted). */
|
|
108
|
+
regions: string[];
|
|
109
|
+
/** Root/OU ids the SCP attaches to. */
|
|
110
|
+
targetIds: string[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type RegionRestrictionResult = {
|
|
114
|
+
scpRegionRestriction: InstanceType<typeof OrganizationsPolicy>;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const RegionRestriction = Composite<RegionRestrictionProps, RegionRestrictionResult>((props) => {
|
|
118
|
+
const policy = regionRestriction(props.regions);
|
|
119
|
+
const scpRegionRestriction = new OrganizationsPolicy({
|
|
120
|
+
Name: "region-restriction",
|
|
121
|
+
Type: "SERVICE_CONTROL_POLICY",
|
|
122
|
+
Content: policy.document,
|
|
123
|
+
Description: policy.description,
|
|
124
|
+
TargetIds: props.targetIds,
|
|
125
|
+
});
|
|
126
|
+
return { scpRegionRestriction };
|
|
127
|
+
}, "RegionRestriction");
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// OrganizationTrail — the audit sink
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
export interface OrganizationTrailProps {
|
|
134
|
+
/** S3 bucket the organization trail delivers into. */
|
|
135
|
+
bucket: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type OrganizationTrailResult = {
|
|
139
|
+
trail: InstanceType<typeof Trail>;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const OrganizationTrail = Composite<OrganizationTrailProps, OrganizationTrailResult>((props) => {
|
|
143
|
+
const trail = new Trail({
|
|
144
|
+
IsLogging: true,
|
|
145
|
+
S3BucketName: props.bucket,
|
|
146
|
+
IsMultiRegionTrail: true,
|
|
147
|
+
IsOrganizationTrail: true,
|
|
148
|
+
});
|
|
149
|
+
return { trail };
|
|
150
|
+
}, "OrganizationTrail");
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { landingZoneConfig, FOUNDATION_OUS } from "./governance";
|
|
3
|
+
|
|
4
|
+
describe("landingZoneConfig (#791)", () => {
|
|
5
|
+
test("the default is the recommended foundation", () => {
|
|
6
|
+
const cfg = landingZoneConfig();
|
|
7
|
+
expect(Object.keys(cfg.ous)).toEqual(["Security", "Infrastructure", "Sandbox", "Workloads"]);
|
|
8
|
+
expect(cfg.organization.scps).toEqual(["deny-leave-organization"]);
|
|
9
|
+
expect(cfg.ous.Security.scps).toEqual(["deny-audit-tamper"]);
|
|
10
|
+
expect(Object.keys(cfg.scps).sort()).toEqual(["deny-audit-tamper", "deny-leave-organization"]);
|
|
11
|
+
expect(cfg.auditSinks).toBeUndefined();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("custom OUs and accounts merge over the foundation (brownfield: partial trees work)", () => {
|
|
15
|
+
const cfg = landingZoneConfig({
|
|
16
|
+
ous: {
|
|
17
|
+
Workloads: {
|
|
18
|
+
children: { Prod: { accounts: [{ name: "checkout", email: "aws+checkout@acme.dev" }] } },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
// Same-name key wins over the foundation's Workloads…
|
|
23
|
+
expect(cfg.ous.Workloads.children?.Prod.accounts?.[0].name).toBe("checkout");
|
|
24
|
+
// …while the rest of the foundation persists.
|
|
25
|
+
expect(cfg.ous.Security).toEqual(FOUNDATION_OUS.Security);
|
|
26
|
+
|
|
27
|
+
const partial = landingZoneConfig({ foundation: false, ous: { Legacy: {} }, rootScps: [] });
|
|
28
|
+
expect(Object.keys(partial.ous)).toEqual(["Legacy"]);
|
|
29
|
+
expect(partial.organization.scps).toBeUndefined();
|
|
30
|
+
expect(partial.scps).toEqual({});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("allowedRegions adds a root region-restriction SCP", () => {
|
|
34
|
+
const cfg = landingZoneConfig({ allowedRegions: ["eu-west-1", "eu-central-1"] });
|
|
35
|
+
expect(cfg.organization.scps).toContain("region-restriction");
|
|
36
|
+
expect(JSON.stringify(cfg.scps["region-restriction"].document)).toContain("eu-central-1");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("cloudtrailBucket declares the audit sink", () => {
|
|
40
|
+
const cfg = landingZoneConfig({ cloudtrailBucket: "acme-audit" });
|
|
41
|
+
expect(cfg.auditSinks?.cloudtrail).toEqual({ bucket: "acme-audit", multiRegion: true });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("only attached SCPs are emitted; attaching an undefined SCP throws", () => {
|
|
45
|
+
const cfg = landingZoneConfig({
|
|
46
|
+
scps: { unused: { document: { Version: "2012-10-17", Statement: [] } } },
|
|
47
|
+
});
|
|
48
|
+
expect(cfg.scps.unused).toBeUndefined();
|
|
49
|
+
|
|
50
|
+
expect(() => landingZoneConfig({ ous: { Security: { scps: ["nope"] } } })).toThrowError(
|
|
51
|
+
'SCP "nope" is attached but not defined',
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS governance authoring (#791, epic #787 C1): the desired-state config
|
|
3
|
+
* shape the AWS cloud warden (#792) reconciles, and `landingZoneConfig()` —
|
|
4
|
+
* the typed authoring layer that emits it.
|
|
5
|
+
*
|
|
6
|
+
* This is deliberately NOT a composite. The evaluability rules (EVL002/004,
|
|
7
|
+
* #916/#952) require composites to declare a fixed set of resources, so a
|
|
8
|
+
* data-driven OU tree walker cannot be one. The split mirrors the SCM
|
|
9
|
+
* wardens: authoring emits config (this module, arbitrary cardinality);
|
|
10
|
+
* resources for greenfield bootstrap are the fixed-shape composites in
|
|
11
|
+
* `composites/landing-zone.ts`; the warden consumes only the config.
|
|
12
|
+
*
|
|
13
|
+
* GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
|
|
14
|
+
* counterparts are tracked as #791 follow-ups.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// The desired-state config shape the AWS cloud warden consumes (#792)
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
/** An SCP definition, keyed by name in `AwsGovernanceConfig.scps`. */
|
|
22
|
+
export interface ScpConfig {
|
|
23
|
+
description?: string;
|
|
24
|
+
/** The policy document (SCP JSON). */
|
|
25
|
+
document: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A member account declared inside an OU. */
|
|
29
|
+
export interface AccountConfig {
|
|
30
|
+
name: string;
|
|
31
|
+
email: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** One OU: its guardrails, accounts, and child OUs, keyed by OU name. */
|
|
35
|
+
export interface OuConfig {
|
|
36
|
+
/** Names of SCPs (from `scps`) attached to this OU. */
|
|
37
|
+
scps?: string[];
|
|
38
|
+
accounts?: AccountConfig[];
|
|
39
|
+
children?: Record<string, OuConfig>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The desired-state governance tree for one AWS organization. This is the
|
|
44
|
+
* shape `wardens/aws` (#792) loads as config — the AWS counterpart of the
|
|
45
|
+
* SCM wardens' GovernanceConfig. Cycles map onto the governance verbs
|
|
46
|
+
* (#790): the OU/account tree is `org-unit`, SCPs are `policy-guardrail`,
|
|
47
|
+
* audit sinks are `audit-sink`.
|
|
48
|
+
*/
|
|
49
|
+
export interface AwsGovernanceConfig {
|
|
50
|
+
organization: {
|
|
51
|
+
/** SCP names attached at the organization root. */
|
|
52
|
+
scps?: string[];
|
|
53
|
+
};
|
|
54
|
+
/** Top-level OUs under the root, keyed by OU name. */
|
|
55
|
+
ous: Record<string, OuConfig>;
|
|
56
|
+
/** SCP definitions, keyed by the names the tree attaches. */
|
|
57
|
+
scps: Record<string, ScpConfig>;
|
|
58
|
+
/** Where audit evidence flows. */
|
|
59
|
+
auditSinks?: {
|
|
60
|
+
cloudtrail?: { bucket: string; multiRegion: boolean };
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Baseline guardrails (shared with the bootstrap composites)
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
export const DENY_LEAVE_ORGANIZATION: ScpConfig = {
|
|
69
|
+
description: "Member accounts may not remove themselves from the organization.",
|
|
70
|
+
document: {
|
|
71
|
+
Version: "2012-10-17",
|
|
72
|
+
Statement: [{ Effect: "Deny", Action: "organizations:LeaveOrganization", Resource: "*" }],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const DENY_AUDIT_TAMPER: ScpConfig = {
|
|
77
|
+
description: "Audit trails and recorders cannot be stopped or deleted from member accounts.",
|
|
78
|
+
document: {
|
|
79
|
+
Version: "2012-10-17",
|
|
80
|
+
Statement: [
|
|
81
|
+
{
|
|
82
|
+
Effect: "Deny",
|
|
83
|
+
Action: [
|
|
84
|
+
"cloudtrail:StopLogging",
|
|
85
|
+
"cloudtrail:DeleteTrail",
|
|
86
|
+
"config:StopConfigurationRecorder",
|
|
87
|
+
"config:DeleteConfigurationRecorder",
|
|
88
|
+
"config:DeleteDeliveryChannel",
|
|
89
|
+
],
|
|
90
|
+
Resource: "*",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** Deny requests outside `regions`, excepting global services. */
|
|
97
|
+
export function regionRestriction(regions: readonly string[]): ScpConfig {
|
|
98
|
+
return {
|
|
99
|
+
description: `Deny requests outside [${regions.join(", ")}] except global services.`,
|
|
100
|
+
document: {
|
|
101
|
+
Version: "2012-10-17",
|
|
102
|
+
Statement: [
|
|
103
|
+
{
|
|
104
|
+
Effect: "Deny",
|
|
105
|
+
NotAction: [
|
|
106
|
+
"iam:*",
|
|
107
|
+
"organizations:*",
|
|
108
|
+
"route53:*",
|
|
109
|
+
"cloudfront:*",
|
|
110
|
+
"sts:*",
|
|
111
|
+
"support:*",
|
|
112
|
+
"budgets:*",
|
|
113
|
+
],
|
|
114
|
+
Resource: "*",
|
|
115
|
+
Condition: { StringNotEquals: { "aws:RequestedRegion": regions } },
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The recommended foundation OU structure. Exported so callers can extend it
|
|
124
|
+
* rather than restate it.
|
|
125
|
+
*/
|
|
126
|
+
export const FOUNDATION_OUS: Record<string, OuConfig> = {
|
|
127
|
+
Security: { scps: ["deny-audit-tamper"] },
|
|
128
|
+
Infrastructure: {},
|
|
129
|
+
Sandbox: {},
|
|
130
|
+
Workloads: {},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Authoring
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
export interface LandingZoneConfigProps {
|
|
138
|
+
/**
|
|
139
|
+
* Start from the recommended foundation: Security / Infrastructure /
|
|
140
|
+
* Sandbox / Workloads OUs, `deny-leave-organization` at the root, and
|
|
141
|
+
* `deny-audit-tamper` on Security. Default true; your `ous`/`scps` merge
|
|
142
|
+
* over it (same-name keys win).
|
|
143
|
+
*/
|
|
144
|
+
foundation?: boolean;
|
|
145
|
+
/** Adds a region-restriction SCP at the root allowing only these regions. */
|
|
146
|
+
allowedRegions?: string[];
|
|
147
|
+
/** OU tree, merged over the foundation's. Greenfield (full tree) and brownfield (partial subtree) are both just this map. */
|
|
148
|
+
ous?: Record<string, OuConfig>;
|
|
149
|
+
/** SCP definitions, merged over the foundation's. */
|
|
150
|
+
scps?: Record<string, ScpConfig>;
|
|
151
|
+
/** Extra SCP names to attach at the organization root. */
|
|
152
|
+
rootScps?: string[];
|
|
153
|
+
/** Declare an organization CloudTrail flowing into this bucket. */
|
|
154
|
+
cloudtrailBucket?: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Author the desired-state tree the AWS cloud warden (#792) reconciles.
|
|
159
|
+
* Pure. Throws when the tree attaches an SCP name with no definition; only
|
|
160
|
+
* SCPs the tree actually attaches are included in the output.
|
|
161
|
+
*/
|
|
162
|
+
export function landingZoneConfig(props: LandingZoneConfigProps = {}): AwsGovernanceConfig {
|
|
163
|
+
const foundation = props.foundation ?? true;
|
|
164
|
+
const scps: Record<string, ScpConfig> = {
|
|
165
|
+
...(foundation
|
|
166
|
+
? { "deny-leave-organization": DENY_LEAVE_ORGANIZATION, "deny-audit-tamper": DENY_AUDIT_TAMPER }
|
|
167
|
+
: {}),
|
|
168
|
+
...(props.allowedRegions?.length ? { "region-restriction": regionRestriction(props.allowedRegions) } : {}),
|
|
169
|
+
...props.scps,
|
|
170
|
+
};
|
|
171
|
+
const ous = { ...(foundation ? FOUNDATION_OUS : {}), ...props.ous };
|
|
172
|
+
const rootScps = [
|
|
173
|
+
...(foundation ? ["deny-leave-organization"] : []),
|
|
174
|
+
...(props.allowedRegions?.length ? ["region-restriction"] : []),
|
|
175
|
+
...(props.rootScps ?? []),
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
const attached = new Set(rootScps);
|
|
179
|
+
const collect = (tree: Record<string, OuConfig>): void => {
|
|
180
|
+
for (const node of Object.values(tree)) {
|
|
181
|
+
for (const s of node.scps ?? []) attached.add(s);
|
|
182
|
+
if (node.children) collect(node.children);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
collect(ous);
|
|
186
|
+
for (const name of attached) {
|
|
187
|
+
if (!scps[name]) throw new Error(`landingZoneConfig: SCP "${name}" is attached but not defined in scps`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
organization: rootScps.length ? { scps: rootScps } : {},
|
|
192
|
+
ous,
|
|
193
|
+
scps: Object.fromEntries(Object.entries(scps).filter(([n]) => attached.has(n))),
|
|
194
|
+
...(props.cloudtrailBucket
|
|
195
|
+
? { auditSinks: { cloudtrail: { bucket: props.cloudtrailBucket, multiRegion: true } } }
|
|
196
|
+
: {}),
|
|
197
|
+
};
|
|
198
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -114,6 +114,7 @@ export {
|
|
|
114
114
|
SolrFargateService,
|
|
115
115
|
MicrovmApp, MICROVM_LIMITS,
|
|
116
116
|
AgentCoreAgent,
|
|
117
|
+
OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail,
|
|
117
118
|
} from "./composites/index";
|
|
118
119
|
export type {
|
|
119
120
|
LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps,
|
|
@@ -124,6 +125,7 @@ export type {
|
|
|
124
125
|
SolrFargateServiceProps,
|
|
125
126
|
MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB,
|
|
126
127
|
AgentCoreAgentProps, AgentCoreAgentResult,
|
|
128
|
+
OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps,
|
|
127
129
|
} from "./composites/index";
|
|
128
130
|
|
|
129
131
|
// Code generation pipeline
|
|
@@ -135,3 +137,8 @@ export type { PackageOptions, PackageResult } from "./codegen/package";
|
|
|
135
137
|
// emr-*, code-deploy, …) contributed to core's capability-plugin seam. Core
|
|
136
138
|
// loads `awsCapabilityPlugin` when a project's chant.config lists this lexicon.
|
|
137
139
|
export { awsCapabilityPlugin } from "./components/capability-plugin";
|
|
140
|
+
|
|
141
|
+
// AWS governance authoring (#791): the desired-state config the AWS cloud
|
|
142
|
+
// warden (#792) reconciles, and the typed landing-zone authoring layer.
|
|
143
|
+
export { landingZoneConfig, regionRestriction, DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, FOUNDATION_OUS } from "./governance";
|
|
144
|
+
export type { AwsGovernanceConfig, LandingZoneConfigProps, OuConfig, ScpConfig, AccountConfig } from "./governance";
|