From c13f77173fe1d83069f585e046a2b358e65b4c76 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Wed, 21 Mar 2018 11:13:05 -0500 Subject: [PATCH] add UsePreviousValue support for parameters when updating a CloudFormation stack (#1504) --- moto/cloudformation/responses.py | 13 ++++++--- .../test_cloudformation_stack_crud_boto3.py | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py index 73d1d2c2..a1295a20 100644 --- a/moto/cloudformation/responses.py +++ b/moto/cloudformation/responses.py @@ -222,17 +222,24 @@ class CloudFormationResponse(BaseResponse): role_arn = self._get_param('RoleARN') template_url = self._get_param('TemplateURL') stack_body = self._get_param('TemplateBody') + stack = self.cloudformation_backend.get_stack(stack_name) if self._get_param('UsePreviousTemplate') == "true": - stack_body = self.cloudformation_backend.get_stack( - stack_name).template + stack_body = stack.template elif not stack_body and template_url: stack_body = self._get_stack_from_s3_url(template_url) + incoming_params = self._get_list_prefix("Parameters.member") parameters = dict([ (parameter['parameter_key'], parameter['parameter_value']) for parameter - in self._get_list_prefix("Parameters.member") + in incoming_params if 'parameter_value' in parameter ]) + previous = dict([ + (parameter['parameter_key'], stack.parameters[parameter['parameter_key']]) + for parameter + in incoming_params if 'use_previous_value' in parameter + ]) + parameters.update(previous) # boto3 is supposed to let you clear the tags by passing an empty value, but the request body doesn't # end up containing anything we can use to differentiate between passing an empty value versus not # passing anything. so until that changes, moto won't be able to clear tags, only update them. diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py index fb9b549c..1dbf80fb 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py +++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py @@ -276,6 +276,33 @@ def test_create_stack_from_s3_url(): json.loads(dummy_template_json, object_pairs_hook=OrderedDict)) +@mock_cloudformation +def test_update_stack_with_previous_value(): + name = 'update_stack_with_previous_value' + cf_conn = boto3.client('cloudformation', region_name='us-east-1') + cf_conn.create_stack( + StackName=name, TemplateBody=dummy_template_yaml_with_ref, + Parameters=[ + {'ParameterKey': 'TagName', 'ParameterValue': 'foo'}, + {'ParameterKey': 'TagDescription', 'ParameterValue': 'bar'}, + ] + ) + cf_conn.update_stack( + StackName=name, UsePreviousTemplate=True, + Parameters=[ + {'ParameterKey': 'TagName', 'UsePreviousValue': True}, + {'ParameterKey': 'TagDescription', 'ParameterValue': 'not bar'}, + ] + ) + stack = cf_conn.describe_stacks(StackName=name)['Stacks'][0] + tag_name = [x['ParameterValue'] for x in stack['Parameters'] + if x['ParameterKey'] == 'TagName'][0] + tag_desc = [x['ParameterValue'] for x in stack['Parameters'] + if x['ParameterKey'] == 'TagDescription'][0] + assert tag_name == 'foo' + assert tag_desc == 'not bar' + + @mock_cloudformation @mock_s3 @mock_ec2