@fjall/components-infrastructure 0.73.17 → 0.74.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/dist/lib/__tests__/patterns/__snapshots__/compute.test.js.snap +433 -0
- package/dist/lib/__tests__/patterns/compute.test.d.ts +1 -0
- package/dist/lib/__tests__/patterns/compute.test.js +137 -0
- package/dist/lib/__tests__/simple.test.d.ts +0 -0
- package/dist/lib/__tests__/simple.test.js +12 -0
- package/dist/lib/config/aws/disasterRecovery.d.ts +27 -0
- package/dist/lib/config/aws/disasterRecovery.js +226 -0
- package/dist/lib/patterns/aws/managedAccount.js +15 -2
- package/dist/lib/resources/aws/backup/backupPlan.d.ts +19 -0
- package/dist/lib/resources/aws/backup/backupPlan.js +71 -0
- package/dist/lib/resources/aws/backup/backupVault.d.ts +19 -0
- package/dist/lib/resources/aws/backup/backupVault.js +43 -0
- package/dist/lib/resources/aws/backup/index.d.ts +2 -0
- package/dist/lib/resources/aws/backup/index.js +19 -0
- package/dist/lib/resources/aws/index.d.ts +1 -0
- package/dist/lib/resources/aws/index.js +2 -1
- package/dist/lib/resources/aws/organisations/account.d.ts +37 -0
- package/dist/lib/resources/aws/organisations/account.js +220 -0
- package/dist/lib/resources/aws/organisations/delegatedAdministrator.d.ts +14 -0
- package/dist/lib/resources/aws/organisations/delegatedAdministrator.js +61 -0
- package/dist/lib/resources/aws/organisations/index.d.ts +8 -0
- package/dist/lib/resources/aws/organisations/index.js +22 -0
- package/dist/lib/resources/aws/organisations/interfaces.d.ts +105 -0
- package/dist/lib/resources/aws/organisations/interfaces.js +3 -0
- package/dist/lib/resources/aws/organisations/organisation.d.ts +47 -0
- package/dist/lib/resources/aws/organisations/organisation.js +263 -0
- package/dist/lib/resources/aws/organisations/organisationalUnit.d.ts +28 -0
- package/dist/lib/resources/aws/organisations/organisationalUnit.js +170 -0
- package/dist/lib/resources/aws/organisations/policy.d.ts +17 -0
- package/dist/lib/resources/aws/organisations/policy.js +93 -0
- package/dist/lib/resources/aws/organisations/trustedServiceAccess.d.ts +13 -0
- package/dist/lib/resources/aws/organisations/trustedServiceAccess.js +58 -0
- package/dist/lib/resources/aws/organisations/types.d.ts +165 -0
- package/dist/lib/resources/aws/organisations/types.js +36 -0
- package/dist/lib/utils/directTagging.d.ts +31 -0
- package/dist/lib/utils/directTagging.js +86 -0
- package/dist/lib/utils/fjallConstruct.d.ts +8 -0
- package/dist/lib/utils/fjallConstruct.js +18 -0
- package/dist/lib/utils/fjallStackSynthesizer.d.ts +9 -0
- package/dist/lib/utils/fjallStackSynthesizer.js +22 -0
- package/dist/lib/utils/getConfig.d.ts +1 -0
- package/dist/lib/utils/getConfig.js +2 -1
- package/dist/lib/utils/tagContext.d.ts +28 -0
- package/dist/lib/utils/tagContext.js +53 -0
- package/dist/lib/utils/tagSynthesizer.d.ts +13 -0
- package/dist/lib/utils/tagSynthesizer.js +55 -0
- package/package.json +3 -3
- package/dist/lib/patterns/aws/ec2.d.ts +0 -43
- package/dist/lib/patterns/aws/ec2.js +0 -123
- package/dist/lib/utils/getCidr.d.ts +0 -8
- package/dist/lib/utils/getCidr.js +0 -40
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Account = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const customResources = require("aws-cdk-lib/custom-resources");
|
|
6
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
7
|
+
const constructs_1 = require("constructs");
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
const awsCustomResource_1 = require("../utilities/awsCustomResource");
|
|
10
|
+
/**
|
|
11
|
+
* AWS Account construct for managing member accounts
|
|
12
|
+
*/
|
|
13
|
+
class Account extends constructs_1.Construct {
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
super(scope, id);
|
|
16
|
+
this.accountName = props.accountName;
|
|
17
|
+
this.email = props.email;
|
|
18
|
+
const importOnDuplicate = props.importOnDuplicate ?? true;
|
|
19
|
+
const removalPolicy = props.removalPolicy ?? aws_cdk_lib_1.RemovalPolicy.RETAIN;
|
|
20
|
+
const iamUserAccessToBilling = props.iamUserAccessToBilling ?? types_1.IamUserAccessToBilling.ALLOW;
|
|
21
|
+
const roleName = props.roleName ?? "OrganisationAccountAccessRole";
|
|
22
|
+
// Create account
|
|
23
|
+
const accountResource = new awsCustomResource_1.AwsCustomResource(this, "AccountResource", {
|
|
24
|
+
functionName: `manageAccount${this.normalizeAccountName(props.accountName)}`,
|
|
25
|
+
onCreate: {
|
|
26
|
+
service: "organizations",
|
|
27
|
+
action: "CreateAccountCommand",
|
|
28
|
+
parameters: {
|
|
29
|
+
Email: props.email,
|
|
30
|
+
AccountName: props.accountName,
|
|
31
|
+
RoleName: roleName,
|
|
32
|
+
IamUserAccessToBilling: iamUserAccessToBilling
|
|
33
|
+
},
|
|
34
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`account-${props.email}`),
|
|
35
|
+
ignoreErrorCodesMatching: importOnDuplicate
|
|
36
|
+
? "FinalizingOrganizationException|AlreadyInOrganizationException"
|
|
37
|
+
: undefined
|
|
38
|
+
},
|
|
39
|
+
onUpdate: {
|
|
40
|
+
service: "organizations",
|
|
41
|
+
action: "DescribeAccountCommand",
|
|
42
|
+
parameters: {
|
|
43
|
+
AccountId: this.accountId
|
|
44
|
+
},
|
|
45
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`account-${props.email}`)
|
|
46
|
+
},
|
|
47
|
+
onDelete: removalPolicy === aws_cdk_lib_1.RemovalPolicy.DESTROY
|
|
48
|
+
? {
|
|
49
|
+
service: "organizations",
|
|
50
|
+
action: "CloseAccountCommand",
|
|
51
|
+
parameters: {
|
|
52
|
+
AccountId: this.accountId
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
: undefined,
|
|
56
|
+
resourceType: "Custom::Account",
|
|
57
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
58
|
+
new aws_iam_1.PolicyStatement({
|
|
59
|
+
actions: [
|
|
60
|
+
"organizations:CreateAccount",
|
|
61
|
+
"organizations:DescribeAccount",
|
|
62
|
+
"organizations:CloseAccount",
|
|
63
|
+
"organizations:ListAccounts",
|
|
64
|
+
"organizations:MoveAccount"
|
|
65
|
+
],
|
|
66
|
+
resources: ["*"],
|
|
67
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
68
|
+
})
|
|
69
|
+
])
|
|
70
|
+
});
|
|
71
|
+
// Get account details from the create operation
|
|
72
|
+
this.accountId = accountResource.getResponseField("CreateAccountStatus.AccountId");
|
|
73
|
+
this.accountArn = `arn:aws:organizations::${this.node.tryGetContext("account")}:account/o-${this.node.tryGetContext("organisationId")}/${this.accountId}`;
|
|
74
|
+
// Move account to the specified parent OU (if not root)
|
|
75
|
+
if (props.parent.organisationalUnitName !== "Root") {
|
|
76
|
+
new awsCustomResource_1.AwsCustomResource(this, "MoveAccount", {
|
|
77
|
+
functionName: `moveAccount${this.normalizeAccountName(props.accountName)}`,
|
|
78
|
+
onCreate: {
|
|
79
|
+
service: "organizations",
|
|
80
|
+
action: "MoveAccountCommand",
|
|
81
|
+
parameters: {
|
|
82
|
+
AccountId: this.accountId,
|
|
83
|
+
SourceParentId: this.getRootId(),
|
|
84
|
+
DestinationParentId: props.parent.organisationalUnitId
|
|
85
|
+
},
|
|
86
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`move-account-${this.accountId}-to-${props.parent.organisationalUnitId}`)
|
|
87
|
+
},
|
|
88
|
+
resourceType: "Custom::MoveAccount",
|
|
89
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
90
|
+
new aws_iam_1.PolicyStatement({
|
|
91
|
+
actions: ["organizations:MoveAccount", "organizations:ListRoots"],
|
|
92
|
+
resources: ["*"],
|
|
93
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
94
|
+
})
|
|
95
|
+
])
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Export account details
|
|
99
|
+
new aws_cdk_lib_1.CfnOutput(this, "AccountId", {
|
|
100
|
+
key: `${id}Id`,
|
|
101
|
+
value: this.accountId,
|
|
102
|
+
exportName: `${id}Id`
|
|
103
|
+
});
|
|
104
|
+
new aws_cdk_lib_1.CfnOutput(this, "AccountArn", {
|
|
105
|
+
key: `${id}Arn`,
|
|
106
|
+
value: this.accountArn,
|
|
107
|
+
exportName: `${id}Arn`
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Attach policy to this account
|
|
112
|
+
*/
|
|
113
|
+
attachPolicy(policy) {
|
|
114
|
+
const policyName = this.normalizePolicyName(policy.policyName);
|
|
115
|
+
new awsCustomResource_1.AwsCustomResource(this, `AttachPolicy${policyName}`, {
|
|
116
|
+
functionName: `attachPolicyToAccount${policyName}${this.normalizeAccountName(this.accountName)}`,
|
|
117
|
+
onCreate: {
|
|
118
|
+
service: "organizations",
|
|
119
|
+
action: "AttachPolicyCommand",
|
|
120
|
+
parameters: {
|
|
121
|
+
PolicyId: policy.policyId,
|
|
122
|
+
TargetId: this.accountId
|
|
123
|
+
},
|
|
124
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`attach-policy-${policy.policyId}-to-${this.accountId}`)
|
|
125
|
+
},
|
|
126
|
+
onDelete: {
|
|
127
|
+
service: "organizations",
|
|
128
|
+
action: "DetachPolicyCommand",
|
|
129
|
+
parameters: {
|
|
130
|
+
PolicyId: policy.policyId,
|
|
131
|
+
TargetId: this.accountId
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
resourceType: "Custom::AttachPolicyToAccount",
|
|
135
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
136
|
+
new aws_iam_1.PolicyStatement({
|
|
137
|
+
actions: [
|
|
138
|
+
"organizations:AttachPolicy",
|
|
139
|
+
"organizations:DetachPolicy",
|
|
140
|
+
"organizations:ListPoliciesForTarget"
|
|
141
|
+
],
|
|
142
|
+
resources: ["*"],
|
|
143
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
144
|
+
})
|
|
145
|
+
])
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Delegate administrator privileges for a service
|
|
150
|
+
*/
|
|
151
|
+
delegateAdministrator(servicePrincipal) {
|
|
152
|
+
const serviceName = this.normalizeServiceName(servicePrincipal);
|
|
153
|
+
new awsCustomResource_1.AwsCustomResource(this, `DelegateAdmin${serviceName}`, {
|
|
154
|
+
functionName: `delegateAdmin${serviceName}${this.normalizeAccountName(this.accountName)}`,
|
|
155
|
+
onCreate: {
|
|
156
|
+
service: "organizations",
|
|
157
|
+
action: "RegisterDelegatedAdministratorCommand",
|
|
158
|
+
parameters: {
|
|
159
|
+
AccountId: this.accountId,
|
|
160
|
+
ServicePrincipal: servicePrincipal
|
|
161
|
+
},
|
|
162
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`delegate-admin-${servicePrincipal}-to-${this.accountId}`)
|
|
163
|
+
},
|
|
164
|
+
onDelete: {
|
|
165
|
+
service: "organizations",
|
|
166
|
+
action: "DeregisterDelegatedAdministratorCommand",
|
|
167
|
+
parameters: {
|
|
168
|
+
AccountId: this.accountId,
|
|
169
|
+
ServicePrincipal: servicePrincipal
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
resourceType: "Custom::DelegateAdministrator",
|
|
173
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
174
|
+
new aws_iam_1.PolicyStatement({
|
|
175
|
+
actions: [
|
|
176
|
+
"organizations:RegisterDelegatedAdministrator",
|
|
177
|
+
"organizations:DeregisterDelegatedAdministrator",
|
|
178
|
+
"organizations:ListDelegatedAdministrators"
|
|
179
|
+
],
|
|
180
|
+
resources: ["*"],
|
|
181
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
182
|
+
})
|
|
183
|
+
])
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Helper to normalize account names for construct IDs
|
|
188
|
+
*/
|
|
189
|
+
normalizeAccountName(accountName) {
|
|
190
|
+
return accountName
|
|
191
|
+
.replace(/[^a-zA-Z0-9]/g, "")
|
|
192
|
+
.replace(/^([a-z])/, (match) => match.toUpperCase());
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Helper to normalize policy names for construct IDs
|
|
196
|
+
*/
|
|
197
|
+
normalizePolicyName(policyName) {
|
|
198
|
+
return policyName
|
|
199
|
+
.replace(/[^a-zA-Z0-9]/g, "")
|
|
200
|
+
.replace(/^([a-z])/, (match) => match.toUpperCase());
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Helper to normalize service names for construct IDs
|
|
204
|
+
*/
|
|
205
|
+
normalizeServiceName(servicePrincipal) {
|
|
206
|
+
return servicePrincipal
|
|
207
|
+
.replace(/[^a-zA-Z0-9]/g, "")
|
|
208
|
+
.replace(/^([a-z])/, (match) => match.toUpperCase());
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get the root ID (placeholder - would need custom logic to get this)
|
|
212
|
+
*/
|
|
213
|
+
getRootId() {
|
|
214
|
+
// This would need to be implemented with a custom resource to get the root ID
|
|
215
|
+
// For now, using a placeholder
|
|
216
|
+
return this.node.tryGetContext("organisationRootId") || "r-placeholder";
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.Account = Account;
|
|
220
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9yZXNvdXJjZXMvYXdzL29yZ2FuaXNhdGlvbnMvYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBdUQ7QUFDdkQsZ0VBQWdFO0FBQ2hFLGlEQUE4RDtBQUM5RCwyQ0FBdUM7QUFFdkMsbUNBQStEO0FBQy9ELHNFQUFtRTtBQUVuRTs7R0FFRztBQUNILE1BQWEsT0FBUSxTQUFRLHNCQUFTO0lBTXBDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBbUI7UUFDM0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7UUFDckMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3pCLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQztRQUMxRCxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxJQUFJLDJCQUFhLENBQUMsTUFBTSxDQUFDO1FBQ2xFLE1BQU0sc0JBQXNCLEdBQzFCLEtBQUssQ0FBQyxzQkFBc0IsSUFBSSw4QkFBc0IsQ0FBQyxLQUFLLENBQUM7UUFDL0QsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSwrQkFBK0IsQ0FBQztRQUVuRSxpQkFBaUI7UUFDakIsTUFBTSxlQUFlLEdBQUcsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7WUFDckUsWUFBWSxFQUFFLGdCQUFnQixJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQzVFLFFBQVEsRUFBRTtnQkFDUixPQUFPLEVBQUUsZUFBZTtnQkFDeEIsTUFBTSxFQUFFLHNCQUFzQjtnQkFDOUIsVUFBVSxFQUFFO29CQUNWLEtB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TyxDQUFDLFVBQVUsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssU0FBUztRQUNmLDhFQUE4RTtRQUM5RSwrQkFBK0I7UUFDL0IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLGVBQWUsQ0FBQztJQUMxRSxDQUFDO0NBQ0Y7QUE5T0QsMEJBOE9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2ZuT3V0cHV0LCBSZW1vdmFsUG9saWN5IH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgKiBhcyBjdXN0b21SZXNvdXJjZXMgZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIjtcbmltcG9ydCB7IEVmZmVjdCwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBJQWNjb3VudCwgSVBvbGljeSB9IGZyb20gXCIuL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IEFjY291bnRQcm9wcywgSWFtVXNlckFjY2Vzc1RvQmlsbGluZyB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBBd3NDdXN0b21SZXNvdXJjZSB9IGZyb20gXCIuLi91dGlsaXRpZXMvYXdzQ3VzdG9tUmVzb3VyY2VcIjtcblxuLyoqXG4gKiBBV1MgQWNjb3VudCBjb25zdHJ1Y3QgZm9yIG1hbmFnaW5nIG1lbWJlciBhY2NvdW50c1xuICovXG5leHBvcnQgY2xhc3MgQWNjb3VudCBleHRlbmRzIENvbnN0cnVjdCBpbXBsZW1lbnRzIElBY2NvdW50IHtcbiAgcmVhZG9ubHkgYWNjb3VudElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGFjY291bnRBcm46IHN0cmluZztcbiAgcmVhZG9ubHkgYWNjb3VudE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgZW1haWw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQWNjb3VudFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuYWNjb3VudE5hbWUgPSBwcm9wcy5hY2NvdW50TmFtZTtcbiAgICB0aGlzLmVtYWlsID0gcHJvcHMuZW1haWw7XG4gICAgY29uc3QgaW1wb3J0T25EdXBsaWNhdGUgPSBwcm9wcy5pbXBvcnRPbkR1cGxpY2F0ZSA/PyB0cnVlO1xuICAgIGNvbnN0IHJlbW92YWxQb2xpY3kgPSBwcm9wcy5yZW1vdmFsUG9saWN5ID8/IFJlbW92YWxQb2xpY3kuUkVUQUlOO1xuICAgIGNvbnN0IGlhbVVzZXJBY2Nlc3NUb0JpbGxpbmcgPVxuICAgICAgcHJvcHMuaWFtVXNlckFjY2Vzc1RvQmlsbGluZyA/PyBJYW1Vc2VyQWNjZXNzVG9CaWxsaW5nLkFMTE9XO1xuICAgIGNvbnN0IHJvbGVOYW1lID0gcHJvcHMucm9sZU5hbWUgPz8gXCJPcmdhbmlzYXRpb25BY2NvdW50QWNjZXNzUm9sZVwiO1xuXG4gICAgLy8gQ3JlYXRlIGFjY291bnRcbiAgICBjb25zdCBhY2NvdW50UmVzb3VyY2UgPSBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJBY2NvdW50UmVzb3VyY2VcIiwge1xuICAgICAgZnVuY3Rpb25OYW1lOiBgbWFuYWdlQWNjb3VudCR7dGhpcy5ub3JtYWxpemVBY2NvdW50TmFtZShwcm9wcy5hY2NvdW50TmFtZSl9YCxcbiAgICAgIG9uQ3JlYXRlOiB7XG4gICAgICAgIHNlcnZpY2U6IFwib3JnYW5pemF0aW9uc1wiLFxuICAgICAgICBhY3Rpb246IFwiQ3JlYXRlQWNjb3VudENvbW1hbmRcIixcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIEVtYWlsOiBwcm9wcy5lbWFpbCxcbiAgICAgICAgICBBY2NvdW50TmFtZTogcHJvcHMuYWNjb3VudE5hbWUsXG4gICAgICAgICAgUm9sZU5hbWU6IHJvbGVOYW1lLFxuICAgICAgICAgIElhbVVzZXJBY2Nlc3NUb0JpbGxpbmc6IGlhbVVzZXJBY2Nlc3NUb0JpbGxpbmdcbiAgICAgICAgfSxcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBjdXN0b21SZXNvdXJjZXMuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKFxuICAgICAgICAgIGBhY2NvdW50LSR7cHJvcHMuZW1haWx9YFxuICAgICAgICApLFxuICAgICAgICBpZ25vcmVFcnJvckNvZGVzTWF0Y2hpbmc6IGltcG9ydE9uRHVwbGljYXRlXG4gICAgICAgICAgPyBcIkZpbmFsaXppbmdPcmdhbml6YXRpb25FeGNlcHRpb258QWxyZWFkeUluT3JnYW5pemF0aW9uRXhjZXB0aW9uXCJcbiAgICAgICAgICA6IHVuZGVmaW5lZFxuICAgICAgfSxcbiAgICAgIG9uVXBkYXRlOiB7XG4gICAgICAgIHNlcnZpY2U6IFwib3JnYW5pemF0aW9uc1wiLFxuICAgICAgICBhY3Rpb246IFwiRGVzY3JpYmVBY2NvdW50Q29tbWFuZFwiLFxuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgQWNjb3VudElkOiB0aGlzLmFjY291bnRJZFxuICAgICAgICB9LFxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IGN1c3RvbVJlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQub2YoXG4gICAgICAgICAgYGFjY291bnQtJHtwcm9wcy5lbWFpbH1gXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICBvbkRlbGV0ZTpcbiAgICAgICAgcmVtb3ZhbFBvbGljeSA9PT0gUmVtb3ZhbFBvbGljeS5ERVNUUk9ZXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIHNlcnZpY2U6IFwib3JnYW5pemF0aW9uc1wiLFxuICAgICAgICAgICAgICBhY3Rpb246IFwiQ2xvc2VBY2NvdW50Q29tbWFuZFwiLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgQWNjb3VudElkOiB0aGlzLmFjY291bnRJZFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpBY2NvdW50XCIsXG4gICAgICBwb2xpY3k6IGN1c3RvbVJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU3RhdGVtZW50cyhbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpDcmVhdGVBY2NvdW50XCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6RGVzY3JpYmVBY2NvdW50XCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6Q2xvc2VBY2NvdW50XCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6TGlzdEFjY291bnRzXCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6TW92ZUFjY291bnRcIlxuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XXG4gICAgICAgIH0pXG4gICAgICBdKVxuICAgIH0pO1xuXG4gICAgLy8gR2V0IGFjY291bnQgZGV0YWlscyBmcm9tIHRoZSBjcmVhdGUgb3BlcmF0aW9uXG4gICAgdGhpcy5hY2NvdW50SWQgPSBhY2NvdW50UmVzb3VyY2UuZ2V0UmVzcG9uc2VGaWVsZChcbiAgICAgIFwiQ3JlYXRlQWNjb3VudFN0YXR1cy5BY2NvdW50SWRcIlxuICAgICk7XG4gICAgdGhpcy5hY2NvdW50QXJuID0gYGFybjphd3M6b3JnYW5pemF0aW9uczo6JHt0aGlzLm5vZGUudHJ5R2V0Q29udGV4dChcImFjY291bnRcIil9OmFjY291bnQvby0ke3RoaXMubm9kZS50cnlHZXRDb250ZXh0KFwib3JnYW5pc2F0aW9uSWRcIil9LyR7dGhpcy5hY2NvdW50SWR9YDtcblxuICAgIC8vIE1vdmUgYWNjb3VudCB0byB0aGUgc3BlY2lmaWVkIHBhcmVudCBPVSAoaWYgbm90IHJvb3QpXG4gICAgaWYgKHByb3BzLnBhcmVudC5vcmdhbmlzYXRpb25hbFVuaXROYW1lICE9PSBcIlJvb3RcIikge1xuICAgICAgbmV3IEF3c0N1c3RvbVJlc291cmNlKHRoaXMsIFwiTW92ZUFjY291bnRcIiwge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IGBtb3ZlQWNjb3VudCR7dGhpcy5ub3JtYWxpemVBY2NvdW50TmFtZShwcm9wcy5hY2NvdW50TmFtZSl9YCxcbiAgICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgICBzZXJ2aWNlOiBcIm9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgICBhY3Rpb246IFwiTW92ZUFjY291bnRDb21tYW5kXCIsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgQWNjb3VudElkOiB0aGlzLmFjY291bnRJZCxcbiAgICAgICAgICAgIFNvdXJjZVBhcmVudElkOiB0aGlzLmdldFJvb3RJZCgpLFxuICAgICAgICAgICAgRGVzdGluYXRpb25QYXJlbnRJZDogcHJvcHMucGFyZW50Lm9yZ2FuaXNhdGlvbmFsVW5pdElkXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IGN1c3RvbVJlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQub2YoXG4gICAgICAgICAgICBgbW92ZS1hY2NvdW50LSR7dGhpcy5hY2NvdW50SWR9LXRvLSR7cHJvcHMucGFyZW50Lm9yZ2FuaXNhdGlvbmFsVW5pdElkfWBcbiAgICAgICAgICApXG4gICAgICAgIH0sXG4gICAgICAgIHJlc291cmNlVHlwZTogXCJDdXN0b206Ok1vdmVBY2NvdW50XCIsXG4gICAgICAgIHBvbGljeTogY3VzdG9tUmVzb3VyY2VzLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TdGF0ZW1lbnRzKFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcIm9yZ2FuaXphdGlvbnM6TW92ZUFjY291bnRcIiwgXCJvcmdhbml6YXRpb25zOkxpc3RSb290c1wiXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1wiKlwiXSxcbiAgICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XXG4gICAgICAgICAgfSlcbiAgICAgICAgXSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEV4cG9ydCBhY2NvdW50IGRldGFpbHNcbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiQWNjb3VudElkXCIsIHtcbiAgICAgIGtleTogYCR7aWR9SWRgLFxuICAgICAgdmFsdWU6IHRoaXMuYWNjb3VudElkLFxuICAgICAgZXhwb3J0TmFtZTogYCR7aWR9SWRgXG4gICAgfSk7XG5cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiQWNjb3VudEFyblwiLCB7XG4gICAgICBrZXk6IGAke2lkfUFybmAsXG4gICAgICB2YWx1ZTogdGhpcy5hY2NvdW50QXJuLFxuICAgICAgZXhwb3J0TmFtZTogYCR7aWR9QXJuYFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCBwb2xpY3kgdG8gdGhpcyBhY2NvdW50XG4gICAqL1xuICBhdHRhY2hQb2xpY3kocG9saWN5OiBJUG9saWN5KTogdm9pZCB7XG4gICAgY29uc3QgcG9saWN5TmFtZSA9IHRoaXMubm9ybWFsaXplUG9saWN5TmFtZShwb2xpY3kucG9saWN5TmFtZSk7XG5cbiAgICBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgYEF0dGFjaFBvbGljeSR7cG9saWN5TmFtZX1gLCB7XG4gICAgICBmdW5jdGlvbk5hbWU6IGBhdHRhY2hQb2xpY3lUb0FjY291bnQke3BvbGljeU5hbWV9JHt0aGlzLm5vcm1hbGl6ZUFjY291bnROYW1lKHRoaXMuYWNjb3VudE5hbWUpfWAsXG4gICAgICBvbkNyZWF0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIm9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgYWN0aW9uOiBcIkF0dGFjaFBvbGljeUNvbW1hbmRcIixcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIFBvbGljeUlkOiBwb2xpY3kucG9saWN5SWQsXG4gICAgICAgICAgVGFyZ2V0SWQ6IHRoaXMuYWNjb3VudElkXG4gICAgICAgIH0sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tUmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZihcbiAgICAgICAgICBgYXR0YWNoLXBvbGljeS0ke3BvbGljeS5wb2xpY3lJZH0tdG8tJHt0aGlzLmFjY291bnRJZH1gXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICBvbkRlbGV0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIm9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgYWN0aW9uOiBcIkRldGFjaFBvbGljeUNvbW1hbmRcIixcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIFBvbGljeUlkOiBwb2xpY3kucG9saWN5SWQsXG4gICAgICAgICAgVGFyZ2V0SWQ6IHRoaXMuYWNjb3VudElkXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpBdHRhY2hQb2xpY3lUb0FjY291bnRcIixcbiAgICAgIHBvbGljeTogY3VzdG9tUmVzb3VyY2VzLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TdGF0ZW1lbnRzKFtcbiAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOkF0dGFjaFBvbGljeVwiLFxuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOkRldGFjaFBvbGljeVwiLFxuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOkxpc3RQb2xpY2llc0ZvclRhcmdldFwiXG4gICAgICAgICAgXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1dcbiAgICAgICAgfSlcbiAgICAgIF0pXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZWdhdGUgYWRtaW5pc3RyYXRvciBwcml2aWxlZ2VzIGZvciBhIHNlcnZpY2VcbiAgICovXG4gIGRlbGVnYXRlQWRtaW5pc3RyYXRvcihzZXJ2aWNlUHJpbmNpcGFsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzZXJ2aWNlTmFtZSA9IHRoaXMubm9ybWFsaXplU2VydmljZU5hbWUoc2VydmljZVByaW5jaXBhbCk7XG5cbiAgICBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgYERlbGVnYXRlQWRtaW4ke3NlcnZpY2VOYW1lfWAsIHtcbiAgICAgIGZ1bmN0aW9uTmFtZTogYGRlbGVnYXRlQWRtaW4ke3NlcnZpY2VOYW1lfSR7dGhpcy5ub3JtYWxpemVBY2NvdW50TmFtZSh0aGlzLmFjY291bnROYW1lKX1gLFxuICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgc2VydmljZTogXCJvcmdhbml6YXRpb25zXCIsXG4gICAgICAgIGFjdGlvbjogXCJSZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JDb21tYW5kXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICBBY2NvdW50SWQ6IHRoaXMuYWNjb3VudElkLFxuICAgICAgICAgIFNlcnZpY2VQcmluY2lwYWw6IHNlcnZpY2VQcmluY2lwYWxcbiAgICAgICAgfSxcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBjdXN0b21SZXNvdXJjZXMuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKFxuICAgICAgICAgIGBkZWxlZ2F0ZS1hZG1pbi0ke3NlcnZpY2VQcmluY2lwYWx9LXRvLSR7dGhpcy5hY2NvdW50SWR9YFxuICAgICAgICApXG4gICAgICB9LFxuICAgICAgb25EZWxldGU6IHtcbiAgICAgICAgc2VydmljZTogXCJvcmdhbml6YXRpb25zXCIsXG4gICAgICAgIGFjdGlvbjogXCJEZXJlZ2lzdGVyRGVsZWdhdGVkQWRtaW5pc3RyYXRvckNvbW1hbmRcIixcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIEFjY291bnRJZDogdGhpcy5hY2NvdW50SWQsXG4gICAgICAgICAgU2VydmljZVByaW5jaXBhbDogc2VydmljZVByaW5jaXBhbFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6RGVsZWdhdGVBZG1pbmlzdHJhdG9yXCIsXG4gICAgICBwb2xpY3k6IGN1c3RvbVJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU3RhdGVtZW50cyhbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpSZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JcIixcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpEZXJlZ2lzdGVyRGVsZWdhdGVkQWRtaW5pc3RyYXRvclwiLFxuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOkxpc3REZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yc1wiXG4gICAgICAgICAgXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1dcbiAgICAgICAgfSlcbiAgICAgIF0pXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIG5vcm1hbGl6ZSBhY2NvdW50IG5hbWVzIGZvciBjb25zdHJ1Y3QgSURzXG4gICAqL1xuICBwcml2YXRlIG5vcm1hbGl6ZUFjY291bnROYW1lKGFjY291bnROYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBhY2NvdW50TmFtZVxuICAgICAgLnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCBcIlwiKVxuICAgICAgLnJlcGxhY2UoL14oW2Etel0pLywgKG1hdGNoKSA9PiBtYXRjaC50b1VwcGVyQ2FzZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gbm9ybWFsaXplIHBvbGljeSBuYW1lcyBmb3IgY29uc3RydWN0IElEc1xuICAgKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVQb2xpY3lOYW1lKHBvbGljeU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBvbGljeU5hbWVcbiAgICAgIC5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgXCJcIilcbiAgICAgIC5yZXBsYWNlKC9eKFthLXpdKS8sIChtYXRjaCkgPT4gbWF0Y2gudG9VcHBlckNhc2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIG5vcm1hbGl6ZSBzZXJ2aWNlIG5hbWVzIGZvciBjb25zdHJ1Y3QgSURzXG4gICAqL1xuICBwcml2YXRlIG5vcm1hbGl6ZVNlcnZpY2VOYW1lKHNlcnZpY2VQcmluY2lwYWw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHNlcnZpY2VQcmluY2lwYWxcbiAgICAgIC5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgXCJcIilcbiAgICAgIC5yZXBsYWNlKC9eKFthLXpdKS8sIChtYXRjaCkgPT4gbWF0Y2gudG9VcHBlckNhc2UoKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSByb290IElEIChwbGFjZWhvbGRlciAtIHdvdWxkIG5lZWQgY3VzdG9tIGxvZ2ljIHRvIGdldCB0aGlzKVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRSb290SWQoKTogc3RyaW5nIHtcbiAgICAvLyBUaGlzIHdvdWxkIG5lZWQgdG8gYmUgaW1wbGVtZW50ZWQgd2l0aCBhIGN1c3RvbSByZXNvdXJjZSB0byBnZXQgdGhlIHJvb3QgSURcbiAgICAvLyBGb3Igbm93LCB1c2luZyBhIHBsYWNlaG9sZGVyXG4gICAgcmV0dXJuIHRoaXMubm9kZS50cnlHZXRDb250ZXh0KFwib3JnYW5pc2F0aW9uUm9vdElkXCIpIHx8IFwici1wbGFjZWhvbGRlclwiO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { DelegatedAdministratorProps } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* AWS Organisations Delegated Administrator construct
|
|
5
|
+
*/
|
|
6
|
+
export declare class DelegatedAdministrator extends Construct {
|
|
7
|
+
readonly servicePrincipal: string;
|
|
8
|
+
readonly accountId: string;
|
|
9
|
+
constructor(scope: Construct, id: string, props: DelegatedAdministratorProps);
|
|
10
|
+
/**
|
|
11
|
+
* Helper to normalize service names for construct IDs
|
|
12
|
+
*/
|
|
13
|
+
private normalizeServiceName;
|
|
14
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DelegatedAdministrator = void 0;
|
|
4
|
+
const customResources = require("aws-cdk-lib/custom-resources");
|
|
5
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
6
|
+
const constructs_1 = require("constructs");
|
|
7
|
+
const awsCustomResource_1 = require("../utilities/awsCustomResource");
|
|
8
|
+
/**
|
|
9
|
+
* AWS Organisations Delegated Administrator construct
|
|
10
|
+
*/
|
|
11
|
+
class DelegatedAdministrator extends constructs_1.Construct {
|
|
12
|
+
constructor(scope, id, props) {
|
|
13
|
+
super(scope, id);
|
|
14
|
+
this.servicePrincipal = props.servicePrincipal;
|
|
15
|
+
this.accountId = props.accountId;
|
|
16
|
+
const serviceName = this.normalizeServiceName(props.servicePrincipal);
|
|
17
|
+
// Register delegated administrator
|
|
18
|
+
new awsCustomResource_1.AwsCustomResource(this, "DelegatedAdministratorResource", {
|
|
19
|
+
functionName: `delegateAdmin${serviceName}`,
|
|
20
|
+
onCreate: {
|
|
21
|
+
service: "organizations",
|
|
22
|
+
action: "RegisterDelegatedAdministratorCommand",
|
|
23
|
+
parameters: {
|
|
24
|
+
AccountId: props.accountId,
|
|
25
|
+
ServicePrincipal: props.servicePrincipal
|
|
26
|
+
},
|
|
27
|
+
physicalResourceId: customResources.PhysicalResourceId.of(`delegate-admin-${props.servicePrincipal}-${props.accountId}`)
|
|
28
|
+
},
|
|
29
|
+
onDelete: {
|
|
30
|
+
service: "organizations",
|
|
31
|
+
action: "DeregisterDelegatedAdministratorCommand",
|
|
32
|
+
parameters: {
|
|
33
|
+
AccountId: props.accountId,
|
|
34
|
+
ServicePrincipal: props.servicePrincipal
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
resourceType: "Custom::DelegatedAdministrator",
|
|
38
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
39
|
+
new aws_iam_1.PolicyStatement({
|
|
40
|
+
actions: [
|
|
41
|
+
"organizations:RegisterDelegatedAdministrator",
|
|
42
|
+
"organizations:DeregisterDelegatedAdministrator",
|
|
43
|
+
"organizations:ListDelegatedAdministrators"
|
|
44
|
+
],
|
|
45
|
+
resources: ["*"],
|
|
46
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
47
|
+
})
|
|
48
|
+
])
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Helper to normalize service names for construct IDs
|
|
53
|
+
*/
|
|
54
|
+
normalizeServiceName(servicePrincipal) {
|
|
55
|
+
return servicePrincipal
|
|
56
|
+
.replace(/[^a-zA-Z0-9]/g, "")
|
|
57
|
+
.replace(/^([a-z])/, (match) => match.toUpperCase());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.DelegatedAdministrator = DelegatedAdministrator;
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVsZWdhdGVkQWRtaW5pc3RyYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9yZXNvdXJjZXMvYXdzL29yZ2FuaXNhdGlvbnMvZGVsZWdhdGVkQWRtaW5pc3RyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxnRUFBZ0U7QUFDaEUsaURBQThEO0FBQzlELDJDQUF1QztBQUV2QyxzRUFBbUU7QUFFbkU7O0dBRUc7QUFDSCxNQUFhLHNCQUF1QixTQUFRLHNCQUFTO0lBSW5ELFlBQ0UsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQWtDO1FBRWxDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFFakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRXRFLG1DQUFtQztRQUNuQyxJQUFJLHFDQUFpQixDQUFDLElBQUksRUFBRSxnQ0FBZ0MsRUFBRTtZQUM1RCxZQUFZLEVBQUUsZ0JBQWdCLFdBQVcsRUFBRTtZQUMzQyxRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLGVBQWU7Z0JBQ3hCLE1BQU0sRUFBRSx1Q0FBdUM7Z0JBQy9DLFVBQVUsRUFBRTtvQkFDVixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7b0JBQzFCLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7aUJBQ3pDO2dCQUNELGtCQUFrQixFQUFFLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQ3ZELGtCQUFrQixLQUFLLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUM5RDthQUNGO1lBQ0QsUUFBUSxFQUFFO2dCQUNSLE9BQU8sRUFBRSxlQUFlO2dCQUN4QixNQUFNLEVBQUUseUNBQXlDO2dCQUNqRCxVQUFVLEVBQUU7b0JBQ1YsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO29CQUMxQixnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZ0JBQWdCO2lCQUN6QzthQUNGO1lBQ0QsWUFBWSxFQUFFLGdDQUFnQztZQUM5QyxNQUFNLEVBQUUsZUFBZSxDQUFDLHVCQUF1QixDQUFDLGNBQWMsQ0FBQztnQkFDN0QsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1AsOENBQThDO3dCQUM5QyxnREFBZ0Q7d0JBQ2hELDJDQUEyQztxQkFDNUM7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO29CQUNoQixNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO2lCQUNyQixDQUFDO2FBQ0gsQ0FBQztTQUNILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLG9CQUFvQixDQUFDLGdCQUF3QjtRQUNuRCxPQUFPLGdCQUFnQjthQUNwQixPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQzthQUM1QixPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0NBQ0Y7QUE3REQsd0RBNkRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3VzdG9tUmVzb3VyY2VzIGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyBFZmZlY3QsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgRGVsZWdhdGVkQWRtaW5pc3RyYXRvclByb3BzIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IEF3c0N1c3RvbVJlc291cmNlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9hd3NDdXN0b21SZXNvdXJjZVwiO1xuXG4vKipcbiAqIEFXUyBPcmdhbmlzYXRpb25zIERlbGVnYXRlZCBBZG1pbmlzdHJhdG9yIGNvbnN0cnVjdFxuICovXG5leHBvcnQgY2xhc3MgRGVsZWdhdGVkQWRtaW5pc3RyYXRvciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHJlYWRvbmx5IHNlcnZpY2VQcmluY2lwYWw6IHN0cmluZztcbiAgcmVhZG9ubHkgYWNjb3VudElkOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yUHJvcHNcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuc2VydmljZVByaW5jaXBhbCA9IHByb3BzLnNlcnZpY2VQcmluY2lwYWw7XG4gICAgdGhpcy5hY2NvdW50SWQgPSBwcm9wcy5hY2NvdW50SWQ7XG5cbiAgICBjb25zdCBzZXJ2aWNlTmFtZSA9IHRoaXMubm9ybWFsaXplU2VydmljZU5hbWUocHJvcHMuc2VydmljZVByaW5jaXBhbCk7XG5cbiAgICAvLyBSZWdpc3RlciBkZWxlZ2F0ZWQgYWRtaW5pc3RyYXRvclxuICAgIG5ldyBBd3NDdXN0b21SZXNvdXJjZSh0aGlzLCBcIkRlbGVnYXRlZEFkbWluaXN0cmF0b3JSZXNvdXJjZVwiLCB7XG4gICAgICBmdW5jdGlvbk5hbWU6IGBkZWxlZ2F0ZUFkbWluJHtzZXJ2aWNlTmFtZX1gLFxuICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgc2VydmljZTogXCJvcmdhbml6YXRpb25zXCIsXG4gICAgICAgIGFjdGlvbjogXCJSZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JDb21tYW5kXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICBBY2NvdW50SWQ6IHByb3BzLmFjY291bnRJZCxcbiAgICAgICAgICBTZXJ2aWNlUHJpbmNpcGFsOiBwcm9wcy5zZXJ2aWNlUHJpbmNpcGFsXG4gICAgICAgIH0sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tUmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZihcbiAgICAgICAgICBgZGVsZWdhdGUtYWRtaW4tJHtwcm9wcy5zZXJ2aWNlUHJpbmNpcGFsfS0ke3Byb3BzLmFjY291bnRJZH1gXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICBvbkRlbGV0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIm9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgYWN0aW9uOiBcIkRlcmVnaXN0ZXJEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yQ29tbWFuZFwiLFxuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgQWNjb3VudElkOiBwcm9wcy5hY2NvdW50SWQsXG4gICAgICAgICAgU2VydmljZVByaW5jaXBhbDogcHJvcHMuc2VydmljZVByaW5jaXBhbFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6RGVsZWdhdGVkQWRtaW5pc3RyYXRvclwiLFxuICAgICAgcG9saWN5OiBjdXN0b21SZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVN0YXRlbWVudHMoW1xuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6UmVnaXN0ZXJEZWxlZ2F0ZWRBZG1pbmlzdHJhdG9yXCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6RGVyZWdpc3RlckRlbGVnYXRlZEFkbWluaXN0cmF0b3JcIixcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpMaXN0RGVsZWdhdGVkQWRtaW5pc3RyYXRvcnNcIlxuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XXG4gICAgICAgIH0pXG4gICAgICBdKVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBub3JtYWxpemUgc2VydmljZSBuYW1lcyBmb3IgY29uc3RydWN0IElEc1xuICAgKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVTZXJ2aWNlTmFtZShzZXJ2aWNlUHJpbmNpcGFsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzZXJ2aWNlUHJpbmNpcGFsXG4gICAgICAucmVwbGFjZSgvW15hLXpBLVowLTldL2csIFwiXCIpXG4gICAgICAucmVwbGFjZSgvXihbYS16XSkvLCAobWF0Y2gpID0+IG1hdGNoLnRvVXBwZXJDYXNlKCkpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Organisation } from "./organisation.js";
|
|
2
|
+
export { OrganisationalUnit } from "./organisationalUnit.js";
|
|
3
|
+
export { Account } from "./account.js";
|
|
4
|
+
export { Policy } from "./policy.js";
|
|
5
|
+
export { DelegatedAdministrator } from "./delegatedAdministrator.js";
|
|
6
|
+
export { TrustedServiceAccess } from "./trustedServiceAccess.js";
|
|
7
|
+
export { PolicyType, FeatureSet, IamUserAccessToBilling } from "./types.js";
|
|
8
|
+
export type { OrganisationProps, OrganisationalUnitProps, AccountProps, PolicyProps, AccountsConfig } from "./types.js";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IamUserAccessToBilling = exports.FeatureSet = exports.PolicyType = exports.TrustedServiceAccess = exports.DelegatedAdministrator = exports.Policy = exports.Account = exports.OrganisationalUnit = exports.Organisation = void 0;
|
|
4
|
+
// Simple approach (more like pepperize)
|
|
5
|
+
var organisation_js_1 = require("./organisation.js");
|
|
6
|
+
Object.defineProperty(exports, "Organisation", { enumerable: true, get: function () { return organisation_js_1.Organisation; } });
|
|
7
|
+
var organisationalUnit_js_1 = require("./organisationalUnit.js");
|
|
8
|
+
Object.defineProperty(exports, "OrganisationalUnit", { enumerable: true, get: function () { return organisationalUnit_js_1.OrganisationalUnit; } });
|
|
9
|
+
var account_js_1 = require("./account.js");
|
|
10
|
+
Object.defineProperty(exports, "Account", { enumerable: true, get: function () { return account_js_1.Account; } });
|
|
11
|
+
var policy_js_1 = require("./policy.js");
|
|
12
|
+
Object.defineProperty(exports, "Policy", { enumerable: true, get: function () { return policy_js_1.Policy; } });
|
|
13
|
+
var delegatedAdministrator_js_1 = require("./delegatedAdministrator.js");
|
|
14
|
+
Object.defineProperty(exports, "DelegatedAdministrator", { enumerable: true, get: function () { return delegatedAdministrator_js_1.DelegatedAdministrator; } });
|
|
15
|
+
var trustedServiceAccess_js_1 = require("./trustedServiceAccess.js");
|
|
16
|
+
Object.defineProperty(exports, "TrustedServiceAccess", { enumerable: true, get: function () { return trustedServiceAccess_js_1.TrustedServiceAccess; } });
|
|
17
|
+
// Enums and types (commonly used)
|
|
18
|
+
var types_js_1 = require("./types.js");
|
|
19
|
+
Object.defineProperty(exports, "PolicyType", { enumerable: true, get: function () { return types_js_1.PolicyType; } });
|
|
20
|
+
Object.defineProperty(exports, "FeatureSet", { enumerable: true, get: function () { return types_js_1.FeatureSet; } });
|
|
21
|
+
Object.defineProperty(exports, "IamUserAccessToBilling", { enumerable: true, get: function () { return types_js_1.IamUserAccessToBilling; } });
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvcmVzb3VyY2VzL2F3cy9vcmdhbmlzYXRpb25zL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHdDQUF3QztBQUN4QyxxREFBaUQ7QUFBeEMsK0dBQUEsWUFBWSxPQUFBO0FBQ3JCLGlFQUE2RDtBQUFwRCwySEFBQSxrQkFBa0IsT0FBQTtBQUMzQiwyQ0FBdUM7QUFBOUIscUdBQUEsT0FBTyxPQUFBO0FBQ2hCLHlDQUFxQztBQUE1QixtR0FBQSxNQUFNLE9BQUE7QUFDZix5RUFBcUU7QUFBNUQsbUlBQUEsc0JBQXNCLE9BQUE7QUFDL0IscUVBQWlFO0FBQXhELCtIQUFBLG9CQUFvQixPQUFBO0FBRTdCLGtDQUFrQztBQUNsQyx1Q0FBNEU7QUFBbkUsc0dBQUEsVUFBVSxPQUFBO0FBQUUsc0dBQUEsVUFBVSxPQUFBO0FBQUUsa0hBQUEsc0JBQXNCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTaW1wbGUgYXBwcm9hY2ggKG1vcmUgbGlrZSBwZXBwZXJpemUpXG5leHBvcnQgeyBPcmdhbmlzYXRpb24gfSBmcm9tIFwiLi9vcmdhbmlzYXRpb24uanNcIjtcbmV4cG9ydCB7IE9yZ2FuaXNhdGlvbmFsVW5pdCB9IGZyb20gXCIuL29yZ2FuaXNhdGlvbmFsVW5pdC5qc1wiO1xuZXhwb3J0IHsgQWNjb3VudCB9IGZyb20gXCIuL2FjY291bnQuanNcIjtcbmV4cG9ydCB7IFBvbGljeSB9IGZyb20gXCIuL3BvbGljeS5qc1wiO1xuZXhwb3J0IHsgRGVsZWdhdGVkQWRtaW5pc3RyYXRvciB9IGZyb20gXCIuL2RlbGVnYXRlZEFkbWluaXN0cmF0b3IuanNcIjtcbmV4cG9ydCB7IFRydXN0ZWRTZXJ2aWNlQWNjZXNzIH0gZnJvbSBcIi4vdHJ1c3RlZFNlcnZpY2VBY2Nlc3MuanNcIjtcblxuLy8gRW51bXMgYW5kIHR5cGVzIChjb21tb25seSB1c2VkKVxuZXhwb3J0IHsgUG9saWN5VHlwZSwgRmVhdHVyZVNldCwgSWFtVXNlckFjY2Vzc1RvQmlsbGluZyB9IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5cbi8vIFByb3BzIG9ubHkgKG1vc3QgdXNlcnMgd29uJ3QgbmVlZCBpbnRlcmZhY2VzKVxuZXhwb3J0IHR5cGUge1xuICBPcmdhbmlzYXRpb25Qcm9wcyxcbiAgT3JnYW5pc2F0aW9uYWxVbml0UHJvcHMsXG4gIEFjY291bnRQcm9wcyxcbiAgUG9saWN5UHJvcHMsXG4gIEFjY291bnRzQ29uZmlnXG59IGZyb20gXCIuL3R5cGVzLmpzXCI7XG4iXX0=
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { PolicyType } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Interface for Organisation
|
|
4
|
+
*/
|
|
5
|
+
export interface IOrganisation {
|
|
6
|
+
/**
|
|
7
|
+
* The organisation ID
|
|
8
|
+
*/
|
|
9
|
+
readonly organisationId: string;
|
|
10
|
+
/**
|
|
11
|
+
* The organisation ARN
|
|
12
|
+
*/
|
|
13
|
+
readonly organisationArn: string;
|
|
14
|
+
/**
|
|
15
|
+
* The organisation's root
|
|
16
|
+
*/
|
|
17
|
+
readonly root: IOrganisationalUnit;
|
|
18
|
+
/**
|
|
19
|
+
* Principal for this organisation
|
|
20
|
+
*/
|
|
21
|
+
readonly principal: string;
|
|
22
|
+
/**
|
|
23
|
+
* Enable AWS service access
|
|
24
|
+
*/
|
|
25
|
+
enableAwsServiceAccess(servicePrincipal: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Enable policy type
|
|
28
|
+
*/
|
|
29
|
+
enablePolicyType(policyType: PolicyType): void;
|
|
30
|
+
/**
|
|
31
|
+
* Attach policy to organisation
|
|
32
|
+
*/
|
|
33
|
+
attachPolicy(policy: IPolicy): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Interface for Organisational Unit
|
|
37
|
+
*/
|
|
38
|
+
export interface IOrganisationalUnit {
|
|
39
|
+
/**
|
|
40
|
+
* The organisational unit ID
|
|
41
|
+
*/
|
|
42
|
+
readonly organisationalUnitId: string;
|
|
43
|
+
/**
|
|
44
|
+
* The organisational unit ARN
|
|
45
|
+
*/
|
|
46
|
+
readonly organisationalUnitArn: string;
|
|
47
|
+
/**
|
|
48
|
+
* The organisational unit name
|
|
49
|
+
*/
|
|
50
|
+
readonly organisationalUnitName: string;
|
|
51
|
+
/**
|
|
52
|
+
* Attach policy to organisational unit
|
|
53
|
+
*/
|
|
54
|
+
attachPolicy(policy: IPolicy): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Interface for Account
|
|
58
|
+
*/
|
|
59
|
+
export interface IAccount {
|
|
60
|
+
/**
|
|
61
|
+
* The account ID
|
|
62
|
+
*/
|
|
63
|
+
readonly accountId: string;
|
|
64
|
+
/**
|
|
65
|
+
* The account ARN
|
|
66
|
+
*/
|
|
67
|
+
readonly accountArn: string;
|
|
68
|
+
/**
|
|
69
|
+
* The account name
|
|
70
|
+
*/
|
|
71
|
+
readonly accountName: string;
|
|
72
|
+
/**
|
|
73
|
+
* The account email
|
|
74
|
+
*/
|
|
75
|
+
readonly email: string;
|
|
76
|
+
/**
|
|
77
|
+
* Attach policy to account
|
|
78
|
+
*/
|
|
79
|
+
attachPolicy(policy: IPolicy): void;
|
|
80
|
+
/**
|
|
81
|
+
* Delegate administrator privileges for a service
|
|
82
|
+
*/
|
|
83
|
+
delegateAdministrator(servicePrincipal: string): void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Interface for Policy
|
|
87
|
+
*/
|
|
88
|
+
export interface IPolicy {
|
|
89
|
+
/**
|
|
90
|
+
* The policy ID
|
|
91
|
+
*/
|
|
92
|
+
readonly policyId: string;
|
|
93
|
+
/**
|
|
94
|
+
* The policy ARN
|
|
95
|
+
*/
|
|
96
|
+
readonly policyArn: string;
|
|
97
|
+
/**
|
|
98
|
+
* The policy name
|
|
99
|
+
*/
|
|
100
|
+
readonly policyName: string;
|
|
101
|
+
/**
|
|
102
|
+
* The policy type
|
|
103
|
+
*/
|
|
104
|
+
readonly policyType: PolicyType;
|
|
105
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9yZXNvdXJjZXMvYXdzL29yZ2FuaXNhdGlvbnMvaW50ZXJmYWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUG9saWN5VHlwZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBPcmdhbmlzYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJT3JnYW5pc2F0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBvcmdhbmlzYXRpb24gSURcbiAgICovXG4gIHJlYWRvbmx5IG9yZ2FuaXNhdGlvbklkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcmdhbmlzYXRpb24gQVJOXG4gICAqL1xuICByZWFkb25seSBvcmdhbmlzYXRpb25Bcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9yZ2FuaXNhdGlvbidzIHJvb3RcbiAgICovXG4gIHJlYWRvbmx5IHJvb3Q6IElPcmdhbmlzYXRpb25hbFVuaXQ7XG5cbiAgLyoqXG4gICAqIFByaW5jaXBhbCBmb3IgdGhpcyBvcmdhbmlzYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IHByaW5jaXBhbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbmFibGUgQVdTIHNlcnZpY2UgYWNjZXNzXG4gICAqL1xuICBlbmFibGVBd3NTZXJ2aWNlQWNjZXNzKHNlcnZpY2VQcmluY2lwYWw6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEVuYWJsZSBwb2xpY3kgdHlwZVxuICAgKi9cbiAgZW5hYmxlUG9saWN5VHlwZShwb2xpY3lUeXBlOiBQb2xpY3lUeXBlKTogdm9pZDtcblxuICAvKipcbiAgICogQXR0YWNoIHBvbGljeSB0byBvcmdhbmlzYXRpb25cbiAgICovXG4gIGF0dGFjaFBvbGljeShwb2xpY3k6IElQb2xpY3kpOiB2b2lkO1xufVxuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgT3JnYW5pc2F0aW9uYWwgVW5pdFxuICovXG5leHBvcnQgaW50ZXJmYWNlIElPcmdhbmlzYXRpb25hbFVuaXQge1xuICAvKipcbiAgICogVGhlIG9yZ2FuaXNhdGlvbmFsIHVuaXQgSURcbiAgICovXG4gIHJlYWRvbmx5IG9yZ2FuaXNhdGlvbmFsVW5pdElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcmdhbmlzYXRpb25hbCB1bml0IEFSTlxuICAgKi9cbiAgcmVhZG9ubHkgb3JnYW5pc2F0aW9uYWxVbml0QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvcmdhbmlzYXRpb25hbCB1bml0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IG9yZ2FuaXNhdGlvbmFsVW5pdE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQXR0YWNoIHBvbGljeSB0byBvcmdhbmlzYXRpb25hbCB1bml0XG4gICAqL1xuICBhdHRhY2hQb2xpY3kocG9saWN5OiBJUG9saWN5KTogdm9pZDtcbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgZm9yIEFjY291bnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJQWNjb3VudCB7XG4gIC8qKlxuICAgKiBUaGUgYWNjb3VudCBJRFxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBhY2NvdW50IEFSTlxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudEFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYWNjb3VudCBuYW1lXG4gICAqL1xuICByZWFkb25seSBhY2NvdW50TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYWNjb3VudCBlbWFpbFxuICAgKi9cbiAgcmVhZG9ubHkgZW1haWw6IHN0cmluZztcblxuICAvKipcbiAgICogQXR0YWNoIHBvbGljeSB0byBhY2NvdW50XG4gICAqL1xuICBhdHRhY2hQb2xpY3kocG9saWN5OiBJUG9saWN5KTogdm9pZDtcblxuICAvKipcbiAgICogRGVsZWdhdGUgYWRtaW5pc3RyYXRvciBwcml2aWxlZ2VzIGZvciBhIHNlcnZpY2VcbiAgICovXG4gIGRlbGVnYXRlQWRtaW5pc3RyYXRvcihzZXJ2aWNlUHJpbmNpcGFsOiBzdHJpbmcpOiB2b2lkO1xufVxuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgUG9saWN5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVBvbGljeSB7XG4gIC8qKlxuICAgKiBUaGUgcG9saWN5IElEXG4gICAqL1xuICByZWFkb25seSBwb2xpY3lJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9saWN5IEFSTlxuICAgKi9cbiAgcmVhZG9ubHkgcG9saWN5QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb2xpY3kgbmFtZVxuICAgKi9cbiAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9saWN5IHR5cGVcbiAgICovXG4gIHJlYWRvbmx5IHBvbGljeVR5cGU6IFBvbGljeVR5cGU7XG59XG4iXX0=
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { IOrganisation, IOrganisationalUnit, IPolicy } from "./interfaces";
|
|
3
|
+
import { OrganisationProps, PolicyType } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Organisation root construct - represents the root organisational unit
|
|
6
|
+
*/
|
|
7
|
+
export declare class OrganisationRoot extends Construct implements IOrganisationalUnit {
|
|
8
|
+
readonly organisationalUnitId: string;
|
|
9
|
+
readonly organisationalUnitArn: string;
|
|
10
|
+
readonly organisationalUnitName: string;
|
|
11
|
+
constructor(scope: Construct, id: string, organisationId: string);
|
|
12
|
+
attachPolicy(policy: IPolicy): void;
|
|
13
|
+
/**
|
|
14
|
+
* Helper to normalize policy names for construct IDs
|
|
15
|
+
*/
|
|
16
|
+
private normalizePolicyName;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* AWS Organisations construct for managing organisations
|
|
20
|
+
*/
|
|
21
|
+
export declare class Organisation extends Construct implements IOrganisation {
|
|
22
|
+
readonly organisationId: string;
|
|
23
|
+
readonly organisationArn: string;
|
|
24
|
+
readonly root: IOrganisationalUnit;
|
|
25
|
+
readonly principal: string;
|
|
26
|
+
constructor(scope: Construct, id: string, props?: OrganisationProps);
|
|
27
|
+
/**
|
|
28
|
+
* Enable AWS service access for the organisation
|
|
29
|
+
*/
|
|
30
|
+
enableAwsServiceAccess(servicePrincipal: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Enable policy type for the organisation
|
|
33
|
+
*/
|
|
34
|
+
enablePolicyType(policyType: PolicyType): void;
|
|
35
|
+
/**
|
|
36
|
+
* Attach policy to organisation root
|
|
37
|
+
*/
|
|
38
|
+
attachPolicy(policy: IPolicy): void;
|
|
39
|
+
/**
|
|
40
|
+
* Helper to normalize service names for construct IDs
|
|
41
|
+
*/
|
|
42
|
+
private normalizeServiceName;
|
|
43
|
+
/**
|
|
44
|
+
* Static method to get organisation from context (for use in member accounts)
|
|
45
|
+
*/
|
|
46
|
+
static of(scope: Construct, id: string): IOrganisation;
|
|
47
|
+
}
|