def terraform_build_handler(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)
def get_tf_modules(config, generate=False): if generate: if not terraform_generate_handler(config=config): return False modules = set() resources = set() for root, _, files in os.walk('terraform'): for file_name in files: path = os.path.join(root, file_name) if path.endswith('.tf.json'): with open(path, 'r') as tf_file: tf_data = json.load(tf_file) modules.update(set((tf_data['module']))) resources.update('{}.{}'.format(resource, value) for resource, values in tf_data.get( 'resource', {}).iteritems() for value in values) return {'module': modules, 'resource': resources}
def deploy_handler(options, config): """CLI handler for deploying new versions of Lambda functions Args: options (argparse.Namespace): Parsed argparse namespace from the CLI config (CLIConfig): Loaded StreamAlert config Returns: bool: False if errors occurred, True otherwise """ # Make sure the Terraform code is up to date if not terraform_generate_handler(config=config): return False functions = options.function if 'all' in options.function: functions = { 'alert', 'alert_merger', 'apps', 'athena', 'classifier', 'rule', 'rule_promo', 'threat_intel_downloader' } if not deploy(functions, config, options.clusters): return False # Update the rule table now if the rules engine is being deployed if 'rule' in functions: _update_rule_table(options, config) return True
def terraform_init(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 _terraform_init_backend() 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.stream_alert_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.stream_alert_secrets', 'aws_kms_alias.stream_alert_secrets' ] 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 = '{}.streamalerts'.format( config['global']['account']['prefix']) create_table('alerts', alerts_bucket, config) LOGGER.info('Building remainding infrastructure') return tf_runner(refresh=False)
def cli_runner(args): """Main StreamAlert CLI handler Args: options (argparse.Namespace): command line arguments passed from the argparser. Contains the following keys for terraform commands: (command, subcommand, target) Contains the following keys for lambda commands: (command, subcommand, env, func, source) Returns: bool: False if errors occurred, True otherwise """ config = CLIConfig() set_logger_levels(args.debug) LOGGER.info( 'Issues? Report here: https://github.com/airbnb/streamalert/issues') cmds = { 'app': lambda opts: app_handler(opts, config), 'athena': lambda opts: athena_handler(opts, config), 'build': lambda opts: terraform_build_handler(opts, config), 'clean': lambda opts: terraform_clean_handler(), 'configure': lambda opts: configure_handler(opts, config), 'create-alarm': lambda opts: _create_alarm_handler(opts, config), 'create-cluster-alarm': lambda opts: _create_alarm_handler(opts, config), 'custom-metrics': lambda opts: _custom_metrics_handler(opts, config), 'deploy': lambda opts: deploy_handler(opts, config), 'destroy': lambda opts: terraform_destroy_handler(opts, config), 'generate': lambda opts: terraform_generate_handler(config, check_creds=False), 'init': lambda opts: terraform_init(opts, config), 'kinesis': lambda opts: kinesis_handler(opts, config), 'list-targets': lambda opts: terraform_list_targets(config), 'output': lambda opts: output_handler(opts, config), 'rollback': lambda opts: rollback_handler(opts, config), 'rule-staging': lambda opts: rule_staging_handler(opts, config), 'status': lambda opts: _status_handler(config), 'test': lambda opts: test_handler(opts, config), 'threat-intel': lambda opts: _threat_intel_handler(opts, config), 'threat-intel-downloader': lambda opts: threat_intel_downloader_handler(opts, config), } result = cmds[args.command](args) LOGGER.info('Completed') return result