@fjall/components-infrastructure 2.30.0 → 2.30.3
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__/setup.d.ts +48 -0
- package/dist/lib/__tests__/setup.js +1 -0
- package/dist/lib/config/aws/accountId.d.ts +6 -0
- package/dist/lib/config/aws/accountId.js +33 -0
- package/dist/lib/config/aws/backupGlobalSettings.d.ts +29 -0
- package/dist/lib/config/aws/backupGlobalSettings.js +51 -0
- package/dist/lib/config/aws/costAllocationTags.d.ts +12 -0
- package/dist/lib/config/aws/costAllocationTags.js +48 -0
- package/dist/lib/config/aws/eventBus.d.ts +7 -0
- package/dist/lib/config/aws/eventBus.js +24 -0
- package/dist/lib/config/aws/identityCenterGroupMembership.d.ts +10 -0
- package/dist/lib/config/aws/identityCenterGroupMembership.js +115 -0
- package/dist/lib/config/aws/ipamDelegateAdmin.d.ts +8 -0
- package/dist/lib/config/aws/ipamDelegateAdmin.js +58 -0
- package/dist/lib/config/aws/ipamPoolId.d.ts +10 -0
- package/dist/lib/config/aws/ipamPoolId.js +39 -0
- package/dist/lib/config/aws/organisation.d.ts +30 -0
- package/dist/lib/config/aws/organisation.js +95 -0
- package/dist/lib/config/aws/organisationId.d.ts +7 -0
- package/dist/lib/config/aws/organisationId.js +46 -0
- package/dist/lib/config/aws/organisationsAccess.d.ts +10 -0
- package/dist/lib/config/aws/organisationsAccess.js +50 -0
- package/dist/lib/config/aws/ramSharing.d.ts +4 -0
- package/dist/lib/config/aws/ramSharing.js +35 -0
- package/dist/lib/config/monitoring.d.ts +18 -0
- package/dist/lib/config/monitoring.js +22 -0
- package/dist/lib/patterns/aws/cicdRole.d.ts +67 -0
- package/dist/lib/patterns/aws/cicdRole.js +68 -0
- package/dist/lib/patterns/aws/compute.js +9 -0
- package/dist/lib/patterns/aws/computeLambda.d.ts +38 -3
- package/dist/lib/patterns/aws/computeLambda.js +29 -2
- package/dist/lib/patterns/aws/hostedZone.d.ts +28 -0
- package/dist/lib/patterns/aws/hostedZone.js +150 -0
- package/dist/lib/patterns/aws/managedAccount.d.ts +9 -0
- package/dist/lib/patterns/aws/managedAccount.js +55 -0
- package/dist/lib/patterns/aws/managedIdentityCenter.d.ts +4 -0
- package/dist/lib/patterns/aws/managedIdentityCenter.js +24 -0
- package/dist/lib/patterns/aws/managedOrganisation.d.ts +36 -0
- package/dist/lib/patterns/aws/managedOrganisation.js +97 -0
- package/dist/lib/patterns/aws/managedPlatform.d.ts +12 -0
- package/dist/lib/patterns/aws/managedPlatform.js +29 -0
- package/dist/lib/patterns/aws/subdomainHostedZone.d.ts +9 -0
- package/dist/lib/patterns/aws/subdomainHostedZone.js +39 -0
- package/dist/lib/resources/aws/cicd/cicdRole.d.ts +65 -0
- package/dist/lib/resources/aws/cicd/cicdRole.js +191 -0
- package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +75 -0
- package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -0
- package/dist/lib/resources/aws/compute/ecsImages.js +3 -25
- package/dist/lib/resources/aws/compute/ecsSpot.d.ts +75 -0
- package/dist/lib/resources/aws/compute/ecsSpot.js +1 -0
- package/dist/lib/resources/aws/compute/imageTagParameter.d.ts +12 -0
- package/dist/lib/resources/aws/compute/imageTagParameter.js +32 -0
- package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.d.ts +20 -0
- package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +1 -0
- package/dist/lib/resources/aws/database/database.d.ts +14 -0
- package/dist/lib/resources/aws/database/database.js +28 -0
- package/dist/lib/resources/aws/database/databaseInstance.d.ts +15 -0
- package/dist/lib/resources/aws/database/databaseInstance.js +30 -0
- package/dist/lib/resources/aws/iam/identityCenter/attachManagedPolicy.d.ts +13 -0
- package/dist/lib/resources/aws/iam/identityCenter/attachManagedPolicy.js +52 -0
- package/dist/lib/resources/aws/iam/securityGroup.d.ts +5 -0
- package/dist/lib/resources/aws/iam/securityGroup.js +14 -0
- package/dist/lib/resources/aws/monitoring/monitoringRole.d.ts +28 -0
- package/dist/lib/resources/aws/monitoring/monitoringRole.js +125 -0
- package/dist/lib/resources/aws/utilities/cfnOutput.d.ts +5 -0
- package/dist/lib/resources/aws/utilities/cfnOutput.js +1 -0
- package/dist/lib/utils/addSuffixToEmail.js +5 -1
- package/dist/lib/utils/capitalizeString.d.ts +1 -0
- package/dist/lib/utils/capitalizeString.js +7 -0
- package/package.json +4 -4
- package/dist/lib/config/aws/identityCenterMembership.d.ts +0 -11
- package/dist/lib/config/aws/identityCenterMembership.js +0 -61
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
4
|
+
const constructs_1 = require("constructs");
|
|
5
|
+
const stripAndCamelCase_1 = require("../../utils/stripAndCamelCase");
|
|
6
|
+
const cdk_organizations_1 = require("@pepperize/cdk-organizations");
|
|
7
|
+
const addSuffixToEmail_1 = require("../../utils/addSuffixToEmail");
|
|
8
|
+
/**
|
|
9
|
+
* A construct for creating multi environment organisations with a production, staging and development account.
|
|
10
|
+
*/
|
|
11
|
+
class Organisation extends constructs_1.Construct {
|
|
12
|
+
constructor(scope, id, props) {
|
|
13
|
+
super(scope, id);
|
|
14
|
+
this.accounts = {};
|
|
15
|
+
this.organisationalUnits = [];
|
|
16
|
+
this.existingAccounts = props.existingAccounts;
|
|
17
|
+
this.addOrganisation(props.organisationName);
|
|
18
|
+
this.addOrganisationUnitsAndAccounts(props.accounts, props.orgEmail);
|
|
19
|
+
}
|
|
20
|
+
addOrganisation(organisationName) {
|
|
21
|
+
this.organisation = new cdk_organizations_1.Organization(this, organisationName, {
|
|
22
|
+
featureSet: cdk_organizations_1.FeatureSet.ALL
|
|
23
|
+
});
|
|
24
|
+
// TODO: Validate this enables trusted access
|
|
25
|
+
this.organisation.enableAwsServiceAccess("account.amazonaws.com");
|
|
26
|
+
const enforcedPolicyTypes = [
|
|
27
|
+
cdk_organizations_1.PolicyType.SERVICE_CONTROL_POLICY,
|
|
28
|
+
cdk_organizations_1.PolicyType.TAG_POLICY,
|
|
29
|
+
cdk_organizations_1.PolicyType.BACKUP_POLICY,
|
|
30
|
+
cdk_organizations_1.PolicyType.AISERVICES_OPT_OUT_POLICY
|
|
31
|
+
];
|
|
32
|
+
for (const policyType of enforcedPolicyTypes) {
|
|
33
|
+
this.organisation.enablePolicyType(policyType);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
addOrganisationUnitsAndAccounts(accounts, orgEmail) {
|
|
37
|
+
for (const [environmentType, accountList] of Object.entries(accounts)) {
|
|
38
|
+
// Create OU for each environment type
|
|
39
|
+
const ouName = environmentType.charAt(0).toUpperCase() + environmentType.slice(1);
|
|
40
|
+
const orgUnit = this.addOrganisationalUnit(`${ouName}OrganizationalUnit`, ouName);
|
|
41
|
+
// Convert single account to array for uniform processing
|
|
42
|
+
const accountsArray = Array.isArray(accountList)
|
|
43
|
+
? accountList
|
|
44
|
+
: [accountList];
|
|
45
|
+
// Add accounts to this OU
|
|
46
|
+
for (const accountName of accountsArray) {
|
|
47
|
+
const accountNameId = (0, stripAndCamelCase_1.stripAndCamelCase)(accountName);
|
|
48
|
+
const importedAccount = this.existingAccounts?.find((account) => account.Name === accountName);
|
|
49
|
+
const accountEmail = importedAccount
|
|
50
|
+
? importedAccount.Email
|
|
51
|
+
: (0, addSuffixToEmail_1.default)(orgEmail, accountNameId.toLowerCase());
|
|
52
|
+
if (accountEmail) {
|
|
53
|
+
this.addAccount(`${accountNameId}Account`, accountName, accountEmail, { env: environmentType }, orgUnit);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
addOrganisationalUnit(id, name) {
|
|
59
|
+
const ou = new cdk_organizations_1.OrganizationalUnit(this, id, {
|
|
60
|
+
organizationalUnitName: name,
|
|
61
|
+
parent: this.organisation.root,
|
|
62
|
+
importOnDuplicate: true
|
|
63
|
+
});
|
|
64
|
+
this.organisationalUnits.push(ou);
|
|
65
|
+
return ou;
|
|
66
|
+
}
|
|
67
|
+
addAccount(id, name, email, tags, organisationalUnit) {
|
|
68
|
+
const acc = new cdk_organizations_1.Account(this, id, {
|
|
69
|
+
accountName: name,
|
|
70
|
+
email: email,
|
|
71
|
+
parent: organisationalUnit,
|
|
72
|
+
importOnDuplicate: true
|
|
73
|
+
});
|
|
74
|
+
for (const tag in tags) {
|
|
75
|
+
aws_cdk_lib_1.Tags.of(acc).add(tag, tags[tag]);
|
|
76
|
+
}
|
|
77
|
+
this.accounts[name] = acc.accountId;
|
|
78
|
+
new aws_cdk_lib_1.CfnOutput(this, `${id}Id`, {
|
|
79
|
+
key: `${id}Id`,
|
|
80
|
+
value: acc.accountId,
|
|
81
|
+
exportName: `${id}Id`
|
|
82
|
+
});
|
|
83
|
+
new aws_cdk_lib_1.CfnOutput(this, `${id}Arn`, {
|
|
84
|
+
key: `${id}Arn`,
|
|
85
|
+
value: acc.accountArn,
|
|
86
|
+
exportName: `${id}Arn`
|
|
87
|
+
});
|
|
88
|
+
return acc;
|
|
89
|
+
}
|
|
90
|
+
getAccounts() {
|
|
91
|
+
return this.accounts;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.default = Organisation;
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pc2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2NvbmZpZy9hd3Mvb3JnYW5pc2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQStEO0FBQy9ELDJDQUF1QztBQUN2QyxxRUFBa0U7QUFFbEUsb0VBTXNDO0FBQ3RDLG1FQUE0RDtBQWM1RDs7R0FFRztBQUVILE1BQXFCLFlBQWEsU0FBUSxzQkFBUztJQVFqRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXdCO1FBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFMWCxhQUFRLEdBQWEsRUFBRSxDQUFDO1FBRXhCLHdCQUFtQixHQUF5QixFQUFFLENBQUM7UUFLckQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUMvQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRU8sZUFBZSxDQUFDLGdCQUF3QjtRQUM5QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksZ0NBQVksQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDM0QsVUFBVSxFQUFFLDhCQUFVLENBQUMsR0FBRztTQUMzQixDQUFDLENBQUM7UUFFSCw2Q0FBNkM7UUFDN0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRWxFLE1BQU0sbUJBQW1CLEdBQWlCO1lBQ3hDLDhCQUFVLENBQUMsc0JBQXNCO1lBQ2pDLDhCQUFVLENBQUMsVUFBVTtZQUNyQiw4QkFBVSxDQUFDLGFBQWE7WUFDeEIsOEJBQVUsQ0FBQyx5QkFBeUI7U0FDckMsQ0FBQztRQUVGLEtBQUssTUFBTSxVQUFVLElBQUksbUJBQW1CLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7SUFDSCxDQUFDO0lBRU8sK0JBQStCLENBQ3JDLFFBQXdCLEVBQ3hCLFFBQWdCO1FBRWhCLEtBQUssTUFBTSxDQUFDLGVBQWUsRUFBRSxXQUFXLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdEUsc0NBQXNDO1lBQ3RDLE1BQU0sTUFBTSxHQUNWLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQ3hDLEdBQUcsTUFBTSxvQkFBb0IsRUFDN0IsTUFBTSxDQUNQLENBQUM7WUFFRix5REFBeUQ7WUFDekQsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7Z0JBQzlDLENBQUMsQ0FBQyxXQUFXO2dCQUNiLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRWxCLDBCQUEwQjtZQUMxQixLQUFLLE1BQU0sV0FBVyxJQUFJLGFBQWEsRUFBRSxDQUFDO2dCQUN4QyxNQUFNLGFBQWEsR0FBRyxJQUFBLHFDQUFpQixFQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUVyRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUNqRCxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxXQUFXLENBQzFDLENBQUM7Z0JBQ0YsTUFBTSxZQUFZLEdBQUcsZUFBZTtvQkFDbEMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLO29CQUN2QixDQUFDLENBQUMsSUFBQSwwQkFBZ0IsRUFBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBRTVELElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLElBQUksQ0FBQyxVQUFVLENBQ2IsR0FBRyxhQUFhLFNBQVMsRUFDekIsV0FBVyxFQUNYLFlBQVksRUFDWixFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsRUFDeEIsT0FBTyxDQUNSLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQixDQUFDLEVBQVUsRUFBRSxJQUFZO1FBQ3BELE1BQU0sRUFBRSxHQUFHLElBQUksc0NBQWtCLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUMxQyxzQkFBc0IsRUFBRSxJQUFJO1lBQzVCLE1BQU0sRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUk7WUFDOUIsaUJBQWlCLEVBQUUsSUFBSTtTQUN4QixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVPLFVBQVUsQ0FDaEIsRUFBVSxFQUNWLElBQVksRUFDWixLQUFhLEVBQ2IsSUFBK0IsRUFDL0Isa0JBQXNDO1FBRXRDLE1BQU0sR0FBRyxHQUFHLElBQUksMkJBQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFO1lBQ2hDLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLEtBQUssRUFBRSxLQUFLO1lBQ1osTUFBTSxFQUFFLGtCQUFrQjtZQUMxQixpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztRQUVILEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7WUFDdkIsa0JBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDO1FBRXBDLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRTtZQUM3QixHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUk7WUFDZCxLQUFLLEVBQUUsR0FBRyxDQUFDLFNBQVM7WUFDcEIsVUFBVSxFQUFFLEdBQUcsRUFBRSxJQUFJO1NBQ3RCLENBQUMsQ0FBQztRQUNILElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRTtZQUM5QixHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUs7WUFDZixLQUFLLEVBQUUsR0FBRyxDQUFDLFVBQVU7WUFDckIsVUFBVSxFQUFFLEdBQUcsRUFBRSxLQUFLO1NBQ3ZCLENBQUMsQ0FBQztRQUVILE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVNLFdBQVc7UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRjtBQTlIRCwrQkE4SEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZm5PdXRwdXQsIFRhZ3MsIHR5cGUgU3RhY2tQcm9wcyB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHN0cmlwQW5kQ2FtZWxDYXNlIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3N0cmlwQW5kQ2FtZWxDYXNlXCI7XG5pbXBvcnQgeyB0eXBlIEFjY291bnQgYXMgRXhpc3RpbmdBY2NvdW50cyB9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtb3JnYW5pemF0aW9uc1wiO1xuaW1wb3J0IHtcbiAgQWNjb3VudCxcbiAgRmVhdHVyZVNldCxcbiAgT3JnYW5pemF0aW9uLFxuICBPcmdhbml6YXRpb25hbFVuaXQsXG4gIFBvbGljeVR5cGVcbn0gZnJvbSBcIkBwZXBwZXJpemUvY2RrLW9yZ2FuaXphdGlvbnNcIjtcbmltcG9ydCBhZGRTdWZmaXhUb0VtYWlsIGZyb20gXCIuLi8uLi91dGlscy9hZGRTdWZmaXhUb0VtYWlsXCI7XG5pbXBvcnQgeyB0eXBlIEtleVZhbHVlIH0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5cbmludGVyZmFjZSBPcmdhbmlzYXRpb25Qcm9wcyBleHRlbmRzIFN0YWNrUHJvcHMge1xuICBvcmdhbmlzYXRpb25OYW1lOiBzdHJpbmc7XG4gIGFjY291bnRzOiBBY2NvdW50c0NvbmZpZztcbiAgb3JnRW1haWw6IHN0cmluZztcbiAgZXhpc3RpbmdBY2NvdW50cz86IEV4aXN0aW5nQWNjb3VudHNbXTtcbn1cblxudHlwZSBBY2NvdW50c0NvbmZpZyA9IHtcbiAgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogcmVhZG9ubHkgc3RyaW5nW10gfCBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEEgY29uc3RydWN0IGZvciBjcmVhdGluZyBtdWx0aSBlbnZpcm9ubWVudCBvcmdhbmlzYXRpb25zIHdpdGggYSBwcm9kdWN0aW9uLCBzdGFnaW5nIGFuZCBkZXZlbG9wbWVudCBhY2NvdW50LlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9yZ2FuaXNhdGlvbiBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyBhY2NvdW50SWQ6IENmbk91dHB1dDtcblxuICBwcml2YXRlIGV4aXN0aW5nQWNjb3VudHM/OiBFeGlzdGluZ0FjY291bnRzW107XG4gIHByaXZhdGUgYWNjb3VudHM6IEtleVZhbHVlID0ge307XG4gIHByaXZhdGUgb3JnYW5pc2F0aW9uOiBPcmdhbml6YXRpb247XG4gIHByaXZhdGUgb3JnYW5pc2F0aW9uYWxVbml0czogT3JnYW5pemF0aW9uYWxVbml0W10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogT3JnYW5pc2F0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5leGlzdGluZ0FjY291bnRzID0gcHJvcHMuZXhpc3RpbmdBY2NvdW50cztcbiAgICB0aGlzLmFkZE9yZ2FuaXNhdGlvbihwcm9wcy5vcmdhbmlzYXRpb25OYW1lKTtcbiAgICB0aGlzLmFkZE9yZ2FuaXNhdGlvblVuaXRzQW5kQWNjb3VudHMocHJvcHMuYWNjb3VudHMsIHByb3BzLm9yZ0VtYWlsKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkT3JnYW5pc2F0aW9uKG9yZ2FuaXNhdGlvbk5hbWU6IHN0cmluZykge1xuICAgIHRoaXMub3JnYW5pc2F0aW9uID0gbmV3IE9yZ2FuaXphdGlvbih0aGlzLCBvcmdhbmlzYXRpb25OYW1lLCB7XG4gICAgICBmZWF0dXJlU2V0OiBGZWF0dXJlU2V0LkFMTFxuICAgIH0pO1xuXG4gICAgLy8gVE9ETzogVmFsaWRhdGUgdGhpcyBlbmFibGVzIHRydXN0ZWQgYWNjZXNzXG4gICAgdGhpcy5vcmdhbmlzYXRpb24uZW5hYmxlQXdzU2VydmljZUFjY2VzcyhcImFjY291bnQuYW1hem9uYXdzLmNvbVwiKTtcblxuICAgIGNvbnN0IGVuZm9yY2VkUG9saWN5VHlwZXM6IFBvbGljeVR5cGVbXSA9IFtcbiAgICAgIFBvbGljeVR5cGUuU0VSVklDRV9DT05UUk9MX1BPTElDWSxcbiAgICAgIFBvbGljeVR5cGUuVEFHX1BPTElDWSxcbiAgICAgIFBvbGljeVR5cGUuQkFDS1VQX1BPTElDWSxcbiAgICAgIFBvbGljeVR5cGUuQUlTRVJWSUNFU19PUFRfT1VUX1BPTElDWVxuICAgIF07XG5cbiAgICBmb3IgKGNvbnN0IHBvbGljeVR5cGUgb2YgZW5mb3JjZWRQb2xpY3lUeXBlcykge1xuICAgICAgdGhpcy5vcmdhbmlzYXRpb24uZW5hYmxlUG9saWN5VHlwZShwb2xpY3lUeXBlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZE9yZ2FuaXNhdGlvblVuaXRzQW5kQWNjb3VudHMoXG4gICAgYWNjb3VudHM6IEFjY291bnRzQ29uZmlnLFxuICAgIG9yZ0VtYWlsOiBzdHJpbmdcbiAgKSB7XG4gICAgZm9yIChjb25zdCBbZW52aXJvbm1lbnRUeXBlLCBhY2NvdW50TGlzdF0gb2YgT2JqZWN0LmVudHJpZXMoYWNjb3VudHMpKSB7XG4gICAgICAvLyBDcmVhdGUgT1UgZm9yIGVhY2ggZW52aXJvbm1lbnQgdHlwZVxuICAgICAgY29uc3Qgb3VOYW1lID1cbiAgICAgICAgZW52aXJvbm1lbnRUeXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgZW52aXJvbm1lbnRUeXBlLnNsaWNlKDEpO1xuICAgICAgY29uc3Qgb3JnVW5pdCA9IHRoaXMuYWRkT3JnYW5pc2F0aW9uYWxVbml0KFxuICAgICAgICBgJHtvdU5hbWV9T3JnYW5pemF0aW9uYWxVbml0YCxcbiAgICAgICAgb3VOYW1lXG4gICAgICApO1xuXG4gICAgICAvLyBDb252ZXJ0IHNpbmdsZSBhY2NvdW50IHRvIGFycmF5IGZvciB1bmlmb3JtIHByb2Nlc3NpbmdcbiAgICAgIGNvbnN0IGFjY291bnRzQXJyYXkgPSBBcnJheS5pc0FycmF5KGFjY291bnRMaXN0KVxuICAgICAgICA/IGFjY291bnRMaXN0XG4gICAgICAgIDogW2FjY291bnRMaXN0XTtcblxuICAgICAgLy8gQWRkIGFjY291bnRzIHRvIHRoaXMgT1VcbiAgICAgIGZvciAoY29uc3QgYWNjb3VudE5hbWUgb2YgYWNjb3VudHNBcnJheSkge1xuICAgICAgICBjb25zdCBhY2NvdW50TmFtZUlkID0gc3RyaXBBbmRDYW1lbENhc2UoYWNjb3VudE5hbWUpO1xuXG4gICAgICAgIGNvbnN0IGltcG9ydGVkQWNjb3VudCA9IHRoaXMuZXhpc3RpbmdBY2NvdW50cz8uZmluZChcbiAgICAgICAgICAoYWNjb3VudCkgPT4gYWNjb3VudC5OYW1lID09PSBhY2NvdW50TmFtZVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBhY2NvdW50RW1haWwgPSBpbXBvcnRlZEFjY291bnRcbiAgICAgICAgICA/IGltcG9ydGVkQWNjb3VudC5FbWFpbFxuICAgICAgICAgIDogYWRkU3VmZml4VG9FbWFpbChvcmdFbWFpbCwgYWNjb3VudE5hbWVJZC50b0xvd2VyQ2FzZSgpKTtcblxuICAgICAgICBpZiAoYWNjb3VudEVtYWlsKSB7XG4gICAgICAgICAgdGhpcy5hZGRBY2NvdW50KFxuICAgICAgICAgICAgYCR7YWNjb3VudE5hbWVJZH1BY2NvdW50YCxcbiAgICAgICAgICAgIGFjY291bnROYW1lLFxuICAgICAgICAgICAgYWNjb3VudEVtYWlsLFxuICAgICAgICAgICAgeyBlbnY6IGVudmlyb25tZW50VHlwZSB9LFxuICAgICAgICAgICAgb3JnVW5pdFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZE9yZ2FuaXNhdGlvbmFsVW5pdChpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBPcmdhbml6YXRpb25hbFVuaXQge1xuICAgIGNvbnN0IG91ID0gbmV3IE9yZ2FuaXphdGlvbmFsVW5pdCh0aGlzLCBpZCwge1xuICAgICAgb3JnYW5pemF0aW9uYWxVbml0TmFtZTogbmFtZSxcbiAgICAgIHBhcmVudDogdGhpcy5vcmdhbmlzYXRpb24ucm9vdCxcbiAgICAgIGltcG9ydE9uRHVwbGljYXRlOiB0cnVlXG4gICAgfSk7XG5cbiAgICB0aGlzLm9yZ2FuaXNhdGlvbmFsVW5pdHMucHVzaChvdSk7XG4gICAgcmV0dXJuIG91O1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRBY2NvdW50KFxuICAgIGlkOiBzdHJpbmcsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgdGFnczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgICBvcmdhbmlzYXRpb25hbFVuaXQ6IE9yZ2FuaXphdGlvbmFsVW5pdFxuICApOiBBY2NvdW50IHtcbiAgICBjb25zdCBhY2MgPSBuZXcgQWNjb3VudCh0aGlzLCBpZCwge1xuICAgICAgYWNjb3VudE5hbWU6IG5hbWUsXG4gICAgICBlbWFpbDogZW1haWwsXG4gICAgICBwYXJlbnQ6IG9yZ2FuaXNhdGlvbmFsVW5pdCxcbiAgICAgIGltcG9ydE9uRHVwbGljYXRlOiB0cnVlXG4gICAgfSk7XG5cbiAgICBmb3IgKGNvbnN0IHRhZyBpbiB0YWdzKSB7XG4gICAgICBUYWdzLm9mKGFjYykuYWRkKHRhZywgdGFnc1t0YWddKTtcbiAgICB9XG5cbiAgICB0aGlzLmFjY291bnRzW25hbWVdID0gYWNjLmFjY291bnRJZDtcblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgYCR7aWR9SWRgLCB7XG4gICAgICBrZXk6IGAke2lkfUlkYCxcbiAgICAgIHZhbHVlOiBhY2MuYWNjb3VudElkLFxuICAgICAgZXhwb3J0TmFtZTogYCR7aWR9SWRgXG4gICAgfSk7XG4gICAgbmV3IENmbk91dHB1dCh0aGlzLCBgJHtpZH1Bcm5gLCB7XG4gICAgICBrZXk6IGAke2lkfUFybmAsXG4gICAgICB2YWx1ZTogYWNjLmFjY291bnRBcm4sXG4gICAgICBleHBvcnROYW1lOiBgJHtpZH1Bcm5gXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYWNjO1xuICB9XG5cbiAgcHVibGljIGdldEFjY291bnRzKCkge1xuICAgIHJldHVybiB0aGlzLmFjY291bnRzO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CfnOutput } from "aws-cdk-lib";
|
|
2
|
+
import { Construct } from "constructs";
|
|
3
|
+
export declare class OrganisationId extends Construct {
|
|
4
|
+
readonly organisationId: CfnOutput;
|
|
5
|
+
readonly organisationAccountArn: CfnOutput;
|
|
6
|
+
constructor(scope: Construct, id: string);
|
|
7
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrganisationId = 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 awsCustomResource_1 = require("../../resources/aws/utilities/awsCustomResource");
|
|
9
|
+
class OrganisationId extends constructs_1.Construct {
|
|
10
|
+
constructor(scope, id) {
|
|
11
|
+
super(scope, id);
|
|
12
|
+
const organisation = new awsCustomResource_1.AwsCustomResource(this, "OrganisationResource", {
|
|
13
|
+
functionName: "organisationId",
|
|
14
|
+
onCreate: {
|
|
15
|
+
service: "organizations",
|
|
16
|
+
action: "DescribeOrganizationCommand", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#describeOrganization-property
|
|
17
|
+
physicalResourceId: customResources.PhysicalResourceId.of("organisationId")
|
|
18
|
+
},
|
|
19
|
+
onUpdate: {
|
|
20
|
+
service: "organizations",
|
|
21
|
+
action: "DescribeOrganizationCommand", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#describeOrganization-property
|
|
22
|
+
physicalResourceId: customResources.PhysicalResourceId.of("organisationId")
|
|
23
|
+
},
|
|
24
|
+
resourceType: "Custom::DescribeOrganisation",
|
|
25
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
26
|
+
new aws_iam_1.PolicyStatement({
|
|
27
|
+
actions: ["organizations:DescribeOrganization"],
|
|
28
|
+
resources: ["*"],
|
|
29
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
30
|
+
})
|
|
31
|
+
])
|
|
32
|
+
});
|
|
33
|
+
this.organisationId = new aws_cdk_lib_1.CfnOutput(this, "OrganisationIdOutput", {
|
|
34
|
+
key: "OrganisationId",
|
|
35
|
+
value: organisation.getResponseField("Organization.Id"),
|
|
36
|
+
exportName: "OrganisationId"
|
|
37
|
+
});
|
|
38
|
+
this.organisationAccountArn = new aws_cdk_lib_1.CfnOutput(this, "OrganisationAccountArnOutput", {
|
|
39
|
+
key: "OrganisationAccountArn",
|
|
40
|
+
value: organisation.getResponseField("Organization.MasterAccountArn"),
|
|
41
|
+
exportName: "OrganisationAccountArn"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.OrganisationId = OrganisationId;
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pc2F0aW9uSWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvY29uZmlnL2F3cy9vcmdhbmlzYXRpb25JZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBd0M7QUFDeEMsZ0VBQWdFO0FBQ2hFLGlEQUE4RDtBQUM5RCwyQ0FBdUM7QUFFdkMsdUZBQW9GO0FBRXBGLE1BQWEsY0FBZSxTQUFRLHNCQUFTO0lBSTNDLFlBQVksS0FBZ0IsRUFBRSxFQUFVO1FBQ3RDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxZQUFZLEdBQUcsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUU7WUFDdkUsWUFBWSxFQUFFLGdCQUFnQjtZQUM5QixRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLGVBQWU7Z0JBQ3hCLE1BQU0sRUFBRSw2QkFBNkIsRUFBRSwyR0FBMkc7Z0JBQ2xKLGtCQUFrQixFQUNoQixlQUFlLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDO2FBQzFEO1lBQ0QsUUFBUSxFQUFFO2dCQUNSLE9BQU8sRUFBRSxlQUFlO2dCQUN4QixNQUFNLEVBQUUsNkJBQTZCLEVBQUUsMkdBQTJHO2dCQUNsSixrQkFBa0IsRUFDaEIsZUFBZSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQzthQUMxRDtZQUNELFlBQVksRUFBRSw4QkFBOEI7WUFDNUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUM7Z0JBQzdELElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFLENBQUMsb0NBQW9DLENBQUM7b0JBQy9DLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztvQkFDaEIsTUFBTSxFQUFFLGdCQUFNLENBQUMsS0FBSztpQkFDckIsQ0FBQzthQUNILENBQUM7U0FDSCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksdUJBQVMsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUU7WUFDaEUsR0FBRyxFQUFFLGdCQUFnQjtZQUNyQixLQUFLLEVBQUUsWUFBWSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDO1lBQ3ZELFVBQVUsRUFBRSxnQkFBZ0I7U0FDN0IsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksdUJBQVMsQ0FDekMsSUFBSSxFQUNKLDhCQUE4QixFQUM5QjtZQUNFLEdBQUcsRUFBRSx3QkFBd0I7WUFDN0IsS0FBSyxFQUFFLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQywrQkFBK0IsQ0FBQztZQUNyRSxVQUFVLEVBQUUsd0JBQXdCO1NBQ3JDLENBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQS9DRCx3Q0ErQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZm5PdXRwdXQgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCAqIGFzIGN1c3RvbVJlc291cmNlcyBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiO1xuaW1wb3J0IHsgRWZmZWN0LCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuaW1wb3J0IHsgQXdzQ3VzdG9tUmVzb3VyY2UgfSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy91dGlsaXRpZXMvYXdzQ3VzdG9tUmVzb3VyY2VcIjtcblxuZXhwb3J0IGNsYXNzIE9yZ2FuaXNhdGlvbklkIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IG9yZ2FuaXNhdGlvbklkOiBDZm5PdXRwdXQ7XG4gIHB1YmxpYyByZWFkb25seSBvcmdhbmlzYXRpb25BY2NvdW50QXJuOiBDZm5PdXRwdXQ7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBvcmdhbmlzYXRpb24gPSBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJPcmdhbmlzYXRpb25SZXNvdXJjZVwiLCB7XG4gICAgICBmdW5jdGlvbk5hbWU6IFwib3JnYW5pc2F0aW9uSWRcIixcbiAgICAgIG9uQ3JlYXRlOiB7XG4gICAgICAgIHNlcnZpY2U6IFwib3JnYW5pemF0aW9uc1wiLFxuICAgICAgICBhY3Rpb246IFwiRGVzY3JpYmVPcmdhbml6YXRpb25Db21tYW5kXCIsIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL2xhdGVzdC9BV1MvT3JnYW5pemF0aW9ucy5odG1sI2Rlc2NyaWJlT3JnYW5pemF0aW9uLXByb3BlcnR5XG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDpcbiAgICAgICAgICBjdXN0b21SZXNvdXJjZXMuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKFwib3JnYW5pc2F0aW9uSWRcIilcbiAgICAgIH0sXG4gICAgICBvblVwZGF0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIm9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgYWN0aW9uOiBcIkRlc2NyaWJlT3JnYW5pemF0aW9uQ29tbWFuZFwiLCAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvQVdTL09yZ2FuaXphdGlvbnMuaHRtbCNkZXNjcmliZU9yZ2FuaXphdGlvbi1wcm9wZXJ0eVxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQ6XG4gICAgICAgICAgY3VzdG9tUmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZihcIm9yZ2FuaXNhdGlvbklkXCIpXG4gICAgICB9LFxuICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6RGVzY3JpYmVPcmdhbmlzYXRpb25cIixcbiAgICAgIHBvbGljeTogY3VzdG9tUmVzb3VyY2VzLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TdGF0ZW1lbnRzKFtcbiAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1wib3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblwiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1dcbiAgICAgICAgfSlcbiAgICAgIF0pXG4gICAgfSk7XG5cbiAgICB0aGlzLm9yZ2FuaXNhdGlvbklkID0gbmV3IENmbk91dHB1dCh0aGlzLCBcIk9yZ2FuaXNhdGlvbklkT3V0cHV0XCIsIHtcbiAgICAgIGtleTogXCJPcmdhbmlzYXRpb25JZFwiLFxuICAgICAgdmFsdWU6IG9yZ2FuaXNhdGlvbi5nZXRSZXNwb25zZUZpZWxkKFwiT3JnYW5pemF0aW9uLklkXCIpLFxuICAgICAgZXhwb3J0TmFtZTogXCJPcmdhbmlzYXRpb25JZFwiXG4gICAgfSk7XG5cbiAgICB0aGlzLm9yZ2FuaXNhdGlvbkFjY291bnRBcm4gPSBuZXcgQ2ZuT3V0cHV0KFxuICAgICAgdGhpcyxcbiAgICAgIFwiT3JnYW5pc2F0aW9uQWNjb3VudEFybk91dHB1dFwiLFxuICAgICAge1xuICAgICAgICBrZXk6IFwiT3JnYW5pc2F0aW9uQWNjb3VudEFyblwiLFxuICAgICAgICB2YWx1ZTogb3JnYW5pc2F0aW9uLmdldFJlc3BvbnNlRmllbGQoXCJPcmdhbml6YXRpb24uTWFzdGVyQWNjb3VudEFyblwiKSxcbiAgICAgICAgZXhwb3J0TmFtZTogXCJPcmdhbmlzYXRpb25BY2NvdW50QXJuXCJcbiAgICAgIH1cbiAgICApO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { type StackProps } from "aws-cdk-lib";
|
|
3
|
+
interface ActivateOrganisationsAccessProps extends StackProps {
|
|
4
|
+
account: string;
|
|
5
|
+
region: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class ActivateOrganisationsAccess extends Construct {
|
|
8
|
+
constructor(scope: Construct, id: string, props: ActivateOrganisationsAccessProps);
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ActivateOrganisationsAccess = void 0;
|
|
4
|
+
const customResources = require("aws-cdk-lib/custom-resources");
|
|
5
|
+
const constructs_1 = require("constructs");
|
|
6
|
+
const awsCustomResource_1 = require("../../resources/aws/utilities/awsCustomResource");
|
|
7
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
8
|
+
class ActivateOrganisationsAccess extends constructs_1.Construct {
|
|
9
|
+
constructor(scope, id, props) {
|
|
10
|
+
super(scope, id);
|
|
11
|
+
new awsCustomResource_1.AwsCustomResource(this, "activateOrganisationsAccess", {
|
|
12
|
+
functionName: "activateOrganisationsAccess",
|
|
13
|
+
onCreate: {
|
|
14
|
+
service: "cloudformation",
|
|
15
|
+
action: "ActivateOrganizationsAccessCommand", // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cloudformation/command/ActivateOrganizationsAccessCommand/
|
|
16
|
+
parameters: {},
|
|
17
|
+
physicalResourceId: customResources.PhysicalResourceId.of("activateOrganisationsAccess")
|
|
18
|
+
},
|
|
19
|
+
resourceType: "Custom::ActivateOrganisationsAccess",
|
|
20
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
21
|
+
new aws_iam_1.PolicyStatement({
|
|
22
|
+
actions: [
|
|
23
|
+
"cloudformation:ActivateOrganizationsAccess",
|
|
24
|
+
"cloudformation:DescribeOrganizationsAccess",
|
|
25
|
+
"organizations:EnableAWSServiceAccess",
|
|
26
|
+
"organizations:DescribeOrganization",
|
|
27
|
+
"organizations:ListRoots",
|
|
28
|
+
"organizations:ListAWSServiceAccessForOrganization",
|
|
29
|
+
"organizations:DisableAWSServiceAccess",
|
|
30
|
+
"iam:CreateServiceLinkedRole",
|
|
31
|
+
"iam:GetRole"
|
|
32
|
+
],
|
|
33
|
+
resources: [
|
|
34
|
+
"*" // TODO: Figure out what access is required here
|
|
35
|
+
],
|
|
36
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
37
|
+
}),
|
|
38
|
+
new aws_iam_1.PolicyStatement({
|
|
39
|
+
actions: ["cloudformation:ActivateOrganizationsAccess"],
|
|
40
|
+
resources: [
|
|
41
|
+
`arn:aws:cloudformation:${props.region}:${props.account}:stackset/*`
|
|
42
|
+
],
|
|
43
|
+
effect: aws_iam_1.Effect.ALLOW
|
|
44
|
+
})
|
|
45
|
+
])
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.ActivateOrganisationsAccess = ActivateOrganisationsAccess;
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pc2F0aW9uc0FjY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9jb25maWcvYXdzL29yZ2FuaXNhdGlvbnNBY2Nlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWdFO0FBQ2hFLDJDQUF1QztBQUV2Qyx1RkFBb0Y7QUFDcEYsaURBQThEO0FBUTlELE1BQWEsMkJBQTRCLFNBQVEsc0JBQVM7SUFDeEQsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBdUM7UUFFdkMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLHFDQUFpQixDQUFDLElBQUksRUFBRSw2QkFBNkIsRUFBRTtZQUN6RCxZQUFZLEVBQUUsNkJBQTZCO1lBQzNDLFFBQVEsRUFBRTtnQkFDUixPQUFPLEVBQUUsZ0JBQWdCO2dCQUN6QixNQUFNLEVBQUUsb0NBQW9DLEVBQUUsMkhBQTJIO2dCQUN6SyxVQUFVLEVBQUUsRUFBRTtnQkFDZCxrQkFBa0IsRUFBRSxlQUFlLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUN2RCw2QkFBNkIsQ0FDOUI7YUFDRjtZQUNELFlBQVksRUFBRSxxQ0FBcUM7WUFDbkQsTUFBTSxFQUFFLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUM7Z0JBQzdELElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLDRDQUE0Qzt3QkFDNUMsNENBQTRDO3dCQUM1QyxzQ0FBc0M7d0JBQ3RDLG9DQUFvQzt3QkFDcEMseUJBQXlCO3dCQUN6QixtREFBbUQ7d0JBQ25ELHVDQUF1Qzt3QkFDdkMsNkJBQTZCO3dCQUM3QixhQUFhO3FCQUNkO29CQUNELFNBQVMsRUFBRTt3QkFDVCxHQUFHLENBQUMsZ0RBQWdEO3FCQUNyRDtvQkFDRCxNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO2lCQUNyQixDQUFDO2dCQUNGLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFLENBQUMsNENBQTRDLENBQUM7b0JBQ3ZELFNBQVMsRUFBRTt3QkFDVCwwQkFBMEIsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxhQUFhO3FCQUNyRTtvQkFDRCxNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO2lCQUNyQixDQUFDO2FBQ0gsQ0FBQztTQUNILENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQS9DRCxrRUErQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjdXN0b21SZXNvdXJjZXMgZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmltcG9ydCB7IEF3c0N1c3RvbVJlc291cmNlIH0gZnJvbSBcIi4uLy4uL3Jlc291cmNlcy9hd3MvdXRpbGl0aWVzL2F3c0N1c3RvbVJlc291cmNlXCI7XG5pbXBvcnQgeyBFZmZlY3QsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyB0eXBlIFN0YWNrUHJvcHMgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuaW50ZXJmYWNlIEFjdGl2YXRlT3JnYW5pc2F0aW9uc0FjY2Vzc1Byb3BzIGV4dGVuZHMgU3RhY2tQcm9wcyB7XG4gIGFjY291bnQ6IHN0cmluZztcbiAgcmVnaW9uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBBY3RpdmF0ZU9yZ2FuaXNhdGlvbnNBY2Nlc3MgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IEFjdGl2YXRlT3JnYW5pc2F0aW9uc0FjY2Vzc1Byb3BzXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJhY3RpdmF0ZU9yZ2FuaXNhdGlvbnNBY2Nlc3NcIiwge1xuICAgICAgZnVuY3Rpb25OYW1lOiBcImFjdGl2YXRlT3JnYW5pc2F0aW9uc0FjY2Vzc1wiLFxuICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgc2VydmljZTogXCJjbG91ZGZvcm1hdGlvblwiLFxuICAgICAgICBhY3Rpb246IFwiQWN0aXZhdGVPcmdhbml6YXRpb25zQWNjZXNzQ29tbWFuZFwiLCAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy92My9sYXRlc3QvY2xpZW50L2Nsb3VkZm9ybWF0aW9uL2NvbW1hbmQvQWN0aXZhdGVPcmdhbml6YXRpb25zQWNjZXNzQ29tbWFuZC9cbiAgICAgICAgcGFyYW1ldGVyczoge30sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tUmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZihcbiAgICAgICAgICBcImFjdGl2YXRlT3JnYW5pc2F0aW9uc0FjY2Vzc1wiXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpBY3RpdmF0ZU9yZ2FuaXNhdGlvbnNBY2Nlc3NcIixcbiAgICAgIHBvbGljeTogY3VzdG9tUmVzb3VyY2VzLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TdGF0ZW1lbnRzKFtcbiAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgXCJjbG91ZGZvcm1hdGlvbjpBY3RpdmF0ZU9yZ2FuaXphdGlvbnNBY2Nlc3NcIixcbiAgICAgICAgICAgIFwiY2xvdWRmb3JtYXRpb246RGVzY3JpYmVPcmdhbml6YXRpb25zQWNjZXNzXCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6RW5hYmxlQVdTU2VydmljZUFjY2Vzc1wiLFxuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOkRlc2NyaWJlT3JnYW5pemF0aW9uXCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6TGlzdFJvb3RzXCIsXG4gICAgICAgICAgICBcIm9yZ2FuaXphdGlvbnM6TGlzdEFXU1NlcnZpY2VBY2Nlc3NGb3JPcmdhbml6YXRpb25cIixcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpEaXNhYmxlQVdTU2VydmljZUFjY2Vzc1wiLFxuICAgICAgICAgICAgXCJpYW06Q3JlYXRlU2VydmljZUxpbmtlZFJvbGVcIixcbiAgICAgICAgICAgIFwiaWFtOkdldFJvbGVcIlxuICAgICAgICAgIF0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICBcIipcIiAvLyBUT0RPOiBGaWd1cmUgb3V0IHdoYXQgYWNjZXNzIGlzIHJlcXVpcmVkIGhlcmVcbiAgICAgICAgICBdLFxuICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XXG4gICAgICAgIH0pLFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJjbG91ZGZvcm1hdGlvbjpBY3RpdmF0ZU9yZ2FuaXphdGlvbnNBY2Nlc3NcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICBgYXJuOmF3czpjbG91ZGZvcm1hdGlvbjoke3Byb3BzLnJlZ2lvbn06JHtwcm9wcy5hY2NvdW50fTpzdGFja3NldC8qYFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1dcbiAgICAgICAgfSlcbiAgICAgIF0pXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RamSharing = 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("../../resources/aws/utilities/awsCustomResource");
|
|
8
|
+
class RamSharing extends constructs_1.Construct {
|
|
9
|
+
constructor(scope, id) {
|
|
10
|
+
super(scope, id);
|
|
11
|
+
new awsCustomResource_1.AwsCustomResource(this, "enableRamSharing", {
|
|
12
|
+
functionName: "enableRamSharing",
|
|
13
|
+
onCreate: {
|
|
14
|
+
service: "RAM",
|
|
15
|
+
action: "enableSharingWithAwsOrganization", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RAM.html#enableSharingWithAwsOrganization-property
|
|
16
|
+
parameters: {},
|
|
17
|
+
physicalResourceId: customResources.PhysicalResourceId.of("enableRamSharing")
|
|
18
|
+
},
|
|
19
|
+
resourceType: "Custom::ram",
|
|
20
|
+
policy: customResources.AwsCustomResourcePolicy.fromStatements([
|
|
21
|
+
new aws_iam_1.PolicyStatement({
|
|
22
|
+
actions: [
|
|
23
|
+
"ram:EnableSharingWithAwsOrganization",
|
|
24
|
+
"iam:CreateServiceLinkedRole",
|
|
25
|
+
"organizations:enableAWSServiceAccess",
|
|
26
|
+
"organizations:DescribeOrganization"
|
|
27
|
+
],
|
|
28
|
+
resources: ["*"] // TODO: Find out the exact pricipal for this
|
|
29
|
+
})
|
|
30
|
+
])
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.RamSharing = RamSharing;
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFtU2hhcmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9jb25maWcvYXdzL3JhbVNoYXJpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWdFO0FBQ2hFLGlEQUFzRDtBQUN0RCwyQ0FBdUM7QUFFdkMsdUZBQW9GO0FBRXBGLE1BQWEsVUFBVyxTQUFRLHNCQUFTO0lBQ3ZDLFlBQVksS0FBZ0IsRUFBRSxFQUFVO1FBQ3RDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDOUMsWUFBWSxFQUFFLGtCQUFrQjtZQUNoQyxRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsTUFBTSxFQUFFLGtDQUFrQyxFQUFFLDZHQUE2RztnQkFDekosVUFBVSxFQUFFLEVBQUU7Z0JBQ2Qsa0JBQWtCLEVBQ2hCLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUM7YUFDNUQ7WUFDRCxZQUFZLEVBQUUsYUFBYTtZQUMzQixNQUFNLEVBQUUsZUFBZSxDQUFDLHVCQUF1QixDQUFDLGNBQWMsQ0FBQztnQkFDN0QsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1Asc0NBQXNDO3dCQUN0Qyw2QkFBNkI7d0JBQzdCLHNDQUFzQzt3QkFDdEMsb0NBQW9DO3FCQUNyQztvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyw2Q0FBNkM7aUJBQy9ELENBQUM7YUFDSCxDQUFDO1NBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBM0JELGdDQTJCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGN1c3RvbVJlc291cmNlcyBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbmltcG9ydCB7IEF3c0N1c3RvbVJlc291cmNlIH0gZnJvbSBcIi4uLy4uL3Jlc291cmNlcy9hd3MvdXRpbGl0aWVzL2F3c0N1c3RvbVJlc291cmNlXCI7XG5cbmV4cG9ydCBjbGFzcyBSYW1TaGFyaW5nIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJlbmFibGVSYW1TaGFyaW5nXCIsIHtcbiAgICAgIGZ1bmN0aW9uTmFtZTogXCJlbmFibGVSYW1TaGFyaW5nXCIsXG4gICAgICBvbkNyZWF0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIlJBTVwiLFxuICAgICAgICBhY3Rpb246IFwiZW5hYmxlU2hhcmluZ1dpdGhBd3NPcmdhbml6YXRpb25cIiwgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9SQU0uaHRtbCNlbmFibGVTaGFyaW5nV2l0aEF3c09yZ2FuaXphdGlvbi1wcm9wZXJ0eVxuICAgICAgICBwYXJhbWV0ZXJzOiB7fSxcbiAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOlxuICAgICAgICAgIGN1c3RvbVJlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQub2YoXCJlbmFibGVSYW1TaGFyaW5nXCIpXG4gICAgICB9LFxuICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6cmFtXCIsXG4gICAgICBwb2xpY3k6IGN1c3RvbVJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU3RhdGVtZW50cyhbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgIFwicmFtOkVuYWJsZVNoYXJpbmdXaXRoQXdzT3JnYW5pemF0aW9uXCIsXG4gICAgICAgICAgICBcImlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVwiLFxuICAgICAgICAgICAgXCJvcmdhbml6YXRpb25zOmVuYWJsZUFXU1NlcnZpY2VBY2Nlc3NcIixcbiAgICAgICAgICAgIFwib3JnYW5pemF0aW9uczpEZXNjcmliZU9yZ2FuaXphdGlvblwiXG4gICAgICAgICAgXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0gLy8gVE9ETzogRmluZCBvdXQgdGhlIGV4YWN0IHByaWNpcGFsIGZvciB0aGlzXG4gICAgICAgIH0pXG4gICAgICBdKVxuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitoring configuration for cross-account access
|
|
3
|
+
*/
|
|
4
|
+
export declare const FJALL_MONITORING_CONFIG: {
|
|
5
|
+
/**
|
|
6
|
+
* Fjall webapp AWS account ID
|
|
7
|
+
* This account will be granted permission to assume monitoring roles
|
|
8
|
+
*/
|
|
9
|
+
readonly webappAwsAccountId: "985539798308";
|
|
10
|
+
/**
|
|
11
|
+
* IAM role naming convention
|
|
12
|
+
*/
|
|
13
|
+
readonly roleNamePrefix: "FjallMonitoring";
|
|
14
|
+
/**
|
|
15
|
+
* IAM role path (for organizational structure)
|
|
16
|
+
*/
|
|
17
|
+
readonly rolePath: "/";
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FJALL_MONITORING_CONFIG = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Monitoring configuration for cross-account access
|
|
6
|
+
*/
|
|
7
|
+
exports.FJALL_MONITORING_CONFIG = {
|
|
8
|
+
/**
|
|
9
|
+
* Fjall webapp AWS account ID
|
|
10
|
+
* This account will be granted permission to assume monitoring roles
|
|
11
|
+
*/
|
|
12
|
+
webappAwsAccountId: "985539798308", // Fjall platform account
|
|
13
|
+
/**
|
|
14
|
+
* IAM role naming convention
|
|
15
|
+
*/
|
|
16
|
+
roleNamePrefix: "FjallMonitoring",
|
|
17
|
+
/**
|
|
18
|
+
* IAM role path (for organizational structure)
|
|
19
|
+
*/
|
|
20
|
+
rolePath: "/"
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uaXRvcmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb25maWcvbW9uaXRvcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7R0FFRztBQUNVLFFBQUEsdUJBQXVCLEdBQUc7SUFDckM7OztPQUdHO0lBQ0gsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLHlCQUF5QjtJQUU3RDs7T0FFRztJQUNILGNBQWMsRUFBRSxpQkFBaUI7SUFFakM7O09BRUc7SUFDSCxRQUFRLEVBQUUsR0FBRztDQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vbml0b3JpbmcgY29uZmlndXJhdGlvbiBmb3IgY3Jvc3MtYWNjb3VudCBhY2Nlc3NcbiAqL1xuZXhwb3J0IGNvbnN0IEZKQUxMX01PTklUT1JJTkdfQ09ORklHID0ge1xuICAvKipcbiAgICogRmphbGwgd2ViYXBwIEFXUyBhY2NvdW50IElEXG4gICAqIFRoaXMgYWNjb3VudCB3aWxsIGJlIGdyYW50ZWQgcGVybWlzc2lvbiB0byBhc3N1bWUgbW9uaXRvcmluZyByb2xlc1xuICAgKi9cbiAgd2ViYXBwQXdzQWNjb3VudElkOiBcIjk4NTUzOTc5ODMwOFwiLCAvLyBGamFsbCBwbGF0Zm9ybSBhY2NvdW50XG5cbiAgLyoqXG4gICAqIElBTSByb2xlIG5hbWluZyBjb252ZW50aW9uXG4gICAqL1xuICByb2xlTmFtZVByZWZpeDogXCJGamFsbE1vbml0b3JpbmdcIixcblxuICAvKipcbiAgICogSUFNIHJvbGUgcGF0aCAoZm9yIG9yZ2FuaXphdGlvbmFsIHN0cnVjdHVyZSlcbiAgICovXG4gIHJvbGVQYXRoOiBcIi9cIlxufSBhcyBjb25zdDtcbiJdfQ==
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { type Role } from "aws-cdk-lib/aws-iam";
|
|
3
|
+
import { type CICDProvider } from "../../resources/aws/cicd/cicdRole";
|
|
4
|
+
export interface CICDRoleProps {
|
|
5
|
+
/**
|
|
6
|
+
* The CI/CD provider (github-actions, buildkite, gitlab-ci)
|
|
7
|
+
*/
|
|
8
|
+
provider: CICDProvider;
|
|
9
|
+
/**
|
|
10
|
+
* For GitHub Actions: repository in format "org/repo"
|
|
11
|
+
* For Buildkite: organization slug
|
|
12
|
+
* For GitLab CI: project path in format "group/project"
|
|
13
|
+
*/
|
|
14
|
+
repositoryOrOrg: string;
|
|
15
|
+
/**
|
|
16
|
+
* Optional custom role name
|
|
17
|
+
* Defaults to "FjallDeploy-{provider}-{appName}"
|
|
18
|
+
*/
|
|
19
|
+
roleName?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Optional ARN of existing OIDC provider (skips creation)
|
|
22
|
+
* Useful when OIDC provider already exists in the account
|
|
23
|
+
*/
|
|
24
|
+
existingProviderArn?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* High-level pattern for adding CI/CD OIDC authentication to an application.
|
|
28
|
+
*
|
|
29
|
+
* This creates an OIDC provider (if needed) and a deploy role that can be assumed
|
|
30
|
+
* by your CI/CD system without long-lived credentials.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { App, CICDRole } from "@fjall/components-infrastructure";
|
|
35
|
+
*
|
|
36
|
+
* const app = App.getApp("MyApp");
|
|
37
|
+
*
|
|
38
|
+
* // Add GitHub Actions OIDC authentication
|
|
39
|
+
* const cicdRole = new CICDRole(app, "GitHubDeployRole", {
|
|
40
|
+
* provider: "github-actions",
|
|
41
|
+
* repositoryOrOrg: "myorg/myrepo"
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* // Continue with normal application setup
|
|
45
|
+
* app.addCompute(/* ... *\/);
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // Use existing OIDC provider (created via fjall cicd setup)
|
|
51
|
+
* const cicdRole = new CICDRole(app, "GitHubDeployRole", {
|
|
52
|
+
* provider: "github-actions",
|
|
53
|
+
* repositoryOrOrg: "myorg/myrepo",
|
|
54
|
+
* existingProviderArn: "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare class CICDRole extends Construct {
|
|
59
|
+
readonly role: Role;
|
|
60
|
+
readonly provider: CICDProvider;
|
|
61
|
+
constructor(scope: Construct, id: string, props: CICDRoleProps);
|
|
62
|
+
/**
|
|
63
|
+
* Get the role ARN for use in CI/CD configuration
|
|
64
|
+
*/
|
|
65
|
+
getRoleArn(): string;
|
|
66
|
+
}
|
|
67
|
+
export default CICDRole;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CICDRole = void 0;
|
|
4
|
+
const constructs_1 = require("constructs");
|
|
5
|
+
const app_1 = require("../../app");
|
|
6
|
+
const cicdRole_1 = require("../../resources/aws/cicd/cicdRole");
|
|
7
|
+
/**
|
|
8
|
+
* High-level pattern for adding CI/CD OIDC authentication to an application.
|
|
9
|
+
*
|
|
10
|
+
* This creates an OIDC provider (if needed) and a deploy role that can be assumed
|
|
11
|
+
* by your CI/CD system without long-lived credentials.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { App, CICDRole } from "@fjall/components-infrastructure";
|
|
16
|
+
*
|
|
17
|
+
* const app = App.getApp("MyApp");
|
|
18
|
+
*
|
|
19
|
+
* // Add GitHub Actions OIDC authentication
|
|
20
|
+
* const cicdRole = new CICDRole(app, "GitHubDeployRole", {
|
|
21
|
+
* provider: "github-actions",
|
|
22
|
+
* repositoryOrOrg: "myorg/myrepo"
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Continue with normal application setup
|
|
26
|
+
* app.addCompute(/* ... *\/);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Use existing OIDC provider (created via fjall cicd setup)
|
|
32
|
+
* const cicdRole = new CICDRole(app, "GitHubDeployRole", {
|
|
33
|
+
* provider: "github-actions",
|
|
34
|
+
* repositoryOrOrg: "myorg/myrepo",
|
|
35
|
+
* existingProviderArn: "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
class CICDRole extends constructs_1.Construct {
|
|
40
|
+
constructor(scope, id, props) {
|
|
41
|
+
super(scope, id);
|
|
42
|
+
// Get the App instance
|
|
43
|
+
const app = scope instanceof app_1.default ? scope : app_1.default.getInstance();
|
|
44
|
+
const networkStack = app.getDefaultNetworkStack();
|
|
45
|
+
this.provider = props.provider;
|
|
46
|
+
// Build the config for the factory
|
|
47
|
+
const config = {
|
|
48
|
+
provider: props.provider,
|
|
49
|
+
appName: app["name"],
|
|
50
|
+
repositoryOrOrg: props.repositoryOrOrg,
|
|
51
|
+
roleName: props.roleName,
|
|
52
|
+
existingProviderArn: props.existingProviderArn
|
|
53
|
+
};
|
|
54
|
+
// Create the CI/CD role using the factory
|
|
55
|
+
this.role = cicdRole_1.default.build(`${app["name"]}CICDRole`, config)(app, networkStack.getStack());
|
|
56
|
+
// Register the role with the network stack
|
|
57
|
+
networkStack.addConstruct(this.role);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the role ARN for use in CI/CD configuration
|
|
61
|
+
*/
|
|
62
|
+
getRoleArn() {
|
|
63
|
+
return this.role.roleArn;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.CICDRole = CICDRole;
|
|
67
|
+
exports.default = CICDRole;
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2ljZFJvbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvcGF0dGVybnMvYXdzL2NpY2RSb2xlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF1QztBQUV2QyxtQ0FBNEI7QUFDNUIsZ0VBRzJDO0FBNEIzQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUNILE1BQWEsUUFBUyxTQUFRLHNCQUFTO0lBSXJDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBb0I7UUFDNUQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQix1QkFBdUI7UUFDdkIsTUFBTSxHQUFHLEdBQUcsS0FBSyxZQUFZLGFBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxhQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDN0QsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFFbEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBRS9CLG1DQUFtQztRQUNuQyxNQUFNLE1BQU0sR0FBbUI7WUFDN0IsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLE9BQU8sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDO1lBQ3BCLGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZTtZQUN0QyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7WUFDeEIsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtTQUMvQyxDQUFDO1FBRUYsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWUsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FDakUsR0FBRyxFQUNILFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FDeEIsQ0FBQztRQUVGLDJDQUEyQztRQUMzQyxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVO1FBQ2YsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUMzQixDQUFDO0NBQ0Y7QUF0Q0QsNEJBc0NDO0FBRUQsa0JBQWUsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHR5cGUgUm9sZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgQXBwIGZyb20gXCIuLi8uLi9hcHBcIjtcbmltcG9ydCBDSUNEUm9sZUZhY3RvcnksIHtcbiAgdHlwZSBDSUNEUHJvdmlkZXIsXG4gIHR5cGUgQ0lDRFJvbGVDb25maWdcbn0gZnJvbSBcIi4uLy4uL3Jlc291cmNlcy9hd3MvY2ljZC9jaWNkUm9sZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIENJQ0RSb2xlUHJvcHMge1xuICAvKipcbiAgICogVGhlIENJL0NEIHByb3ZpZGVyIChnaXRodWItYWN0aW9ucywgYnVpbGRraXRlLCBnaXRsYWItY2kpXG4gICAqL1xuICBwcm92aWRlcjogQ0lDRFByb3ZpZGVyO1xuXG4gIC8qKlxuICAgKiBGb3IgR2l0SHViIEFjdGlvbnM6IHJlcG9zaXRvcnkgaW4gZm9ybWF0IFwib3JnL3JlcG9cIlxuICAgKiBGb3IgQnVpbGRraXRlOiBvcmdhbml6YXRpb24gc2x1Z1xuICAgKiBGb3IgR2l0TGFiIENJOiBwcm9qZWN0IHBhdGggaW4gZm9ybWF0IFwiZ3JvdXAvcHJvamVjdFwiXG4gICAqL1xuICByZXBvc2l0b3J5T3JPcmc6IHN0cmluZztcblxuICAvKipcbiAgICogT3B0aW9uYWwgY3VzdG9tIHJvbGUgbmFtZVxuICAgKiBEZWZhdWx0cyB0byBcIkZqYWxsRGVwbG95LXtwcm92aWRlcn0te2FwcE5hbWV9XCJcbiAgICovXG4gIHJvbGVOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBBUk4gb2YgZXhpc3RpbmcgT0lEQyBwcm92aWRlciAoc2tpcHMgY3JlYXRpb24pXG4gICAqIFVzZWZ1bCB3aGVuIE9JREMgcHJvdmlkZXIgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGFjY291bnRcbiAgICovXG4gIGV4aXN0aW5nUHJvdmlkZXJBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSGlnaC1sZXZlbCBwYXR0ZXJuIGZvciBhZGRpbmcgQ0kvQ0QgT0lEQyBhdXRoZW50aWNhdGlvbiB0byBhbiBhcHBsaWNhdGlvbi5cbiAqXG4gKiBUaGlzIGNyZWF0ZXMgYW4gT0lEQyBwcm92aWRlciAoaWYgbmVlZGVkKSBhbmQgYSBkZXBsb3kgcm9sZSB0aGF0IGNhbiBiZSBhc3N1bWVkXG4gKiBieSB5b3VyIENJL0NEIHN5c3RlbSB3aXRob3V0IGxvbmctbGl2ZWQgY3JlZGVudGlhbHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IEFwcCwgQ0lDRFJvbGUgfSBmcm9tIFwiQGZqYWxsL2NvbXBvbmVudHMtaW5mcmFzdHJ1Y3R1cmVcIjtcbiAqXG4gKiBjb25zdCBhcHAgPSBBcHAuZ2V0QXBwKFwiTXlBcHBcIik7XG4gKlxuICogLy8gQWRkIEdpdEh1YiBBY3Rpb25zIE9JREMgYXV0aGVudGljYXRpb25cbiAqIGNvbnN0IGNpY2RSb2xlID0gbmV3IENJQ0RSb2xlKGFwcCwgXCJHaXRIdWJEZXBsb3lSb2xlXCIsIHtcbiAqICAgcHJvdmlkZXI6IFwiZ2l0aHViLWFjdGlvbnNcIixcbiAqICAgcmVwb3NpdG9yeU9yT3JnOiBcIm15b3JnL215cmVwb1wiXG4gKiB9KTtcbiAqXG4gKiAvLyBDb250aW51ZSB3aXRoIG5vcm1hbCBhcHBsaWNhdGlvbiBzZXR1cFxuICogYXBwLmFkZENvbXB1dGUoLyogLi4uICpcXC8pO1xuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIFVzZSBleGlzdGluZyBPSURDIHByb3ZpZGVyIChjcmVhdGVkIHZpYSBmamFsbCBjaWNkIHNldHVwKVxuICogY29uc3QgY2ljZFJvbGUgPSBuZXcgQ0lDRFJvbGUoYXBwLCBcIkdpdEh1YkRlcGxveVJvbGVcIiwge1xuICogICBwcm92aWRlcjogXCJnaXRodWItYWN0aW9uc1wiLFxuICogICByZXBvc2l0b3J5T3JPcmc6IFwibXlvcmcvbXlyZXBvXCIsXG4gKiAgIGV4aXN0aW5nUHJvdmlkZXJBcm46IFwiYXJuOmF3czppYW06OjEyMzQ1Njc4OTAxMjpvaWRjLXByb3ZpZGVyL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tXCJcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBDSUNEUm9sZSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSByb2xlOiBSb2xlO1xuICBwdWJsaWMgcmVhZG9ubHkgcHJvdmlkZXI6IENJQ0RQcm92aWRlcjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ0lDRFJvbGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvLyBHZXQgdGhlIEFwcCBpbnN0YW5jZVxuICAgIGNvbnN0IGFwcCA9IHNjb3BlIGluc3RhbmNlb2YgQXBwID8gc2NvcGUgOiBBcHAuZ2V0SW5zdGFuY2UoKTtcbiAgICBjb25zdCBuZXR3b3JrU3RhY2sgPSBhcHAuZ2V0RGVmYXVsdE5ldHdvcmtTdGFjaygpO1xuXG4gICAgdGhpcy5wcm92aWRlciA9IHByb3BzLnByb3ZpZGVyO1xuXG4gICAgLy8gQnVpbGQgdGhlIGNvbmZpZyBmb3IgdGhlIGZhY3RvcnlcbiAgICBjb25zdCBjb25maWc6IENJQ0RSb2xlQ29uZmlnID0ge1xuICAgICAgcHJvdmlkZXI6IHByb3BzLnByb3ZpZGVyLFxuICAgICAgYXBwTmFtZTogYXBwW1wibmFtZVwiXSxcbiAgICAgIHJlcG9zaXRvcnlPck9yZzogcHJvcHMucmVwb3NpdG9yeU9yT3JnLFxuICAgICAgcm9sZU5hbWU6IHByb3BzLnJvbGVOYW1lLFxuICAgICAgZXhpc3RpbmdQcm92aWRlckFybjogcHJvcHMuZXhpc3RpbmdQcm92aWRlckFyblxuICAgIH07XG5cbiAgICAvLyBDcmVhdGUgdGhlIENJL0NEIHJvbGUgdXNpbmcgdGhlIGZhY3RvcnlcbiAgICB0aGlzLnJvbGUgPSBDSUNEUm9sZUZhY3RvcnkuYnVpbGQoYCR7YXBwW1wibmFtZVwiXX1DSUNEUm9sZWAsIGNvbmZpZykoXG4gICAgICBhcHAsXG4gICAgICBuZXR3b3JrU3RhY2suZ2V0U3RhY2soKVxuICAgICk7XG5cbiAgICAvLyBSZWdpc3RlciB0aGUgcm9sZSB3aXRoIHRoZSBuZXR3b3JrIHN0YWNrXG4gICAgbmV0d29ya1N0YWNrLmFkZENvbnN0cnVjdCh0aGlzLnJvbGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcm9sZSBBUk4gZm9yIHVzZSBpbiBDSS9DRCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0Um9sZUFybigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJvbGUucm9sZUFybjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDSUNEUm9sZTtcbiJdfQ==
|
|
@@ -221,6 +221,10 @@ export class ComputeFactory {
|
|
|
221
221
|
...computeProps,
|
|
222
222
|
appName: app.getName()
|
|
223
223
|
};
|
|
224
|
+
// `ecrRepository` is already defaulted to the app's shared default
|
|
225
|
+
// container registry above (line ~323) when omitted — the same
|
|
226
|
+
// repo ECS services push into — so a container Lambda always has
|
|
227
|
+
// one by this point, whether or not `docker` is set.
|
|
224
228
|
// Always register Lambda with manifest collector for CLI discovery
|
|
225
229
|
// This ensures all Lambdas are discoverable for secrets management,
|
|
226
230
|
// even those that don't currently have secrets configured
|
|
@@ -242,6 +246,11 @@ export class ComputeFactory {
|
|
|
242
246
|
if (lambdaImportedSecretNames.size > 0) {
|
|
243
247
|
manifestLambda.importedSecretNames = Array.from(lambdaImportedSecretNames);
|
|
244
248
|
}
|
|
249
|
+
if (lambdaComputeProps.deployment === "container" &&
|
|
250
|
+
lambdaComputeProps.docker !== undefined) {
|
|
251
|
+
manifestLambda.docker = lambdaComputeProps.docker;
|
|
252
|
+
manifestLambda.imageKey = lambdaComputeProps.image ?? id;
|
|
253
|
+
}
|
|
245
254
|
collector.addLambda(manifestLambda);
|
|
246
255
|
return new LambdaCompute(scope, id, lambdaComputeProps);
|
|
247
256
|
}
|
|
@@ -8,6 +8,7 @@ import { type ILambdaCompute } from "./interfaces/compute.js";
|
|
|
8
8
|
import { type ConnectionSpec } from "./interfaces/connector.js";
|
|
9
9
|
import { LambdaFunction } from "../../resources/aws/compute/lambda.js";
|
|
10
10
|
import { type SecretImport } from "../../resources/aws/secrets/index.js";
|
|
11
|
+
import { type DockerBuild } from "@fjall/util/manifest/schemas";
|
|
11
12
|
export { Architecture, HttpMethod, InvokeMode, type FunctionUrlCorsOptions } from "aws-cdk-lib/aws-lambda";
|
|
12
13
|
/**
|
|
13
14
|
* Lambda function URL configuration.
|
|
@@ -114,17 +115,47 @@ interface BaseLambdaProps {
|
|
|
114
115
|
* automatically set to FROM_IMAGE.
|
|
115
116
|
*
|
|
116
117
|
* @example
|
|
118
|
+
* // Bring your own image (built/pushed out of band)
|
|
117
119
|
* app.addCompute(ComputeFactory.build("ImageLambda", {
|
|
118
120
|
* type: "lambda",
|
|
119
121
|
* deployment: "container",
|
|
120
122
|
* ecrRepository: app.getDefaultContainerRegistry()
|
|
121
123
|
* }));
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* // fjall builds and pushes the image on every `fjall deploy`
|
|
127
|
+
* app.addCompute(ComputeFactory.build("ImageLambda", {
|
|
128
|
+
* type: "lambda",
|
|
129
|
+
* deployment: "container",
|
|
130
|
+
* docker: { path: "lambda.Dockerfile" }
|
|
131
|
+
* }));
|
|
122
132
|
*/
|
|
123
133
|
export interface ContainerLambdaProps extends BaseLambdaProps {
|
|
124
134
|
/** Container-based deployment using ECR image */
|
|
125
135
|
deployment: "container";
|
|
126
|
-
/**
|
|
127
|
-
|
|
136
|
+
/**
|
|
137
|
+
* ECR repository containing the Lambda container image. Optional when
|
|
138
|
+
* `docker` is set — defaults to the app's shared default container
|
|
139
|
+
* registry (the same repo ECS services push into).
|
|
140
|
+
*/
|
|
141
|
+
ecrRepository?: Repository | RepositoryImage;
|
|
142
|
+
/**
|
|
143
|
+
* When set, `fjall deploy` builds and pushes this Dockerfile into the app's
|
|
144
|
+
* shared default container registry, then wires the function to the
|
|
145
|
+
* resulting content-hash-tagged image — the same mechanism ECS services
|
|
146
|
+
* already use. Omit to keep managing the image out of band (the previous
|
|
147
|
+
* behaviour: the function tracks a moving `:latest` tag in `ecrRepository`).
|
|
148
|
+
*/
|
|
149
|
+
docker?: DockerBuild;
|
|
150
|
+
/**
|
|
151
|
+
* Shared build/tag key for Lambda functions that intentionally run the
|
|
152
|
+
* same container image (e.g. several handlers packaged from one
|
|
153
|
+
* Dockerfile). Functions sharing one `image` value build once and share
|
|
154
|
+
* one content-hash tag. Defaults to this Lambda's own construct id, so
|
|
155
|
+
* omitting it is safe when no sharing is intended. Only meaningful when
|
|
156
|
+
* `docker` is set.
|
|
157
|
+
*/
|
|
158
|
+
image?: string;
|
|
128
159
|
}
|
|
129
160
|
/**
|
|
130
161
|
* Code-based Lambda using inline code or S3.
|
|
@@ -177,8 +208,12 @@ export interface ResolvedLambdaDeployment {
|
|
|
177
208
|
/**
|
|
178
209
|
* Resolve Lambda deployment configuration from props.
|
|
179
210
|
* Handles container vs code deployment types.
|
|
211
|
+
*
|
|
212
|
+
* `scope`/`id` are only used on the container-with-`docker` path, to create
|
|
213
|
+
* (or reuse) the per-key `CfnParameter` that `fjall deploy` overrides with
|
|
214
|
+
* the content-hash tag after building and pushing the image.
|
|
180
215
|
*/
|
|
181
|
-
export declare function resolveLambdaDeployment(props: LambdaComputeProps): ResolvedLambdaDeployment;
|
|
216
|
+
export declare function resolveLambdaDeployment(scope: Construct, id: string, props: LambdaComputeProps): ResolvedLambdaDeployment;
|
|
182
217
|
/**
|
|
183
218
|
* Lambda compute wrapper implementing ILambdaCompute.
|
|
184
219
|
* Provides type-safe access to Lambda-specific resources.
|
|
@@ -4,18 +4,45 @@ import { Repository } from "aws-cdk-lib/aws-ecr";
|
|
|
4
4
|
import { Construct } from "constructs";
|
|
5
5
|
import { processConnections } from "../../utils/connections.js";
|
|
6
6
|
import { LambdaFunction } from "../../resources/aws/compute/lambda.js";
|
|
7
|
+
import { getOrCreateImageTagParameter } from "../../resources/aws/compute/imageTagParameter.js";
|
|
7
8
|
import { COMPUTE_DEFAULTS } from "./compute.js";
|
|
9
|
+
import { evaluateBakeGuard } from "@fjall/util/docker";
|
|
10
|
+
import { toKebab } from "@fjall/util";
|
|
8
11
|
// Re-export Lambda types from CDK for user convenience
|
|
9
12
|
export { Architecture, HttpMethod, InvokeMode } from "aws-cdk-lib/aws-lambda";
|
|
10
13
|
/**
|
|
11
14
|
* Resolve Lambda deployment configuration from props.
|
|
12
15
|
* Handles container vs code deployment types.
|
|
16
|
+
*
|
|
17
|
+
* `scope`/`id` are only used on the container-with-`docker` path, to create
|
|
18
|
+
* (or reuse) the per-key `CfnParameter` that `fjall deploy` overrides with
|
|
19
|
+
* the content-hash tag after building and pushing the image.
|
|
13
20
|
*/
|
|
14
|
-
export function resolveLambdaDeployment(props) {
|
|
21
|
+
export function resolveLambdaDeployment(scope, id, props) {
|
|
15
22
|
if (props.deployment === "container") {
|
|
23
|
+
if (!props.ecrRepository) {
|
|
24
|
+
throw new Error(`Lambda '${id}': ecrRepository is required unless \`docker\` is set ` +
|
|
25
|
+
"(ComputeFactory fills it in automatically from the app's default container registry when docker is present).");
|
|
26
|
+
}
|
|
16
27
|
if (!(props.ecrRepository instanceof Repository)) {
|
|
17
28
|
throw new Error("ecrRepository must be a Repository instance for Lambda compute type");
|
|
18
29
|
}
|
|
30
|
+
if (props.docker !== undefined) {
|
|
31
|
+
const appPrefix = props.appName !== undefined ? toKebab(props.appName) : "";
|
|
32
|
+
const findings = evaluateBakeGuard(props.docker.buildArgs, appPrefix).findings;
|
|
33
|
+
if (findings.length > 0) {
|
|
34
|
+
throw new Error(`Lambda '${id}': ${findings.map((f) => f.message).join(" ")}`);
|
|
35
|
+
}
|
|
36
|
+
const tagKey = props.image ?? id;
|
|
37
|
+
const param = getOrCreateImageTagParameter(scope, tagKey);
|
|
38
|
+
return {
|
|
39
|
+
code: Code.fromEcrImage(props.ecrRepository, {
|
|
40
|
+
tagOrDigest: param.valueAsString
|
|
41
|
+
}),
|
|
42
|
+
handler: Handler.FROM_IMAGE,
|
|
43
|
+
runtime: Runtime.FROM_IMAGE
|
|
44
|
+
};
|
|
45
|
+
}
|
|
19
46
|
return {
|
|
20
47
|
code: Code.fromEcrImage(props.ecrRepository, {
|
|
21
48
|
tagOrDigest: COMPUTE_DEFAULTS.ECS.IMAGE_TAG
|
|
@@ -40,7 +67,7 @@ export class LambdaCompute extends Construct {
|
|
|
40
67
|
lambdaFunction;
|
|
41
68
|
constructor(scope, id, props) {
|
|
42
69
|
super(scope, id);
|
|
43
|
-
const { code, handler, runtime } = resolveLambdaDeployment(props);
|
|
70
|
+
const { code, handler, runtime } = resolveLambdaDeployment(scope, id, props);
|
|
44
71
|
// Convert presence-based functionUrl config to legacy boolean format
|
|
45
72
|
const functionUrlConfig = props.functionUrl;
|
|
46
73
|
const enableFunctionUrl = functionUrlConfig !== undefined && functionUrlConfig !== false;
|