diff --git a/examples/2016-10-31/lambda_safe_deployments/template.yaml b/examples/2016-10-31/lambda_safe_deployments/template.yaml index 1079f8c591..02f2d6e452 100644 --- a/examples/2016-10-31/lambda_safe_deployments/template.yaml +++ b/examples/2016-10-31/lambda_safe_deployments/template.yaml @@ -3,7 +3,8 @@ Transform: AWS::Serverless-2016-10-31 Description: A sample Lambda Safe Deployment Application Resources: - + mySNSTopic: + Type: AWS::SNS::Topic safeTest: Type: AWS::Serverless::Function Properties: @@ -16,6 +17,14 @@ Resources: Hooks: PreTraffic: !Ref preTrafficHook + TriggerConfigurations: + - TriggerEvents: + - DeploymentSuccess + - DeploymentFailure + TriggerName: TestTrigger + TriggerTargetArn: !Ref mySNSTopic + + preTrafficHook: Type: AWS::Serverless::Function Properties: diff --git a/samtranslator/model/codedeploy.py b/samtranslator/model/codedeploy.py index e6e28b1219..b65a662fc2 100644 --- a/samtranslator/model/codedeploy.py +++ b/samtranslator/model/codedeploy.py @@ -23,6 +23,7 @@ class CodeDeployDeploymentGroup(Resource): 'DeploymentConfigName': PropertyType(False, one_of(is_str(), is_type(dict))), 'DeploymentStyle': PropertyType(False, is_type(dict)), 'ServiceRoleArn': PropertyType(True, one_of(is_str(), is_type(dict))), + 'TriggerConfigurations': PropertyType(False, is_type(list)) } runtime_attrs = { diff --git a/samtranslator/model/preferences/deployment_preference.py b/samtranslator/model/preferences/deployment_preference.py index 65ff0ae0e1..354f773cb6 100644 --- a/samtranslator/model/preferences/deployment_preference.py +++ b/samtranslator/model/preferences/deployment_preference.py @@ -20,10 +20,12 @@ :param role: An IAM role ARN that CodeDeploy will use for traffic shifting, an IAM role will not be created if this is supplied :param enabled: Whether this deployment preference is enabled (true by default) +:param trigger_configurations: Information about triggers associated with the deployment group. Duplicates are + not allowed. """ DeploymentPreferenceTuple = namedtuple('DeploymentPreferenceTuple', ['deployment_type', 'pre_traffic_hook', 'post_traffic_hook', 'alarms', - 'enabled', 'role']) + 'enabled', 'role', 'trigger_configurations']) class DeploymentPreference(DeploymentPreferenceTuple): @@ -42,7 +44,7 @@ def from_dict(cls, logical_id, deployment_preference_dict): """ enabled = deployment_preference_dict.get('Enabled', True) if not enabled: - return DeploymentPreference(None, None, None, None, False, None) + return DeploymentPreference(None, None, None, None, False, None, None) if 'Type' not in deployment_preference_dict: raise InvalidResourceException(logical_id, "'DeploymentPreference' is missing required Property 'Type'") @@ -57,4 +59,6 @@ def from_dict(cls, logical_id, deployment_preference_dict): post_traffic_hook = hooks.get('PostTraffic', None) alarms = deployment_preference_dict.get('Alarms', None) role = deployment_preference_dict.get('Role', None) - return DeploymentPreference(deployment_type, pre_traffic_hook, post_traffic_hook, alarms, enabled, role) + trigger_configurations = deployment_preference_dict.get('TriggerConfigurations', None) + return DeploymentPreference(deployment_type, pre_traffic_hook, post_traffic_hook, alarms, enabled, role, + trigger_configurations) diff --git a/samtranslator/model/preferences/deployment_preference_collection.py b/samtranslator/model/preferences/deployment_preference_collection.py index b7d301760d..767d8ced08 100644 --- a/samtranslator/model/preferences/deployment_preference_collection.py +++ b/samtranslator/model/preferences/deployment_preference_collection.py @@ -132,6 +132,9 @@ def deployment_group(self, function_logical_id): if deployment_preference.role: deployment_group.ServiceRoleArn = deployment_preference.role + if deployment_preference.trigger_configurations: + deployment_group.TriggerConfigurations = deployment_preference.trigger_configurations + return deployment_group def _replace_deployment_types(self, value, key=None): diff --git a/tests/translator/input/function_with_deployment_preference_all_parameters.yaml b/tests/translator/input/function_with_deployment_preference_all_parameters.yaml index 5b0311484b..cbbc80e5f7 100644 --- a/tests/translator/input/function_with_deployment_preference_all_parameters.yaml +++ b/tests/translator/input/function_with_deployment_preference_all_parameters.yaml @@ -14,6 +14,12 @@ Resources: PostTraffic: !Ref MyValidationTestFunction Alarms: - !Ref MyCloudWatchAlarm + TriggerConfigurations: + - TriggerEvents: + - DeploymentSuccess + - DeploymentFailure + TriggerName: TestTrigger + TriggerTargetArn: !Ref MySNSTopic MySanityTestFunction: Type: 'AWS::Serverless::Function' @@ -42,3 +48,6 @@ Resources: Namespace: AWS/EC2 Period: 300 Threshold: 10 + + MySNSTopic: + Type: AWS::SNS::Topic \ No newline at end of file diff --git a/tests/translator/model/preferences/test_deployment_preference.py b/tests/translator/model/preferences/test_deployment_preference.py index 4dfba33f9f..332a8dc6b0 100644 --- a/tests/translator/model/preferences/test_deployment_preference.py +++ b/tests/translator/model/preferences/test_deployment_preference.py @@ -12,20 +12,33 @@ def setUp(self): self.post_traffic_hook = 'post_traffic_function_ref' self.alarms = ['alarm1ref', 'alarm2ref'] self.role = {"Ref": "MyRole"} + self.trigger_configurations = { + "TriggerEvents": [ + "DeploymentSuccess", + "DeploymentFailure" + ], + "TriggerTargetArn": { + "Ref": "MySNSTopic" + }, + "TriggerName": "TestTrigger" + } self.expected_deployment_preference = DeploymentPreference(self.deployment_type, self.pre_traffic_hook, - self.post_traffic_hook, self.alarms, True, self.role) + self.post_traffic_hook, self.alarms, True, self.role, + self.trigger_configurations) def test_from_dict_with_intrinsic_function_type(self): type = {"Ref": "SomeType"} expected_deployment_preference = DeploymentPreference(type, self.pre_traffic_hook, - self.post_traffic_hook, self.alarms, True, self.role) + self.post_traffic_hook, self.alarms, True, self.role, + self.trigger_configurations) deployment_preference_yaml_dict = dict() deployment_preference_yaml_dict['Type'] = type deployment_preference_yaml_dict['Hooks'] = {'PreTraffic': self.pre_traffic_hook, 'PostTraffic': self.post_traffic_hook} deployment_preference_yaml_dict['Alarms'] = self.alarms deployment_preference_yaml_dict['Role'] = self.role + deployment_preference_yaml_dict['TriggerConfigurations'] = self.trigger_configurations deployment_preference_from_yaml_dict = DeploymentPreference.from_dict('logical_id', deployment_preference_yaml_dict) self.assertEqual(expected_deployment_preference, deployment_preference_from_yaml_dict) @@ -36,12 +49,13 @@ def test_from_dict(self): deployment_preference_yaml_dict['Hooks'] = {'PreTraffic': self.pre_traffic_hook, 'PostTraffic': self.post_traffic_hook} deployment_preference_yaml_dict['Alarms'] = self.alarms deployment_preference_yaml_dict['Role'] = self.role + deployment_preference_yaml_dict['TriggerConfigurations'] = self.trigger_configurations deployment_preference_from_yaml_dict = DeploymentPreference.from_dict('logical_id', deployment_preference_yaml_dict) self.assertEqual(self.expected_deployment_preference, deployment_preference_from_yaml_dict) def test_from_dict_with_disabled_preference_does_not_require_other_parameters(self): - expected_deployment_preference = DeploymentPreference(None, None, None, None, False, None) + expected_deployment_preference = DeploymentPreference(None, None, None, None, False, None, None) deployment_preference_yaml_dict = dict() deployment_preference_yaml_dict['Enabled'] = False diff --git a/tests/translator/output/aws-cn/function_with_deployment_preference_all_parameters.json b/tests/translator/output/aws-cn/function_with_deployment_preference_all_parameters.json index 9472e991c6..1d0ba288d7 100644 --- a/tests/translator/output/aws-cn/function_with_deployment_preference_all_parameters.json +++ b/tests/translator/output/aws-cn/function_with_deployment_preference_all_parameters.json @@ -123,7 +123,19 @@ "CodeDeployServiceRole", "Arn" ] - } + }, + "TriggerConfigurations": [ + { + "TriggerEvents": [ + "DeploymentSuccess", + "DeploymentFailure" + ], + "TriggerTargetArn": { + "Ref": "MySNSTopic" + }, + "TriggerName": "TestTrigger" + } + ] } }, "MySanityTestFunction": { @@ -265,6 +277,9 @@ ] } } + }, + "MySNSTopic": { + "Type": "AWS::SNS::Topic" } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/function_with_deployment_preference_all_parameters.json b/tests/translator/output/aws-us-gov/function_with_deployment_preference_all_parameters.json index 1323d7c7c1..a1dc4c9e53 100644 --- a/tests/translator/output/aws-us-gov/function_with_deployment_preference_all_parameters.json +++ b/tests/translator/output/aws-us-gov/function_with_deployment_preference_all_parameters.json @@ -123,7 +123,19 @@ "CodeDeployServiceRole", "Arn" ] - } + }, + "TriggerConfigurations": [ + { + "TriggerEvents": [ + "DeploymentSuccess", + "DeploymentFailure" + ], + "TriggerTargetArn": { + "Ref": "MySNSTopic" + }, + "TriggerName": "TestTrigger" + } + ] } }, "MySanityTestFunction": { @@ -265,6 +277,9 @@ ] } } + }, + "MySNSTopic": { + "Type": "AWS::SNS::Topic" } } } \ No newline at end of file diff --git a/tests/translator/output/function_with_deployment_preference_all_parameters.json b/tests/translator/output/function_with_deployment_preference_all_parameters.json index b8a44e7ff3..5e3f641473 100644 --- a/tests/translator/output/function_with_deployment_preference_all_parameters.json +++ b/tests/translator/output/function_with_deployment_preference_all_parameters.json @@ -123,7 +123,19 @@ "CodeDeployServiceRole", "Arn" ] - } + }, + "TriggerConfigurations": [ + { + "TriggerEvents": [ + "DeploymentSuccess", + "DeploymentFailure" + ], + "TriggerTargetArn": { + "Ref": "MySNSTopic" + }, + "TriggerName": "TestTrigger" + } + ] } }, "MySanityTestFunction": { @@ -265,6 +277,9 @@ ] } } + }, + "MySNSTopic": { + "Type": "AWS::SNS::Topic" } } } \ No newline at end of file diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 7ee40841b2..1f4e9bcb5b 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -784,7 +784,8 @@ DeadLetterQueue: ``` #### DeploymentPreference Object -Specifies the configurations to enable Safe Lambda Deployments. Read the [usage guide](../docs/safe_lambda_deployments.rst) for detailed information. The following shows all available properties of this object +Specifies the configurations to enable Safe Lambda Deployments. Read the [usage guide](../docs/safe_lambda_deployments.rst) for detailed information. The following shows all available properties of this object. +TriggerConfigurations takes a list of [TriggerConfig](https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_TriggerConfig.html) objects. ```yaml DeploymentPreference: @@ -798,6 +799,15 @@ DeploymentPreference: # Validation Lambda functions that are run before & after traffic shifting PreTraffic: !Ref PreTrafficLambdaFunction PostTraffic: !Ref PostTrafficLambdaFunction + TriggerConfigurations: + # A list of trigger configurations you want to associate with the deployment group. Used to notify an SNS topic on + # lifecycle events. + - TriggerEvents: + # A list of events to trigger on. + - DeploymentSuccess + - DeploymentFailure + TriggerName: TestTrigger + TriggerTargetArn: !Ref MySNSTopic ``` #### Cors Configuration