Skip to content

Commit 2c56104

Browse files
authored
Add initial OUs and Accounts for shared-services, finance, and scp-tests (#7)
1 parent e371918 commit 2c56104

1 file changed

Lines changed: 228 additions & 18 deletions

File tree

cdk/stacks/cdk_organization.py

Lines changed: 228 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,24 @@
2828

2929
class OrganizationStack(Stack):
3030
"""
31-
Class to create the infrastructure of the AWS Organizations.
31+
Class to create the infrastructure for AWS Organizations.
3232
"""
3333

3434
def __init__(
3535
self, scope: Construct, construct_id: str, deployment_environment: str, **kwargs
3636
) -> None:
37+
"""
38+
:param scope (Construct): Parent of this stack, usually an ``App`` or a ``Stage``, but could be any construct.
39+
:param construct_id (str): The construct ID of this stack.
40+
:param main_resources_name (str): The main solution name being deployed.
41+
:param deployment_environment (str): Value that represents the deployment environment. For example: "dev" or "prod".
42+
"""
3743
super().__init__(scope, construct_id, **kwargs)
3844

3945
self.construct_id = construct_id
4046
self.deployment_environment = deployment_environment
4147

42-
# Organization creation, services configuration and SCPs
48+
# AWS Organization creation, services configuration and SCPs
4349
self.create_root_organization()
4450
self.configure_organization_services()
4551
self.configure_service_control_policies()
@@ -48,6 +54,19 @@ def __init__(
4854
self.create_ou_sandbox()
4955
self.create_accounts_inside_ou_sandbox()
5056

57+
# Create "infrastructure" OU with inner OUs and accounts inside
58+
self.create_ou_infrastructure()
59+
self.create_accounts_inside_ou_infrastructure()
60+
61+
# Create "workloads" OU with inner OUs and accounts inside
62+
self.create_ou_workloads()
63+
self.create_ou_finance()
64+
self.create_accounts_inside_ou_finance()
65+
66+
# Create "policy_staging_tests" OU with inner OUs and accounts inside
67+
self.create_ou_policy_staging_tests()
68+
self.create_accounts_inside_ou_policy_staging_tests()
69+
5170
# !IMPORTANT: this is mandatory for adding CDK dependencies for each account
5271
self.add_cdk_accounts_dependencies() # DO NOT REMOVE!
5372

@@ -60,7 +79,7 @@ def create_root_organization(self):
6079
"""
6180
self.organization = Organization(
6281
self,
63-
id="RootOrganization",
82+
"RootOrganization",
6483
feature_set=FeatureSet.ALL,
6584
)
6685

@@ -107,7 +126,7 @@ def configure_service_control_policies(self):
107126
# SCP for preventing accounts of leaving organization
108127
self.policy_deny_leave_org = Policy(
109128
self,
110-
id="PolicyDenyLeave",
129+
"PolicyDenyLeave",
111130
content=json.dumps(scp_prevent_leaving_org),
112131
policy_name="PreventLeavingOrganization",
113132
policy_type=PolicyType.SERVICE_CONTROL_POLICY,
@@ -118,7 +137,7 @@ def configure_service_control_policies(self):
118137
# SCP for only allow access to specific regions in AWS (deny others)
119138
self.policy_allow_specific_regions = Policy(
120139
self,
121-
id="PolicyAllowSpecificRegions",
140+
"PolicyAllowSpecificRegions",
122141
content=json.dumps(scp_allow_specific_regions),
123142
policy_name="AllowSpecificRegions",
124143
policy_type=PolicyType.SERVICE_CONTROL_POLICY,
@@ -128,47 +147,196 @@ def configure_service_control_policies(self):
128147

129148
def create_ou_sandbox(self):
130149
"""
131-
Method that creates inner Organizational Units (OUs) inside organization.
150+
Method that creates inner Organizational Units (OUs) inside the AWS
151+
Organization for "Sandbox".
132152
"""
133153
self.top_level_ou_sandbox = OrganizationalUnit(
134154
self,
135-
id="SandboxOU",
155+
"SandboxOU",
136156
parent=self.organization.root,
137157
organizational_unit_name="sandbox",
138158
)
139159

140160
def create_accounts_inside_ou_sandbox(self):
141161
"""
142-
Method that creates AWS Accounts inside the required Organizational
143-
Units (OUs).
162+
Method that creates AWS Accounts inside the Organizational Units (OUs)
163+
for "Sandbox".
144164
"""
145165
self.account_sandbox_1 = Account(
146166
self,
147-
id="SandboxAccount1",
167+
"SandboxAccount1",
148168
account_name="san99tiago-sandbox-1",
149169
email="san99tiagodemo+san99tiago-sandbox-1@gmail.com",
150170
parent=self.top_level_ou_sandbox,
151171
role_name="OrganizationAccountAccessRole",
152172
)
153173
self.account_sandbox_2 = Account(
154174
self,
155-
id="SandboxAccount2",
175+
"SandboxAccount2",
156176
account_name="san99tiago-sandbox-2",
157177
email="san99tiagodemo+san99tiago-sandbox-2@gmail.com",
158178
parent=self.top_level_ou_sandbox,
159179
role_name="OrganizationAccountAccessRole",
160180
)
161181

182+
def create_ou_infrastructure(self):
183+
"""
184+
Method that creates inner Organizational Units (OUs) inside the AWS
185+
Organization for "Infrastructure".
186+
"""
187+
self.top_level_ou_infrastructure = OrganizationalUnit(
188+
self,
189+
"OUInfrastructure",
190+
parent=self.organization.root,
191+
organizational_unit_name="infrastructure",
192+
)
193+
self.ou_infrastructure_non_prod = OrganizationalUnit(
194+
self,
195+
"OUInfrastructureNonProd",
196+
parent=self.top_level_ou_infrastructure,
197+
organizational_unit_name="non-prod",
198+
)
199+
self.ou_infrastructure_prod = OrganizationalUnit(
200+
self,
201+
"OUInfrastructureProd",
202+
parent=self.top_level_ou_infrastructure,
203+
organizational_unit_name="prod",
204+
)
205+
206+
def create_accounts_inside_ou_infrastructure(self):
207+
"""
208+
Method that creates AWS Accounts inside the Organizational Units (OUs)
209+
for "Infrastructure".
210+
"""
211+
self.account_shared_services_non_prod = Account(
212+
self,
213+
"AccountSharedServicesNonProd",
214+
account_name="shared-services-non-prod",
215+
email="san99tiagodemo+shared-services-non-prod@gmail.com",
216+
parent=self.ou_infrastructure_non_prod,
217+
role_name="OrganizationAccountAccessRole",
218+
)
219+
self.account_shared_services_prod = Account(
220+
self,
221+
"AccountSharedServicesProd",
222+
account_name="shared-services-prod",
223+
email="san99tiagodemo+shared-services-prod@gmail.com",
224+
parent=self.ou_infrastructure_prod,
225+
role_name="OrganizationAccountAccessRole",
226+
)
227+
228+
def create_ou_workloads(self):
229+
"""
230+
Method that creates inner Organizational Units (OUs) inside the AWS
231+
Organization for "Workloads".
232+
"""
233+
self.top_level_ou_workloads = OrganizationalUnit(
234+
self,
235+
"OUWorkloads",
236+
parent=self.organization.root,
237+
organizational_unit_name="workloads",
238+
)
239+
240+
def create_ou_finance(self):
241+
"""
242+
Method that creates inner Organizational Units (OUs) inside the AWS
243+
Organization for "Finance".
244+
"""
245+
self.ou_finance = OrganizationalUnit(
246+
self,
247+
"OUFinance",
248+
parent=self.top_level_ou_workloads,
249+
organizational_unit_name="finance",
250+
)
251+
self.ou_finance_non_prod = OrganizationalUnit(
252+
self,
253+
"OUFinanceNonProd",
254+
parent=self.ou_finance,
255+
organizational_unit_name="non-prod",
256+
)
257+
self.ou_finance_prod = OrganizationalUnit(
258+
self,
259+
"OUFinanceProd",
260+
parent=self.ou_finance,
261+
organizational_unit_name="prod",
262+
)
263+
264+
def create_accounts_inside_ou_finance(self):
265+
"""
266+
Method that creates AWS Accounts inside the Organizational Units (OUs)
267+
for "Finance".
268+
"""
269+
self.account_finance_dev = Account(
270+
self,
271+
"AccountFinanceDev",
272+
account_name="finance-dev",
273+
email="san99tiagodemo+finance-dev@gmail.com",
274+
parent=self.ou_finance_non_prod,
275+
role_name="OrganizationAccountAccessRole",
276+
)
277+
self.account_finance_qa = Account(
278+
self,
279+
"AccountFinanceQA",
280+
account_name="finance-qa",
281+
email="san99tiagodemo+finance-qa@gmail.com",
282+
parent=self.ou_finance_non_prod,
283+
role_name="OrganizationAccountAccessRole",
284+
)
285+
self.account_finance_prod = Account(
286+
self,
287+
"AccountFinanceProd",
288+
account_name="finance-prod",
289+
email="san99tiagodemo+finance-prod@gmail.com",
290+
parent=self.ou_finance_prod,
291+
role_name="OrganizationAccountAccessRole",
292+
)
293+
294+
def create_ou_policy_staging_tests(self):
295+
"""
296+
Method that creates inner Organizational Units (OUs) inside the AWS
297+
Organization for "PolicyStagingTests".
298+
"""
299+
self.top_level_ou_policy_staging_tests = OrganizationalUnit(
300+
self,
301+
"OUPolicyStagingTests",
302+
parent=self.organization.root,
303+
organizational_unit_name="policy-staging-tests",
304+
)
305+
306+
def create_accounts_inside_ou_policy_staging_tests(self):
307+
"""
308+
Method that creates AWS Accounts inside the Organizational Units (OUs)
309+
for "PolicyStagingTests".
310+
"""
311+
self.account_policy_staging_tests = Account(
312+
self,
313+
"AccountPolicyStagingTests",
314+
account_name="policy-staging-tests",
315+
email="san99tiagodemo+policy-staging-tests@gmail.com",
316+
parent=self.top_level_ou_policy_staging_tests,
317+
role_name="OrganizationAccountAccessRole",
318+
)
319+
162320
def add_cdk_accounts_dependencies(self):
163321
"""
164-
ULTRA IMPORTANT METHOD to add CDK dependencies for the AWS Accounts that
165-
are being created (to avoid 2 accounts creation simultaneously, which is
322+
IMPORTANT METHOD to add CDK dependencies for the AWS Accounts that are
323+
being created (to avoid 2 accounts creation simultaneously, which is
166324
not supported by AWS). This is because of AWS Organizations limitation.
167325
"""
168326
# ! IMPORTANT: We MUST add these dependencies, as AWS Organizations only support
169327
# ... one account creation "IN_PROGRESS". We add CDK dependency to solve issue
170328
# ... and wait for the previous one to finish, to continue with the next...
171329
self.account_sandbox_2.node.add_dependency(self.account_sandbox_1)
330+
self.account_shared_services_non_prod.node.add_dependency(
331+
self.account_sandbox_2
332+
)
333+
self.account_shared_services_prod.node.add_dependency(
334+
self.account_shared_services_non_prod
335+
)
336+
self.account_finance_dev.node.add_dependency(self.account_shared_services_prod)
337+
self.account_finance_qa.node.add_dependency(self.account_finance_dev)
338+
self.account_finance_prod.node.add_dependency(self.account_finance_qa)
339+
self.account_policy_staging_tests.node.add_dependency(self.account_finance_prod)
172340

173341
def generate_cloudformation_outputs(self):
174342
"""
@@ -186,21 +354,21 @@ def generate_cloudformation_outputs(self):
186354
self,
187355
"OrganizationId",
188356
value=self.organization.organization_id,
189-
description="ID of the Organization",
357+
description="ID of AWS Organization",
190358
)
191359

192360
CfnOutput(
193361
self,
194362
"RootId",
195363
value=self.organization.root.identifier(),
196-
description="ID of the Root OU",
364+
description="ID of AWS Organization Root OU",
197365
)
198366

199367
CfnOutput(
200368
self,
201369
"ManagementAccountId",
202370
value=self.organization.management_account_id,
203-
description="ID of the Management Account",
371+
description="ID of Management Account",
204372
)
205373

206374
CfnOutput(
@@ -214,12 +382,54 @@ def generate_cloudformation_outputs(self):
214382
self,
215383
"AccountSandbox1Id",
216384
value=self.account_sandbox_1.account_id,
217-
description="ID of the SandboxAccount1",
385+
description="ID of SandboxAccount1 Account",
218386
)
219387

220388
CfnOutput(
221389
self,
222390
"AccountSandbox2Id",
223391
value=self.account_sandbox_2.account_id,
224-
description="ID of the SandboxAccount2",
392+
description="ID of SandboxAccount2 Account",
393+
)
394+
395+
CfnOutput(
396+
self,
397+
"AccountSharedServicesNonProdId",
398+
value=self.account_shared_services_non_prod.account_id,
399+
description="ID of AccountSharedServicesNonProd Account",
400+
)
401+
402+
CfnOutput(
403+
self,
404+
"AccountSharedServicesProdId",
405+
value=self.account_shared_services_prod.account_id,
406+
description="ID of AccountSharedServicesProd Account",
407+
)
408+
409+
CfnOutput(
410+
self,
411+
"AccountFinanceDevId",
412+
value=self.account_finance_dev.account_id,
413+
description="ID of AccountFinanceDev Account",
414+
)
415+
416+
CfnOutput(
417+
self,
418+
"AccountFinanceQAId",
419+
value=self.account_finance_qa.account_id,
420+
description="ID of AccountFinanceQA Account",
421+
)
422+
423+
CfnOutput(
424+
self,
425+
"AccountFinanceProdId",
426+
value=self.account_finance_prod.account_id,
427+
description="ID of AccountFinanceProd Account",
428+
)
429+
430+
CfnOutput(
431+
self,
432+
"AccountPolicyStagingTestsId",
433+
value=self.account_policy_staging_tests.account_id,
434+
description="ID of AccountPolicyStagingTests Account",
225435
)

0 commit comments

Comments
 (0)