def lambda_handler(event, context): repo_name = None account_Id = event["AccountId"] account_info = avm_common.get_account_details(account_Id) account_details = account_info["org_details"] #pp.pprint(account_details) baseline_details = json.loads(account_details["baseline_details"]) account_type = account_details["accountType"] baseline_repo = baseline_details["git"] repo_name = baseline_repo.split("/")[-1].replace(".git","") print(repo_name) ## Might want to make this a global variable vended_baselines_project = avm_common.get_param("vended_baselines_project") #project = "tlz-vb" #pp.pprint(project.upper()) git = gitMgr() template = git.get_baseline_template_repo(repo_name) print(template) # Create baseline repo git.fork_repo(template,vended_baselines_project.upper(),repo_name) #print(account_details) try: account_request = json.loads(account_details["account_request"]) environment_type = account_request["intEnvironment"].lower() except Exception: environment_type = "null" user_managed_roles = avm_common.get_delegated_user_managed_roles() group_list = avm_common.generate_okta_group_names(account_Id, account_type, environment_type, account_details["alias"].lower()) for group in group_list: for role in user_managed_roles: if group.endswith(role): print(f"Group to be granted permissions to Bitbucket baseline repo: {group}") git.create_group(group) git.grant_repository_access(vended_baselines_project.upper(), repo_name, group, get_repository_access_for_role(role, "baseline")) # TODO: Add merge check restriction if avm_common.resource_workspace_required(account_type): # Create an additional repo for the application and sandbox # app-repo template app_details = json.loads(account_details["app_details"]) print("App details") print(app_details) app_repo = app_details["git"] repo_name = app_repo.split("/")[-1].replace(".git","") print(repo_name) vended_applications_project = avm_common.get_param("vended_applications_project") template = f"{account_type.lower()}-resources" git.fork_repo(template,vended_applications_project.upper(),repo_name) for group in group_list: for role in user_managed_roles: if group.endswith(role): print(f"Group to be granted permissions to Bitbucket resource repo: {group}") git.grant_repository_access(vended_applications_project.upper(), repo_name, group, get_repository_access_for_role(role, "resource"))
def lambda_handler_inner(event, context): account_id = event["AccountId"] account_info = avm_common.get_account_details(account_id) account_details = account_info["org_details"] account_contact_email = account_info["request_details"][ "accountEmail"].lower() #print(account_details) account_type = account_details["accountType"].lower() try: environment_type = json.loads(account_details["account_request"]) environment_type = environment_type["intEnvironment"].lower() except Exception: environment_type = "null" # Assuming a group was created, attach the contact email address to the admin group. This involves: # - Determining the principal ID for the corresponding email address # - Adding that principal to each group that makes sense secret = okta_config["token"] account_contact_userid = get_user_id(account_contact_email, secret) group_names = avm_common.generate_okta_group_names( event["AccountId"], account_type, environment_type, account_details["alias"].lower()) for group_name in group_names: print(group_name) group_id = get_group_id(group_name, secret) print(f"GroupId : {group_id}") if not group_id: group_id = create_group(group_name, secret) print("Group ID is " + group_id + "\nAttaching Apps " + account_type + " to new Group ID.") else: print("Group ID is " + group_id + "\nAttaching Apps " + account_type + " to new Group ID" + "env_type:" + environment_type) # If the group name happens to be the 'admin' role name, and there is a user_id to attach, do so: # (NOTE: This 'in' test is a little loose for e.g. 'tlz_developer' vs. 'tlz_developer_ro', but for 'tlz_admin' it is fine. ) if ((group_name.endswith(avm_common.get_delegated_admin_role())) and account_contact_userid): if (assign_user_group(account_contact_userid, group_id, secret) == HTTPStatus.OK): print("Successfully attached contact email to group...") else: print( "Unable to attach contact email to group (invalid, non-matching, or a DL?)..." ) # Assign the group to app app_resp = None account_code = avm_common.get_short_account_code( account_type, environment_type) app_resp = assign_group_app(group_id, okta_config[account_code + "_APP_ID"], secret) if (app_resp == HTTPStatus.OK): print("Successfully attached App to Group ID") else: print("Failed to attach App to Group ID.")
def get_workspace_name(account_id): account_info = avm_common.get_account_details(account_id) details = account_info["org_details"] #print(details) baseline_details = json.loads(details["baseline_details"]) ws_name = baseline_details["tfe_workspace"] return ws_name
def lambda_handler_inner(event, context): account_id = event["AccountId"] account_type = "sandbox" account_info = avm_common.get_account_details(account_id) account_details = account_info["org_details"] if not account_details: raise Exception( f"Account with id [{account_id}] not found in DynamoDB") account_type = account_details["accountType"].lower() print(f"account_type is {account_type}") print("starting process to delete default vpcs in all regions...") process(event, context)
def lambda_handler_inner(event, context): account_id = event["AccountId"] account_details = avm_common.get_account_details(account_id) account_type = account_details["org_details"]["accountType"] print(f"account_type is {account_type}") skip_process = True if account_type.lower() in ["application"]: skip_process = False if not skip_process: print(f"Invite dns invites for account: {account_id}" ) process(event,context) else: print(f"skip dns invite for the account {account_id}" )
def lambda_handler(event, context): repo_name = None account_id = event["AccountId"] account_info = avm_common.get_account_details(account_id) account_details = account_info["org_details"] #pprint.pprint(account_details) #pprint.pprint(account_info) baseline_details = json.loads(account_details["baseline_details"]) account_type = account_details["accountType"] baseline_repo = baseline_details["git"] repo_name = baseline_repo.split("/")[-1].replace(".git", "") ## Might want to make this a global variable vended_baselines_project = avm_common.get_param("vended_baselines_project") #print(f"vended_baselines_project: {vended_baselines_project}") #print(f"baseline_repo: {baseline_repo}") git = gitMgr() # template = git.get_baseline_template_repo(account_type) template = git.get_baseline_template_repo(repo_name) print(f"Template: {template}") print(f"Repo to create : {repo_name}") #git.list_all_repos() # Create baseline repo git.clone_repo(vended_baselines_project, repo_name, template, account_id, account_info) if avm_common.resource_workspace_required(account_type): # Create an additional repo for the application and sandbox # app-repo template app_details = json.loads(account_details["app_details"]) print("App details") print(app_details) app_repo = app_details["git"] repo_name = app_repo.split("/")[-1].replace(".git", "") vended_applications_project = avm_common.get_param( "vended_applications_project") apptemplate = f"{account_type.lower()}-resources" #print(f"vended_applications_project: {vended_applications_project}") #print(f"template: {apptemplate}") #print(f"app_repo: {app_repo}") #print(f"repo_name: {repo_name}") git.clone_repo(vended_applications_project, repo_name, apptemplate, account_id, account_info)
def lambda_handler_inner(event, context): account_id = event["AccountId"] account_details = avm_common.get_account_details(account_id) core_logging = avm_common.get_param("core_logging_account") master_role = avm_common.get_param("tlz_admin_role") primary_region, secondary_region = avm_common.get_regions(account_id) ROLE_ARN_LOGGING = f"arn:aws:iam::{core_logging}:role/{master_role}" session_assumed = avm_common.aws_session(role=ROLE_ARN_LOGGING, session_name='logging-services') s3 = session_assumed.resource('s3') #s3 = session_assumed.client('s3') update_alb_bucket_policy_primary( s3, account_id, f"tlz-alb-access-central-primary-{core_logging}", core_logging, primary_region) update_alb_bucket_policy_secondary( s3, account_id, f"tlz-alb-access-central-secondary-{core_logging}", core_logging, secondary_region)
def add_account_to_redlock(account_id): redlock = avm_common.get_secret("redlock") result = avm_common.get_account_details(account_id) account_alias = f"{result['org_details']['name']}" if result['request_details']: if "subAccountType" in result['request_details'].keys(): account_alias += f"-{result['request_details']['subAccountType']}" body = {"username": redlock["user"], "password": redlock["password"]} header = {'Content-Type': 'application/json'} r = requests.post(f'{redlock["rest_api_url"]}/login', headers=header, data=json.dumps(body)) if r.status_code == requests.codes.ok: resp = json.loads(r.text) token = resp["token"] account_payload = { "accountId": account_id, "enabled": True, "externalId": extract_externalid(account_id), "groupIds": [redlock["group_id"]], "name": f"{account_alias}-{account_id}", "roleArn": f"arn:aws:iam::{account_id}:role/tlz_redlock_read_only" } headers = {"x-redlock-auth": token, "Content-Type": "application/json"} addaccount_r = requests.post(f'{redlock["rest_api_url"]}/cloud/aws', headers=headers, data=json.dumps(account_payload)) else: body = f"{r.json()}" sub = "ERROR: Unable to add account {account_id} to redlock" func = "redlock-addaccount" sns_topic = avm_common.get_param("sns_topic_arn") avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body)
def lambda_handler_inner(event, context): response = None newAccountID = event["AccountId"] client = boto3.client('ses', region_name="us-west-2") message = MIMEMultipart() message['Subject'] = f"AWS account {newAccountID} created successfully" message['From'] = avm_common.get_param('post_account_sender_email') print(avm_common.get_param('post_account_sender_email')) result = avm_common.get_account_details(newAccountID) subscribers = avm_common.get_param('post_account_subscriber_emails') print(f"subscribers : {subscribers}") target = subscribers.split(",") body = f"""<h1>AWS Account creation details</h1> <h4>Account {newAccountID} created successfully!!</h4> """ output = io.StringIO() writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC) if result["request_details"]: body += f""" <h2>Request details from webform</h2> <table border="1"> <tr><th>Parameter</th><th>Value</th></tr> """ writer.writerow(["Account Request Details"]) writer.writerow([",", "Parameter", "Value"]) for k in result["request_details"].keys(): writer.writerow(["", k, result["request_details"][k]]) body += f'<tr><td>{k}</td><td>{result["request_details"][k]}</td></tr>' body += f"""</table><p/>""" body += f""" <h2>Response from AccountVendingMachine</h2> <table border="1"> <tr><th>Parameter</th><th>Value</th></tr> """ writer.writerow(["Response from AccountVendingMachine"]) writer.writerow(["", "Parameter", "Value"]) for k in result["org_details"].keys(): writer.writerow([",", k, result["org_details"][k]]) body += f'<tr><td>{k}</td><td>{result["org_details"][k]}</td></tr>' body += f"""</table> <p/> """ attached_file_name = f"aws_account_{newAccountID}.csv" # message body part = MIMEText(body, 'html') message.attach(part) attachment_string = None #print(output.getvalue()) #print(body) # attachment if attachment_string: # if bytestring available part = MIMEApplication(str.encode('attachment_string')) else: # if file provided part = MIMEApplication(output.getvalue()) part.add_header('Content-Disposition', 'attachment', filename=attached_file_name) message.attach(part) response = client.send_raw_email( Source=message['From'], Destinations=target, RawMessage={'Data': message.as_string()}) print("Sent an email to subscribers") # Send the SNS notification # Create an SNS client sns = boto3.client('sns') # Publish a simple message to the specified SNS topic response = sns.publish( TopicArn=avm_common.get_param('sns_topic_arn'), Message=f'account : {newAccountID} created successfully', ) # Print out the response print(response)
def handler_inner(event, context): account_id = event["AccountId"] # Retrieve secrets from AWS Secrets Manager aws_secrets = avm_common.get_secret("tfe_aws_keys") # Look these single values up directly: tfe_key = avm_common.get_secret("terraform")["terraform"] vcs_oauth_token = avm_common.get_secret("vcs_oauth_token")["oauth_token"] # Get workspace name from dynamodb from event.accountId # Grab account details account_info = avm_common.get_account_details(account_id) #pp.pprint(account_info) account_details = account_info["org_details"] request_details = account_info["request_details"] #print(account_details) # Defines both repository names from account_details data baseline_details = json.loads(account_details["baseline_details"]) account_request = json.loads(account_details["account_request"]) print(baseline_details) baseline_repo_concat = "/".join( baseline_details["git"].split('/')[3:]).replace('.git', '') ws_name = baseline_details["tfe_workspace"] # instantiates workspace creation for baseline & application workspaces workspace_id = create_workspace(ws_name, tfe_key, vcs_oauth_token, baseline_repo_concat) if not workspace_id: return None #workspace_id = get_workspace(ws_name, tfe_key) # okta variables okta_account_type = account_details["accountType"].lower() try: account_request = json.loads(account_details["account_request"]) environment_type = account_request["intEnvironment"].lower() okta_account_type = f"{okta_account_type}_{environment_type}" except Exception: environment_type = "NA" primary_region, secondary_region = avm_common.get_regions(account_id) azs_primary, azs_secondary = avm_common.az_map_by_region(primary_region) okta_config = avm_common.get_secret("okta") okta_app_id_index = { "core": okta_config["COR_LINK_ID"], "sandbox": okta_config["SBX_LINK_ID"], "application_npd": okta_config["NPD_LINK_ID"], "application_prd": okta_config["PRD_LINK_ID"] } okta_url = okta_config["url"].replace("https://", "") okta_prefix = "aws" + avm_common.get_short_account_code( okta_account_type, environment_type) tfe_host_name = avm_common.get_param("tfe_api_url").replace( "https://", "").replace("/api/v2", "") workspace_vars = [{ "key": "AWS_ACCESS_KEY_ID", "value": aws_secrets["AWS_ACCESS_KEY_ID"], "category": "env", "sensitive": False, "hcl": False }, { "key": "AWS_SECRET_ACCESS_KEY", "value": aws_secrets["AWS_SECRET_ACCESS_KEY"], "category": "env", "sensitive": True, "hcl": False }, { "key": "account_id", "value": account_id, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "repo_name", "value": baseline_repo_concat, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "name", "value": account_details["name"].lower(), "category": "terraform", "sensitive": False, "hcl": False }, { "key": "account_type", "value": account_details["accountType"].lower(), "category": "terraform", "sensitive": False, "hcl": False }, { "key": "account_org", "value": account_details["org_name"].lower(), "category": "terraform", "sensitive": False, "hcl": False }, { "key": "owner", "value": account_details["email"], "category": "terraform", "sensitive": False, "hcl": False }, { "key": "environment", "value": account_request["env"].lower(), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "int_environment", "value": environment_type, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "cidr_primary", "value": request_details["primaryVpcCidr"], "category": "terraform", "sensitive": False, "hcl": False }, { "key": "cidr_secondary", "value": request_details["secondaryVpcCidr"], "category": "terraform", "sensitive": False, "hcl": False }, { "key": "region_primary", "value": primary_region, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "region_secondary", "value": secondary_region, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "azs_primary", "value": azs_primary, "category": "terraform", "sensitive": False, "hcl": True }, { "key": "azs_secondary", "value": azs_secondary, "category": "terraform", "sensitive": False, "hcl": True }, { "key": "okta_provider_domain", "value": okta_url, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "okta_app_id", "value": okta_app_id_index[okta_account_type], "category": "terraform", "sensitive": False, "hcl": False }, { "key": "tfe_org_name", "value": avm_common.get_param("tfe_org_name"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tfe_avm_workspace_name", "value": avm_common.get_param("avm_workspace_name"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tfe_host_name", "value": tfe_host_name, "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tfe_core_logging_workspace_name", "value": avm_common.get_param("logging_workspace_name"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "master_payer_org_id", "value": avm_common.get_param("master_payer_org_id"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "master_payer_account", "value": avm_common.get_param("master_payer_account"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "core_security_account", "value": avm_common.get_param("core_security_account"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tlz_org_account_access_role", "value": avm_common.get_param("tlz_org_account_access_role"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "role_name", "value": avm_common.get_param("tlz_admin_role"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "okta_token", "value": okta_config["token"], "category": "terraform", "sensitive": True, "hcl": False }] for var in workspace_vars: print(f"Attaching the var {var['key']}") response = attach_vars_to_workspace(ws_name, tfe_key, var["key"], var["value"], var["category"], var["sensitive"], var["hcl"]) # Make teams with the same name as the Okta role names and assign them privileges to the baseline and resources workspaces. # This will be reused in the resources workspace block later. user_teams_to_assign = avm_common.get_delegated_user_managed_roles() group_list = avm_common.generate_okta_group_names( account_id, okta_account_type, environment_type, account_details["alias"].lower()) for team in group_list: for role in user_teams_to_assign: if team.endswith(role): # Try to find it first: team_id = get_team(tfe_key, team) # Otherwise, create it: if not team_id: team_id = create_team_for_org(tfe_key, team) assign_team_to_workspace( tfe_key, team_id, workspace_id, get_workspace_access_for_role(role, "baseline")) print(baseline_repo_concat) # Add network_account core_network_account = avm_common.get_param("core_network_account") if core_network_account != None: if account_details["accountType"].lower() in [ "application" ] or (account_details["accountType"].lower() == "core" and account_request["account_name"].lower() == "shared_services"): attach_vars_to_workspace(ws_name, tfe_key, "core_network_account", core_network_account, "terraform", False, False) if avm_common.resource_workspace_required(account_details["accountType"]): app_details = json.loads(account_details["app_details"]) app_repo_concat = "/".join(app_details["git"].split('/')[4:]).replace( '.git', '') baseline_workspace_name = ws_name ws_name = app_details["tfe_workspace"] create_workspace(ws_name, tfe_key, vcs_oauth_token, app_repo_concat) workspace_id = get_workspace(ws_name, tfe_key) print(app_repo_concat) workspace_vars = [{ "key": "tfe_host_name", "value": tfe_host_name, "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tfe_org_name", "value": avm_common.get_param("tfe_org_name"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "name", "value": account_details["name"].lower(), "category": "terraform", "sensitive": False, "hcl": False }, { "key": "owner", "value": account_details["email"], "category": "terraform", "sensitive": False, "hcl": False }, { "key": "environment", "value": account_request["env"].lower(), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "baseline_workspace_name", "value": baseline_workspace_name, "category": "terraform", "sensitive": True, "hcl": False }, { "key": "region_primary", "value": primary_region, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "region_secondary", "value": secondary_region, "category": "terraform", "sensitive": False, "hcl": False }, { "key": "baseline_workspace_name", "value": baseline_workspace_name, "category": "terraform", "sensitive": True, "hcl": False }, { "key": "tlz_org_account_access_role", "value": avm_common.get_param("tlz_org_account_access_role"), "category": "terraform", "sensitive": True, "hcl": False }, { "key": "role_name", "value": avm_common.get_param("tlz_admin_role"), "category": "terraform", "sensitive": True, "hcl": False }] for var in workspace_vars: print(f"Attaching the var {var['key']}") response = attach_vars_to_workspace(ws_name, tfe_key, var["key"], var["value"], var["category"], var["sensitive"], var["hcl"]) # Assign the teams (already created in the baseline block) to this workspace as well. for team in group_list: for role in user_teams_to_assign: if team.endswith(role): # Get the team ID--it was made in the baseline already. team_id = get_team(tfe_key, team) assign_team_to_workspace( tfe_key, team_id, workspace_id, get_workspace_access_for_role(role, "resource")) elif account_details["accountType"].lower() == "core" and account_request[ "account_name"].lower() == "shared_services": workspace_vars = [{ "key": "primary_zone_name", "value": avm_common.get_param("primary_zone_name"), "category": "terraform", "sensitive": False, "hcl": False }] for var in workspace_vars: print(f"Attaching the var {var['key']}") response = attach_vars_to_workspace(ws_name, tfe_key, var["key"], var["value"], var["category"], var["sensitive"], var["hcl"])
def lambda_handler_inner(event, context): core_security = avm_common.get_param("core_security_account") master_role = avm_common.get_param("tlz_admin_role") ROLE_ARN_SECURITY=f"arn:aws:iam::{core_security}:role/{master_role}" session_assumed = avm_common.aws_session(role=ROLE_ARN_SECURITY, session_name='security-services') gd_client = session_assumed.client('ec2', region_name='us-east-1') if core_security == event["AccountId"]: print("No need to send guradduty invites as guardDuty master account cannot be member to itself") return regions = get_regions(gd_client) for region in regions:# print("Processing %s region" %(region)) try: client = session_assumed.client('guardduty', region_name=region) #Find out if GuardDuty already enabled: detectors_list = client.list_detectors() if not detectors_list["DetectorIds"]: print ("GuardDuty is not enabled ... enabling GuardDuty on master account") response = client.create_detector(Enable=True) # Save DetectorID handler DetectorId = response["DetectorId"] else: print("GuardDuty already enabled on account") DetectorId = detectors_list['DetectorIds'][0] # Do error handling here # print all Detectorts detectors_list = client.list_detectors() print ("Detector lists: ") for x in detectors_list["DetectorIds"]: #print(x, end=" ") print(x) account_id = event["AccountId"] account = avm_common.get_account_details(account_id) print(f"id from event : {account_id} id from orgdetails: {account['org_details']['id']}") if account: # invite an account print(account['org_details']) print ("\nInviting member account " + account_id) invite_member = client.create_members( AccountDetails=[ { 'AccountId': account_id, 'Email': account['org_details']["email"] }, ], DetectorId=DetectorId ) gd_members = client.get_members( AccountIds=[ account_id, ], DetectorId=DetectorId ) # the future member account is now staged if gd_members: print(gd_members) print ("Memeber account RelationshipStatus: " + gd_members['Members'][0]['RelationshipStatus']) # Invite members account(s) response = client.invite_members( AccountIds=[ account_id, ], DetectorId=DetectorId, Message='Please join AWS GuardDuty master account' ) gd_members = client.get_members( AccountIds=[ account_id, ], DetectorId=DetectorId ) # the future member account should be 'pending' print ("Memeber account RelationshipStatus: " + gd_members['Members'][0]['RelationshipStatus']) except ClientError as e: send_error_notification(e,account_id) # Enable GuardDuty on target account and accept the invites print(f"About to enable and accept requests for {account_id}") target_session = avm_common.aws_session(role=f"arn:aws:iam::{account_id}:role/{master_role}", session_name='target-account') for region in regions: print("Processing %s region" %(region)) try: client = target_session.client('guardduty', region_name=region) #Find out if GuardDuty already enabled: detectors_list = client.list_detectors() if not detectors_list["DetectorIds"]: print (f"GuardDuty is not enabled ... enabling GuardDuty on {account_id} account") response = client.create_detector(Enable=True) # Save DetectorID handler DetectorId = response["DetectorId"] else: print(f"GuardDuty already enabled on account {account_id}") DetectorId = detectors_list['DetectorIds'][0] # accept the invites response = client.list_invitations(MaxResults=10) if response: invites = [i for i in response['Invitations']] for i in invites: r = client.accept_invitation(DetectorId=DetectorId,InvitationId=i["InvitationId"],MasterId=i["AccountId"]) except ClientError as e: body = f"Unexpected error : {e}" print(body) send_error_notification(e,account_id)