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)
예제 #3
0
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
예제 #4
0
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)
예제 #6
0
 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)
예제 #9
0
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)
예제 #10
0
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)
예제 #12
0
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
예제 #13
0
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
예제 #15
0
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
예제 #16
0
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)
예제 #18
0
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")
예제 #20
0
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
예제 #21
0
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
예제 #22
0
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
예제 #23
0
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)
예제 #24
0
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
예제 #26
0
    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"])
예제 #29
0
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)
예제 #30
0
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))