Example #1
0
def clean(parameter_store, deployment_map):
    """
    Function used to remove stale entries in Parameter Store and
    Deployment Pipelines that are no longer in the Deployment Map
    """
    current_pipeline_parameters = parameter_store.fetch_parameters_by_path(
        '/deployment/')

    parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)
    cloudformation = CloudFormation(
        region=DEPLOYMENT_ACCOUNT_REGION,
        deployment_account_region=DEPLOYMENT_ACCOUNT_REGION,
        role=boto3)
    stacks_to_remove = []
    for parameter in current_pipeline_parameters:
        name = parameter.get('Name').split('/')[-2]
        if name not in [
                p.get('name') for p in deployment_map.map_contents['pipelines']
        ]:
            parameter_store.delete_parameter(name)
            stacks_to_remove.append(name)

    for stack in list(set(stacks_to_remove)):
        cloudformation.delete_stack("{0}-{1}".format(ADF_PIPELINE_PREFIX,
                                                     stack))
Example #2
0
def worker_thread(sts, region, account_id, role, event):
    partition = get_partition(REGION_DEFAULT)

    role = sts.assume_cross_account_role(
        f'arn:{partition}:iam::{account_id}:role/{role}', 'remove_base')

    parameter_store = ParameterStore(region, role)
    paginator = parameter_store.client.get_paginator('describe_parameters')
    page_iterator = paginator.paginate()
    for page in page_iterator:
        for parameter in page['Parameters']:
            if 'Used by The AWS Deployment Framework' in parameter.get(
                    'Description', ''):
                parameter_store.delete_parameter(parameter.get('Name'))

    cloudformation = CloudFormation(
        region=region,
        deployment_account_region=event.get('deployment_account_region'),
        role=role,
        wait=True,
        stack_name=None,
        s3=None,
        s3_key_path=None,
        account_id=account_id)
    return cloudformation.delete_all_base_stacks()
Example #3
0
def lambda_handler(event, _):
    message = extract_message(event)
    pipeline = extract_pipeline(message)
    parameter_store = ParameterStore(os.environ["AWS_REGION"], boto3)
    secrets_manager = boto3.client(
        "secretsmanager", region_name=os.environ["AWS_REGION"]
    )
    channel = parameter_store.fetch_parameter(
        name="/notification_endpoint/{0}".format(pipeline["name"]),
        with_decryption=False,
    )
    # All slack url"s must be stored in /adf/slack/channel_name since ADF only has access to the /adf/ prefix by default
    url = secrets_manager.get_secret_value(
        SecretId="/notification_endpoint/hooks/slack/{0}".format(channel)
    )["SecretString"]

    if is_approval(message):
        send_message(url[channel], create_approval(channel, message))
        return
    if is_bootstrap(event):
        send_message(url[channel], create_bootstrap_message_text(channel, message))
        return

    if is_text(message):
        send_message(url, create_bootstrap_message_text(channel, message))
        return

    send_message(url[channel], create_pipeline_message_text(channel, pipeline))
    return
def main():
    parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)
    deployment_map = DeploymentMap(parameter_store,
                                   os.environ["ADF_PIPELINE_PREFIX"])
    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, boto3, S3_BUCKET_NAME)
    sts = STS(boto3)
    role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}-org-access-adf'.format(
            MASTER_ACCOUNT_ID,
            parameter_store.fetch_parameter('cross_account_access_role')),
        'pipeline')

    organizations = Organizations(role)
    clean(parameter_store, deployment_map)

    for p in deployment_map.map_contents.get('pipelines'):
        pipeline = Pipeline(p)

        for target in p['targets']:
            target_structure = TargetStructure(target)
            for step in target_structure.target:
                for path in step.get('path'):
                    try:
                        regions = step.get(
                            'regions',
                            p.get('regions', DEPLOYMENT_ACCOUNT_REGION))
                        pipeline.stage_regions.append(regions)
                        pipeline_target = Target(path, regions,
                                                 target_structure,
                                                 organizations)
                        pipeline_target.fetch_accounts_for_target()
                    except BaseException:
                        raise Exception(
                            "Failed to return accounts for {0}".format(path))

            pipeline.template_dictionary["targets"].append(
                target_structure.account_list)

        if DEPLOYMENT_ACCOUNT_REGION not in regions:
            pipeline.stage_regions.append(DEPLOYMENT_ACCOUNT_REGION)

        parameters = pipeline.generate_parameters()
        pipeline.generate()
        deployment_map.update_deployment_parameters(pipeline)
        s3_object_path = upload_if_required(s3, pipeline)

        store_regional_parameter_config(pipeline, parameter_store)
        cloudformation = CloudFormation(
            region=DEPLOYMENT_ACCOUNT_REGION,
            deployment_account_region=DEPLOYMENT_ACCOUNT_REGION,
            role=boto3,
            template_url=s3_object_path,
            parameters=parameters,
            wait=True,
            stack_name="{0}-{1}".format(os.environ["ADF_PIPELINE_PREFIX"],
                                        pipeline.name),
            s3=None,
            s3_key_path=None)

        cloudformation.create_stack()
def lambda_handler(event, _):
    # Return if we need to update the pipelines only
    if event.get('update_only'):
        LOGGER.info('Will only update pipelines for this execution.')
        return event
    try:
        sts = STS(boto3)
        parameter_store = ParameterStore(
            event.get('deployment_account_region'), boto3)
        for region in list(
                set([event.get('deployment_account_region')] +
                    event.get("regions"))):
            kms_key_arn = parameter_store.fetch_parameter(
                "/cross_region/kms_arn/{0}".format(region))
            s3_bucket = parameter_store.fetch_parameter(
                "/cross_region/s3_regional_bucket/{0}".format(region))
            for account_id in event.get('account_ids'):
                try:
                    role = sts.assume_cross_account_role(
                        'arn:aws:iam::{0}:role/{1}'.format(
                            account_id, 'adf-cloudformation-deployment-role'),
                        'base_cfn_role')
                    IAMUpdater(kms_key_arn, s3_bucket, role)
                    kms = KMS(region, boto3, kms_key_arn, account_id)
                    kms.enable_cross_account_access()
                except ClientError:
                    continue
        return event
    except BaseException as error:
        LOGGER.exception(error)
def prepare_deployment_account(sts, deployment_account_id, config):
    """
    Ensures configuration is up to date on the deployment account
    and returns the role that can be assumed by the master account
    to access the deployment account
    """
    deployment_account_role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}'.format(deployment_account_id,
                                           config.cross_account_access_role),
        'master')
    for region in list(
            set([config.deployment_account_region] + config.target_regions)):
        deployment_account_parameter_store = ParameterStore(
            region, deployment_account_role)
        deployment_account_parameter_store.put_parameter(
            'organization_id', os.environ["ORGANIZATION_ID"])

    deployment_account_parameter_store = ParameterStore(
        config.deployment_account_region, deployment_account_role)
    deployment_account_parameter_store.put_parameter(
        'deployment_account_bucket', DEPLOYMENT_ACCOUNT_S3_BUCKET_NAME)
    if '@' not in config.notification_endpoint:
        config.notification_channel = config.notification_endpoint
        config.notification_endpoint = "arn:aws:lambda:{0}:{1}:function:SendSlackNotification".format(
            config.deployment_account_region, deployment_account_id)
    for item in ('cross_account_access_role', 'notification_type',
                 'notification_endpoint', 'notification_channel'):
        if getattr(config, item) is not None:
            deployment_account_parameter_store.put_parameter(
                '/notification_endpoint/main'
                if item == 'notification_channel' else item,
                str(getattr(config, item)))

    return deployment_account_role
Example #7
0
def main():
    LOGGER.info('ADF Version %s', ADF_VERSION)
    LOGGER.info("ADF Log Level is %s", ADF_LOG_LEVEL)

    parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)
    deployment_map = DeploymentMap(parameter_store, ADF_PIPELINE_PREFIX)
    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, S3_BUCKET_NAME)
    sts = STS()
    role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}-readonly'.format(
            MASTER_ACCOUNT_ID,
            parameter_store.fetch_parameter('cross_account_access_role')),
        'pipeline')

    organizations = Organizations(role)
    clean(parameter_store, deployment_map)

    try:
        auto_create_repositories = parameter_store.fetch_parameter(
            'auto_create_repositories')
    except ParameterNotFoundError:
        auto_create_repositories = 'enabled'

    threads = []
    for p in deployment_map.map_contents.get('pipelines'):
        thread = PropagatingThread(target=worker_thread,
                                   args=(p, organizations,
                                         auto_create_repositories, s3,
                                         deployment_map, parameter_store))
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()
def update_master_account_parameters(parsed_event, parameter_store):
    """
    Update the Master account parameter store in us-east-1 with the deployment_account_id
    then updates the main deployment region with that same value
    """
    parameter_store.put_parameter('deployment_account_id', parsed_event.account_id)
    parameter_store = ParameterStore(parsed_event.deployment_account_region, boto3)
    parameter_store.put_parameter('deployment_account_id', parsed_event.account_id)
 def __init__(self):
     # The scope of permissions request from the user
     self._scope = "playlist-modify-public"
     # Parameter store to get and update Spotify secrets
     self._parameter_store = ParameterStore('Spotify',
                                            constants.SPOTIFY_SECRETS)
     self._sp_oauth = self._init_spotify_oauth()
     self._client = self._init_spotify_client()
 def __init__(self):
     self._api_service_name = "youtube"
     self._api_version = "v3"
     # The scopes of permissions request from the user
     self._scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
     # Parameter store to get and update Spotify secrets
     self._parameter_store = ParameterStore('Youtube', constants.YOUTUBE_SECRETS)
     self._credentials = self._init_credentials()
     self._client = self._init_youtube_client()
Example #11
0
def main():  #pylint: disable=R0915
    LOGGER.info('ADF Version %s', ADF_VERSION)
    LOGGER.info("ADF Log Level is %s", ADF_LOG_LEVEL)

    parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)
    deployment_map = DeploymentMap(parameter_store, ADF_PIPELINE_PREFIX)
    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, S3_BUCKET_NAME)
    sts = STS()
    role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}-readonly'.format(
            MASTER_ACCOUNT_ID,
            parameter_store.fetch_parameter('cross_account_access_role')),
        'pipeline')

    organizations = Organizations(role)
    clean(parameter_store, deployment_map)

    for p in deployment_map.map_contents.get('pipelines'):
        pipeline = Pipeline(p)

        for target in p.get('targets', []):
            target_structure = TargetStructure(target)
            for step in target_structure.target:
                for path in step.get('path'):
                    regions = step.get(
                        'regions', p.get('regions', DEPLOYMENT_ACCOUNT_REGION))
                    step_name = step.get('name')
                    params = step.get('params', {})
                    pipeline.stage_regions.append(regions)
                    pipeline_target = Target(path, regions, target_structure,
                                             organizations, step_name, params)
                    pipeline_target.fetch_accounts_for_target()

            pipeline.template_dictionary["targets"].append(
                target_structure.account_list)

        if DEPLOYMENT_ACCOUNT_REGION not in regions:
            pipeline.stage_regions.append(DEPLOYMENT_ACCOUNT_REGION)

        parameters = pipeline.generate_parameters()
        pipeline.generate()
        deployment_map.update_deployment_parameters(pipeline)
        s3_object_path = upload_pipeline(s3, pipeline)

        store_regional_parameter_config(pipeline, parameter_store)
        cloudformation = CloudFormation(
            region=DEPLOYMENT_ACCOUNT_REGION,
            deployment_account_region=DEPLOYMENT_ACCOUNT_REGION,
            role=boto3,
            template_url=s3_object_path,
            parameters=parameters,
            wait=True,
            stack_name="{0}-{1}".format(ADF_PIPELINE_PREFIX, pipeline.name),
            s3=None,
            s3_key_path=None,
            account_id=DEPLOYMENT_ACCOUNT_ID)
        cloudformation.create_stack()
Example #12
0
def configure_generic_account(sts, event, region, role):
    """
    Fetches the kms_arn from the deployment account main region
    and adds the it plus the deployment_account_id parameter to the
    target account so it can be consumed in CloudFormation. These
    are required for the global.yml in all target accounts.
    """
    try:
        deployment_account_role = sts.assume_cross_account_role(
            'arn:aws:iam::{0}:role/{1}'.format(
                event['deployment_account_id'],
                event['cross_account_access_role']
            ), 'configure_generic'
        )
        parameter_store_deployment_account = ParameterStore(
            event['deployment_account_region'],
            deployment_account_role
        )
        parameter_store_target_account = ParameterStore(
            region,
            role
        )
        kms_arn = parameter_store_deployment_account.fetch_parameter('/cross_region/kms_arn/{0}'.format(region))
    except (ClientError, ParameterNotFoundError):
        raise GenericAccountConfigureError(
            'Account {0} cannot yet be bootstrapped '
            'as the Deployment Account has not yet been bootstrapped. '
            'Have you moved your Deployment account into the deployment OU?'.format(event['account_id'])
        )
    parameter_store_target_account.put_parameter('kms_arn', kms_arn)
    parameter_store_target_account.put_parameter('deployment_account_id', event['deployment_account_id'])
Example #13
0
    def _store_cross_region_config(self):
        """
        Stores cross_account_access_role Parameter
        in Parameter Store on the master account
        in deployment account main region.
        """
        self.client_deployment_region = ParameterStore(
            self.deployment_account_region, boto3)

        self.client_deployment_region.put_parameter(
            'cross_account_access_role', self.cross_account_access_role)
Example #14
0
def fetch_required_ssm_params(regions):
    output = {}
    for region in regions:
        parameter_store = ParameterStore(region, boto3)
        output[region] = {
            "s3": parameter_store.fetch_parameter('/cross_region/s3_regional_bucket/{0}'.format(region)),
            "kms": parameter_store.fetch_parameter('/cross_region/kms_arn/{0}'.format(region))
        }
        if region == DEPLOYMENT_ACCOUNT_REGION:
            output[region]["modules"] = parameter_store.fetch_parameter('deployment_account_bucket')
    return output
Example #15
0
def configure_deployment_account_parameters(event, role):
    """
    Applies the Parameters from adfconfig plus other essential
    Parameters to the Deployment Account in each region as defined in
    adfconfig.yml
    """
    for region in list(
            set([event["deployment_account_region"]] + event["regions"])):
        parameter_store = ParameterStore(region, role)
        for key, value in event['deployment_account_parameters'].items():
            parameter_store.put_parameter(key, value)
Example #16
0
def worker_thread(account_id, sts, config, s3, cache, kms_dict):
    """
    The Worker thread function that is created for each account
    in which CloudFormation create_stack is called
    """
    LOGGER.debug("%s - Starting new worker thread", account_id)

    organizations = Organizations(role=boto3, account_id=account_id)
    ou_id = organizations.get_parent_info().get("ou_parent_id")

    account_state = is_account_in_invalid_state(ou_id, config.config)
    if account_state:
        LOGGER.info("%s %s", account_id, account_state)
        return

    account_path = organizations.build_account_path(
        ou_id,
        [],  # Initial empty array to hold OU Path,
        cache)
    try:
        role = ensure_generic_account_can_be_setup(sts, config, account_id)

        # Regional base stacks can be updated after global
        for region in list(
                set([config.deployment_account_region] +
                    config.target_regions)):
            # Ensuring the kms_arn on the target account is up-to-date
            parameter_store = ParameterStore(region, role)
            parameter_store.put_parameter('kms_arn', kms_dict[region])

            cloudformation = CloudFormation(
                region=region,
                deployment_account_region=config.deployment_account_region,
                role=role,
                wait=True,
                stack_name=None,
                s3=s3,
                s3_key_path=account_path,
                account_id=account_id)
            try:
                cloudformation.create_stack()
            except GenericAccountConfigureError as error:
                if 'Unable to fetch parameters' in str(error):
                    LOGGER.error(
                        '%s - Failed to update its base stack due to missing parameters (deployment_account_id or kms_arn), '
                        'ensure this account has been bootstrapped correctly by being moved from the root '
                        'into an Organizational Unit within AWS Organizations.',
                        account_id)
                raise Exception from error

    except GenericAccountConfigureError as generic_account_error:
        LOGGER.info(generic_account_error)
        return
def main():
    LOGGER.info('ADF Version %s', ADF_VERSION)
    LOGGER.info("ADF Log Level is %s", ADF_LOG_LEVEL)

    parameter_store = ParameterStore(
        DEPLOYMENT_ACCOUNT_REGION,
        boto3
    )
    deployment_map = DeploymentMap(
        parameter_store,
        ADF_PIPELINE_PREFIX
    )
    s3 = S3(
        DEPLOYMENT_ACCOUNT_REGION,
        S3_BUCKET_NAME
    )
    sts = STS()
    role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}-readonly'.format(
            MASTER_ACCOUNT_ID,
            parameter_store.fetch_parameter('cross_account_access_role')
        ), 'pipeline'
    )

    organizations = Organizations(role)
    clean(parameter_store, deployment_map)

    try:
        auto_create_repositories = parameter_store.fetch_parameter('auto_create_repositories')
    except ParameterNotFoundError:
        auto_create_repositories = 'enabled'

    threads = []
    for counter, p in enumerate(deployment_map.map_contents.get('pipelines')):
        thread = PropagatingThread(target=worker_thread, args=(
            p,
            organizations,
            auto_create_repositories,
            s3,
            deployment_map,
            parameter_store
        ))
        thread.start()
        threads.append(thread)
        _batcher = counter % 10
        if _batcher == 9: # 9 meaning we have hit a set of 10 threads since n % 10
            _interval = random.randint(5, 11)
            LOGGER.debug('Waiting for %s seconds before starting next batch of 10 threads.', _interval)
            time.sleep(_interval)

    for thread in threads:
        thread.join()
Example #18
0
def update_deployment_account_output_parameters(
        deployment_account_region,
        region,
        deployment_account_role,
        cloudformation):
    """
    Update parameters on the deployment account across target
    regions based on the output of CloudFormation base stacks
    in the deployment account.
    """
    deployment_account_parameter_store = ParameterStore(
        deployment_account_region, deployment_account_role
    )
    parameter_store = ParameterStore(
        region, deployment_account_role
    )

    for key, value in cloudformation.get_stack_regional_outputs().items():
        deployment_account_parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region),
            value
        )
        parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region),
            value
        )
def lambda_handler(event, _):
    parameter_store = ParameterStore(REGION_DEFAULT, boto3)
    configuration_options = ast.literal_eval(
        parameter_store.fetch_parameter('config'))

    to_root_option = list(
        filter(lambda option: option.get("name", []) == "to-root",
               configuration_options.get('moves')))

    action = to_root_option.pop().get('action')
    account_id = event.get('account_id')
    execute_move_action(action, account_id, parameter_store, event)

    return event
Example #20
0
def update_deployment_account_output_parameters(
        deployment_account_region,
        region,
        kms_and_bucket_dict,
        deployment_account_role,
        cloudformation):
    """
    Update parameters on the deployment account across target
    regions based on the output of CloudFormation base stacks
    in the deployment account.
    """
    deployment_account_parameter_store = ParameterStore(
        deployment_account_region, deployment_account_role
    )
    parameter_store = ParameterStore(
        region, deployment_account_role
    )
    outputs = cloudformation.get_stack_regional_outputs()
    kms_and_bucket_dict[region] = {}
    kms_and_bucket_dict[region]['kms'] = outputs['kms_arn']
    kms_and_bucket_dict[region]['s3_regional_bucket'] = outputs['s3_regional_bucket']
    for key, value in outputs.items():
        deployment_account_parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region),
            value
        )
        parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region),
            value
        )

    return kms_and_bucket_dict
Example #21
0
def main():
    LOGGER.info('ADF Version %s', ADF_VERSION)
    LOGGER.info("ADF Log Level is %s", ADF_LOG_LEVEL)

    _create_inputs_folder()
    parameter_store = ParameterStore(
        DEPLOYMENT_ACCOUNT_REGION,
        boto3
    )
    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, SHARED_MODULES_BUCKET)
    deployment_map = DeploymentMap(
        parameter_store,
        s3,
        ADF_PIPELINE_PREFIX
    )
    sts = STS()
    role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}-readonly'.format(
            MASTER_ACCOUNT_ID,
            parameter_store.fetch_parameter('cross_account_access_role')
        ), 'pipeline'
    )
    organizations = Organizations(role)
    clean(parameter_store, deployment_map)
    ensure_event_bus_status(ORGANIZATION_ID)
    try:
        auto_create_repositories = parameter_store.fetch_parameter('auto_create_repositories')
    except ParameterNotFoundError:
        auto_create_repositories = 'enabled'
    threads = []
    _cache = Cache()
    for p in deployment_map.map_contents.get('pipelines', []):
        _source_account_id = p.get('default_providers', {}).get('source', {}).get('properties', {}).get('account_id', {})
        if _source_account_id and int(_source_account_id) != int(DEPLOYMENT_ACCOUNT_ID) and not _cache.check(_source_account_id):
            rule = Rule(p['default_providers']['source']['properties']['account_id'])
            rule.create_update()
            _cache.add(p['default_providers']['source']['properties']['account_id'], True)
        thread = PropagatingThread(target=worker_thread, args=(
            p,
            organizations,
            auto_create_repositories,
            deployment_map,
            parameter_store
        ))
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()
def main():
    accounts = read_config_files(ACCOUNTS_FOLDER)
    if not bool(accounts):
        LOGGER.info(f"Found {len(accounts)} account(s) in configuration file(s). Account provisioning will not continue.")
        return
    LOGGER.info(f"Found {len(accounts)} account(s) in configuration file(s).")
    organizations = Organizations(boto3)
    all_accounts = organizations.get_accounts()
    parameter_store = ParameterStore(os.environ.get('AWS_REGION', 'us-east-1'), boto3)
    adf_role_name = parameter_store.fetch_parameter('cross_account_access_role')
    for account in accounts:
        try:
            account_id = next(acc["Id"] for acc in all_accounts if acc["Name"] == account.full_name)
        except StopIteration: # If the account does not exist yet..
            account_id = None
        create_or_update_account(organizations, account, adf_role_name, account_id)
Example #23
0
def configure_master_account_parameters(event):
    """
    Update the Master account parameter store in us-east-1 with the deployment_account_id
    then updates the main deployment region with that same value
    """
    parameter_store_master_account_region = ParameterStore(os.environ["AWS_REGION"], boto3)
    parameter_store_master_account_region.put_parameter('deployment_account_id', event['account_id'])

    parameter_store_deployment_account_region = ParameterStore(event['deployment_account_region'], boto3)
    parameter_store_deployment_account_region.put_parameter('deployment_account_id', event['account_id'])
Example #24
0
def lambda_handler(event, _):
    target_role_policies = {
        'adf-cloudformation-deployment-role': 'adf-cloudformation-deployment-role-policy-kms',
        'adf-cloudformation-role': 'adf-cloudformation-role-policy'
    }

    role_policies = {
        'adf-codepipeline-role': 'adf-codepipeline-role-policy',
        'adf-cloudformation-deployment-role': 'adf-cloudformation-deployment-role-policy',
        'adf-cloudformation-role': 'adf-cloudformation-role-policy'
    }

    sts = STS()
    partition = get_partition(REGION_DEFAULT)

    parameter_store = ParameterStore(
        region=event.get('deployment_account_region'),
        role=boto3
    )
    account_id = event.get("account_id")
    kms_key_arns = []
    s3_buckets = []
    for region in list(set([event.get('deployment_account_region')] + event.get("regions", []))):
        kms_key_arn = parameter_store.fetch_parameter(
            f"/cross_region/kms_arn/{region}"
        )
        kms_key_arns.append(kms_key_arn)
        s3_bucket = parameter_store.fetch_parameter(
            f"/cross_region/s3_regional_bucket/{region}"
        )
        s3_buckets.append(s3_bucket)
        try:
            role = sts.assume_cross_account_role(
                f'arn:{partition}:iam::{account_id}:role/adf-cloudformation-deployment-role',
                'base_cfn_role'
            )
            LOGGER.debug("Role has been assumed for %s", account_id)
            update_iam(role, s3_bucket, kms_key_arn, target_role_policies)
        except ClientError as err:
            LOGGER.debug("%s could not be assumed (%s), continuing", account_id, err, exc_info=True)
            continue

    update_iam(boto3, s3_buckets, kms_key_arns, role_policies)

    return event
def update_deployment_account_output_parameters(deployment_account_region,
                                                region,
                                                deployment_account_role,
                                                cloudformation):

    deployment_account_parameter_store = ParameterStore(
        deployment_account_region, deployment_account_role)
    regional_parameter_store = ParameterStore(region, deployment_account_role)
    # Regions needs to know to organization ID for Bucket Policy
    regional_parameter_store.put_parameter("organization_id",
                                           os.environ['ORGANIZATION_ID'])
    # Regions needs to store its kms arn and s3 bucket in master and regional
    for key, value in cloudformation.get_stack_regional_outputs().items():
        LOGGER.info('Updating %s on deployment account in %s', key, region)
        deployment_account_parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region), value)
        regional_parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region), value)
def main():
    parameters = Parameters(
        PROJECT_NAME,
        ParameterStore(
            DEPLOYMENT_ACCOUNT_REGION,
            boto3
        )
    )
    parameters.create_parameter_files()
Example #27
0
def prepare_deployment_account(sts, deployment_account_id, config):
    deployment_account_role = sts.assume_cross_account_role(
        'arn:aws:iam::{0}:role/{1}'.format(deployment_account_id,
                                           config.cross_account_access_role),
        'master')
    for region in list(
            set([config.deployment_account_region] + config.target_regions)):
        deployment_account_parameter_store = ParameterStore(
            region, deployment_account_role)
        deployment_account_parameter_store.put_parameter(
            'organization_id', os.environ["ORGANIZATION_ID"])

    deployment_account_parameter_store = ParameterStore(
        config.deployment_account_region, deployment_account_role)
    deployment_account_parameter_store.put_parameter(
        'cross_account_access_role', str(config.cross_account_access_role))
    deployment_account_parameter_store.put_parameter(
        'deployment_account_bucket', DEPLOYMENT_ACCOUNT_S3_BUCKET)
    return deployment_account_role
Example #28
0
def main():
    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, SHARED_MODULES_BUCKET)
    parameters = Parameters(
        PROJECT_NAME,
        ParameterStore(
            DEPLOYMENT_ACCOUNT_REGION,
            boto3
        ),
        s3
    )
    parameters.create_parameter_files()
def main():
    LOGGER.info('ADF Version %s', ADF_VERSION)
    LOGGER.info("ADF Log Level is %s", ADF_LOG_LEVEL)

    parameter_store = ParameterStore(DEPLOYMENT_ACCOUNT_REGION, boto3)

    s3 = S3(DEPLOYMENT_ACCOUNT_REGION, SHARED_MODULES_BUCKET)
    deployment_map = DeploymentMap(parameter_store, s3, ADF_PIPELINE_PREFIX)

    LOGGER.info('Cleaning Stale Deployment Map entries')
    clean(parameter_store, deployment_map)
Example #30
0
def update_deployment_account_output_parameters(deployment_account_region,
                                                region,
                                                deployment_account_role,
                                                cloudformation):
    deployment_account_parameter_store = ParameterStore(
        deployment_account_region, deployment_account_role)
    parameter_store = ParameterStore(region, deployment_account_role)

    for key, value in cloudformation.get_stack_regional_outputs().items():
        deployment_account_parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region), value)
        parameter_store.put_parameter(
            "/cross_region/{0}/{1}".format(key, region), value)