9
9
import os
10
10
from concurrent .futures import ThreadPoolExecutor
11
11
import boto3
12
+ import tenacity
12
13
from organizations import Organizations
13
14
from logger import configure_logger
14
15
from parameter_store import ParameterStore
17
18
18
19
19
20
LOGGER = configure_logger (__name__ )
20
- ACCOUNTS_FOLDER = os .path .abspath (os .path .join (os .path .dirname (__file__ ), '..' , '..' , 'adf-accounts' ))
21
+ ACCOUNTS_FOLDER = os .path .abspath (os .path .join (
22
+ os .path .dirname (__file__ ), '..' , '..' , 'adf-accounts' ))
23
+
21
24
22
25
def main ():
23
26
accounts = read_config_files (ACCOUNTS_FOLDER )
24
27
if not bool (accounts ):
25
- LOGGER .info (f"Found { len (accounts )} account(s) in configuration file(s). Account provisioning will not continue." )
28
+ LOGGER .info (
29
+ f"Found { len (accounts )} account(s) in configuration file(s). Account provisioning will not continue." )
26
30
return
27
31
LOGGER .info (f"Found { len (accounts )} account(s) in configuration file(s)." )
28
32
organizations = Organizations (boto3 )
29
33
support = Support (boto3 )
30
34
all_accounts = organizations .get_accounts ()
31
- parameter_store = ParameterStore (os .environ .get ('AWS_REGION' , 'us-east-1' ), boto3 )
32
- adf_role_name = parameter_store .fetch_parameter ('cross_account_access_role' )
35
+ parameter_store = ParameterStore (
36
+ os .environ .get ('AWS_REGION' , 'us-east-1' ), boto3 )
37
+ adf_role_name = parameter_store .fetch_parameter (
38
+ 'cross_account_access_role' )
33
39
for account in accounts :
34
40
try :
35
- account_id = next (acc ["Id" ] for acc in all_accounts if acc ["Name" ] == account .full_name )
36
- except StopIteration : # If the account does not exist yet..
41
+ account_id = next (
42
+ acc ["Id" ] for acc in all_accounts if acc ["Name" ] == account .full_name )
43
+ except StopIteration : # If the account does not exist yet..
37
44
account_id = None
38
- create_or_update_account (organizations , support , account , adf_role_name , account_id )
45
+ create_or_update_account (
46
+ organizations , support , account , adf_role_name , account_id )
39
47
40
48
41
49
def create_or_update_account (org_session , support_session , account , adf_role_name , account_id = None ):
@@ -57,24 +65,12 @@ def create_or_update_account(org_session, support_session, account, adf_role_nam
57
65
), 'adf_account_provisioning'
58
66
)
59
67
60
- LOGGER .info (f'Ensuring account { account_id } (alias { account .alias } ) is in OU { account .ou_path } ' )
68
+ LOGGER .info (
69
+ f'Ensuring account { account_id } (alias { account .alias } ) is in OU { account .ou_path } ' )
61
70
org_session .move_account (account_id , account .ou_path )
62
71
if account .delete_default_vpc :
63
72
ec2_client = role .client ('ec2' )
64
- all_regions = [
65
- region ['RegionName' ]
66
- for region in ec2_client .describe_regions (
67
- AllRegions = False ,
68
- Filters = [
69
- {
70
- 'Name' : 'opt-in-status' ,
71
- 'Values' : [
72
- 'opt-in-not-required' ,
73
- ]
74
- }
75
- ]
76
- )['Regions' ]
77
- ]
73
+ all_regions = get_all_regions (ec2_client )
78
74
args = (
79
75
(account_id , region , role )
80
76
for region in all_regions
@@ -88,10 +84,38 @@ def create_or_update_account(org_session, support_session, account, adf_role_nam
88
84
org_session .create_account_alias (account .alias , role )
89
85
90
86
if account .tags :
91
- LOGGER .info (f'Ensuring tags exist for account { account_id } : { account .tags } ' )
87
+ LOGGER .info (
88
+ f'Ensuring tags exist for account { account_id } : { account .tags } ' )
92
89
org_session .create_account_tags (account_id , account .tags )
93
90
94
91
92
+ @tenacity .retry (
93
+ stop = tenacity .stop_after_attempt (9 ),
94
+ wait = tenacity .wait_random_exponential (),
95
+ )
96
+ def get_all_regions (ec2_client ):
97
+ try :
98
+ all_regions = [
99
+ region ['RegionName' ]
100
+ for region in ec2_client .describe_regions (
101
+ AllRegions = False ,
102
+ Filters = [
103
+ {
104
+ 'Name' : 'opt-in-status' ,
105
+ 'Values' : [
106
+ 'opt-in-not-required' ,
107
+ ]
108
+ }
109
+ ]
110
+ )['Regions' ]
111
+ ]
112
+ LOGGER .info (f'Regions are: { all_regions } ' )
113
+ return all_regions
114
+ except Exception as ce :
115
+ LOGGER .info ('Failed to describe regions: %s, retrying...' , ce )
116
+ raise
117
+
118
+
95
119
def schedule_delete_default_vpc (account_id , region , role ):
96
120
"""Schedule a delete_default_vpc on a thread
97
121
:param account_id: The account ID to remove the VPC from
@@ -101,5 +125,6 @@ def schedule_delete_default_vpc(account_id, region, role):
101
125
ec2_client = role .client ('ec2' , region_name = region )
102
126
delete_default_vpc (ec2_client , account_id , region , role )
103
127
128
+
104
129
if __name__ == '__main__' :
105
130
main ()
0 commit comments