Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ init:

test:
# Run unit tests
pytest src/lambda_codebase/account -vvv -s -c src/lambda_codebase/account/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-bootstrap/deployment/lambda_codebase/pytest.ini
pytest src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python -vvv -s -c src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/python/pytest.ini
Expand Down
46 changes: 39 additions & 7 deletions src/lambda_codebase/account/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
SSM_CLIENT = boto3.client("ssm")
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.INFO)
MAX_RETRIES = 120 # => 120 retries * 5 seconds = 10 minutes


class InvalidPhysicalResourceId(Exception):
Expand Down Expand Up @@ -113,8 +114,8 @@ def delete_(event, _context):
def ensure_account(existing_account_id: str,
account_name: str,
account_email: str,
cross_account_access_role_name: str) -> Tuple[AccountId,
bool]:
cross_account_access_role_name: str,
no_retries: int = 0) -> Tuple[AccountId, bool]:
# If an existing account ID was provided, use that:
if existing_account_id:
return existing_account_id, False
Expand All @@ -137,17 +138,22 @@ def ensure_account(existing_account_id: str,
IamUserAccessToBilling="ALLOW",
)
except ORGANIZATION_CLIENT.exceptions.ConcurrentModificationException as err:
LOGGER.info(err)
time.sleep(5)
ensure_account(
return handle_concurrent_modification(
err,
existing_account_id,
account_name,
account_email,
cross_account_access_role_name)
cross_account_access_role_name,
no_retries + 1,
)

request_id = create_account["CreateAccountStatus"]["Id"]
LOGGER.info("Account creation requested, request ID: %s", request_id)

return wait_on_account_creation(request_id)


def wait_on_account_creation(request_id: str) -> Tuple[AccountId, bool]:
while True:
account_status = ORGANIZATION_CLIENT.describe_create_account_status(
CreateAccountRequestId=request_id
Expand All @@ -157,10 +163,36 @@ def ensure_account(existing_account_id: str,
raise Exception("Failed to create account because %s" % reason)
if account_status["CreateAccountStatus"]["State"] == "IN_PROGRESS":
LOGGER.info(
"Account creation still in progress, waiting.. then calling again with %s",
"Account creation still in progress, waiting.. "
"then calling again with %s",
request_id)
time.sleep(10)
else:
account_id = account_status["CreateAccountStatus"]["AccountId"]
LOGGER.info("Account created: %s", account_id)
return account_id, True


def handle_concurrent_modification(
error: Exception,
existing_account_id: str,
account_name: str,
account_email: str,
cross_account_access_role_name: str,
no_retries: int = 0,
) -> Tuple[AccountId, bool]:
LOGGER.info("Attempt %d - hit %s", no_retries + 1, error)
if no_retries > MAX_RETRIES:
LOGGER.error(
"Reached maximum number of retries to create the account. "
"Raising error to abort the execution."
)
raise error
time.sleep(5)
return ensure_account(
existing_account_id,
account_name,
account_email,
cross_account_access_role_name,
no_retries + 1,
)
2 changes: 2 additions & 0 deletions src/lambda_codebase/account/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
testpaths = tests
4 changes: 4 additions & 0 deletions src/lambda_codebase/account/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

# pylint: skip-file
Loading