Skip to content

Commit ac42992

Browse files
fix(core): Fixing policy change event (#720)
* Fixing policy change event * Only accepting ou and account level scp for attaching manually * Adding AttachPolicy event to cwl rule * Handling account scps for DetachPolicy event * adding additional validation * Fixing Detach and Attach Policy Co-authored-by: Brian969 <56414362+Brian969@users.noreply.github.com>
1 parent 4aaca6d commit ac42992

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed

src/deployments/cdk/src/deployments/ou-validation-events/policy-changes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export async function changePolicy(input: PolicyChangeEventProps) {
7070
'detail-type': ['AWS API Call via CloudTrail'],
7171
detail: {
7272
eventSource: ['organizations.amazonaws.com'],
73-
eventName: ['UpdatePolicy', 'DeletePolicy', 'DetachPolicy'],
73+
eventName: ['UpdatePolicy', 'DeletePolicy', 'DetachPolicy', 'AttachPolicy'],
7474
},
7575
};
7676

src/deployments/runtime/src/ou-validation-events/move-account-organization.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,11 @@ async function startStateMachine(stateMachineArn: string): Promise<string> {
419419
if (runningExecutions.length === 0) {
420420
await stepfunctions.startExecution({
421421
stateMachineArn,
422+
input: JSON.stringify({
423+
scope: 'NEW_ACCOUNTS',
424+
mode: 'APPLY',
425+
verbose: '0',
426+
}),
422427
});
423428
} else {
424429
return 'SM_ALREADY_RUNNING';

src/deployments/runtime/src/ou-validation-events/policy-changes.ts

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export const handler = async (input: PolicyChangeEvent) => {
7474
return 'INVALID_REQUEST';
7575
}
7676
const eventName = requestDetail.eventName;
77-
if (eventName !== 'DeletePolicy' && !(await isAcceleratorScp(policyId, scpNames))) {
77+
if (!['DeletePolicy', 'AttachPolicy'].includes(eventName) && !(await isAcceleratorScp(policyId, scpNames))) {
7878
console.log(`SCP ${policyId} is not managed by Accelerator`);
7979
return 'SUCCESS';
8080
}
@@ -87,7 +87,7 @@ export const handler = async (input: PolicyChangeEvent) => {
8787
organizationAdminRole,
8888
});
8989
const { organizationalUnits, accounts } = await loadAccountsAndOrganizationsFromConfig(config);
90-
if (eventName === 'DetachPolicy') {
90+
if (eventName === 'DetachPolicy' || eventName === 'AttachPolicy') {
9191
const { targetId } = requestDetail.requestParameters;
9292
if (!targetId) {
9393
console.warn(`Missing required parameters, Ignoring`);
@@ -98,20 +98,60 @@ export const handler = async (input: PolicyChangeEvent) => {
9898
const destinationOrg = await organizations.getOrganizationalUnitWithPath(targetId);
9999
const destinationRootOrg = destinationOrg.Name!;
100100
if (ignoredOus.includes(destinationRootOrg)) {
101-
console.log(`DetachPolicy is on ignored-ou from ROOT, no need to reattach`);
101+
console.log(`${eventName} is on ignored-ou from ROOT, no need to reattach`);
102102
return 'IGNORE';
103103
}
104104
} else {
105105
const accountObject = accounts.find(acc => acc.accountId === targetId);
106106
if (ignoredOus.includes(accountObject?.organizationalUnit!)) {
107-
console.log(`DetachPolicy is on account in ignored-ous from ROOT, no need to reattach`);
107+
console.log(`${eventName} is on account in ignored-ous from ROOT, no need to reattach`);
108108
return 'IGNORE';
109109
}
110110
}
111111
}
112-
// ReAttach target to policy
113-
console.log(`Reattaching target "${targetId}" to policy "${policyId}"`);
114-
await organizations.attachPolicy(policyId, targetId);
112+
const targetScpNames: string[] = [];
113+
if (targetId.startsWith('ou-')) {
114+
const destinationOrg = await organizations.getOrganizationalUnitWithPath(targetId);
115+
const destinationRootOrg = destinationOrg.Name!;
116+
const targetOuConfig = config.getOrganizationalUnits().find(([ouKey, _]) => ouKey === destinationRootOrg)?.[1];
117+
targetScpNames.push(...(targetOuConfig?.scps || []));
118+
} else {
119+
const accountObject = accounts.find(acc => acc.accountId === targetId);
120+
if (!accountObject) {
121+
console.log('Account is not in Configuration');
122+
return 'IGNORE';
123+
}
124+
const accountConfig = config.getAccountByKey(accountObject.accountKey);
125+
const targetOuConfig = config.getOrganizationalUnits().find(([ouKey, _]) => ouKey === accountConfig.ou)?.[1];
126+
targetScpNames.push(...(targetOuConfig?.scps || []));
127+
if (accountConfig.scps) {
128+
targetScpNames.push(...accountConfig.scps);
129+
}
130+
}
131+
const acclScpNames = targetScpNames.map(scp =>
132+
ServiceControlPolicy.policyNameToAcceleratorPolicyName({
133+
acceleratorPrefix,
134+
policyName: scp,
135+
}),
136+
);
137+
console.log(`SCP Names for Target are :: ${acclScpNames}`);
138+
if (eventName === 'AttachPolicy') {
139+
if (await isAcceleratorScp(policyId, acclScpNames)) {
140+
console.log('Accelerator Managed policy is attached');
141+
return 'IGNORE';
142+
}
143+
// Detach target from policy
144+
console.log(`Detaching target "${targetId}" from policy "${policyId}"`);
145+
await organizations.detachPolicy(policyId, targetId);
146+
} else {
147+
if (!(await isAcceleratorScp(policyId, acclScpNames))) {
148+
console.log('Non Accelerator Managed policy is detached');
149+
return 'IGNORE';
150+
}
151+
// ReAttach target to policy
152+
console.log(`Reattaching target "${targetId}" to policy "${policyId}"`);
153+
await organizations.attachPolicy(policyId, targetId);
154+
}
115155
} else if (eventName === 'UpdatePolicy' || eventName === 'DeletePolicy') {
116156
console.log(`${eventName}, changing back to original config from config`);
117157

@@ -137,11 +177,12 @@ export const handler = async (input: PolicyChangeEvent) => {
137177
const acceleratorOuIds = organizationalUnits.map(ou => ou.ouId);
138178
const acceleratorAccountIds = accounts.map(a => a.accountId!);
139179
const acceleratorTargetIds = [...rootIds, ...acceleratorOuIds, ...acceleratorAccountIds];
180+
const acceleratorTargetOuIds = [...rootIds, ...acceleratorOuIds];
140181

141182
// Detach non-Accelerator policies from Accelerator accounts
142183
await scps.detachPoliciesFromTargets({
143184
policyNamesToKeep: acceleratorPolicyNames,
144-
policyTargetIdsToInclude: acceleratorTargetIds,
185+
policyTargetIdsToInclude: acceleratorTargetOuIds,
145186
});
146187

147188
await scps.attachFullAwsAccessPolicyToTargets({
@@ -155,6 +196,20 @@ export const handler = async (input: PolicyChangeEvent) => {
155196
acceleratorOus: config.getOrganizationalUnits(),
156197
acceleratorPrefix,
157198
});
199+
200+
await scps.attachOrDetachPoliciesToAccounts({
201+
existingPolicies,
202+
configurationAccounts: accounts.map(acc => ({
203+
key: acc.accountKey,
204+
id: acc.accountId!,
205+
arn: '',
206+
name: acc.accountName,
207+
ou: acc.organizationalUnit,
208+
email: acc.emailAddress,
209+
})),
210+
accountConfigs: config.getAccountConfigs(),
211+
acceleratorPrefix,
212+
});
158213
}
159214
return 'SUCCESS';
160215
};

0 commit comments

Comments
 (0)