Skip to content

Commit e76b939

Browse files
authored
fix: fix bug in custom DeploymentPreference feature (#966)
1 parent 6615433 commit e76b939

8 files changed

+2607
-334
lines changed

samtranslator/model/preferences/deployment_preference_collection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,19 @@ def deployment_group(self, function_logical_id):
134134

135135
return deployment_group
136136

137-
def _replace_deployment_types(self, value):
137+
def _replace_deployment_types(self, value, key=None):
138138
if isinstance(value, list):
139139
for i in range(len(value)):
140140
value[i] = self._replace_deployment_types(value[i])
141141
return value
142142
elif is_instrinsic(value):
143143
for (k, v) in value.items():
144-
value[k] = self._replace_deployment_types(v)
144+
value[k] = self._replace_deployment_types(v, k)
145145
return value
146146
else:
147147
if value in CODEDEPLOY_PREDEFINED_CONFIGURATIONS_LIST:
148+
if key == "Fn::Sub": # Don't nest a "Sub" in a "Sub"
149+
return ["CodeDeployDefault.Lambda${ConfigName}", {"ConfigName": value}]
148150
return fnSub("CodeDeployDefault.Lambda${ConfigName}", {"ConfigName": value})
149151
return value
150152

samtranslator/model/sam_resources.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def to_cloudformation(self, **kwargs):
8787
"""
8888
resources = []
8989
intrinsics_resolver = kwargs["intrinsics_resolver"]
90+
mappings_resolver = kwargs.get("mappings_resolver", None)
9091

9192
if self.DeadLetterQueue:
9293
self._validate_dlq()
@@ -105,7 +106,8 @@ def to_cloudformation(self, **kwargs):
105106
if self.DeploymentPreference:
106107
self._validate_deployment_preference_and_add_update_policy(kwargs.get('deployment_preference_collection',
107108
None),
108-
lambda_alias, intrinsics_resolver)
109+
lambda_alias, intrinsics_resolver,
110+
mappings_resolver)
109111

110112
managed_policy_map = kwargs.get('managed_policy_map', {})
111113
if not managed_policy_map:
@@ -392,13 +394,20 @@ def _construct_alias(self, name, function, version):
392394
return alias
393395

394396
def _validate_deployment_preference_and_add_update_policy(self, deployment_preference_collection, lambda_alias,
395-
intrinsics_resolver):
397+
intrinsics_resolver, mappings_resolver):
396398
if 'Enabled' in self.DeploymentPreference:
397399
self.DeploymentPreference['Enabled'] = intrinsics_resolver.resolve_parameter_refs(
398400
self.DeploymentPreference['Enabled'])
399401
if isinstance(self.DeploymentPreference['Enabled'], dict):
400402
raise InvalidResourceException(self.logical_id, "'Enabled' must be a boolean value")
401403

404+
if 'Type' in self.DeploymentPreference:
405+
# resolve intrinsics and mappings for Type
406+
preference_type = self.DeploymentPreference['Type']
407+
preference_type = intrinsics_resolver.resolve_parameter_refs(preference_type)
408+
preference_type = mappings_resolver.resolve_parameter_refs(preference_type)
409+
self.DeploymentPreference['Type'] = preference_type
410+
402411
if deployment_preference_collection is None:
403412
raise ValueError('deployment_preference_collection required for parsing the deployment preference')
404413

samtranslator/translator/translator.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from samtranslator.model.exceptions import (InvalidDocumentException, InvalidResourceException,
77
DuplicateLogicalIdException, InvalidEventException)
88
from samtranslator.intrinsics.resolver import IntrinsicsResolver
9+
from samtranslator.intrinsics.actions import FindInMapAction
910
from samtranslator.intrinsics.resource_refs import SupportedResourceReferences
1011
from samtranslator.plugins.api.default_definition_body_plugin import DefaultDefinitionBodyPlugin
1112
from samtranslator.plugins.application.serverless_app_plugin import ServerlessAppPlugin
@@ -62,6 +63,8 @@ def translate(self, sam_template, parameter_values):
6263
template = copy.deepcopy(sam_template)
6364
macro_resolver = ResourceTypeResolver(sam_resources)
6465
intrinsics_resolver = IntrinsicsResolver(parameter_values)
66+
mappings_resolver = IntrinsicsResolver(template.get('Mappings', {}),
67+
{FindInMapAction.intrinsic_name: FindInMapAction()})
6568
deployment_preference_collection = DeploymentPreferenceCollection()
6669
supported_resource_refs = SupportedResourceReferences()
6770
document_errors = []
@@ -76,6 +79,7 @@ def translate(self, sam_template, parameter_values):
7679
kwargs = macro.resources_to_link(sam_template['Resources'])
7780
kwargs['managed_policy_map'] = self.managed_policy_map
7881
kwargs['intrinsics_resolver'] = intrinsics_resolver
82+
kwargs['mappings_resolver'] = mappings_resolver
7983
kwargs['deployment_preference_collection'] = deployment_preference_collection
8084
translated = macro.to_cloudformation(**kwargs)
8185

tests/translator/input/function_with_custom_codedeploy_deployment_preference.yaml

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
Mappings:
2+
DeploymentPreferenceMap:
3+
prod:
4+
DeploymentPreference:
5+
AllAtOnce
6+
beta:
7+
DeploymentPreference:
8+
CustomDeployment
9+
10+
Parameters:
11+
Stage:
12+
Type: String
13+
Default: 'beta'
14+
Deployment:
15+
Type: String
16+
Default: 'AllAtOnce'
17+
Custom:
18+
Type: String
19+
Default: 'CustomDeployment'
20+
21+
Conditions:
22+
MyCondition:
23+
Fn::Equals:
24+
- true
25+
- false
26+
127
Resources:
228
MinimalFunction:
329
Type: 'AWS::Serverless::Function'
@@ -7,4 +33,64 @@ Resources:
733
Runtime: python2.7
834
AutoPublishAlias: live
935
DeploymentPreference:
10-
Type: TestDeploymentConfiguration
36+
Type: TestDeploymentConfiguration
37+
38+
CustomWithFindInMap: # Doesn't work
39+
Type: 'AWS::Serverless::Function'
40+
Properties:
41+
CodeUri: s3://sam-demo-bucket/hello.zip
42+
Handler: hello.handler
43+
Runtime: python2.7
44+
AutoPublishAlias: live
45+
DeploymentPreference:
46+
Type: !FindInMap [DeploymentPreferenceMap, !Ref Stage, DeploymentPreference]
47+
48+
CustomWithCondition: # Works
49+
Type: 'AWS::Serverless::Function'
50+
Properties:
51+
CodeUri: s3://sam-demo-bucket/hello.zip
52+
Handler: hello.handler
53+
Runtime: python2.7
54+
AutoPublishAlias: live
55+
DeploymentPreference:
56+
Type: !If [MyCondition, TestDeploymentConfiguration, AllAtOnce]
57+
58+
CustomWithCondition2:
59+
Type: 'AWS::Serverless::Function'
60+
Properties:
61+
CodeUri: s3://sam-demo-bucket/hello.zip
62+
Handler: hello.handler
63+
Runtime: python2.7
64+
AutoPublishAlias: live
65+
DeploymentPreference:
66+
Type: !If [MyCondition, !Sub "${Deployment}", !Ref Custom]
67+
68+
NormalWithSub:
69+
Type: 'AWS::Serverless::Function'
70+
Properties:
71+
CodeUri: s3://sam-demo-bucket/hello.zip
72+
Handler: hello.handler
73+
Runtime: python2.7
74+
AutoPublishAlias: live
75+
DeploymentPreference:
76+
Type: !Sub ${Deployment}
77+
78+
CustomWithSub:
79+
Type: 'AWS::Serverless::Function'
80+
Properties:
81+
CodeUri: s3://sam-demo-bucket/hello.zip
82+
Handler: hello.handler
83+
Runtime: python2.7
84+
AutoPublishAlias: live
85+
DeploymentPreference:
86+
Type: !Sub ${Custom}
87+
88+
NormalWithRef:
89+
Type: 'AWS::Serverless::Function'
90+
Properties:
91+
CodeUri: s3://sam-demo-bucket/hello.zip
92+
Handler: hello.handler
93+
Runtime: python2.7
94+
AutoPublishAlias: live
95+
DeploymentPreference:
96+
Type: !Ref Deployment

0 commit comments

Comments
 (0)