Ejemplo n.º 1
0
 def __init__(
     self,
     name,
     priority, # ALB target group's priority
     imports_format, # format of your exports, like "mycorp-prod-%s"
     domains = None,
     public=False,
     memory=512,
     port=8080,
     desired_count=1,
     deployment_configuration = ecs.DeploymentConfiguration(MinimumHealthyPercent=100, MaximumPercent=200),
     healthcheck_path = "/health",
     healthcheck_interval = 10,
     container_name = None,
     envs = {},
     resource_name_format='%s', # Useful if you want to have multiple services in a single infrastructure file
     docker_image=Ref('DockerImage'),
     logs_datetime_format='%Y-%m-%d %H:%M:%S',
 ):
     self.name = name
     self.priority = priority
     self.domains = domains if domains is not None else ["%s.*" %(name)]
     self.public = public
     self.memory = memory
     self.port = port
     self.desired_count = desired_count
     self.deployment_configuration = deployment_configuration
     self.healthcheck_path = healthcheck_path
     self.healthcheck_interval = healthcheck_interval
     self.container_name = container_name if container_name is not None else name
     self.envs = envs
     self.resource_name_format = resource_name_format
     self.imports_format = imports_format
     self.docker_image = docker_image
     self.logs_datetime_format = logs_datetime_format
Ejemplo n.º 2
0
    def __init__(self, title, scheme, **kwargs):
        super().__init__(title, **kwargs)

        self.Cluster = get_expvalue('Cluster', 'ClusterStack')

        # DAEMON MODE DO NOT SUPPORT DESIRED OR PLACEMENT STRATEGIES,
        # IS SIMPLY ONE TASK FOR CONTAINER INSTANCE
        if cfg.SchedulingStrategy == 'REPLICA':
            self.DesiredCount = get_endvalue('CapacityDesired')
            self.DeploymentConfiguration = ecs.DeploymentConfiguration(
                MaximumPercent=get_endvalue(
                    'DeploymentConfigurationMaximumPercent'),
                MinimumHealthyPercent=get_endvalue(
                    'DeploymentConfigurationMinimumHealthyPercent'),
            )
            self.PlacementStrategies = If(
                'LaunchTypeFarGate',
                Ref('AWS::NoValue'),
                [
                    # ecs.PlacementStrategy(
                    #    Type='spread',
                    #    Field='attribute:ecs.availability-zone'
                    # ),
                    ecs.PlacementStrategy(
                        Type='spread',
                        Field='instanceId'
                    )
                ]
            )
        elif cfg.SchedulingStrategy == 'DAEMON':
            self.SchedulingStrategy = 'DAEMON'

        self.LaunchType = get_endvalue('LaunchType')

        if cfg.HealthCheckGracePeriodSeconds != 0:
            self.HealthCheckGracePeriodSeconds = (
                get_endvalue('HealthCheckGracePeriodSeconds'))

        # self.PlatformVersion = 'LATEST'

        if cfg.LoadBalancerApplication:
            self.LoadBalancers = []
            self.Role = If(
                'NetworkModeAwsVpc',
                Ref('AWS::NoValue'),
                get_expvalue('RoleECSService')
            )
            # When creating a service that specifies multiple target groups,
            # the Amazon ECS service-linked role must be created.
            # The role is created by omitting the Role property
            # in AWS CloudFormation
            if (cfg.LoadBalancerApplicationExternal and
                    cfg.LoadBalancerApplicationInternal):
                self.Role = Ref('AWS::NoValue')

        self.TaskDefinition = Ref('TaskDefinition')
Ejemplo n.º 3
0
def create_scheduler_service_resource(template, ecs_cluster_resource,
                                      scheduler_task_definition_resource,
                                      scheduler_task_count_parameter):
    return template.add_resource(
        ecs.Service('SchedulerService',
                    ServiceName='scheduler',
                    Cluster=Ref(ecs_cluster_resource),
                    TaskDefinition=Ref(scheduler_task_definition_resource),
                    DeploymentConfiguration=ecs.DeploymentConfiguration(
                        MinimumHealthyPercent=0, MaximumPercent=100),
                    DesiredCount=Ref(scheduler_task_count_parameter),
                    LaunchType='EC2'))
Ejemplo n.º 4
0
    def gen_service(self):
        load_balancer = ecs.LoadBalancer(
            ContainerName=self.service_name,
            ContainerPort=80,
            TargetGroupArn=Ref(self.target_group),
        )

        # We put this service in public subnets because for demo purposes,
        # we only created public subnets. In a real application, you would
        # almost certainly put this in a private subnet.
        network_configuration = ecs.NetworkConfiguration(
            AwsvpcConfiguration=ecs.AwsvpcConfiguration(
                AssignPublicIp="ENABLED",
                Subnets=[
                    self.import_value("vpc", "PublicSubnet0"),
                    self.import_value("vpc", "PublicSubnet1"),
                ],
                SecurityGroups=[
                    self.import_value("load-balancer",
                                      "WebAppMembershipSecurityGroup"),
                    self.import_value("load-balancer", "WebAppSecurityGroup"),
                ],
            ))

        self.service = ecs.Service(
            "Service",
            ServiceName=self.service_name,
            Cluster=Ref(self.cluster),
            DeploymentConfiguration=ecs.DeploymentConfiguration(
                MinimumHealthyPercent=100, MaximumPercent=200),
            DesiredCount=1,
            LaunchType="FARGATE",
            LoadBalancers=[load_balancer],
            NetworkConfiguration=network_configuration,
            SchedulingStrategy="REPLICA",
            TaskDefinition=Ref(self.task_definition),
        )
        self.template.add_resource(self.service)
Ejemplo n.º 5
0
def create_api_service_resource(template, ecs_cluster_resource, api_task_definition_resource, api_task_count_parameter,
                                api_tarcreate_group_resource, ecs_service_role_resource, load_balancer_listener_resource):
    return template.add_resource(
        ecs.Service(
            'ApiService',
            ServiceName='api',
            Cluster=Ref(ecs_cluster_resource),
            TaskDefinition=Ref(api_task_definition_resource),
            DeploymentConfiguration=ecs.DeploymentConfiguration(
                MinimumHealthyPercent=100,
                MaximumPercent=200
            ),
            DesiredCount=Ref(api_task_count_parameter),
            LaunchType='EC2',
            LoadBalancers=[ecs.LoadBalancer(
                ContainerName='api',
                ContainerPort=80,
                TargetGroupArn=Ref(api_tarcreate_group_resource)
            )],
            Role=Ref(ecs_service_role_resource),
            DependsOn=[load_balancer_listener_resource]
        )
    )
Ejemplo n.º 6
0
    def create_ecs_resources(self):
        t = self.template

        # Give the instances access that the Empire daemon needs.
        t.add_resource(
            PolicyType(
                "AccessPolicy",
                PolicyName="empire",
                PolicyDocument=empire_policy({
                    "Environment":
                    Ref("Environment"),
                    "CustomResourcesTopic":
                    Ref("CustomResourcesTopic"),
                    "CustomResourcesQueue": (GetAtt("CustomResourcesQueue",
                                                    "Arn")),
                    "TemplateBucket":
                    (Join("", ["arn:aws:s3:::",
                               Ref("TemplateBucket"), "/*"]))
                }),
                Roles=[Ref("InstanceRole")]))

        t.add_resource(
            sns.Topic(
                EVENTS_TOPIC,
                DisplayName="Empire events",
                Condition="CreateSNSTopic",
            ))
        t.add_output(
            Output("EventsSNSTopic",
                   Value=Ref(EVENTS_TOPIC),
                   Condition="CreateSNSTopic"))

        # Add SNS Events policy if Events are enabled
        t.add_resource(
            PolicyType("SNSEventsPolicy",
                       PolicyName="EmpireSNSEventsPolicy",
                       Condition="EnableSNSEvents",
                       PolicyDocument=sns_events_policy(
                           If("CreateSNSTopic", Ref(EVENTS_TOPIC),
                              Ref("EventsSNSTopicName"))),
                       Roles=[Ref("InstanceRole")]))

        # Add run logs policy if run logs are enabled
        t.add_resource(
            PolicyType("RunLogsPolicy",
                       PolicyName="EmpireRunLogsPolicy",
                       Condition="EnableCloudwatchLogs",
                       PolicyDocument=runlogs_policy(
                           If("CreateRunLogsGroup", Ref(RUN_LOGS),
                              Ref("RunLogsCloudwatchGroup"))),
                       Roles=[Ref("InstanceRole")]))

        # Allow the controller to write empire events to kinesis if kinesis is
        # enabled.
        t.add_resource(
            PolicyType("AppEventStreamPolicy",
                       PolicyName="EmpireAppEventStreamPolicy",
                       Condition="EnableAppEventStream",
                       PolicyDocument=logstream_policy(),
                       Roles=[Ref("InstanceRole")]))

        t.add_resource(
            ecs.TaskDefinition(
                "TaskDefinition",
                Volumes=[
                    ecs.Volume(
                        Name="dockerSocket",
                        Host=ecs.Host(SourcePath="/var/run/docker.sock")),
                    ecs.Volume(Name="dockerCfg",
                               Host=ecs.Host(SourcePath="/root/.dockercfg"))
                ],
                ContainerDefinitions=[
                    ecs.ContainerDefinition(
                        Command=["server", "-automigrate=true"],
                        Name="empire",
                        Environment=self.get_empire_environment(),
                        Essential=True,
                        Image=Ref("DockerImage"),
                        MountPoints=[
                            ecs.MountPoint(
                                SourceVolume="dockerSocket",
                                ContainerPath="/var/run/docker.sock",
                                ReadOnly=False),
                            ecs.MountPoint(SourceVolume="dockerCfg",
                                           ContainerPath="/root/.dockercfg",
                                           ReadOnly=False)
                        ],
                        PortMappings=[
                            ecs.PortMapping(HostPort=8081, ContainerPort=8081)
                        ],
                        Cpu=Ref("TaskCPU"),
                        Memory=Ref("TaskMemory"))
                ]))

        t.add_resource(
            Role("ServiceRole",
                 AssumeRolePolicyDocument=get_ecs_assumerole_policy(),
                 Path="/",
                 Policies=[
                     Policy(PolicyName="ecs-service-role",
                            PolicyDocument=service_role_policy())
                 ]))

        t.add_resource(
            ecs.Service(
                "Service",
                Cluster=Ref("ControllerCluster"),
                DeploymentConfiguration=ecs.DeploymentConfiguration(
                    MaximumPercent=Ref("ServiceMaximumPercent"),
                    MinimumHealthyPercent=Ref("ServiceMinimumHealthyPercent"),
                ),
                DesiredCount=Ref("DesiredCount"),
                LoadBalancers=[
                    ecs.LoadBalancer(ContainerName="empire",
                                     ContainerPort=8081,
                                     LoadBalancerName=Ref("LoadBalancer"))
                ],
                Role=Ref("ServiceRole"),
                TaskDefinition=Ref("TaskDefinition")))
Ejemplo n.º 7
0
                        }
                    ]
                }
            )
        ]
    )
)

api_service = template.add_resource(
    ecs.Service(
        'ApiService',
        ServiceName='api',
        Cluster=Ref(ecs_cluster),
        TaskDefinition=Ref(api_task_definition),
        DeploymentConfiguration=ecs.DeploymentConfiguration(
            MinimumHealthyPercent=100,
            MaximumPercent=200
        ),
        DesiredCount=Ref(api_task_count),
        LaunchType='EC2',
        LoadBalancers=[ecs.LoadBalancer(
            ContainerName='api',
            ContainerPort=80,
            TargetGroupArn=Ref(api_target_group)
        )],
        Role=Ref(ecs_service_role),
        DependsOn=[load_balancer_listener]
    )
)

queue_worker_service = template.add_resource(
    ecs.Service(
Ejemplo n.º 8
0
    def add_resources(self):
        """Add resources to template."""
        class EcsServiceWithHealthCheckGracePeriodSeconds(ecs.Service):
            """ECS Service class with HealthCheckGracePeriodSeconds added."""

            props = ecs.Service.props
            props['HealthCheckGracePeriodSeconds'] = (positive_integer, False)

        pkg_version = pkg_resources.get_distribution('troposphere').version
        if LooseVersion(pkg_version) < LooseVersion('2.1.3'):
            ecs_service = EcsServiceWithHealthCheckGracePeriodSeconds
        else:
            ecs_service = ecs.Service

        template = self.template
        variables = self.get_variables()

        ecstaskrole = template.add_resource(
            iam.Role('EcsTaskRole',
                     AssumeRolePolicyDocument=get_ecs_task_assumerole_policy(),
                     RoleName=variables['EcsTaskRoleName'].ref))

        loggroup = template.add_resource(
            logs.LogGroup(
                'CloudWatchLogGroup',
                LogGroupName=Join('', [
                    '/ecs/', variables['ContainerName'].ref, '-',
                    variables['EnvironmentName'].ref
                ]),
                RetentionInDays=variables['EcsCloudWatchLogRetention'].ref))

        ecscontainerdef = ecs.ContainerDefinition(
            Image=Join('', [
                Ref('AWS::AccountId'), '.dkr.ecr.',
                Ref('AWS::Region'), '.amazonaws.com/',
                variables['ContainerName'].ref, '-',
                variables['EnvironmentName'].ref
            ]),
            LogConfiguration=ecs.LogConfiguration(LogDriver='awslogs',
                                                  Options={
                                                      'awslogs-group':
                                                      Ref(loggroup),
                                                      'awslogs-region':
                                                      Ref('AWS::Region'),
                                                      'awslogs-stream-prefix':
                                                      'ecs'
                                                  }),
            Name=Join('-', [
                variables['ContainerName'].ref,
                variables['EnvironmentName'].ref
            ]),
            PortMappings=[
                ecs.PortMapping(ContainerPort=variables['ContainerPort'].ref)
            ])

        ecstaskdef = template.add_resource(
            ecs.TaskDefinition(
                'EcsTaskDef',
                ContainerDefinitions=[ecscontainerdef],
                Cpu=variables['TaskCpu'].ref,
                Memory=variables['TaskMem'].ref,
                ExecutionRoleArn=variables['EcsTaskExecIamRoleArn'].ref,
                TaskRoleArn=Ref(ecstaskrole),
                Family=Join('-', [
                    variables['ContainerName'].ref,
                    variables['EnvironmentName'].ref
                ]),
                NetworkMode='awsvpc',
                RequiresCompatibilities=['FARGATE']))

        ecscluster = template.add_resource(
            ecs.Cluster('EcsCluster',
                        ClusterName=Join('-', [
                            variables['ContainerName'].ref,
                            variables['EnvironmentName'].ref
                        ])))

        ecsservice = template.add_resource(
            ecs_service(
                'EcsService',
                Cluster=Join('-', [
                    variables['ContainerName'].ref,
                    variables['EnvironmentName'].ref
                ]),
                DeploymentConfiguration=ecs.DeploymentConfiguration(
                    MinimumHealthyPercent=variables['MinHealthyPercent'].ref,
                    MaximumPercent=variables['MaxPercent'].ref),
                DesiredCount=variables['NumberOfTasks'].ref,
                HealthCheckGracePeriodSeconds=variables[
                    'HealthCheckGracePeriod'].ref,
                LaunchType='FARGATE',
                LoadBalancers=[
                    ecs.LoadBalancer(
                        ContainerName=Join('-', [
                            variables['ContainerName'].ref,
                            variables['EnvironmentName'].ref
                        ]),
                        ContainerPort=variables['ContainerPort'].ref,
                        TargetGroupArn=variables['TargetGroupArn'].ref)
                ],
                NetworkConfiguration=ecs.NetworkConfiguration(
                    AwsvpcConfiguration=ecs.AwsvpcConfiguration(
                        SecurityGroups=variables['SgIdList'].ref,
                        Subnets=variables['Subnets'].ref)),
                ServiceName=Join('-', [
                    variables['ContainerName'].ref,
                    variables['EnvironmentName'].ref
                ]),
                TaskDefinition=Ref(ecstaskdef)))

        template.add_output(
            Output("{}Arn".format(ecstaskrole.title),
                   Description="ECS Task Role ARN",
                   Value=GetAtt(ecstaskrole, "Arn"),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % ecstaskrole.title))))

        template.add_output(
            Output("{}Name".format(ecstaskrole.title),
                   Description="ECS Task Role Name",
                   Value=Ref(ecstaskrole)))

        template.add_output(
            Output("{}Arn".format(ecsservice.title),
                   Description="ARN of the ECS Service",
                   Value=Ref(ecsservice),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % ecsservice.title))))

        template.add_output(
            Output("{}Name".format(ecsservice.title),
                   Description="Name of the ECS Service",
                   Value=GetAtt(ecsservice, "Name"),
                   Export=Export(
                       Sub('${AWS::StackName}-%sName' % ecsservice.title))))

        template.add_output(
            Output("{}Arn".format(ecscluster.title),
                   Description="ECS Cluster ARN",
                   Value=GetAtt(ecscluster, "Arn"),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % ecscluster.title))))

        template.add_output(
            Output("{}Arn".format(ecstaskdef.title),
                   Description="ARN of the Task Definition",
                   Value=Ref(ecstaskdef),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % ecstaskdef.title))))
Ejemplo n.º 9
0
    def add_resources(self):
        """Add resources to template."""
        class EcsServiceWithHealthCheckGracePeriodSeconds(ecs.Service):
            """ECS Service class with HealthCheckGracePeriodSeconds added."""

            props = ecs.Service.props
            props['HealthCheckGracePeriodSeconds'] = (positive_integer, False)

        pkg_version = pkg_resources.get_distribution('troposphere').version
        if LooseVersion(pkg_version) < LooseVersion('2.1.3'):
            ecs_service = EcsServiceWithHealthCheckGracePeriodSeconds
        else:
            ecs_service = ecs.Service

        template = self.template
        variables = self.get_variables()

        ecsservice = template.add_resource(
            ecs_service(
                'EcsService',
                ServiceName=Join('-', [
                    variables['ContainerName'].ref,
                    variables['EnvironmentName'].ref
                ]),
                Cluster=variables['ClusterArn'].ref,
                DeploymentConfiguration=ecs.DeploymentConfiguration(
                    MinimumHealthyPercent=variables['MinHealthyPercent'].ref,
                    MaximumPercent=variables['MaxPercent'].ref),
                DesiredCount=variables['NumberOfTasks'].ref,
                HealthCheckGracePeriodSeconds=variables[
                    'HealthCheckGracePeriod'].ref,
                LaunchType=variables['LaunchType'].ref,
                # TODO: put an IF function or conditional here
                LoadBalancers=[
                    ecs.LoadBalancer(
                        #ContainerName=Join('-', [
                        #    variables['ContainerName'].ref,
                        #    variables['EnvironmentName'].ref
                        #]),
                        ContainerName=variables['ContainerName'].ref,
                        ContainerPort=variables['ContainerPort'].ref,
                        TargetGroupArn=variables['TargetGroupArn'].ref)
                ],
                # NetworkConfiguration needed for 'awsvpc' network mode
                # TODO: add an 'IF' CF function or Conditional
                #NetworkConfiguration=ecs.NetworkConfiguration(
                #    AwsvpcConfiguration=ecs.AwsvpcConfiguration(
                #        SecurityGroups=variables['SgIdList'].ref,
                #        Subnets=variables['Subnets'].ref
                #    )
                #),
                TaskDefinition=variables['TaskDefinitionArn'].ref,
            ))

        template.add_output(
            Output("{}Arn".format(ecsservice.title),
                   Description="ARN of the ECS Service",
                   Value=Ref(ecsservice),
                   Export=Export(
                       Sub('${AWS::StackName}-%sArn' % ecsservice.title))))

        template.add_output(
            Output("{}Name".format(ecsservice.title),
                   Description="Name of the ECS Service",
                   Value=GetAtt(ecsservice, "Name"),
                   Export=Export(
                       Sub('${AWS::StackName}-%sName' % ecsservice.title))))
Ejemplo n.º 10
0
        Cluster=ImportValue(Sub("${EcsStack}-Cluster")),
        DependsOn=service_role,
        DesiredCount=Ref(autoscaling_min),
        LoadBalancers=[
            ecs.LoadBalancer(ContainerName=Ref(container_name),
                             ContainerPort=Ref(container_port),
                             TargetGroupArn=Ref(target_group)),
        ],
        PlacementStrategies=[
            ecs.PlacementStrategy(Type="spread",
                                  Field="attribute:ecs.availability-zone"),
            ecs.PlacementStrategy(Type="binpack", Field="memory"),
        ],
        Role=Ref(service_role),
        TaskDefinition=Ref(task_definition),
        DeploymentConfiguration=ecs.DeploymentConfiguration(
            MaximumPercent="100", MinimumHealthyPercent="50"),
        PlacementConstraints=[
            ecs.PlacementConstraint(Type="distinctInstance")
        ],
    ))
"""
Make the service a ScalableTarget
"""
# scalable_target = t.add_resource(applicationautoscaling.ScalableTarget(
#     'ScalableTarget',
#     MaxCapacity=Ref(autoscaling_max),
#     MinCapacity=Ref(autoscaling_min),
#     ResourceId=Join("/", [
#         "service",
#         ImportValue(Sub("${EcsStack}-Cluster")),
#         GetAtt(service, "Name")