Exemplo n.º 1
0
def define_deployment_options(family, props: dict) -> None:
    """
    Function to define the DeploymentConfiguration
    Default is to have Rollback and CircuitBreaker on.

    :param ecs_composex.ecs.ecs_family.ComposeFamily family:
    :param dict props: the troposphere.ecs.Service properties definition to update with deployment config.
    """
    default = DeploymentConfiguration(
        DeploymentCircuitBreaker=DeploymentCircuitBreaker(Enable=True,
                                                          Rollback=True), )
    deployment_config = set_service_update_config(family)
    if deployment_config:
        deploy_config = DeploymentConfiguration(
            MaximumPercent=int(deployment_config["MaximumPercent"]),
            MinimumHealthyPercent=int(
                deployment_config["MinimumHealthyPercent"]),
            DeploymentCircuitBreaker=DeploymentCircuitBreaker(
                Enable=True,
                Rollback=keyisset("RollBack", deployment_config),
            ),
        )
        props.update({"DeploymentConfiguration": deploy_config})
    else:
        props.update({"DeploymentConfiguration": default})
Exemplo n.º 2
0
 def add_ecs_service(self):
     '''
     Add ECS service
     '''
     self.cfn_template.add_resource(
         Service(
             title=constants.SERVICE,
             Cluster=ImportValue(Sub('${Environment}-CLUSTER')),
             LaunchType='EC2',
             DesiredCount=int('1'),
             TaskDefinition=Ref(constants.TASK),
             Role=Ref(constants.SERVICE_ROLE),
             DeploymentConfiguration=DeploymentConfiguration(
                 MaximumPercent=int('200'),
                 MinimumHealthyPercent=int('100')),
             LoadBalancers=[
                 LoadBalancer(ContainerName='anchore-engine',
                              ContainerPort=int('8228'),
                              TargetGroupArn=ImportValue(
                                  Sub('${Environment}-TARGETGROUP-ARN')))
             ],
             PlacementStrategies=[
                 PlacementStrategy(Type='spread',
                                   Field='attribute:ecs.availability-zone'),
                 PlacementStrategy(Type='spread', Field='instanceId')
             ]))
     return self.cfn_template
Exemplo n.º 3
0
    def ecs_redirect(self, cluster, url):
        self._ecs_redirect = True
        self.template.add_resource(
            TaskDefinition(
                "RedirectTaskDef",
                Volumes=[],
                Family=Sub("${AWS::StackName}-redirect"),
                NetworkMode="bridge",
                ContainerDefinitions=[
                    ContainerDefinition(
                        Name="redirect",
                        Cpu=1,
                        Environment=[Environment(Name="REDIRECT", Value=url)],
                        Essential=True,
                        Hostname=Sub("${AWS::StackName}-redirect"),
                        Image="cusspvz/redirect:0.0.2",
                        Memory=512,
                        MemoryReservation=128,
                        PortMappings=[
                            PortMapping(ContainerPort=80, Protocol="tcp")
                        ])
                ]))

        self.template.add_resource(
            Service("RedirectService",
                    TaskDefinition=Ref("RedirectTaskDef"),
                    Cluster=cluster,
                    DesiredCount=1,
                    DeploymentConfiguration=DeploymentConfiguration(
                        MaximumPercent=200, MinimumHealthyPercent=100),
                    LoadBalancers=[
                        EcsLoadBalancer(
                            ContainerName="redirect",
                            ContainerPort=80,
                            TargetGroupArn=Ref("DefaultTargetGroup"))
                    ]))
    def _add_service(self, service_name, config):
        launch_type = self.LAUNCH_TYPE_FARGATE if 'fargate' in config else self.LAUNCH_TYPE_EC2
        env_config = build_config(
            self.env,
            self.application_name,
            self.env_sample_file_path
        )
        container_definition_arguments = {
            "Environment": [
                Environment(Name=k, Value=v) for (k, v) in env_config
            ],
            "Name": service_name + "Container",
            "Image": self.ecr_image_uri + ':' + self.current_version,
            "Essential": 'true',
            "LogConfiguration": self._gen_log_config(service_name),
            "MemoryReservation": int(config['memory_reservation']),
            "Cpu": 0
        }

        if 'http_interface' in config:
            container_definition_arguments['PortMappings'] = [
                PortMapping(
                    ContainerPort=int(
                        config['http_interface']['container_port']
                    )
                )
            ]

        if config['command'] is not None:
            container_definition_arguments['Command'] = [config['command']]

        cd = ContainerDefinition(**container_definition_arguments)

        task_role = self.template.add_resource(Role(
            service_name + "Role",
            AssumeRolePolicyDocument=PolicyDocument(
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[AssumeRole],
                        Principal=Principal("Service", ["ecs-tasks.amazonaws.com"])
                    )
                ]
            )
        ))

        launch_type_td = {}
        if launch_type == self.LAUNCH_TYPE_FARGATE:
            launch_type_td = {
                'RequiresCompatibilities': ['FARGATE'],
                'ExecutionRoleArn': boto3.resource('iam').Role('ecsTaskExecutionRole').arn,
                'NetworkMode': 'awsvpc',
                'Cpu': str(config['fargate']['cpu']),
                'Memory': str(config['fargate']['memory'])
            }

        td = TaskDefinition(
            service_name + "TaskDefinition",
            Family=service_name + "Family",
            ContainerDefinitions=[cd],
            TaskRoleArn=Ref(task_role),
            **launch_type_td
        )

        self.template.add_resource(td)
        desired_count = self._get_desired_task_count_for_service(service_name)
        deployment_configuration = DeploymentConfiguration(
            MinimumHealthyPercent=100,
            MaximumPercent=200
        )
        if 'http_interface' in config:
            alb, lb, service_listener, alb_sg = self._add_alb(cd, service_name, config, launch_type)

            if launch_type == self.LAUNCH_TYPE_FARGATE:
                # if launch type is ec2, then services inherit the ec2 instance security group
                # otherwise, we need to specify a security group for the service
                service_security_group = SecurityGroup(
                    pascalcase("FargateService" + self.env + service_name),
                    GroupName=pascalcase("FargateService" + self.env + service_name),
                    SecurityGroupIngress=[{
                        'IpProtocol': 'TCP',
                        'SourceSecurityGroupId': Ref(alb_sg),
                        'ToPort': int(config['http_interface']['container_port']),
                        'FromPort': int(config['http_interface']['container_port']),
                    }],
                    VpcId=Ref(self.vpc),
                    GroupDescription=pascalcase("FargateService" + self.env + service_name)
                )
                self.template.add_resource(service_security_group)

                launch_type_svc = {
                    'NetworkConfiguration': NetworkConfiguration(
                        AwsvpcConfiguration=AwsvpcConfiguration(
                            Subnets=[
                                Ref(self.private_subnet1),
                                Ref(self.private_subnet2)
                            ],
                            SecurityGroups=[
                                Ref(service_security_group)
                            ]
                        )
                    )
                }
            else:
                launch_type_svc = {
                    'Role': Ref(self.ecs_service_role),
                    'PlacementStrategies': self.PLACEMENT_STRATEGIES
                }
            svc = Service(
                service_name,
                LoadBalancers=[lb],
                Cluster=self.cluster_name,
                TaskDefinition=Ref(td),
                DesiredCount=desired_count,
                DependsOn=service_listener.title,
                LaunchType=launch_type,
                **launch_type_svc,
            )
            self.template.add_output(
                Output(
                    service_name + 'EcsServiceName',
                    Description='The ECS name which needs to be entered',
                    Value=GetAtt(svc, 'Name')
                )
            )
            self.template.add_output(
                Output(
                    service_name + "URL",
                    Description="The URL at which the service is accessible",
                    Value=Sub("https://${" + alb.name + ".DNSName}")
                )
            )
            self.template.add_resource(svc)
        else:
            launch_type_svc = {}
            if launch_type == self.LAUNCH_TYPE_FARGATE:
                # if launch type is ec2, then services inherit the ec2 instance security group
                # otherwise, we need to specify a security group for the service
                service_security_group = SecurityGroup(
                    pascalcase("FargateService" + self.env + service_name),
                    GroupName=pascalcase("FargateService" + self.env + service_name),
                    SecurityGroupIngress=[],
                    VpcId=Ref(self.vpc),
                    GroupDescription=pascalcase("FargateService" + self.env + service_name)
                )
                self.template.add_resource(service_security_group)
                launch_type_svc = {
                    'NetworkConfiguration': NetworkConfiguration(
                        AwsvpcConfiguration=AwsvpcConfiguration(
                            Subnets=[
                                Ref(self.private_subnet1),
                                Ref(self.private_subnet2)
                            ],
                            SecurityGroups=[
                                Ref(service_security_group)
                            ]
                        )
                    )
                }
            else:
                launch_type_svc = {
                    'PlacementStrategies': self.PLACEMENT_STRATEGIES
                }
            svc = Service(
                service_name,
                Cluster=self.cluster_name,
                TaskDefinition=Ref(td),
                DesiredCount=desired_count,
                DeploymentConfiguration=deployment_configuration,
                LaunchType=launch_type,
                **launch_type_svc
            )
            self.template.add_output(
                Output(
                    service_name + 'EcsServiceName',
                    Description='The ECS name which needs to be entered',
                    Value=GetAtt(svc, 'Name')
                )
            )
            self.template.add_resource(svc)
        self._add_service_alarms(svc)
Exemplo n.º 5
0
    def _add_service(self, service_name, config):
        env_config = build_config(
            self.env,
            self.application_name,
            self.env_sample_file_path
        )
        container_definition_arguments = {
            "Environment": [
                Environment(Name=k, Value=v) for (k, v) in env_config
            ],
            "Name": service_name + "Container",
            "Image": self.ecr_image_uri + ':' + self.current_version,
            "Essential": 'true',
            "LogConfiguration": self._gen_log_config(service_name),
            "MemoryReservation": int(config['memory_reservation']),
            "Cpu": 0
        }

        if 'http_interface' in config:
            container_definition_arguments['PortMappings'] = [
                PortMapping(
                    ContainerPort=int(
                        config['http_interface']['container_port']
                    )
                )
            ]

        if config['command'] is not None:
            container_definition_arguments['Command'] = [config['command']]

        cd = ContainerDefinition(**container_definition_arguments)

        task_role = self.template.add_resource(Role(
            service_name + "Role",
            AssumeRolePolicyDocument=PolicyDocument(
                Statement=[
                    Statement(
                        Effect=Allow,
                        Action=[AssumeRole],
                        Principal=Principal("Service", ["ecs-tasks.amazonaws.com"])
                    )
                ]
            )
        ))

        td = TaskDefinition(
            service_name + "TaskDefinition",
            Family=service_name + "Family",
            ContainerDefinitions=[cd],
            TaskRoleArn=Ref(task_role)
        )
        self.template.add_resource(td)
        desired_count = self._get_desired_task_count_for_service(service_name)
        deployment_configuration = DeploymentConfiguration(
            MinimumHealthyPercent=100,
            MaximumPercent=200
        )
        if 'http_interface' in config:
            alb, lb, service_listener = self._add_alb(cd, service_name, config)
            svc = Service(
                service_name,
                LoadBalancers=[lb],
                Cluster=self.cluster_name,
                Role=Ref(self.ecs_service_role),
                TaskDefinition=Ref(td),
                DesiredCount=desired_count,
                DependsOn=service_listener.title,
                PlacementStrategies=self.PLACEMENT_STRATEGIES
            )
            self.template.add_output(
                Output(
                    service_name + 'EcsServiceName',
                    Description='The ECS name which needs to be entered',
                    Value=GetAtt(svc, 'Name')
                )
            )
            self.template.add_output(
                Output(
                    service_name + "URL",
                    Description="The URL at which the service is accessible",
                    Value=Sub("https://${" + alb.name + ".DNSName}")
                )
            )
            self.template.add_resource(svc)
        else:
            svc = Service(
                service_name,
                Cluster=self.cluster_name,
                TaskDefinition=Ref(td),
                DesiredCount=desired_count,
                DeploymentConfiguration=deployment_configuration,
                PlacementStrategies=self.PLACEMENT_STRATEGIES
            )
            self.template.add_output(
                Output(
                    service_name + 'EcsServiceName',
                    Description='The ECS name which needs to be entered',
                    Value=GetAtt(svc, 'Name')
                )
            )
            self.template.add_resource(svc)
        self._add_service_alarms(svc)
Exemplo n.º 6
0
                        "ec2:Describe*",
                        "ec2:AuthorizeSecurityGroupIngress",
                    ],
                    Resource="*",
                )
            ], ),
        ),
    ])

application_service = Service(
    "ApplicationService",
    template=template,
    Cluster=Ref(cluster),
    Condition=deploy_condition,
    DependsOn=[autoscaling_group_name, application_listener.title],
    DeploymentConfiguration=DeploymentConfiguration(
        MaximumPercent=135,
        MinimumHealthyPercent=30,
    ),
    DesiredCount=web_worker_desired_count,
    LoadBalancers=[
        LoadBalancer(
            ContainerName="WebWorker",
            ContainerPort=web_worker_port,
            TargetGroupArn=Ref(application_target_group),
        )
    ],
    TaskDefinition=Ref(web_task_definition),
    Role=Ref(application_service_role),
)
Exemplo n.º 7
0
        task.ContainerDefinitions.append(definition)
    t.add_resource(task)

    if schedule:
        target = Target(
            Id="{}-Schedule".format(name),
            Arn=GetAtt(netkan_ecs, 'Arn'),
            RoleArn=GetAtt(netkan_scheduler_role, 'Arn'),
            EcsParameters=EcsParameters(TaskDefinitionArn=Ref(task)))
        t.add_resource(
            Rule(
                '{}Rule'.format(name),
                Description='{} scheduled task'.format(name),
                ScheduleExpression=schedule,
                Targets=[target],
            ))
        continue

    t.add_resource(
        Service(
            '{}Service'.format(name),
            Cluster='NetKANCluster',
            DesiredCount=1,
            TaskDefinition=Ref(task),
            # Allow for in place service redeployments
            DeploymentConfiguration=DeploymentConfiguration(
                MaximumPercent=100, MinimumHealthyPercent=0),
            DependsOn=['NetKANCluster']))

print(t.to_yaml())
Exemplo n.º 8
0
                   Memory="1024",
                   NetworkMode="awsvpc",
                   RequiresCompatibilities=["FARGATE"]))

### ECS Service ###

resources["HelloWorldECSService"] = template.add_resource(
    Service(
        "HelloWorldECSService",
        DependsOn=[
            resource for resource in
            ["ALBHTTPlistener", "HelloWorldTaskDef", "HelloWorldECSCluster"]
        ],
        Cluster=GetAtt(template.resources["HelloWorldECSCluster"], "Arn"),
        DeploymentConfiguration=DeploymentConfiguration(
            "HelloWorldECSDeployConf",
            MaximumPercent=100,
            MinimumHealthyPercent=0),
        DesiredCount=1,
        HealthCheckGracePeriodSeconds=300,
        LaunchType="FARGATE",
        LoadBalancers=[
            LoadBalancer(
                "HelloWorldECSServiceLB",
                ContainerName="hello-world-web",
                ContainerPort=80,
                TargetGroupArn=Ref(resources["ALBTargetGroup"]),
            )
        ],
        NetworkConfiguration=NetworkConfiguration(
            "HelloWorldNetConf",
            AwsvpcConfiguration=AwsvpcConfiguration(