diff --git a/infra_buckets/infra_buckets.py b/infra_buckets/infra_buckets.py index 94c20ed..4d96a5b 100644 --- a/infra_buckets/infra_buckets.py +++ b/infra_buckets/infra_buckets.py @@ -95,13 +95,27 @@ def _create_bucket( region: str ) -> None: try: - self.client.create_bucket( - ACL='private', - Bucket=bucket_name, - CreateBucketConfiguration={ - 'LocationConstraint': region - } - ) + if region == 'us-east-1': + self.session.client( + "s3", + region_name=region, + endpoint_url=self.endpoint_url + ).create_bucket( + ACL='private', + Bucket=bucket_name + ) + else: + self.session.client( + "s3", + region_name=region, + endpoint_url=self.endpoint_url + ).create_bucket( + ACL='private', + Bucket=bucket_name, + CreateBucketConfiguration={ + 'LocationConstraint': region + } + ) self.log.info("Bucket %s creation succeeded", bucket_name) except Exception as e: self.log.error("Bucket %s creation failed with error: %s", bucket_name, e) diff --git a/setup_account.py b/setup_account.py index 3afc5dd..2e451c6 100644 --- a/setup_account.py +++ b/setup_account.py @@ -10,7 +10,7 @@ from setup_sso.setup_sso import AccountSetup from time import sleep from typing import Optional, List -from vpc_cleaner.vpc_cleaner import VPCCleaner, AccountCleaner +from vpc_cleaner.vpc_cleaner import AccountCleaner _LOG_LEVEL_STRINGS = { 'CRITICAL': logging.CRITICAL, @@ -30,7 +30,7 @@ def main( purpose: str, log_level: str = "INFO", email: Optional[str] = None, - regions: Optional[List[str]] = None, + regions: Optional[List[str]] = None ) -> None: # Setup logging facility logging.basicConfig(format="%(asctime)s %(levelname)s (%(threadName)s) [%(name)s] %(message)s") @@ -43,7 +43,7 @@ def main( account = AccountCreator() account.create(email, account_name) sub_account_role_arn = f"arn:aws:iam::{account.account_id}:role/OrganizationAccountAccessRole" - sleep_time: int = 10 + sleep_time: int = 20 log.info(f"Waiting {sleep_time} seconds after account was created before assuming sub account role") sleep(sleep_time) assume_role = boto3.client('sts').assume_role( @@ -58,7 +58,6 @@ def main( else: log.info("No E-Mail was provided so I will not create a sub-account") sub_account_session = None - sub_account_iam = None # Setup AWS alias and roles setup_sso = AccountSetup(session=sub_account_session) diff --git a/setup_sso/setup_sso.py b/setup_sso/setup_sso.py index b5a795e..3b428e0 100644 --- a/setup_sso/setup_sso.py +++ b/setup_sso/setup_sso.py @@ -3,7 +3,6 @@ import boto3 import logging -from mypy_boto3_iam.client import IAMClient from pathlib import Path from typing import Optional @@ -15,6 +14,7 @@ 'DEBUG': logging.DEBUG } + class AccountSetup: log = logging.getLogger(__name__) alias_name = None @@ -25,7 +25,8 @@ class AccountSetup: 'aws-cn': 'https://signin.amazonaws.cn/saml', 'aws-us-gov': 'https://signin.amazonaws-us-gov.com/saml' } - start_of_policy = '{"Version":"2012-10-17","Statement":[{"Action":"sts:AssumeRoleWithSAML","Effect":"Allow","Condition":{"StringEquals":{"SAML:aud":"' + start_of_policy = '{"Version":"2012-10-17","Statement":[{"Action":"sts:AssumeRoleWithSAML","Effect":"Allow",' \ + '"Condition":{"StringEquals":{"SAML:aud":" ' middle_of_policy = '"}},"Principal":{"Federated":"' end_of_policy = '"}}]}' @@ -102,7 +103,7 @@ def _create_role(self, role_name: str, policy_document: str) -> dict: def _attach_role_policy(self, role_name: str, policy_arn: str) -> None: """ Attach a policy to am IAM Role """ try: - attach_response = self.client.attach_role_policy( + self.client.attach_role_policy( RoleName=role_name, PolicyArn=policy_arn ) @@ -113,7 +114,11 @@ def create_role(self, role_name: str, policy_arn: str, policy_document: str) -> """ Create Role and attach a Policy to it """ if self.roles_arn.get(role_name) is None: try: - self.log.info("I will try to create role with name %s for account ID %s", role_name, self.saml_provider.split(':')[4]) + self.log.info( + "I will try to create role with name %s for account ID %s", + role_name, + self.saml_provider.split(':')[4] + ) role = self._create_role(role_name, policy_document) self._attach_role_policy(role_name, policy_arn) self.roles_arn[role_name] = role['Arn'] @@ -126,23 +131,38 @@ def create_default_roles(self) -> None: """ Create Default Roles """ try: aws_partition = self.saml_provider.split(':')[1] - policy_document = self.start_of_policy + self.saml_audiences[aws_partition] + self.middle_of_policy + self.saml_provider + self.end_of_policy + policy_document = ''.join([ + self.start_of_policy, + self.saml_audiences[aws_partition], + self.middle_of_policy, + self.saml_provider, + self.end_of_policy + ]) admin_role_name = 'SSOAdministratorAccess' admin_policy_arn = f"arn:{aws_partition}:iam::aws:policy/AdministratorAccess" - self.create_role(role_name=admin_role_name, policy_arn=admin_policy_arn, policy_document=policy_document) + self.create_role( + role_name=admin_role_name, + policy_arn=admin_policy_arn, + policy_document=policy_document + ) read_role_name = 'SSOViewOnlyAccess' read_policy_arn = f"arn:{aws_partition}:iam::aws:policy/job-function/ViewOnlyAccess" - self.create_role(role_name=read_role_name, policy_arn=read_policy_arn, policy_document=policy_document) + self.create_role( + role_name=read_role_name, + policy_arn=read_policy_arn, + policy_document=policy_document + ) except Exception as e: self.log.exception("Creation of default roles failed with error %s", e) + def main( sub_account_name: str, ivy_tag: str, saml_provider: str, saml_file: str, log_level: str = 'INFO' - ) -> None: +) -> None: logging.basicConfig(format="%(asctime)s %(levelname)s (%(threadName)s) [%(name)s] %(message)s") log = logging.getLogger() # Gets the root logger log.setLevel(_LOG_LEVEL_STRINGS[log_level]) @@ -153,6 +173,7 @@ def main( setup_sso.saml(saml_name, saml_path) setup_sso.create_default_roles() + if __name__ == "__main__": parser = argparse.ArgumentParser( description="Sets up an AWS account's alias, SAML provider, Admin role and Read-Only role" @@ -192,10 +213,9 @@ def main( ) args = parser.parse_args() main( - args.sub_account_name, - args.ivy_tag, - args.saml_provider, - args.saml_file, - args.gov_account_name, - args.log_level + sub_account_name=args.sub_account_name, + ivy_tag=args.ivy_tag, + saml_provider=args.saml_provider, + saml_file=args.saml_file, + log_level=args.log_level )