diff --git a/.gitignore b/.gitignore index eab571678..cf46a0d2f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ nosetests.xml .project .pydevproject .idea +.venv # Vim *.sw* diff --git a/tests/test_ecs.py b/tests/test_ecs.py index 8e631404c..73333bec5 100644 --- a/tests/test_ecs.py +++ b/tests/test_ecs.py @@ -6,6 +6,39 @@ class TestECS(unittest.TestCase): + def test_allow_placement_strategy_constraint(self): + task_definition = ecs.TaskDefinition( + "mytaskdef", + ContainerDefinitions=[ + ecs.ContainerDefinition( + Image="myimage", + Memory="300", + Name="mycontainer", + ) + ], + Volumes=[ + ecs.Volume(Name="my-vol"), + ], + ) + ecs_service = ecs.Service( + 'Service', + Cluster='cluster', + DesiredCount=2, + PlacementStrategies=[ + ecs.PlacementStrategy( + Type="random", + ) + ], + PlacementConstraints=[ + ecs.PlacementConstraint( + Type="distinctInstance", + ) + ], + TaskDefinition=Ref(task_definition), + ) + + ecs_service.to_dict() + def test_allow_string_cluster(self): task_definition = ecs.TaskDefinition( "mytaskdef", diff --git a/troposphere/ecs.py b/troposphere/ecs.py index 5677e24c7..a00c0ab21 100644 --- a/troposphere/ecs.py +++ b/troposphere/ecs.py @@ -26,6 +26,36 @@ class DeploymentConfiguration(AWSProperty): } +def placement_strategy_validator(x): + valid_values = ['random', 'spread', 'binpack'] + if x not in valid_values: + raise ValueError("Placement Strategy type must be one of: %s" % + ', '.join(valid_values)) + return x + + +def placement_constraint_validator(x): + valid_values = ['distinctInstance', 'memberOf'] + if x not in valid_values: + raise ValueError("Placement Constraint type must be one of: %s" % + ', '.join(valid_values)) + return x + + +class PlacementConstraint(AWSProperty): + props = { + 'Type': (placement_constraint_validator, True), + 'Expression': (basestring, False), + } + + +class PlacementStrategy(AWSProperty): + props = { + 'Type': (placement_strategy_validator, True), + 'Field': (basestring, False), + } + + class Service(AWSObject): resource_type = "AWS::ECS::Service" @@ -35,6 +65,9 @@ class Service(AWSObject): 'DesiredCount': (positive_integer, False), 'LoadBalancers': ([LoadBalancer], False), 'Role': (basestring, False), + 'PlacementConstraints': ([PlacementConstraint], False), + 'PlacementStrategies': ([PlacementStrategy], False), + 'ServiceName': (basestring, False), 'TaskDefinition': (basestring, True), }