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): core_logging = avm_common.get_param("core_logging_account") master_role = avm_common.get_param("tlz_admin_role") 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') update_cw_destination_policy(session_assumed,event)
def lambda_handler(event, context): try: insert_event = [i for i in event["Records"] if i["eventName"] == "INSERT"] if not len(insert_event): print("ERROR: No account to create") return newImage = insert_event[0]["dynamodb"]["NewImage"] account_email = newImage["id"]["S"] sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) sub = "ERROR: tfe avm-tfe-master-lambda" func = "avm-tfe-master-lambda" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) #(accountId, snsARN, function_name, subject, body): avm_common.send_pipeline_notification(account_email,sns_topic,func, sub,body) raise e except Exception as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_email,sns_topic,func, sub,body) raise e
def lambda_handler_inner(event, context): session_assumed = avm_common.aws_session(role=None, session_name='logging-services') account_id = event["AccountId"] iamclient = session_assumed.client('iam') iamresource = session_assumed.resource('iam') current_account = session_assumed.client('sts').get_caller_identity().get('Account') POLICY_ARN_AVM=f"arn:aws:iam::{current_account}:policy/tlz_accounts_assumerole_policy" versionid = iamclient.get_policy(PolicyArn=POLICY_ARN_AVM) versionid1 = versionid["Policy"]["DefaultVersionId"][1:] previousversion = int(versionid1)-1 versiondelete = "v" + str(previousversion) # Update a new version of the specified managed policy and set as Default policy = iamresource.Policy(POLICY_ARN_AVM) version = policy.default_version policyJson = version.document #policy = json.loads(policyJson) #print() resources = policyJson['Statement'][0]['Resource'] master_role = avm_common.get_param("tlz_admin_role") new_policy = f'arn:aws:iam::{account_id}:role/{master_role}' if new_policy not in resources: print(f"Adding {account_id} to policy resources") policyJson['Statement'][0]['Resource'].append(new_policy) policystring = json.dumps(policyJson) print(policystring) if previousversion > 0: deleteresponse = iamclient.delete_policy_version(PolicyArn=POLICY_ARN_AVM,VersionId=versiondelete) print(deleteresponse) policy_version = policy.create_version(PolicyDocument=policystring,SetAsDefault=True) print(policy_version) else: print(f"{account_id} is already part of existing resources")
def notify(self, message): # TODO: Set up notifications sub = "INFO: accountpipeline keyrotation-for-terraform-user" func = "accountpipeline-tfe-secret-rotation" sns_topic = avm_common.get_param("sns_topic_arn") avm_common.send_pipeline_notification(self._account, sns_topic, func, sub, message)
def __init__(self, account): self._account = account master_role = avm_common.get_param("tlz_admin_role") self._session = avm_common.aws_session(role=f"arn:aws:iam::{account}:role/{master_role}", session_name='target-account') self._iam = self._session.client('iam') session = boto3.session.Session() dynamodb = session.resource('dynamodb',region_name=aws_region_name) self._ddb_table = dynamodb.Table(DDB_TABLE)
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"] tlzKeyMan = tlzKeyRotator(account_id) #response = iam.list_users() #user_name = response["Users"][0]["UserName"] secret_name = avm_common.get_param("terraform_service_user") keys = tlzKeyMan.get_access_keys(secret_name) tlzKeyMan.update_tfe_workspaces(keys, secret_name, account_id)
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 lambda_handler(event, context): try: account_id = event["AccountId"] lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" sns_topic = avm_common.get_param("sns_topic_arn") sub = "ERROR: Managed policy update" func = "avm-iam-managedpolicy-update-for-new-account" avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) raise e
def send_error_notification(e, account_id): body = f"Unexpected error : {e}" print(body) sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: GuardDuty invites" func = "avm-guardduty-invite-member-accounts" #(accountId, snsARN, function_name, subject, body): avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body)
def lambda_handler(event, context): try: account_id = event["AccountId"] lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: DNS Invite" func = "avm-dns-invite-member-account" avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) raise e
def lambda_handler(event, context): try: account_id = event["AccountId"] lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: accountpipeline s3 update corelogging bucket policies" func = "avm-s3-updatepolicy" #(accountId, snsARN, function_name, subject, body): #avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) raise e
def lambda_handler(event, context): try: account_id = event["AccountId"] handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: TFE Create Workspaces" func = "avm-tfe-create-workspaces" avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e
def extract_externalid(account_id): sts_client = boto3.client('sts') master_role = avm_common.get_param("tlz_admin_role") response = sts_client.assume_role( RoleArn=f"arn:aws:iam::{account_id}:role/{master_role}", RoleSessionName="AssumeRoleSession1") iam_policies = boto3.resource( 'iam', aws_access_key_id=response['Credentials']['AccessKeyId'], aws_secret_access_key=response['Credentials']['SecretAccessKey'], aws_session_token=response['Credentials']['SessionToken']) externalID = "" for role in iam_policies.roles.all(): if role.name == "tlz_redlock_read_only": externalID = role.assume_role_policy_document['Statement'][0][ 'Condition']['StringEquals']['sts:ExternalId'] return externalID
def lambda_handler(event, context): try: account_id = event["AccountId"] sns_topic = avm_common.get_param("sns_topic_arn") sub = "ERROR: redlock addaccount" func = "avm-3rdparty-redlock-addaccount" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e except Exception as e: body = f"Unexpected error : {e}" avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e
def lambda_handler(event, context): try: account_id = event["AccountId"] sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: accountpipeline CW destination policy update" func = "accountpipeline-cw-destination-policy-update" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) #(accountId, snsARN, function_name, subject, body): avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) except Exception as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body)
def lambda_handler(event, context): try: account_id = event["AccountId"] sns_topic = avm_common.get_param("sns_topic_arn") sub = "ERROR: okta create groups" func = "avm-okta-create-groups" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e except Exception as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e
def fork_repo(self,source_repo_name,target_project,target_repo_name): print("starting clone_repo function...") # Steps # 1. Check if repo exists target_repo = self.get_repo(target_repo_name,target_project) print(target_repo) if not target_repo: templates_project = avm_common.get_param("project_for_templates") src_repo = self.get_repo(source_repo_name, templates_project) if src_repo: print(f"Create a new repo {target_repo_name} in {target_project}") try: response = src_repo.fork(target_repo_name,target_project) return response except stashy.errors.GenericException as e: raise e else: print(f"{source_repo_name} repo not found") else: print(f"{target_repo_name} repo already exists. Nothing to fork")
def lambda_handler(event, context): try: account_id = event["AccountId"] sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: accountpipeline keyrotation-for-terraform-user" func = "accountpipeline-tfe-secret-rotation" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) #(accountId, snsARN, function_name, subject, body): avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) raise e except Exception as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_id,sns_topic,func, sub,body) raise e
def lambda_handler_inner(event, context): account_id = event["AccountId"] exec_id = event["execution_id"] session = avm_common.aws_session(session_name="target_account") client = session.client('ssm') response = client.get_automation_execution(AutomationExecutionId=exec_id) failed_steps = [ f for f in response["AutomationExecution"]["StepExecutions"] if f["StepStatus"] == "Failed" ] if len(failed_steps): body = str(failed_steps) sns_topic = avm_common.get_param("sns_topic_arn") sub = f"SSM automation with {exec_id} failed for account {account_id}" avm_common.send_pipeline_notification( account_id, sns_topic, response["AutomationExecution"]["DocumentName"], sub, body) return 200
def lambda_handler(event, context): try: account_id = event["AccountId"] sns_topic = avm_common.get_param("sns_topic_arn") print(sns_topic) print(account_id) sub = "ERROR: avm sns post account creation email" func = "avm-sns-post-account-creation-email" lambda_handler_inner(event, context) except ClientError as e: body = f"Unexpected error : {e}" print(body) #(accountId, snsARN, function_name, subject, body): avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e except Exception as e: body = f"Unexpected error : {e}" print(body) avm_common.send_pipeline_notification(account_id, sns_topic, func, sub, body) raise e
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)
### # Performs a plan and apply on a workspace in Terraform Enterprise ### import json import requests import time import sys import boto3 import base64 from botocore.exceptions import ClientError import avm_common from botocore.exceptions import ClientError org = avm_common.get_param("tfe_org_name") tfe_api = avm_common.get_param("tfe_api_url") def get_workspace(headers,workspace_name): #workspace_name = "baseline-tv-demo-app1-dev" workspace_id = None tfe_url = f'{tfe_api}/organizations/{org}/workspaces/{workspace_name}' r = requests.get(tfe_url, headers=headers) data = r.json() if "data" in data.keys(): workspace_id = data["data"]["id"] else: print(f"No workspace found : {tfe_url}") return workspace_id
def create_account(self,account_request): print(account_request) role_name = self._org_account_access_role print(f'Email : {account_request["email"]}') account = self.get_account_by_email(account_request["email"]) print("Response from Create account") print(account) account_created = False max_attempts = 30 attempts = 0 response = None create_account = False if account: return account else: print(f"Account with email: {account_request['email']} not found and creating a new account") create_account = True if create_account: alias = self.get_account_alias(account_request["accountType"],account_request["account_name"],account_request["lob"], account_request["env"], account_request["accountPrefix"]) response = self._client.create_account( Email=account_request["email"], AccountName=alias, RoleName=role_name ) print(response) account_created = False max_attempts = 50 while account_created != True: response = self._client.describe_create_account_status(CreateAccountRequestId=response["CreateAccountStatus"]["Id"]) if response["CreateAccountStatus"]["State"] == "SUCCEEDED": account_created = True break else: time.sleep(5) attempts = attempts + 1 if attempts > max_attempts: break # By now account should have been created if account_created: acc = self._client.describe_account(AccountId=response["CreateAccountStatus"]["AccountId"]) # retry 5 times until sts succeeds sleep_time = 10 num_retries = 5 result_account = None for x in range(0, num_retries): try: target_session = self.assume_role_to_target(acc,role_name) # Update trust-policy of the role_name so that CSS can assume the role_name break except Exception as str_error: time.sleep(sleep_time) sleep_time *= 2 if not result_account: # send an SNS notification body = f"Master account unable to assume {self._master_role} for {acc}" sns_topic = avm_common.get_param("sns_topic_arn") sub = "WARN: tfe avm-tfe-master-lambda" func = "avm-tfe-master-lambda" avm_common.send_pipeline_notification(account_request['email'],sns_topic,func, sub,body) return self.get_account(acc) else: return None
def get_param(self, param): return avm_common.get_param(param)
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): master_account = avm_common.get_param("master_payer_account") master_role = avm_common.get_param("tlz_admin_role") org_account_access_role = avm_common.get_param("tlz_org_account_access_role") #print("Received event: " + json.dumps(event, indent=2)) master_role_arn = f"arn:aws:iam::{master_account}:role/{org_account_access_role}" session_local = avm_common.aws_session() current_account = session_local.client('sts').get_caller_identity().get('Account') session_regular = avm_common.aws_session(role=master_role_arn) account_request = {} insert_event = [i for i in event["Records"] if i["eventName"] == "INSERT"] if not len(insert_event): print("ERROR: No account to create") return newImage = insert_event[0]["dynamodb"]["NewImage"] account_request["email"] = newImage["id"]["S"] account_request["account_name"] = newImage["appName"]["S"] account_request["accountType"] = newImage["accountType"]["S"] account_request["accountPrefix"] = newImage["accountPrefix"]["S"] account_request["lob"] = newImage["lob"]["S"] if account_request["accountType"].lower() != "application": account_request["lob"] = account_request["accountType"].title() account_request["env"] = newImage["envType"]["S"] # CloudOps interal variable definition that will be used in certain areas where only prd, npd, sbx or dev are needed if (account_request["env"] == "stg" or account_request["env"] == "qa" or account_request["env"] == "dev"): account_request["intEnvironment"] = "npd" elif (account_request["env"] == "pre-prod" or account_request["env"] == "prd"): account_request["intEnvironment"] = "prd" print(account_request) orgMan = awsOrgManager(session_regular,current_account,master_account,master_role,org_account_access_role) account = orgMan.create_account(account_request) # By now account should have been created if account: target_ou = "Sandbox" # Move the account the target organizational_unit if account_request["accountType"].lower() != "application": target_ou = account_request["accountType"].title() else: if "lob" in account_request.keys(): if account_request["lob"]: target_ou = account_request["lob"] orgMan.move_account(account["id"],target_ou) acc = orgMan._client.describe_account(AccountId=account["id"]) # update account with additional details account["account_request"] = json.dumps(account_request,default=defaultencode) alias = orgMan.get_account_alias(account_request["accountType"],account_request["account_name"],account_request["lob"], account_request["env"], account_request["accountPrefix"] ) account["alias"] = alias account["accountType"] = account_request["accountType"] org = account_request["lob"].title() git_url = avm_common.get_param("tlz_git_url") print(git_url) vended_applications_project = avm_common.get_param("vended_applications_project") vended_baselines_project = avm_common.get_param("vended_baselines_project") if avm_common.resource_workspace_required(account_request["accountType"]): account["app_details"] = json.dumps({'git' : f'{git_url}/{vended_applications_project}/{alias}.git', 'tfe_workspace': f'{alias}-resources'}) account["baseline_details"] = json.dumps({'git' : f'{git_url}/{vended_baselines_project}/{alias}.git', 'tfe_workspace': f'{alias}-baseline'}) else: account["baseline_details"] = json.dumps({'git' : f'{git_url}/{vended_baselines_project}/{alias}.git', 'tfe_workspace': f'{alias}'}) print(account) orgMan.ingest_data(session_local,account) additional_info = {} additional_info["alias"] = alias additional_info["account_type"] = account_request["accountType"] additional_info["org_name"] = account_request["lob"] additional_info["owner"] = newImage["responsible"]["S"] additional_info["environment"] = account_request["env"] additional_info["intEnvironment"] = account_request["env"] additional_info["primaryVpcCidr"] = newImage["primaryVpcCidr"]["S"] additional_info["secondaryVpcCidr"] = newImage["secondaryVpcCidr"]["S"] #for k in newImage.keys(): # additional_info[k] = newImage[k]["S"] #additional_info["account"] = account orgMan.update_org_account_access_role(account["id"]) print("About to call the automation document") orgMan.start_pipeline(session_local, account["id"], additional_info)
def process(event, context): # 1. Identify target account VPC ID. # aws ec2 describe-vpcs # Assume role to target_account account_id = event["AccountId"] master_role = avm_common.get_param("tlz_admin_role") primary_region, secondary_region = avm_common.get_regions(account_id) target_session = avm_common.aws_session(role=f"arn:aws:iam::{account_id}:role/{master_role}", session_name='target-account') regions = [secondary_region, primary_region] vpcs = [] for region in regions: print("Processing %s region" %(region)) try: ec2 = target_session.client('ec2', region_name=region) response = ec2.describe_vpcs() v = [ {"VPCId" : x['VpcId'], "VPCRegion" : region} for x in response["Vpcs"]] vpcs.extend(v) except ClientError as e: print(e) except: print("Unexpected error") #print(vpcs) # 2. On core-common-shared-service account (Route 53 Privated Hosted Zone SOA and InfoBlox forwarder), create vpc association authorization. # aws route53 list-hosted-zones (assume the below is the default zone and will not change) core_shared_services = avm_common.get_param("core_shared_services_account") ROLE_ARN_SharedServices=f"arn:aws:iam::{core_shared_services}:role/{master_role}" session_common_shared = avm_common.aws_session(role=ROLE_ARN_SharedServices, session_name='core-shared-services') print("Able to assume role") route53 = session_common_shared.client('route53') zones_response = route53.list_hosted_zones() #print(zones_response) # Get the hosted_zone_id for HostedZone-> aws.spe.sony.com. hosted_zone_ids = [ z['Id'] for z in zones_response['HostedZones'] if "aws.tlz-avm.com" in z['Name']] print(hosted_zone_ids) for x in hosted_zone_ids: for vpc in vpcs: response = route53.create_vpc_association_authorization( HostedZoneId = x, VPC = vpc ) print(json.dumps(response)) print("****** Step : Accept VPC association authorization ******") # 3. On target account, accept vpc association authorization. # aws route53 associate-vpc-with-hosted-zone --hosted-zone-id "/hostedzone/$awsR53PHZ" --vpc VPCRegion=" $awsRegion",VPCId="$targetAccountVPCID" route53_target = target_session.client('route53') for x in hosted_zone_ids: for vpc in vpcs: try: accept_response = route53_target.associate_vpc_with_hosted_zone( HostedZoneId = x, VPC = vpc ) print(json.dumps(accept_response)) except ClientError as e: print(e) except: print("Unknown error") # 4. On core-common-shared-service account, delete vpc assoiciation authorization. # aws route53 delete-vpc-association-authorization --hosted-zone-id "/hostedzone/$awsR53PHZ " --vpc VPCRegion="$awsRegion ",VPCId="$targetAccountVPCID " print("****** Step: Delete VPC association authorization for core shared******") for x in hosted_zone_ids: for vpc in vpcs: delete_response = route53.delete_vpc_association_authorization( HostedZoneId = x, VPC = vpc ) print(json.dumps(delete_response))