コード例 #1
0
    def create_template(self):
        t = self.template

        cluster = t.add_resource(ecs.Cluster("Cluster"))

        t.add_output(Output("ClusterId", Value=cluster.Ref()))
        t.add_output(Output("ClusterArn", Value=cluster.GetAtt("Arn")))
コード例 #2
0
    def __init__(self, key):
        # Resources
        R_Cluster = ecs.Cluster('Cluster')

        add_obj([
            R_Cluster,
        ])
コード例 #3
0
ファイル: cluster.py プロジェクト: AdaCore/e3-aws
    def resources(self, stack: Stack) -> list[AWSObject]:
        """Construct and return ECS cluster troposphere resources."""
        c_settings = None
        if self.cluster_settings:
            c_settings = [
                ecs.ClusterSetting(**cs) for cs in self.cluster_settings
            ]

        provider_strategy = None
        if self.default_capacity_provider_strategy:
            provider_strategy = [
                ecs.CapacityProviderStrategyItem(**ps)
                for ps in self.default_capacity_provider_strategy
            ]

        kwargs = {
            key: val
            for key, val in {
                "ClusterName": self.name,
                "ClusterSettings": c_settings,
                "CapacityProviders": self.capacity_providers,
                "DefaultCapacityProviderStrategy": provider_strategy,
                "Tags": Tags({
                    "Name": self.name,
                    **self.tags
                }),
            }.items() if val is not None
        }

        return [ecs.Cluster(name_to_id(self.name), **kwargs)]
コード例 #4
0
ファイル: ecs.py プロジェクト: ibejohn818/stackformation
    def add_to_template(self, template):

        t = template
        cluster = t.add_resource(ecs.Cluster("{}ECSCluster".format(self.name)))

        if len(self.name) > 0:
            cluster.ClusterName = self.name

        t.add_output([
            Output("{}ECSCluster".format(self.name), Value=Ref(cluster)),
            Output("{}ECSClusterArn".format(self.name),
                   Value=GetAtt(cluster, 'Arn')),
        ])
コード例 #5
0
    def build_hook(self):
        print "Building Template for AWS Frederick ECS"

        hosted_zone_name = self.config.get('hosted_zone')
        ecs_config = self.config.get('ecs')
        if ecs_config is not None:
            cluster = self.add_resource(
                ecs.Cluster('filesharefrederick',
                            ClusterName='filesharefrederick'))
            for ecs in ecs_config:
                self.add_ecs(ecs.get('name'), ecs.get('image'), ecs.get('cpu'),
                             ecs.get('memory'), ecs.get('container_port'),
                             ecs.get('alb_port'), ecs.get('envvars'),
                             self.cidr_range, hosted_zone_name)
コード例 #6
0
    def add_resources(self):
        """Add resources to template."""
        template = self.template
        variables = self.get_variables()

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

        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("{}Name".format(ecscluster.title),
                   Description="ECS Cluster Name",
                   Value=Ref(ecscluster),
                   Export=Export(
                       Sub('${AWS::StackName}-%sName' % ecscluster.title))))
コード例 #7
0
ファイル: test_ecs.py プロジェクト: zetsuchan/troposphere
    def test_allow_ref_cluster(self):
        task_definition = ecs.TaskDefinition(
            "mytaskdef",
            ContainerDefinitions=[
                ecs.ContainerDefinition(
                    Image="myimage",
                    Memory="300",
                    Name="mycontainer",
                )
            ],
            Volumes=[
                ecs.Volume(Name="my-vol"),
            ],
        )
        cluster = ecs.Cluster("mycluster")
        ecs_service = ecs.Service(
            'Service',
            Cluster=Ref(cluster),
            DesiredCount=2,
            TaskDefinition=Ref(task_definition),
        )

        ecs_service.JSONrepr()
コード例 #8
0
 def create_ecs_cluster(self):
     t = self.template
     t.add_resource(ecs.Cluster("EmpireControllerCluster"))
     t.add_output(Output("ECSCluster",
                         Value=Ref("EmpireControllerCluster")))
コード例 #9
0
def main():
    template = Template()

    template.add_resource(
        ecs.Cluster("ECSCluster", ClusterName="WorldCheckCluster"))

    template.add_resource(
        iam.Role("ECSTaskRole",
                 AssumeRolePolicyDocument={
                     "Version":
                     "2012-10-17",
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ecs-tasks.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 }))

    template.add_resource(
        iam.Role(
            "ECSServiceSchedulerRole",
            AssumeRolePolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["ecs.amazonaws.com"]
                    },
                    "Action": ["sts:AssumeRole"]
                }]
            },
            Policies=[
                iam.Policy(PolicyDocument={
                    "Version":
                    "2012-10-17",
                    "Statement": [{
                        "Effect":
                        "Allow",
                        "Action": [
                            "ec2:Describe*",
                            "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                            "elasticloadbalancing:DeregisterTargets",
                            "elasticloadbalancing:Describe*",
                            "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                            "elasticloadbalancing:RegisterTargets"
                        ],
                        "Resource":
                        "*"
                    }]
                },
                           PolicyName="ecs-service")
            ]))

    template.add_resource(
        iam.Role("EC2InstanceRole",
                 AssumeRolePolicyDocument={
                     "Version":
                     "2012-10-17",
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ec2.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 },
                 Policies=[
                     iam.Policy(PolicyDocument={
                         "Version":
                         "2012-10-17",
                         "Statement": [{
                             "Effect":
                             "Allow",
                             "Action": [
                                 "ecs:CreateCluster",
                                 "ecs:DeregisterContainerInstance",
                                 "ecs:DiscoverPollEndpoint", "ecs:Poll",
                                 "ecs:RegisterContainerInstance",
                                 "ecs:StartTelemetrySession",
                                 "ecr:GetAuthorizationToken",
                                 "ecr:BatchGetImage",
                                 "ecr:GetDownloadUrlForLayer", "ecs:Submit*",
                                 "logs:CreateLogStream", "logs:PutLogEvents",
                                 "ec2:DescribeTags", "cloudwatch:PutMetricData"
                             ],
                             "Resource":
                             "*"
                         }]
                     },
                                PolicyName="ecs-service")
                 ]))
    template.add_resource(
        iam.InstanceProfile("EC2InstanceProfile",
                            Roles=[Ref("EC2InstanceRole")]))

    with open("user-data.sh", "r") as f:
        user_data_content = f.readlines()

    template.add_resource(
        ec2.Instance(
            "EC2Instance",
            ImageId="ami-13f7226a",
            InstanceType="t2.micro",
            SecurityGroups=["default"],
            UserData=Base64(Join('', [Sub(x) for x in user_data_content])),
            IamInstanceProfile=Ref("EC2InstanceProfile"),
        ))

    template.add_resource(
        ecs.TaskDefinition(
            "ECSTaskDefinition",
            TaskRoleArn=Ref("ECSTaskRole"),
            ContainerDefinitions=[
                ecs.ContainerDefinition(
                    Name="SimpleServer",
                    Memory="128",
                    Image="abbas123456/simple-server:latest",
                    PortMappings=[ecs.PortMapping(ContainerPort=8000)],
                )
            ]))

    template.add_resource(
        elb.TargetGroup(
            "ECSTargetGroup",
            VpcId="vpc-925497f6",
            Port=8000,
            Protocol="HTTP",
        ))

    template.add_resource(
        elb.LoadBalancer(
            "LoadBalancer",
            Subnets=["subnet-a321c8fb", "subnet-68fa271e", "subnet-689d350c"],
            SecurityGroups=["sg-0202bd65"]))

    template.add_resource(
        elb.Listener(
            "LoadBalancerListener",
            DefaultActions=[
                elb.Action(Type="forward",
                           TargetGroupArn=Ref("ECSTargetGroup"))
            ],
            LoadBalancerArn=Ref("LoadBalancer"),
            Port=80,
            Protocol="HTTP",
        ))

    template.add_resource(
        ecs.Service("ECSService",
                    Cluster=Ref("ECSCluster"),
                    DesiredCount=1,
                    LoadBalancers=[
                        ecs.LoadBalancer(ContainerPort=8000,
                                         ContainerName="SimpleServer",
                                         TargetGroupArn=Ref("ECSTargetGroup"))
                    ],
                    Role=Ref("ECSServiceSchedulerRole"),
                    TaskDefinition=Ref("ECSTaskDefinition"),
                    DependsOn="LoadBalancerListener"))

    return template.to_json()
コード例 #10
0
def create_ecs_cluster_resource(template):
    return template.add_resource(
        ecs.Cluster(
            'ApiCluster'
        )
    )
コード例 #11
0
ファイル: cloudformation.py プロジェクト: BookATest/api
                }
            ]
        }
    )
)

ec2_instance_profile = template.add_resource(
    iam.InstanceProfile(
        'EC2InstanceProfile',
        Roles=[Ref(ecs_cluster_role)]
    )
)

ecs_cluster = template.add_resource(
    ecs.Cluster(
        'ApiCluster'
    )
)

launch_template = template.add_resource(
    ec2.LaunchTemplate(
        'LaunchTemplate',
        LaunchTemplateName=Ref(api_launch_template_name),
        LaunchTemplateData=ec2.LaunchTemplateData(
            ImageId='ami-066826c6a40879d75',
            InstanceType=Ref(api_instance_class),
            IamInstanceProfile=ec2.IamInstanceProfile(
                Arn=GetAtt(ec2_instance_profile, 'Arn')
            ),
            InstanceInitiatedShutdownBehavior='terminate',
            Monitoring=ec2.Monitoring(Enabled=True),
コード例 #12
0
 def create_ecs_cluster(self):
     t = self.template
     t.add_resource(ecs.Cluster("EmpireMinionCluster"))
     t.add_output(
         Output("MinionECSCluster", Value=Ref("EmpireMinionCluster")))
コード例 #13
0
jicketsmtphost = "SETME"

jicketticketaddress = "SETME"

jicketjiraurl = "SETME"
jicketjirauser = "******"
jicketjirapass = "******"
jicketjiraproject = "SETME"

jicketthreadtemplate = "/etc/jicket/threadtemplate.html"

t = Template("Jicket ECS Deployment")

# ECS Cluster
# =============
cluster = ecs.Cluster("JicketCluster")
cluster.ClusterName = "Jicket"

t.add_resource(cluster)

# ECS Task Definition
# =====================
taskdef = ecs.TaskDefinition("JicketTask")

contdef = ecs.ContainerDefinition()
contdef.Cpu = 0
contdef.Environment = [
    ecs.Environment(Name="JICKET_IMAP_HOST", Value=jicketimaphost),
    ecs.Environment(Name="JICKET_JIRA_USER", Value=jicketjirauser),
    ecs.Environment(Name="JICKET_TICKET_ADDRESS", Value=jicketticketaddress),
    ecs.Environment(Name="JICKET_SMTP_HOST", Value=jicketsmtphost),
コード例 #14
0
                 BlockDeviceMappings=[
                     ec2.BlockDeviceMapping(
                         DeviceName='/dev/xvda',
                         Ebs=ec2.EBSBlockDevice(
                             Encrypted=False,
                             VolumeSize=8,
                             SnapshotId='snap-0ed4f88be6558a32a',
                             VolumeType='gp2',
                             DeleteOnTermination=True))
                 ],
                 HibernationOptions={"Configured": False}))

ECSCluster = template.add_resource(
    ecs.Cluster('ECSCluster',
                ClusterName='default',
                ClusterSettings=[{
                    "Name": 'containerInsights',
                    "Value": 'disabled'
                }]))

RDSDBInstance = template.add_resource(
    rds.DBInstance('RDSDBInstance',
                   DBInstanceIdentifier='wcmbpm',
                   AllocatedStorage=20,
                   DBInstanceClass='db.t2.micro',
                   Engine='mysql',
                   MasterUsername='******',
                   MasterUserPassword='******',
                   PreferredBackupWindow='07:30-08:00',
                   BackupRetentionPeriod=7,
                   AvailabilityZone='us-east-2b',
                   PreferredMaintenanceWindow='mon:06:04-mon:06:34',
コード例 #15
0
))

deploy_cloud9 = t.add_parameter(Parameter(
    "DeployCloud9",
    Type="String",
    Description="Whether to deploy Cloud9",
    AllowedValues=["true","false"],
    Default="true"
))

cloud9_condition = t.add_condition("Cloud9Condition", Equals(Ref(deploy_cloud9), "true"))


# Create the ECS Cluster
ECSCluster = t.add_resource(ecs.Cluster(
    "ECSCluster",
    ClusterName="Ghost"
))

# Create the CodeCommit Repo
GhostRepo = t.add_resource(codecommit.Repository(
    "GhostRepo",
    RepositoryName="ghost-ecs-fargate-pipeline"
))

# Create each required stack

init_db_lambda_build = t.add_resource(cloudformation.Stack(
    "InitDBLambdaBuild",
    TemplateURL="https://s3.amazonaws.com/ghost-ecs-fargate-pipeline/init-db-lambda-build.template",
))
コード例 #16
0
 def gen_cluster(self):
     self.cluster = ecs.Cluster("ECSCluster",
                                ClusterName="conducto-demo-cluster")
     self.template.add_resource(self.cluster)
コード例 #17
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))))
コード例 #18
0
    ecs, ec2, elasticloadbalancingv2, logs, iam

t = Template()
t.add_version("2010-09-09")

# Get nginx image parameter
NginxImage = t.add_parameter(Parameter(
    "NginxImage",
    Default="nginx:alpine",
    Description="The nginx container image to run (e.g. nginx:alpine)",
    Type="String"
))

# Create the ECS Cluster
ECSCluster = t.add_resource(ecs.Cluster(
    "ECSCluster",
    ClusterName="Fargate"
))

# Create the VPC
VPC = t.add_resource(ec2.VPC(
    "VPC",
    CidrBlock="10.0.0.0/16",
    EnableDnsSupport="true",
    EnableDnsHostnames="true"
))

PubSubnetAz1 = t.add_resource(ec2.Subnet(
    "PubSubnetAz1",
    CidrBlock="10.0.0.0/24",
    VpcId=Ref(VPC),
    AvailabilityZone=Join("", [Ref('AWS::Region'), "a"]),
コード例 #19
0
def GenerateStepPublisherLayer():
    t = Template()

    t.add_description("""\
    StepScheduler Layer
    """)

    stackname_param = t.add_parameter(
        Parameter(
            "StackName",
            Description="Environment Name (default: hackathon)",
            Type="String",
            Default="hackathon",
        ))

    vpcid_param = t.add_parameter(
        Parameter(
            "VpcId",
            Type="String",
            Description="VpcId of your existing Virtual Private Cloud (VPC)",
            Default="vpc-fab00e9f"))

    subnets = t.add_parameter(
        Parameter(
            "Subnets",
            Type="CommaDelimitedList",
            Description=(
                "The list SubnetIds, for public subnets in the "
                "region and in your Virtual Private Cloud (VPC) - minimum one"
            ),
            Default="subnet-b68f3bef,subnet-9a6208ff,subnet-bfdd4fc8"))

    keypair_param = t.add_parameter(
        Parameter("KeyPair",
                  Description="Name of an existing EC2 KeyPair to enable SSH "
                  "access to the instance",
                  Type="String",
                  Default="glueteam"))

    scheduler_ami_id_param = t.add_parameter(
        Parameter(
            "SchedulerAmiId",
            Description="Scheduler server AMI ID (default: ami-a10897d6)",
            Type="String",
            Default="ami-a10897d6"))

    cluster_ami_id_param = t.add_parameter(
        Parameter("ClusterAmiId",
                  Description="Cluster server AMI ID (default: ami-3db4ca4a)",
                  Type="String",
                  Default="ami-3db4ca4a"))

    iam_role_param = t.add_parameter(
        Parameter(
            "IamRole",
            Description="IAM Role name",
            Type="String",
        ))

    hashkeyname_param = t.add_parameter(
        Parameter(
            "HaskKeyElementName",
            Description="HashType PrimaryKey Name (default: id)",
            Type="String",
            AllowedPattern="[a-zA-Z0-9]*",
            MinLength="1",
            MaxLength="2048",
            ConstraintDescription="must contain only alphanumberic characters",
            Default="id"))

    crontab_tablename_param = t.add_parameter(
        Parameter(
            "CrontabTablename",
            Description="Crontab Table Name",
            Type="String",
        ))

    containerlauncher_param = t.add_parameter(
        Parameter(
            "Containerlauncher",
            Description=
            "Container Launcher zip file (default: containerLauncher-1.0.zip)",
            Type="String",
            Default="containerLauncher-1.0.zip"))

    zipfileversion_param = t.add_parameter(
        Parameter(
            "ZipfileVersion",
            Description="Container Launcher zip file version",
            Type="String",
        ))

    # --------- Lambda Container Launcher

    lambda_function = t.add_resource(
        Function(
            "containerLauncher",
            Code=Code(
                S3Bucket="hackathon-glueteam-lambda",
                S3Key=Ref(containerlauncher_param),
                S3ObjectVersion=Ref(zipfileversion_param),
            ),
            Description=Join('',
                             [Ref(stackname_param), " container Launcher"]),
            MemorySize=256,
            Handler="com.philips.glueteam.DockerLauncher::myHandler",
            Runtime="java8",
            Timeout=60,
            Role=Join('', [
                "arn:aws:iam::",
                Ref("AWS::AccountId"), ":role/",
                Ref(iam_role_param)
            ]),
        ))

    townclock_topic = t.add_resource(
        sns.Topic(
            "TownClock",
            Subscription=[
                sns.Subscription(Endpoint=GetAtt("containerLauncher", "Arn"),
                                 Protocol="lambda"),
            ],
        ))

    # --------- Scheduler instance

    scheduler_sg = t.add_resource(
        ec2.SecurityGroup(
            'SchedulerSG',
            GroupDescription='Security group for Scheduler host',
            VpcId=Ref(vpcid_param),
            Tags=Tags(Name=Join("", [Ref(stackname_param), "SchedulerSG"])),
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="22",
                    ToPort="22",
                    CidrIp="0.0.0.0/0",
                ),
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="8080",
                    ToPort="8080",
                    CidrIp="0.0.0.0/0",
                ),
            ]))

    cluster = t.add_resource(ecs.Cluster("ECSCluster", ))

    scheduler_host = t.add_resource(
        ec2.Instance(
            'SchedulerHost',
            ImageId=Ref(scheduler_ami_id_param),
            InstanceType='t2.micro',
            KeyName=Ref(keypair_param),
            IamInstanceProfile=Ref(iam_role_param),
            NetworkInterfaces=[
                ec2.NetworkInterfaceProperty(
                    AssociatePublicIpAddress=True,
                    SubnetId=Select(0, Ref(subnets)),
                    DeleteOnTermination=True,
                    GroupSet=[
                        Ref(scheduler_sg),
                    ],
                    DeviceIndex=0,
                ),
            ],
            Tags=Tags(Name=Join("", [Ref(stackname_param), "Scheduler"]),
                      Id=Join("", [Ref(stackname_param), "Scheduler"])),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'yum update -y aws-cfn-bootstrap\n',
                    'sns_topic_arn="',
                    Ref(townclock_topic),
                    '"\n',
                    'region="',
                    Ref("AWS::Region"),
                    '"\n',
                    'crontab_tablename="',
                    Ref(crontab_tablename_param),
                    '"\n',
                    'ecs_clustername="',
                    Ref(cluster),
                    '"\n',
                    'publish_source=https://raw.githubusercontent.com/hngkr/hackathon/master/ansible/files/unreliable-town-clock-publish\n',
                    'publish=/usr/local/bin/unreliable-town-clock-publish\n',
                    'curl -s --location --retry 10 -o $publish $publish_source\n',
                    'chmod +x $publish\n',
                    'cat <<EOF >/etc/cron.d/unreliable-town-clock\n',
                    '*/2 * * * * ec2-user $publish "$sns_topic_arn" "$region" "$crontab_tablename" "$ecs_clustername"\n',
                    'EOF\n',
                ])),
        ))

    cluster_sg = t.add_resource(
        ec2.SecurityGroup(
            'ClusterSG',
            GroupDescription='Security group for Cluster host',
            VpcId=Ref(vpcid_param),
            Tags=Tags(Name=Join("", [Ref(stackname_param), "ClusterSG"])),
            SecurityGroupIngress=[
                ec2.SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="22",
                    ToPort="22",
                    CidrIp="0.0.0.0/0",
                ),
            ]))

    cluster_host = t.add_resource(
        ec2.Instance(
            'ClusterHost',
            ImageId=Ref(cluster_ami_id_param),
            InstanceType='t2.micro',
            KeyName=Ref(keypair_param),
            # TODO: Should have multiple separate iam roles for townclock / clusterhost
            IamInstanceProfile=Ref(iam_role_param),
            NetworkInterfaces=[
                ec2.NetworkInterfaceProperty(
                    AssociatePublicIpAddress=True,
                    SubnetId=Select(0, Ref(subnets)),
                    DeleteOnTermination=True,
                    GroupSet=[
                        Ref(cluster_sg),
                    ],
                    DeviceIndex=0,
                ),
            ],
            Tags=Tags(Name=Join("", [Ref(stackname_param), "ClusterNode"]),
                      Id=Join("", [Ref(stackname_param), "ClusterNode"])),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'mkdir /etc/ecs\n',
                    'cat <<EOF >/etc/ecs/ecs.config\n',
                    'ECS_CLUSTER=',
                    Ref(cluster),
                    '\n',
                    'EOF\n',
                ])),
        ))

    # --------- Expected DynamoDB Tables

    dirtylist_table = t.add_resource(
        dynamodb.Table(
            "DirtyList",
            AttributeDefinitions=[
                dynamodb.AttributeDefinition(Ref(hashkeyname_param), "S"),
            ],
            KeySchema=[dynamodb.Key(Ref(hashkeyname_param), "HASH")],
            ProvisionedThroughput=dynamodb.ProvisionedThroughput(1, 1)))

    runlog_table = t.add_resource(
        dynamodb.Table(
            "RunLog",
            AttributeDefinitions=[
                dynamodb.AttributeDefinition(Ref(hashkeyname_param), "S"),
            ],
            KeySchema=[dynamodb.Key(Ref(hashkeyname_param), "HASH")],
            ProvisionedThroughput=dynamodb.ProvisionedThroughput(1, 1)))

    # --------- Outputs
    t.add_output(
        [Output(
            "clusterid",
            Description="Cluster Id",
            Value=Ref(cluster),
        )])

    t.add_output([
        Output(
            "dirtylist",
            Description="DirtyList Tablename",
            Value=Ref(dirtylist_table),
        )
    ])

    t.add_output([
        Output(
            "runlog",
            Description="Runlog Tablename",
            Value=Ref(runlog_table),
        )
    ])

    t.add_output([
        Output(
            "lambdafunctionname",
            Description="Lambda Function Name",
            Value=Ref(lambda_function),
        )
    ])

    t.add_output([
        Output(
            "clocktowertopicarn",
            Description="Clock Tower Topic Arn",
            Value=Ref(townclock_topic),
        )
    ])

    return t