def reject(ctx, profile, config_file, environment, region, change_set_name, change_set_id): """ Reject a CloudFormation ChangeSet, deleting the stack if in REVIEW_IN_PROGRESS status and has no other ChangeSets. If using --change-set-name then --config --environment and --region are required. If using --change-set-id no other values are required (although --profile and --region may be needed). """ if not change_set_name and not change_set_id: raise click.UsageError( "Option '--change-set-name' or '--change-set-id' required.") try: if change_set_id: runner = create_changeset_runner(profile, region, change_set_id) runner.reject_change_set() else: if not config_file: raise click.UsageError( "Missing option '-c' / '--config-file'.") if not environment: raise click.UsageError( "Missing option '-e' / '--environment'.") cfg = load_config(config_file, ctx.obj.config, environment, False, ChangeSetName=change_set_name) runner = create_runner(profile, cfg) runner.reject_change_set() except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def delete(ctx, profile, config, environment, region, retain_resources): try: cfg = load_config(config, environment, region, None, None) runner = create_runner(profile, cfg, None, False) runner.delete(retain_resources) except (ValidationError, StackError) as e: error(f'\nError: {e}')
def apply(ctx, profile, config_file, environment, region, change_set_name, change_set_id): """ Apply a CloudFormation ChangeSet to create or update a CloudFormation stack. If using --change-set-name then --config --environment and --region are required. If using --change-set-id no other values are required (although --profile and --region may be needed). """ if not change_set_name and not change_set_id: raise click.UsageError( "Option '--change-set-name' or '--change-set-id' required.") try: if change_set_id: runner = create_changeset_runner(profile, region, change_set_id) runner.apply_change_set() else: if not config_file: raise click.UsageError( "Missing option '-c' / '--config-file'.") if not environment: raise click.UsageError( "Missing option '-e' / '--environment'.") cfg = load_config(config_file, ctx.obj.config, environment, False, ChangeSetName=change_set_name) runner = create_runner(profile, cfg) runner.apply_change_set() except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def apply(ctx, profile, config, environment, region, change_set_name): try: cfg = load_config(config, environment, region, None, None) runner = create_runner(profile, cfg, change_set_name, False) runner.execute_change_set() except (ValidationError, StackError) as e: error(f'\nError: {e}')
def deploy(ctx, profile, config, environment, region, template, parameter, change_set_name, auto_approve): try: cfg = load_config(config, environment, region, template, parameter) runner = create_runner(profile, cfg, change_set_name, auto_approve) runner.deploy() except (ValidationError, StackError) as e: error(f'\nError: {e}')
def delete(ctx, profile, config_file, environment, region, retain_resources): """ Delete a CloudFormation stack. """ try: cfg = load_config(config_file, ctx.obj.config, environment, False) runner = create_runner(profile, cfg) runner.delete(retain_resources) except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def get_output(ctx, profile, config_file, environment, region, output_key): """ Returns matching Output value if it exists. """ try: cfg = load_config(config_file, ctx.obj.config, environment, False) runner = create_runner(profile, cfg) output_value = runner.get_output(output_key) echo(output_value) except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def status(ctx, profile, config_file, environment, region, event_days): """ Print current status of Stack. Includes pending ChangeSets and recent events. """ try: cfg = load_config(config_file, ctx.obj.config, environment, False) runner = create_runner(profile, cfg) runner.status(event_days) except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def test_loader_prod(): config = load_config(config_file(), Config({'Region': 'us-east-2'}), 'prod', False) assert config.environment == 'prod' assert config.region == 'us-east-2' assert config.template == 'integration/template.yaml' assert config.parameters == { 'Environment': 'prod', 'SSMKey': '/Company/p/us-east-2/Key', 'Domain': 'prod.example.com', 'KeyId': 'guid4' } assert config.tags == {'Application': 'Example', 'Environment': 'prod'} assert config.capabilities == ['CAPABILITY_NAMED_IAM']
def test_loader_dev(): config = load_config(config_file(), 'dev', 'us-east-1', None, None) assert config.environment == 'dev' assert config.region == 'us-east-1' assert config.template == 'integration/template.yaml' assert config.parameters == { 'Environment': 'dev', 'SSMKey': '/Company/dev/us-east-1/Key', 'Domain': 'dev.example.com', 'KeyId': 'guid1' } assert config.tags == { 'Application': 'Example', 'Environment': 'dev' } assert config.capabilities == ['CAPABILITY_NAMED_IAM']
def test_loader_dev_overrides(): override_parameters = [ ('SSMKey', '/Other/{{ Environment }}/Key'), ('Domain', 'notdev.example.com'), ('Extra', 'OverrideDefault') ] config = load_config(config_file(), 'dev', 'us-east-1', 'integration/config.yaml', override_parameters) assert config.environment == 'dev' assert config.region == 'us-east-1' assert config.template == 'integration/config.yaml' assert config.parameters == { 'Environment': 'dev', 'SSMKey': '/Other/dev/Key', 'Domain': 'notdev.example.com', 'KeyId': 'guid1', 'Extra': 'OverrideDefault' }
def deploy(ctx, profile, config_file, environment, region, template, parameter, parameter_use_previous, change_set_name, existing_changes, auto_apply): """ Create or update a CloudFormation stack using ChangeSets. """ try: cfg = load_config(config_file, ctx.obj.config, environment, Template=template, Parameters=parameter, PreviousParameters=parameter_use_previous, ChangeSetName=change_set_name, ExistingChanges=existing_changes, AutoApply=auto_apply) runner = create_runner(profile, cfg) runner.deploy() except (ValidationError, StackError) as e: error(f'\nError: {e}') exit(1)
def test_loader_dev_overrides(): previous_parameters = ('Previous', 'LambdaKey') override_parameters = (('SSMKey', '/Other/{{ Environment }}/Key'), ('Domain', 'notdev.example.com'), ('Extra', 'OverrideDefault'), ('LambdaKey', 'd/e/f')) arg_config = Config({}) arg_config.region = 'us-east-1' arg_config.add_parameters({ 'LambdaBucket': 'mybucket', 'LambdaKey': 'a/b/c' }) config = load_config(config_file(), arg_config, 'dev', False, Template='integration/config.yaml', Parameters=override_parameters, PreviousParameters=previous_parameters, ChangeSetName='TestChangeSet', AutoApply=True) assert config.environment == 'dev' assert config.region == 'us-east-1' assert config.template == 'integration/config.yaml' assert config.parameters == { 'Environment': 'dev', 'SSMKey': '/Other/dev/Key', 'Domain': 'notdev.example.com', 'KeyId': 'guid1', 'Extra': 'OverrideDefault', 'LambdaBucket': 'mybucket', 'LambdaKey': 'd/e/f', 'Previous': '<<UsePreviousValue>>' } assert config.change_set_name == 'TestChangeSet' assert config.auto_apply is True
def test_loader_missing_region(): with pytest.raises(ValidationError, match='Environment dev for us-west-1 not found in .*'): load_config(config_file(), Config({'Region': 'us-west-1'}), 'dev')
def test_loader_missing_environment(): with pytest.raises(ValidationError, match='Environment test for us-east-1 not found in .*'): load_config(config_file(), 'test', 'us-east-1', None, None)