Skip to content

Commit

Permalink
infra_buckets/infra_buckets.py now creates buckets with different par…
Browse files Browse the repository at this point in the history
…ameters depending on region

- see boto/boto3#125
  • Loading branch information
missingcharacter committed Dec 11, 2020
1 parent fa02b7d commit dc6bace
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 25 deletions.
28 changes: 21 additions & 7 deletions infra_buckets/infra_buckets.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 3 additions & 4 deletions setup_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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")
Expand All @@ -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(
Expand All @@ -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)
Expand Down
48 changes: 34 additions & 14 deletions setup_sso/setup_sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import boto3
import logging

from mypy_boto3_iam.client import IAMClient
from pathlib import Path
from typing import Optional

Expand All @@ -15,6 +14,7 @@
'DEBUG': logging.DEBUG
}


class AccountSetup:
log = logging.getLogger(__name__)
alias_name = None
Expand All @@ -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 = '"}}]}'

Expand Down Expand Up @@ -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
)
Expand All @@ -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']
Expand All @@ -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])
Expand All @@ -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"
Expand Down Expand Up @@ -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
)

0 comments on commit dc6bace

Please sign in to comment.