def test_generate_task_definitions_write_output(tmpdir): task_data = """ { "family": "default", "volumes": [], "containerDefinitions": [ { "name": "web-1", "image": "${image}", "essential": true, "command": ["hello", "world"], "memory": 256, "logConfiguration": {}, "cpu": 0, "portMappings": [ { "containerPort": 8080, "hostPort": 0 } ] } ] } """.strip() base_path = tmpdir.join("input").mkdir() filename = base_path.join("task_definition.json") filename.write(task_data) config = { "environment": { "DATABASE_URL": "postgresql://" }, "task_definitions": { "task-def-1": { "template": "task_definition.json", "overrides": { "web-1": { "memory": 512, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "default", "awslogs-region": "eu-west-1", }, }, } }, } }, } task_definitions.generate_task_definitions( config, template_vars={"image": "my-docker-image:1.0"}, base_path=base_path.strpath, output_path=tmpdir.join("output").mkdir().strpath, ) assert tmpdir.join("output").join("task-def-1.json").exists()
def main(config, var, output_path, dry_run): base_path = os.path.dirname(config.name) config = yaml.load(config) template_vars = dict(var) connection = Connection() cluster_name = config['cluster_name'] services = config['services'] logger.info("Starting deploy on cluster %s (%s services)", cluster_name, len(services)) # Generate the task definitions task_definitions = generate_task_definitions(config, template_vars, base_path, output_path) # Check if all task definitions required by the services exists for service_name, service in services.items(): if service['task_definition'] not in task_definitions: logger.error("Missing task definition %r for service %r", service['task_definition'], service_name) # Run the deployment if not dry_run: try: start_deployment(config, connection, task_definitions) except DeploymentFailed: sys.exit(1) sys.exit(0)
def run( filename: str, template_vars: typing.Dict[str, str], role_arn: typing.Optional[str] = None, output_path: typing.Optional[str] = None, create_missing_services=False, dry_run=False, ): base_path = os.path.dirname(filename) with open(filename, "r") as fh: config = yaml.safe_load(fh.read()) connection = Connection(role_arn) cluster_name = config["cluster_name"] services = config["services"] logger.info("Starting deploy on cluster %s (%s services)", cluster_name, len(services)) # Generate the task definitions task_definitions = generate_task_definitions(config, template_vars, base_path, output_path) # Check if all task definitions required by the services exists for service_name, service in services.items(): if service["task_definition"] not in task_definitions: logger.error( "Missing task definition %r for service %r", service["task_definition"], service_name, ) # Run the deployment if not dry_run: start_deployment(config, connection, task_definitions, create_missing_services)
def test_generate_multiple_task_definitions(tmpdir): task_data = """ { "family": "default", "volumes": [], "containerDefinitions": [ { "name": "web-1", "image": "${image}", "essential": true, "command": ["hello", "world"], "memory": 256, "cpu": 0, "portMappings": [ { "containerPort": 8080, "hostPort": 0 } ] }, { "name": "web-2", "image": "${image}", "essential": true, "command": ["hello", "world"], "memory": 256, "cpu": 0, "portMappings": [ { "containerPort": 8080, "hostPort": 0 } ] } ] } """.strip() filename = tmpdir.join("task_definition.json") filename.write(task_data) config = { "environment": { "DATABASE_URL": "postgresql://" }, "environment_groups": { "group-1": { "ENV_CODE": "group-1" }, "group-2": { "ENV_CODE": "group-2" }, }, "task_definitions": { "task-def-1": { "template": filename.strpath, "environment_group": "group-1", "overrides": { "web-1": { "memory": 512 } }, }, "task-def-2": { "template": filename.strpath, "environment_group": "group-2", "overrides": { "web-1": { "memory": 512 } }, }, }, } result = task_definitions.generate_task_definitions( config, template_vars={"image": "my-docker-image:1.0"}, base_path=None) expected = { "task-def-1": task_definitions.TaskDefinition({ "family": "task-def-1", "volumes": [], "containerDefinitions": [ { "name": "web-1", "image": "my-docker-image:1.0", "essential": True, "command": ["hello", "world"], "hostname": "task-def-1-web-1", "memory": 512, "cpu": 0, "portMappings": [{ "containerPort": 8080, "hostPort": 0 }], "environment": { "DATABASE_URL": "postgresql://", "ENV_CODE": "group-1", }, }, { "name": "web-2", "image": "my-docker-image:1.0", "essential": True, "command": ["hello", "world"], "hostname": "task-def-1-web-2", "memory": 256, "cpu": 0, "portMappings": [{ "containerPort": 8080, "hostPort": 0 }], "environment": { "DATABASE_URL": "postgresql://", "ENV_CODE": "group-1", }, }, ], "tags": [{ "key": "createdBy", "value": "ecs-deplojo" }], }), "task-def-2": task_definitions.TaskDefinition({ "family": "task-def-2", "volumes": [], "containerDefinitions": [ { "name": "web-1", "image": "my-docker-image:1.0", "essential": True, "hostname": "task-def-2-web-1", "command": ["hello", "world"], "memory": 512, "cpu": 0, "portMappings": [{ "containerPort": 8080, "hostPort": 0 }], "environment": { "DATABASE_URL": "postgresql://", "ENV_CODE": "group-2", }, }, { "name": "web-2", "image": "my-docker-image:1.0", "hostname": "task-def-2-web-2", "essential": True, "command": ["hello", "world"], "memory": 256, "cpu": 0, "portMappings": [{ "containerPort": 8080, "hostPort": 0 }], "environment": { "DATABASE_URL": "postgresql://", "ENV_CODE": "group-2", }, }, ], "tags": [{ "key": "createdBy", "value": "ecs-deplojo" }], }), } assert result == expected
def test_generate_task_definitions(tmpdir): task_data = """ { "family": "default", "volumes": [], "containerDefinitions": [ { "name": "web-1", "image": "${image}", "essential": true, "command": ["hello", "world"], "memory": 256, "cpu": 0, "portMappings": [ { "containerPort": 8080, "hostPort": 0 } ] }, { "name": "web-2", "image": "${image}", "essential": true, "command": ["hello", "world"], "memory": 256, "cpu": 0, "portMappings": [ { "containerPort": 8080, "hostPort": 0 } ] } ] } """.strip() filename = tmpdir.join('task_definition.json') filename.write(task_data) config = { 'environment': { 'DATABASE_URL': 'postgresql://', }, 'environment_groups': { 'group-1': { 'ENV_CODE': 'group-1', }, 'group-2': { 'ENV_CODE': 'group-2', }, }, 'task_definitions': { 'task-def-1': { 'template': filename.strpath, 'environment_group': 'group-1', 'overrides': { 'web-1': { 'memory': 512, } } }, 'task-def-2': { 'template': filename.strpath, 'environment_group': 'group-2', 'overrides': { 'web-1': { 'memory': 512, } } } } } result = task_definitions.generate_task_definitions( config, template_vars={ 'image': 'my-docker-image:1.0', }, base_path=None) expected = { 'task-def-1': { 'definition': { 'family': 'task-def-1', 'volumes': [], 'containerDefinitions': [{ 'name': 'web-1', 'image': 'my-docker-image:1.0', 'essential': True, 'command': ['hello', 'world'], 'memory': 512, 'cpu': 0, 'portMappings': [{ 'containerPort': 8080, 'hostPort': 0 }], 'environment': { 'DATABASE_URL': 'postgresql://', 'ENV_CODE': 'group-1', } }, { 'name': 'web-2', 'image': 'my-docker-image:1.0', 'essential': True, 'command': ['hello', 'world'], 'memory': 256, 'cpu': 0, 'portMappings': [{ 'containerPort': 8080, 'hostPort': 0 }], 'environment': { 'DATABASE_URL': 'postgresql://', 'ENV_CODE': 'group-1', } }] }, }, 'task-def-2': { 'definition': { 'family': 'task-def-2', 'volumes': [], 'containerDefinitions': [{ 'name': 'web-1', 'image': 'my-docker-image:1.0', 'essential': True, 'command': ['hello', 'world'], 'memory': 512, 'cpu': 0, 'portMappings': [{ 'containerPort': 8080, 'hostPort': 0 }], 'environment': { 'DATABASE_URL': 'postgresql://', 'ENV_CODE': 'group-2', } }, { 'name': 'web-2', 'image': 'my-docker-image:1.0', 'essential': True, 'command': ['hello', 'world'], 'memory': 256, 'cpu': 0, 'portMappings': [{ 'containerPort': 8080, 'hostPort': 0 }], 'environment': { 'DATABASE_URL': 'postgresql://', 'ENV_CODE': 'group-2', } }] } } } assert result == expected