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
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')
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'))
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)
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] ) )
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")))
} ] } ) ] ) ) 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(
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))))
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))))
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")