5

I am trying to write a cloud-formation template for AWS ECS with blue green deployment support. This blue-green feature was added recently by AWS in ECS and couldn't find any reference for updating it in cloud-formation template. They have given documentation on, how to do it through UI but not through cloud-formation. I guess, AWS might not updated their cloud-formation documentation as it is a new feature. Any help to find the documentation would be appreciated. Thanking you in advance.

  • Use "CodeDeploy" keyword when searching for docs around it as that's the service behind the scenes that takes care of the deployment stuff. Here's some links https://aws.amazon.com/blogs/devops/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ and https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-groups-create-ecs.html – Milan Cermak Jan 22 '19 at 14:04
  • Can you please give me some basic examples to include this code deploy resource in ecs service template. – Gokula Adabala Jan 23 '19 at 04:59
  • 2
    These Links may help you with examples. https://docs.aws.amazon.com/AmazonECS/latest/userguide/ecs-cd-pipeline.html https://github.com/aws-samples/ecs-blue-green-deployment https://aws.amazon.com/blogs/compute/bluegreen-deployments-with-amazon-ecs/ – Sunil Valmiki Jan 30 '19 at 05:56
  • As of today there is no cloud formation support for the new blue/green deployment feature in ecs. – broun Feb 07 '19 at 03:21
  • thanks for your reply. If you find any sources please let me know – Gokula Adabala Feb 07 '19 at 07:47
  • 1
    The Github issue tracking this has been moved to "Working on it" as of 5/21/19. https://github.com/aws/containers-roadmap/issues/130 – wmute Jun 06 '19 at 22:16
  • Thank you very much. But, i didn't see any documentation related to blue green deployment example. – Gokula Adabala Jun 08 '19 at 05:05
  • Any updates on this feature from AWS team? – kk. Jun 18 '19 at 16:20
  • No, I am waiting for that update only since long. – Gokula Adabala Jun 19 '19 at 06:40
  • https://github.com/aws-cloudformation/aws-cloudformation-coverage-roadmap/issues/37 – Pat Myron Sep 15 '19 at 01:26

2 Answers2

5

Support for blue/green deployment in CloudFormation has been added. It can be found here in the documentation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-service-deploymentcontroller.html

In the "Type" property you can choose "CODE_DEPLOY" as the deployment type. Hope this helps!

Nora
  • 1,825
  • 8
  • 31
  • 47
0

Currently cloudformation does not support the DeploymentController parameter in which you can specify CODE_DEPLOY. Keep yourself update by visiting this page for documentation updates: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html

For now - use custom cloudformation resource. Use Boto3 library to create the service with CODE_DEPLOY setting. Read more here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.create_service

This is the python class which can create/delete/upadte ecs:

import boto3

from botocore.exceptions import ClientError
from typing import Any, Dict

client = boto3.client('ecs')


class Service:
    @staticmethod
    def create(**kwargs) -> Dict[str, Any]:
        kwargs = dict(
            cluster=kwargs.get('cluster'),
            serviceName=kwargs.get('serviceName'),
            taskDefinition=kwargs.get('taskDefinition'),
            loadBalancers=kwargs.get('loadBalancers'),
            serviceRegistries=kwargs.get('serviceRegistries'),
            desiredCount=kwargs.get('desiredCount'),
            clientToken=kwargs.get('clientToken'),
            launchType=kwargs.get('launchType'),
            platformVersion=kwargs.get('platformVersion'),
            role=kwargs.get('role'),
            deploymentConfiguration=kwargs.get('deploymentConfiguration'),
            placementConstraints=kwargs.get('placementConstraints'),
            placementStrategy=kwargs.get('placementStrategy'),
            networkConfiguration=kwargs.get('networkConfiguration'),
            healthCheckGracePeriodSeconds=kwargs.get('healthCheckGracePeriodSeconds'),
            schedulingStrategy=kwargs.get('schedulingStrategy'),
            deploymentController=kwargs.get('deploymentController'),
            tags=kwargs.get('tags'),
            enableECSManagedTags=kwargs.get('enableECSManagedTags'),
            propagateTags=kwargs.get('propagateTags'),
        )

        kwargs = {key: value for key, value in kwargs.items() if key and value}
        return client.create_service(**kwargs)

    @staticmethod
    def update(**kwargs: Dict[str, Any]) -> Dict[str, Any]:
        filtered_kwargs = dict(
            cluster=kwargs.get('cluster'),
            service=kwargs.get('serviceName'),
            desiredCount=kwargs.get('desiredCount'),
            taskDefinition=kwargs.get('taskDefinition'),
            deploymentConfiguration=kwargs.get('deploymentConfiguration'),
            networkConfiguration=kwargs.get('networkConfiguration'),
            platformVersion=kwargs.get('platformVersion'),
            forceNewDeployment=kwargs.get('forceNewDeployment'),
            healthCheckGracePeriodSeconds=kwargs.get('healthCheckGracePeriodSeconds')
        )

        try:
            filtered_kwargs = {key: value for key, value in filtered_kwargs.items() if key and value}
            return client.update_service(**filtered_kwargs)
        except ClientError as ex:
            if ex.response['Error']['Code'] == 'InvalidParameterException':
                if 'use aws codedeploy' in ex.response['Error']['Message'].lower():
                    # For services using the blue/green (CODE_DEPLOY ) deployment controller,
                    # only the desired count, deployment configuration, and health check grace period
                    # can be updated using this API. If the network configuration, platform version, or task definition
                    # need to be updated, a new AWS CodeDeploy deployment should be created.
                    filtered_kwargs = dict(
                        cluster=kwargs.get('cluster'),
                        service=kwargs.get('serviceName'),
                        desiredCount=kwargs.get('desiredCount'),
                        deploymentConfiguration=kwargs.get('deploymentConfiguration'),
                        healthCheckGracePeriodSeconds=kwargs.get('healthCheckGracePeriodSeconds'),
                    )

                    filtered_kwargs = {key: value for key, value in filtered_kwargs.items() if key and value}
                    return client.update_service(**filtered_kwargs)
            elif ex.response['Error']['Code'] == 'ServiceNotActiveException':
                # We can not update ecs service if it is inactive.
                return {'Code': 'ServiceNotActiveException'}
            elif ex.response['Error']['Code'] == 'ServiceNotFoundException':
                # If for some reason service was not found - don't update and return.
                return {'Code': 'ServiceNotFoundException'}
            raise

    @staticmethod
    def delete(**kwargs: Dict[str, Any]) -> Dict[str, Any]:
        kwargs = dict(
            cluster=kwargs.get('cluster'),
            service=kwargs.get('serviceName'),
            force=True
        )

        kwargs = {key: value for key, value in kwargs.items() if key and value}
        return client.delete_service(**kwargs)
Laimonas Sutkus
  • 3,247
  • 2
  • 26
  • 47
  • 2
    CFN has added support for the CODE_DEPLOY DeploymentController type: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-service-deploymentcontroller.html – Boris Dec 22 '19 at 04:38