Example #1
0
    def handler(cls, options, config):
        """Initialize infrastructure using Terraform

        Args:
            config (CLIConfig): Loaded StreamAlert config

        Returns:
            bool: False if errors occurred, True otherwise
        """

        # Stop here if only initializing the backend
        if options.backend:
            return cls._terraform_init_backend(config)

        LOGGER.info('Initializing StreamAlert')

        # generate init Terraform files
        if not terraform_generate_handler(config=config, init=True):
            return False

        LOGGER.info('Initializing Terraform')
        if not run_command(['terraform', 'init']):
            return False

        # build init infrastructure
        LOGGER.info('Building initial infrastructure')
        init_targets = [
            'aws_s3_bucket.lambda_source', 'aws_s3_bucket.logging_bucket',
            'aws_s3_bucket.streamalert_secrets', 'aws_s3_bucket.terraform_remote_state',
            'aws_s3_bucket.streamalerts',
            'aws_kms_key.server_side_encryption', 'aws_kms_alias.server_side_encryption',
            'aws_kms_key.streamalert_secrets', 'aws_kms_alias.streamalert_secrets',
            'aws_dynamodb_table.terraform_remote_state_lock'
        ]
        if not tf_runner(targets=init_targets):
            LOGGER.error('An error occurred while running StreamAlert init')
            return False

        # generate the main.tf with remote state enabled
        LOGGER.info('Configuring Terraform Remote State')
        if not terraform_generate_handler(config=config, check_tf=False, check_creds=False):
            return False

        if not run_command(['terraform', 'init']):
            return False

        LOGGER.info('Deploying Lambda Functions')

        functions = ['rule', 'alert', 'alert_merger', 'athena', 'classifier']

        deploy(functions, config)

        # we need to manually create the streamalerts table since terraform does not support this
        # See: https://github.com/terraform-providers/terraform-provider-aws/issues/1486
        alerts_bucket = firehose_alerts_bucket(config)
        create_table('alerts', alerts_bucket, config)

        LOGGER.info('Building remainding infrastructure')
        return tf_runner(refresh=False)
Example #2
0
    def handler(cls, options, config):
        """Use Terraform to destroy any existing infrastructure

        Args:
            options (argparse.Namespace): Parsed arguments from manage.py
            config (CLIConfig): Loaded StreamAlert config

        Returns:
            bool: False if errors occurred, True otherwise
        """
        # Check for valid credentials
        if not check_credentials():
            return False

        # Verify terraform is installed
        if not terraform_check():
            return False

        # Ask for approval here since multiple Terraform commands may be necessary
        if not continue_prompt(message='Are you sure you want to destroy?'):
            return False

        if options.target:
            target_modules, valid = _get_valid_tf_targets(config, options.target)
            if not valid:
                return False

            return tf_runner(
                action='destroy',
                auto_approve=True,
                targets=target_modules if target_modules else None
            )

        # Migrate back to local state so Terraform can successfully
        # destroy the S3 bucket used by the backend.
        # Do not check for terraform or aws creds again since these were checked above
        if not terraform_generate_handler(config=config, init=True, check_tf=False,
                                          check_creds=False):
            return False

        if not run_command(['terraform', 'init']):
            return False

        # Destroy all of the infrastructure
        if not tf_runner(action='destroy', auto_approve=True):
            return False

        # Remove old Terraform files
        return TerraformCleanCommand.handler(options, config)
Example #3
0
    def handler(cls, options, config):
        """Main handler for the Kinesis parser

        Args:
            options (argparse.Namespace): Parsed arguments
            config (CLIConfig): Loaded StreamAlert config

        Returns:
            bool: False if errors occurred, True otherwise
        """
        enable = options.action == 'enable-events'
        LOGGER.info('%s Kinesis Events', 'Enabling' if enable else 'Disabling')

        for cluster in options.clusters or config.clusters():
            if 'kinesis_events' in config['clusters'][cluster]['modules']:
                config['clusters'][cluster]['modules']['kinesis_events'][
                    'enabled'] = enable

        config.write()

        if options.skip_terraform:
            return True  # not an error

        if not terraform_generate_handler(config):
            return False

        return tf_runner(action='apply',
                         targets=[
                             'module.{}_{}'.format('kinesis_events', cluster)
                             for cluster in config.clusters()
                         ])
Example #4
0
def deploy(functions, config, clusters=None):
    """Deploy the functions

    Args:
        functions (set): Set of functions being deployed
        config (CLIConfig): Loaded StreamAlert config
        clusters (set=None): Optional clusters to target for this deploy

    Returns:
        bool: False if errors occurred, True otherwise
    """

    LOGGER.info('Deploying: %s', ' '.join(sorted(functions)))

    # Terraform apply only to the module which contains our lambda functions
    deploy_targets = set()
    packages = []

    for function in functions:
        package, targets = _create(function, config, clusters)
        # Continue if the package isn't enabled
        if not all([package, targets]):
            continue

        packages.append(package)
        deploy_targets.update(targets)

    # Terraform applies the new package and publishes a new version
    return helpers.tf_runner(targets=deploy_targets)
Example #5
0
def deploy(config, functions, clusters=None):
    """Deploy the functions

    Args:
        functions (set): Set of functions being deployed
        config (CLIConfig): Loaded StreamAlert config
        clusters (set=None): Optional clusters to target for this deploy

    Returns:
        bool: False if errors occurred, True otherwise
    """
    LOGGER.info('Deploying: %s', ', '.join(sorted(functions)))

    deployment_package = package.LambdaPackage(config)
    package_path = deployment_package.create()
    if not package_path:
        return False

    # Terraform apply only to the module which contains our lambda functions
    clusters = clusters or config.clusters()

    deploy_targets = _lambda_terraform_targets(config, functions, clusters)

    LOGGER.debug('Applying terraform targets: %s', ', '.join(sorted(deploy_targets)))

    # Terraform applies the new package and publishes a new version
    return helpers.tf_runner(targets=deploy_targets)
Example #6
0
    def handler(cls, options, config):
        """Run Terraform with an optional set of targets and clusters

        Args:
            options (argparse.Namespace): Parsed arguments from manage.py
            config (CLIConfig): Loaded StreamAlert config

        Returns:
            bool: False if errors occurred, True otherwise
        """
        if not terraform_generate_handler(config=config):
            return False

        target_modules, valid = _get_valid_tf_targets(config, options.target)
        if not valid:
            return False

        return tf_runner(targets=target_modules if target_modules else None)