Esempio n. 1
0
def define_cluster(root_stack, cluster_def):
    """
    Function to create the cluster from provided properties.

    :param dict cluster_def:
    :param ecs_composex.common.stacks.ComposeXStack root_stack:
    :return: cluster
    :rtype: troposphere.ecs.Cluster
    """
    cluster_params = {}
    if not keyisset("Properties", cluster_def):
        return get_default_cluster_config()
    props = cluster_def["Properties"]
    if keyisset("ClusterName", props):
        root_stack.Parameters.update({CLUSTER_NAME_T: props["ClusterName"]})
    if not keyisset("CapacityProviders", props):
        LOG.warning("No capacity providers defined. Setting it to default.")
        cluster_params["CapacityProviders"] = DEFAULT_PROVIDERS
    else:
        cluster_params["CapacityProviders"] = props["CapacityProviders"]
    if not keyisset("DefaultCapacityProviderStrategy", props):
        LOG.warning("No Default Strategy set. Setting to default.")
        cluster_params["DefaultCapacityProviderStrategy"] = DEFAULT_STRATEGY
    else:
        cluster_params[
            "DefaultCapacityProviderStrategy"] = import_capacity_strategy(
                props["DefaultCapacityProviderStrategy"])
    cluster_params["Metadata"] = metadata
    cluster_params["ClusterName"] = If(GENERATED_CLUSTER_NAME_CON_T,
                                       Ref(AWS_STACK_NAME),
                                       Ref(CLUSTER_NAME_T))
    cluster = Cluster(CLUSTER_T, **cluster_params)
    return cluster
Esempio n. 2
0
    def set_default_cluster_config(self, root_stack):
        """
        Function to get the default defined ECS Cluster configuration

        :return: cluster
        :rtype: troposphere.ecs.Cluster
        """
        self.log_group = LogGroup(
            "EcsExecLogGroup",
            LogGroupName=Sub(f"ecs/execute-logs/${{{AWS_STACK_NAME}}}"),
            RetentionInDays=120,
        )
        self.cfn_resource = Cluster(
            CLUSTER_T,
            ClusterName=Ref(AWS_STACK_NAME),
            CapacityProviders=FARGATE_PROVIDERS,
            DefaultCapacityProviderStrategy=DEFAULT_STRATEGY,
            Configuration=ClusterConfiguration(
                ExecuteCommandConfiguration=ExecuteCommandConfiguration(
                    Logging="OVERRIDE",
                    LogConfiguration=ExecuteCommandLogConfiguration(
                        CloudWatchLogGroupName=Ref(self.log_group), ),
                )),
            Metadata=metadata,
        )
        root_stack.stack_template.add_resource(self.log_group)
        root_stack.stack_template.add_resource(self.cfn_resource)
        self.capacity_providers = FARGATE_PROVIDERS
        self.default_strategy_providers = [
            cap.CapacityProvider for cap in DEFAULT_STRATEGY
        ]
        self.cluster_identifier = Ref(self.cfn_resource)
 def add_ecs_cluster(self):
     '''
     Add ECS cluster
     '''
     self.cfn_template.add_resource(
         Cluster(title=constants.CLUSTER)
     )
     return self.cfn_template
 def _add_cluster(self):
     cluster = Cluster(
         'Cluster',
         ClusterName=Ref('AWS::StackName'),
         Tags=Tags(environment=self.env)
         )
     self.template.add_resource(cluster)
     self._add_ec2_auto_scaling()
     self._add_cluster_alarms(cluster)
     return cluster
Esempio n. 5
0
def get_default_cluster_config():
    """
    Function to get the default defined ECS Cluster configuration

    :return: cluster
    :rtype: troposphere.ecs.Cluster
    """

    return Cluster(
        CLUSTER_T,
        ClusterName=If(GENERATED_CLUSTER_NAME_CON_T, Ref(AWS_STACK_NAME),
                       Ref(CLUSTER_NAME_T)),
        CapacityProviders=DEFAULT_PROVIDERS,
        DefaultCapacityProviderStrategy=DEFAULT_STRATEGY,
        Metadata=metadata,
    )
Esempio n. 6
0
 def define_cluster(self, root_stack, settings: ComposeXSettings):
     """
     Function to create the cluster from provided properties.
     """
     props = import_record_properties(self.properties, Cluster)
     props["Metadata"] = metadata
     if not keyisset("ClusterName", props):
         props["ClusterName"] = Ref(AWS_STACK_NAME)
     if keyisset("DefaultCapacityProviderStrategy",
                 props) and not keyisset("CapacityProviders", props):
         raise KeyError("When specifying DefaultCapacityProviderStrategy"
                        " you must specify CapacityProviders")
     cluster_name = props["ClusterName"]
     if self.parameters:
         configuration = self.update_props_from_parameters(
             cluster_name, root_stack, settings)
         props["Configuration"] = configuration
     self.cfn_resource = Cluster(CLUSTER_T, **props)
     root_stack.stack_template.add_resource(self.cfn_resource)
     self.cluster_identifier = Ref(self.cfn_resource)
Esempio n. 7
0
def main():
    """Generates the CloudFormation template"""
    template = Template()
    template.add_version('2010-09-09')
    template.add_description(
        'This template deploys an ECS cluster to the ' +
        'provided VPC and subnets using an Auto Scaling Group')

    # Parameters
    # EnvironmentName
    env_name_param = template.add_parameter(
        Parameter(
            'EnvironmentName',
            Type='String',
            Description=
            'An environment name that will be prefixed to resource names',
        ))

    # InstanceType
    instance_type_param = template.add_parameter(
        Parameter(
            'InstanceType',
            Type='String',
            Default='t2.nano',
            Description=
            'Which instance type should we use to build the ECS cluster?',
            AllowedValues=[
                't2.nano',
                't2.micro',
                't2.small',
                't2.medium',
                't2.large',
                't2.xlarge',
                't2.2xlarge',
            ],
        ))

    # ClusterSize
    cluster_size_param = template.add_parameter(
        Parameter(
            'ClusterSize',
            Type='Number',
            Description='How many ECS hosts do you want to initially deploy?',
            Default='1',
        ))

    # VPC
    template.add_parameter(
        Parameter(
            'VPC',
            Type='AWS::EC2::VPC::Id',
            Description=
            'Choose which VPC this ECS cluster should be deployed to',
        ))

    # Subnets
    subnets_param = template.add_parameter(
        Parameter(
            'Subnets',
            Type='List<AWS::EC2::Subnet::Id>',
            Description=
            'Choose which subnets this ECS cluster should be deployed to',
        ))

    # SecurityGroup
    sg_param = template.add_parameter(
        Parameter(
            'SecurityGroup',
            Type='AWS::EC2::SecurityGroup::Id',
            Description=
            'Select the Security Group to use for the ECS cluster hosts',
        ))

    # Mappings
    # AWSRegionToAMI
    template.add_mapping(
        'AWSRegionToAMI',
        {
            'us-east-1': {
                'AMI': 'ami-a58760b3'
            },
            'us-east-2': {
                'AMI': 'ami-a6e4bec3'
            },
            'us-west-1': {
                'AMI': 'ami-74cb9b14'
            },
            'us-west-2': {
                'AMI': 'ami-5b6dde3b'
            },
            'eu-west-1': {
                'AMI': 'ami-e3fbd290'
            },
            'eu-west-2': {
                'AMI': 'ami-77f6fc13'
            },
            'eu-central-1': {
                'AMI': 'ami-38dc1157'
            },
            'ap-northeast-1': {
                'AMI': 'ami-30bdce57'
            },
            'ap-southeast-1': {
                'AMI': 'ami-9f75ddfc'
            },
            'ap-southeast-2': {
                'AMI': 'ami-cf393cac'
            },
            'ca-central-1': {
                'AMI': 'ami-1b01b37f'
            },
        },
    )

    # Resources
    ecs_role = template.add_resource(
        Role(
            'ECSRole',
            Path='/',
            RoleName=Sub('${EnvironmentName}-ECSRole-${AWS::Region}'),
            AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[
                awacs.aws.Statement(
                    Effect=awacs.aws.Allow,
                    Action=[awacs.aws.Action('sts', 'AssumeRole')],
                    Principal=awacs.aws.Principal('Service',
                                                  ['ec2.amazonaws.com']),
                ),
            ]),
            Policies=[
                Policy(
                    PolicyName='ecs-service',
                    PolicyDocument=awacs.aws.Policy(Statement=[
                        awacs.aws.Statement(
                            Effect=awacs.aws.Allow,
                            Action=[
                                awacs.aws.Action('ecs', 'CreateCluster'),
                                awacs.aws.Action(
                                    'ecs', 'DeregisterContainerInstance'),
                                awacs.aws.Action('ecs',
                                                 'DiscoverPollEndpoint'),
                                awacs.aws.Action('ecs', 'Poll'),
                                awacs.aws.Action('ecs',
                                                 'RegisterContainerInstance'),
                                awacs.aws.Action('ecs',
                                                 'StartTelemetrySession'),
                                awacs.aws.Action('ecs', 'Submit*'),
                                awacs.aws.Action('logs', 'CreateLogStream'),
                                awacs.aws.Action(
                                    'ecr', 'BatchCheckLayerAvailability'),
                                awacs.aws.Action('ecr', 'BatchGetImage'),
                                awacs.aws.Action('ecr',
                                                 'GetDownloadUrlForLayer'),
                                awacs.aws.Action('ecr',
                                                 'GetAuthorizationToken'),
                            ],
                            Resource=['*'],
                        ),
                    ], ),
                ),
            ],
        ))

    ecs_instance_profile = template.add_resource(
        InstanceProfile(
            'ECSInstanceProfile',
            Path='/',
            Roles=[Ref(ecs_role)],
        ))

    # ECSCluster
    ecs_cluster = template.add_resource(
        Cluster(
            'ECSCluster',
            ClusterName=Ref(env_name_param),
        ))

    instance_metadata = Metadata(
        Init({
            'config':
            InitConfig(
                commands={
                    '01_add_instance_to_cluster': {
                        'command':
                        Join('', [
                            '#!/bin/bash\n', 'echo ECS_CLUSTER=',
                            Ref(ecs_cluster), ' >> /etc/ecs/ecs.config'
                        ])
                    },
                },
                files=InitFiles({
                    '/etc/cfn/cfn-hup.conf':
                    InitFile(
                        mode='000400',
                        owner='root',
                        group='root',
                        content=Join('', [
                            '[main]\n', 'stack=',
                            Ref('AWS::StackId'), '\n', 'region=',
                            Ref('AWS::Region'), '\n'
                        ]),
                    ),
                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
                    InitFile(
                        mode='000400',
                        owner='root',
                        group='root',
                        content=Join('', [
                            '[cfn-auto-reloader-hook]\n',
                            'triggers=post.update\n',
                            'path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init\n'
                            'action=/opt/aws/bin/cfn-init -v --region ',
                            Ref('AWS::Region'), ' --stack ',
                            Ref('AWS::StackId'),
                            ' --resource ECSLaunchConfiguration\n'
                        ]),
                    )
                }),
                services=InitServices({
                    'cfn-hup':
                    InitService(enabled='true',
                                ensureRunning='true',
                                files=[
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ])
                }),
            )
        }))

    ecs_launch_config = template.add_resource(
        LaunchConfiguration(
            'ECSLaunchConfiguration',
            ImageId=FindInMap('AWSRegionToAMI', Ref('AWS::Region'), 'AMI'),
            InstanceType=Ref(instance_type_param),
            SecurityGroups=[Ref(sg_param)],
            IamInstanceProfile=Ref(ecs_instance_profile),
            UserData=Base64(
                Join('', [
                    '#!/bin/bash\n',
                    'yum install -y aws-cfn-bootstrap\n',
                    '/opt/aws/bin/cfn-init -v --region ',
                    Ref('AWS::Region'),
                    ' --stack ',
                    Ref('AWS::StackName'),
                    ' --resource ECSLaunchConfiguration\n',
                    '/opt/aws/bin/cfn-signal -e $? --region ',
                    Ref('AWS::Region'),
                    ' --stack ',
                    Ref('AWS::StackName'),
                    ' --resource ECSAutoScalingGroup\n',
                ])),
            Metadata=instance_metadata,
        ))

    # ECSAutoScalingGroup:
    template.add_resource(
        AutoScalingGroup(
            'ECSAutoScalingGroup',
            VPCZoneIdentifier=Ref(subnets_param),
            LaunchConfigurationName=Ref(ecs_launch_config),
            MinSize=Ref(cluster_size_param),
            MaxSize=Ref(cluster_size_param),
            DesiredCapacity=Ref(cluster_size_param),
            Tags=ASTags(Name=(Sub('${EnvironmentName} ECS host'), True)),
            CreationPolicy=CreationPolicy(
                ResourceSignal=ResourceSignal(Timeout='PT15M'), ),
            UpdatePolicy=UpdatePolicy(
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    MinInstancesInService='1',
                    MaxBatchSize='1',
                    PauseTime='PT15M',
                    WaitOnResourceSignals=True,
                )),
        ))

    # Output
    template.add_output(
        Output(
            'Cluster',
            Description='A reference to the ECS cluster',
            Value=Ref(ecs_cluster),
        ))
    print(template.to_json())
Esempio n. 8
0
        Type="AWS::EC2::KeyPair::KeyName",
        ConstraintDescription="must be the name of an existing EC2 KeyPair.",
    ))

t.add_parameter(Parameter("VpcId", Type="AWS::EC2::VPC::Id",
                          Description="VPC"))

t.add_parameter(
    Parameter("PublicSubnet",
              Type="List<AWS::EC2::Subnet::Id>",
              Description="PublicSubnet",
              ConstraintDescription="PublicSubnet"))

# Cluster Config
t.add_resource(Cluster(
    "ECSCluster",
    ClusterName="CodingTestCluster",
))

# Networking Config, VPC, Subnet, SecuritGroup
t.add_resource(
    ec2.SecurityGroup("SecurityGroup",
                      GroupDescription="Allow SSH and private network access",
                      GroupName="CodingTestCluster-SG",
                      SecurityGroupIngress=[
                          ec2.SecurityGroupRule(IpProtocol="tcp",
                                                FromPort=0,
                                                ToPort=65535,
                                                CidrIp="10.0.64.0/18"),
                          ec2.SecurityGroupRule(IpProtocol="tcp",
                                                FromPort=0,
                                                ToPort=65535,
Esempio n. 9
0
def main():
    t = Template()
    t.add_version('2010-09-09')
    t.set_description("AWS CloudFormation ECS example")

    # Add the Parameters

    AMI = t.add_parameter(Parameter(
        "AMI",
        Type="String",
    ))

    ClusterSize = t.add_parameter(Parameter(
        "ClusterSize",
        Type="String",
    ))

    ClusterType = t.add_parameter(Parameter(
        "ClusterType",
        Type="String",
    ))

    InstanceType = t.add_parameter(Parameter(
        "InstanceType",
        Type="String",
    ))

    IamInstanceProfile = t.add_parameter(
        Parameter(
            "IamInstanceProfile",
            Type="String",
        ))

    KeyName = t.add_parameter(
        Parameter(
            "KeyName",
            Type="AWS::EC2::KeyPair::KeyName",
        ))

    MaxClusterSize = t.add_parameter(
        Parameter(
            "MaxClusterSize",
            Type="String",
        ))

    RollingUpdate = t.add_parameter(Parameter(
        "RollingUpdate",
        Type="String",
    ))

    Stage = t.add_parameter(Parameter(
        "Stage",
        Type="String",
    ))

    Subnets = t.add_parameter(
        Parameter(
            "Subnets",
            Type="List<AWS::EC2::Subnet::Id>",
        ))

    VpcCidr = t.add_parameter(Parameter(
        "VpcCidr",
        Type="String",
    ))

    VpcId = t.add_parameter(Parameter(
        "VpcId",
        Type="AWS::EC2::VPC::Id",
    ))

    ContainerInstances = t.add_resource(
        LaunchConfiguration(
            'ContainerInstances',
            UserData=Base64(
                Join('', [
                    '#!/bin/bash -xe\n', 'echo ECS_CLUSTER=',
                    Ref('AWS::StackName'), '>> /etc/ecs/ecs.config\n',
                    'systemctl enable [email protected]\n',
                    'systemctl start [email protected]\n',
                    '/usr/bin/cfn-signal -e $? ', '         --stack ',
                    Ref('AWS::StackName'),
                    '         --resource ECSAutoScalingGroup ',
                    '         --region ',
                    Ref('AWS::Region'), '\n'
                ])),
            ImageId=Ref(AMI),
            KeyName=Ref(KeyName),
            SecurityGroups=[Ref('EcsSecurityGroup')],
            IamInstanceProfile=Ref(IamInstanceProfile),
            InstanceType=Ref(InstanceType)))

    ECSCluster = t.add_resource(
        Cluster('EcsCluster', ClusterName=Ref('AWS::StackName')))

    ECSAutoScalingGroup = t.add_resource(
        AutoScalingGroup(
            'ECSAutoScalingGroup',
            DesiredCapacity=Ref(ClusterSize),
            MinSize=Ref(ClusterSize),
            MaxSize=Ref(MaxClusterSize),
            VPCZoneIdentifier=Ref(Subnets),
            LaunchConfigurationName=Ref('ContainerInstances'),
            HealthCheckType="EC2",
            UpdatePolicy=UpdatePolicy(
                AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
                    WillReplace=True, ),
                AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                    PauseTime='PT5M',
                    MinInstancesInService=Ref(ClusterSize),
                    MaxBatchSize='1',
                    WaitOnResourceSignals=True)),
            Tags=[
                Tag("Project", "demo", True),
                Tag("Stage", Ref(Stage), True),
                Tag("Name", "home-ecs", True),
            ]))

    t.add_resource(
        ScalingPolicy("EcsAsgScaleDown",
                      AdjustmentType="PercentChangeInCapacity",
                      AutoScalingGroupName=Ref("ECSAutoScalingGroup"),
                      MetricAggregationType="Average",
                      MinAdjustmentMagnitude="1",
                      PolicyType="StepScaling",
                      StepAdjustments=[
                          StepAdjustments(MetricIntervalLowerBound="-10",
                                          MetricIntervalUpperBound="0",
                                          ScalingAdjustment="-10"),
                          StepAdjustments(MetricIntervalUpperBound="-10",
                                          ScalingAdjustment="-20")
                      ]))

    t.add_resource(
        ScalingPolicy('EcsScaleUp',
                      AdjustmentType="PercentChangeInCapacity",
                      AutoScalingGroupName=Ref("ECSAutoScalingGroup"),
                      EstimatedInstanceWarmup="300",
                      MetricAggregationType="Average",
                      MinAdjustmentMagnitude="1",
                      PolicyType="StepScaling",
                      StepAdjustments=[
                          StepAdjustments(MetricIntervalLowerBound="0",
                                          MetricIntervalUpperBound="10",
                                          ScalingAdjustment="10"),
                          StepAdjustments(MetricIntervalLowerBound="10",
                                          ScalingAdjustment="20")
                      ]))

    t.add_resource(
        cloudwatch.Alarm("EcsScaleDownAlarm",
                         ActionsEnabled="True",
                         MetricName="CPUUtilization",
                         AlarmActions=[Ref("EcsAsgScaleDown")],
                         AlarmDescription="Scale down ECS Instances",
                         Namespace="AWS/EC2",
                         Statistic="Average",
                         Period="60",
                         EvaluationPeriods="6",
                         Threshold="25",
                         ComparisonOperator="LessThanThreshold",
                         Dimensions=[
                             cloudwatch.MetricDimension(
                                 Name="AutoScalingGroupName",
                                 Value=Ref("ECSAutoScalingGroup"))
                         ]))

    t.add_resource(
        cloudwatch.Alarm("EcsAsgScaleUpAlarm",
                         ActionsEnabled="True",
                         MetricName="CPUUtilization",
                         AlarmActions=[Ref("EcsScaleUp")],
                         AlarmDescription="Scale up ECS Instances",
                         Namespace="AWS/EC2",
                         Statistic="Average",
                         Period="60",
                         EvaluationPeriods="3",
                         Threshold="65",
                         ComparisonOperator="GreaterThanThreshold",
                         Dimensions=[
                             cloudwatch.MetricDimension(
                                 Name="AutoScalingGroupName",
                                 Value=Ref("ECSAutoScalingGroup"))
                         ]))

    EC2SecurityGroup = t.add_resource(
        ec2.SecurityGroup('EcsSecurityGroup',
                          GroupDescription='ECS InstanceSecurityGroup',
                          SecurityGroupIngress=[
                              ec2.SecurityGroupRule(IpProtocol='tcp',
                                                    FromPort='22',
                                                    ToPort='22',
                                                    CidrIp='0.0.0.0/0'),
                              ec2.SecurityGroupRule(IpProtocol='tcp',
                                                    FromPort='31000',
                                                    ToPort='61000',
                                                    CidrIp='0.0.0.0/0')
                          ],
                          VpcId=Ref(VpcId)))

    with open("ecs-ec2-cluster-cf.yaml", "w") as yamlout:
        yamlout.write(t.to_yaml())
    def init_template(self):
        self.template.add_description(self.TEMPLATE_DESCRIPTION)

        ecs_cluster = self.template.add_resource(Cluster(self.CLUSTER_NAME))

        ecs_instance_role = self.template.add_resource(
            Role('sitInstanceRole',
                 Path='/',
                 AssumeRolePolicyDocument={
                     "Statement": [{
                         "Effect": "Allow",
                         "Principal": {
                             "Service": ["ec2.amazonaws.com"]
                         },
                         "Action": ["sts:AssumeRole"]
                     }]
                 }))

        ecs_instance_profile = self.template.add_resource(
            InstanceProfile('sitInstanceProfile',
                            Path='/',
                            Roles=[Ref(ecs_instance_role)]))

        ecs_instance_policy = self.template.add_resource(
            PolicyType('sitInstancePolicy',
                       PolicyName='ecs-policy',
                       Roles=[Ref(ecs_instance_role)],
                       PolicyDocument={
                           "Statement": [{
                               "Effect":
                               "Allow",
                               "Action": [
                                   "ecs:CreateCluster",
                                   "ecs:RegisterContainerInstance",
                                   "ecs:DeregisterContainerInstance",
                                   "ecs:DiscoverPollEndpoint", "ecs:Submit*",
                                   "ecs:Poll", "ecs:StartTelemetrySession",
                                   "ecr:GetAuthorizationToken",
                                   "ecr:BatchCheckLayerAvailability",
                                   "ecr:GetDownloadUrlForLayer",
                                   "ecr:BatchGetImage", "logs:CreateLogStream",
                                   "logs:PutLogEvents"
                               ],
                               "Resource":
                               "*"
                           }],
                       }))

        commands = {
            '01_add_instance_to_cluster': {
                'command':
                Join('', [
                    '#!/bin/bash\n', 'echo ECS_CLUSTER=',
                    Ref(ecs_cluster),
                    '$"\n"ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=',
                    self.ECS_TASK_CLEANUP_WAIT, ' >> /etc/ecs/ecs.config'
                ])
            }
        }

        files = {
            "/etc/cfn/cfn-hup.conf": {
                "content":
                Join("", [
                    "[main]\n", "stack=",
                    Ref("AWS::StackId"), "\n", "region=",
                    Ref("AWS::Region"), "\n"
                ]),
                "mode":
                "000400",
                "owner":
                "root",
                "group":
                "root"
            },
            "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content":
                Join("", [
                    "[cfn-auto-reloader-hook]\n", "triggers=post.update\n",
                    "path=Resources.{0}.Metadata.AWS::CloudFormation::Init\n".
                    format(self.LAUNCH_CONFIGURATION_NAME),
                    "action=/opt/aws/bin/cfn-init -v ", "         --stack ",
                    Ref("AWS::StackName"), "         --resource {0}".format(
                        self.LAUNCH_CONFIGURATION_NAME), "         --region ",
                    Ref("AWS::Region"), "\n", "runas=root\n"
                ])
            }
        }

        services = {
            "sysvinit": {
                "cfn-hup": {
                    "enabled":
                    "true",
                    "ensureRunning":
                    "true",
                    "files": [
                        "/etc/cfn/cfn-hup.conf",
                        "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                    ]
                }
            }
        }

        launch_configuration = self.template.add_resource(
            LaunchConfiguration(self.LAUNCH_CONFIGURATION_NAME,
                                ImageId=self.AMI_ID,
                                IamInstanceProfile=Ref(ecs_instance_profile),
                                InstanceType=self.INSTANCE_TYPE,
                                UserData=self.user_data.get_base64_data(),
                                AssociatePublicIpAddress=False,
                                SecurityGroups=self.SECURITY_GROUPS,
                                KeyName=self.KEY_NAME,
                                Metadata=autoscaling.Metadata(
                                    cloudformation.Init({
                                        "config":
                                        cloudformation.InitConfig(
                                            commands=commands,
                                            files=files,
                                            services=services)
                                    })),
                                BlockDeviceMappings=[
                                    autoscaling.BlockDeviceMapping(
                                        DeviceName=self.EBS_DEVICE_NAME,
                                        Ebs=autoscaling.EBSBlockDevice(
                                            DeleteOnTermination=True,
                                            VolumeSize=self.EBS_VOLUME_SIZE,
                                            VolumeType='gp2'))
                                ]))

        auto_scaling_group = self.template.add_resource(
            AutoScalingGroup(self.AUTOSCALING_GROUP_NAME,
                             MaxSize=self.MAX_SIZE,
                             MinSize=self.MIN_SIZE,
                             Cooldown=60,
                             LaunchConfigurationName=Ref(launch_configuration),
                             VPCZoneIdentifier=[self.SUBNET]))
        """ Scale UP Policy """
        scaling_up_policy = self.template.add_resource(
            ScalingPolicy('{0}ScaleUpPolicy'.format(
                self.AUTOSCALING_GROUP_NAME),
                          AdjustmentType='ChangeInCapacity',
                          AutoScalingGroupName=Ref(auto_scaling_group),
                          Cooldown=60,
                          ScalingAdjustment='1'))

        for alarm_name, alarm in self.AUTOSCALE_UP_ALARMS.iteritems():
            """ Cloud Watch Alarm """
            self.template.add_resource(
                Alarm('{0}ScaleUp{1}'.format(self.AUTOSCALING_GROUP_NAME,
                                             alarm_name),
                      ActionsEnabled=True,
                      Namespace='AWS/ECS',
                      MetricName=alarm['scaling_metric'],
                      ComparisonOperator='GreaterThanOrEqualToThreshold',
                      Threshold=alarm['scale_up_threshold'],
                      EvaluationPeriods=1,
                      Statistic=alarm['statistic'],
                      Period=alarm['period'],
                      AlarmActions=[Ref(scaling_up_policy)],
                      Dimensions=[
                          MetricDimension(Name='ClusterName',
                                          Value=Ref(ecs_cluster))
                      ]))
        """ Scale DOWN Policy """
        scaling_down_policy = self.template.add_resource(
            ScalingPolicy('{0}ScaleDownPolicy'.format(
                self.AUTOSCALING_GROUP_NAME),
                          AdjustmentType='ChangeInCapacity',
                          AutoScalingGroupName=Ref(auto_scaling_group),
                          Cooldown=60,
                          ScalingAdjustment='-1'))

        for alarm_name, alarm in self.AUTOSCALE_DOWN_ALARMS.iteritems():
            """ Cloud Watch Alarm """
            self.template.add_resource(
                Alarm('{0}ScaleDown{1}'.format(self.AUTOSCALING_GROUP_NAME,
                                               alarm_name),
                      ActionsEnabled=True,
                      Namespace='AWS/ECS',
                      MetricName=alarm['scaling_metric'],
                      ComparisonOperator='LessThanOrEqualToThreshold',
                      Threshold=alarm['scale_down_threshold'],
                      EvaluationPeriods=1,
                      Statistic=alarm['statistic'],
                      Period=alarm['period'],
                      AlarmActions=[Ref(scaling_down_policy)],
                      Dimensions=[
                          MetricDimension(Name='ClusterName',
                                          Value=Ref(ecs_cluster))
                      ]))
Esempio n. 11
0
                        "Action": [
                            "ecr:BatchCheckLayerAvailability",
                            "ecr:GetDownloadUrlForLayer",
                            "ecr:BatchGetImage"
                        ],
                        "Resource": "*",
                    }
                ]
            }
        ),
    ]
))


hugged_cluster = t.add_resource(Cluster(
    "HuggedCluster",
    ClusterName="AllTheHugs",
))

cfn_hup = InitFile(
    content=Sub(
        "[main]\nstack=${AWS::StackId}\nregion=${AWS::Region}\n"
    ),
    mode='000400',
    owner='root',
    group='root'
)
reloader = InitFile(
    content=Sub("""
[cfn-auto-reloader-hook]
triggers=post.add, post.update
path=Resources.NetKANCompute.Metadata.AWS::CloudFormation::Init
Esempio n. 12
0
def generate_template(d):

    # Set template metadata
    t = Template()
    t.add_version("2010-09-09")
    t.set_description(d["cf_template_description"])

    # aws_account_id = Ref("AWS::AccountId")
    # aws_region = Ref("AWS::Region")

    # ALB SG
    ALBSG = t.add_resource(
        SecurityGroup(
            "ALBSG",
            GroupDescription="Enable HTTP access.",
            SecurityGroupIngress=[
                SecurityGroupRule(IpProtocol="tcp",
                                  FromPort="80",
                                  ToPort="80",
                                  CidrIp="0.0.0.0/0")
            ],
            VpcId=ImportValue(d["network_stack_name"] + "-VPCId"),
        ))

    # ALB
    ALB = t.add_resource(
        elb.LoadBalancer(
            "ALB",
            Name=d["project_name"],
            Scheme="internet-facing",
            SecurityGroups=[Ref("ALBSG")],
            Subnets=[
                ImportValue(d["network_stack_name"] + "-PublicSubnetId1"),
                ImportValue(d["network_stack_name"] + "-PublicSubnetId2"),
            ],
            Tags=Tags(d["tags"]),
        ))

    # ECS cluster
    ECSCluster = t.add_resource(
        Cluster("ECSCluster",
                ClusterName=d["project_name"],
                Tags=Tags(d["tags"])))

    # ECS cluster SG
    ClusterSG = t.add_resource(
        SecurityGroup(
            "ClusterSG",
            GroupDescription="Enable HTTP access.",
            SecurityGroupIngress=[
                SecurityGroupRule(
                    IpProtocol="tcp",
                    FromPort="0",
                    ToPort="65535",
                    SourceSecurityGroupId=Ref(ALBSG),
                )
            ],
            VpcId=ImportValue(d["network_stack_name"] + "-VPCId"),
        ))

    # ALB listener
    listener80 = t.add_resource(
        elb.Listener(
            "Listener80",
            Port="80",
            Protocol="HTTP",
            LoadBalancerArn=Ref("ALB"),
            DefaultActions=[
                elb.Action(
                    Type="fixed-response",
                    FixedResponseConfig=elb.FixedResponseConfig(
                        StatusCode="200",
                        MessageBody=(
                            "This is a fixed response for the default "
                            "ALB action"),
                        ContentType="text/plain",
                    ),
                )
            ],
        ))

    # ECS service role
    ECSClusterRole = t.add_resource(
        Role("ECSClusterRole",
             RoleName="ECSClusterRole",
             AssumeRolePolicyDocument={
                 "Version":
                 "2012-10-17",
                 "Statement": [{
                     "Effect": "Allow",
                     "Principal": {
                         "Service": "ecs-tasks.amazonaws.com"
                     },
                     "Action": "sts:AssumeRole",
                 }],
             }))

    # ECS Cluster Role Policy
    t.add_resource(
        PolicyType(
            'ECSClusterRolePolicy',
            PolicyName="ECSCLusterRolePolicy",
            Roles=[Ref(ECSClusterRole)],
            PolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Sid":
                    "ECSTaskManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "ec2:AttachNetworkInterface",
                        "ec2:CreateNetworkInterface",
                        "ec2:CreateNetworkInterfacePermission",
                        "ec2:DeleteNetworkInterface",
                        "ec2:DeleteNetworkInterfacePermission",
                        "ec2:Describe*",
                        "ec2:DetachNetworkInterface",
                        "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                        "elasticloadbalancing:DeregisterTargets",
                        "elasticloadbalancing:Describe*",
                        "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                        "elasticloadbalancing:RegisterTargets",
                        "route53:ChangeResourceRecordSets",
                        "route53:CreateHealthCheck",
                        "route53:DeleteHealthCheck",
                        "route53:Get*",
                        "route53:List*",
                        "route53:UpdateHealthCheck",
                        "servicediscovery:DeregisterInstance",
                        "servicediscovery:Get*",
                        "servicediscovery:List*",
                        "servicediscovery:RegisterInstance",
                        "servicediscovery:UpdateInstanceCustomHealthStatus",
                        "ecr:*",
                        "cloudwatch:*",
                        "logs:*",
                        "iam:*",
                    ],
                    "Resource":
                    "*"
                }, {
                    "Sid": "AutoScaling",
                    "Effect": "Allow",
                    "Action": ["autoscaling:Describe*"],
                    "Resource": "*"
                }, {
                    "Sid":
                    "AutoScalingManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "autoscaling:DeletePolicy",
                        "autoscaling:PutScalingPolicy",
                        "autoscaling:SetInstanceProtection",
                        "autoscaling:UpdateAutoScalingGroup"
                    ],
                    "Resource":
                    "*",
                    "Condition": {
                        "Null": {
                            "autoscaling:ResourceTag/AmazonECSManaged": "false"
                        }
                    }
                }, {
                    "Sid":
                    "AutoScalingPlanManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "autoscaling-plans:CreateScalingPlan",
                        "autoscaling-plans:DeleteScalingPlan",
                        "autoscaling-plans:DescribeScalingPlans"
                    ],
                    "Resource":
                    "*"
                }, {
                    "Sid":
                    "CWAlarmManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "cloudwatch:DeleteAlarms", "cloudwatch:DescribeAlarms",
                        "cloudwatch:PutMetricAlarm"
                    ],
                    "Resource":
                    "arn:aws:cloudwatch:*:*:alarm:*"
                }, {
                    "Sid": "ECSTagging",
                    "Effect": "Allow",
                    "Action": ["ec2:CreateTags"],
                    "Resource": "arn:aws:ec2:*:*:network-interface/*"
                }, {
                    "Sid":
                    "CWLogGroupManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "logs:CreateLogGroup", "logs:DescribeLogGroups",
                        "logs:PutRetentionPolicy"
                    ],
                    "Resource":
                    "arn:aws:logs:*:*:log-group:/aws/ecs/*"
                }, {
                    "Sid":
                    "CWLogStreamManagement",
                    "Effect":
                    "Allow",
                    "Action": [
                        "logs:CreateLogStream", "logs:DescribeLogStreams",
                        "logs:PutLogEvents"
                    ],
                    "Resource":
                    "arn:aws:logs:*:*:log-group:/aws/ecs/*:log-stream:*"
                }]
            }))

    # Codebuild role
    CodebuildDeveloperRole = t.add_resource(
        Role("CodebuildDeveloperRole",
             RoleName="CodebuilDevelopRole",
             AssumeRolePolicyDocument={
                 "Version":
                 "2012-10-17",
                 "Statement": [{
                     "Effect": "Allow",
                     "Principal": {
                         "Service": "codebuild.amazonaws.com"
                     },
                     "Action": "sts:AssumeRole",
                 }],
             }))

    # Codebuild developer role policy
    t.add_resource(
        PolicyType(
            'CodebuildDeveloperRolePolicy',
            PolicyName="CodebuildDeveloperRolePolicy",
            Roles=[Ref(CodebuildDeveloperRole)],
            PolicyDocument={
                "Statement": [{
                    "Action": [
                        "codebuild:StartBuild", "codebuild:StopBuild",
                        "codebuild:BatchGet*", "codebuild:GetResourcePolicy",
                        "codebuild:DescribeTestCases", "codebuild:List*",
                        "codecommit:GetBranch", "codecommit:GetCommit",
                        "codecommit:GetRepository", "codecommit:ListBranches",
                        "cloudwatch:GetMetricStatistics",
                        "events:DescribeRule", "events:ListTargetsByRule",
                        "events:ListRuleNamesByTarget", "logs:GetLogEvents",
                        "s3:*", "logs:*", "ecr:*"
                    ],
                    "Effect":
                    "Allow",
                    "Resource":
                    "*"
                }, {
                    "Effect":
                    "Allow",
                    "Action": ["ssm:PutParameter"],
                    "Resource":
                    "arn:aws:ssm:*:*:parameter/CodeBuild/*"
                }, {
                    "Sid":
                    "CodeStarNotificationsReadWriteAccess",
                    "Effect":
                    "Allow",
                    "Action": [
                        "codestar-notifications:CreateNotificationRule",
                        "codestar-notifications:DescribeNotificationRule",
                        "codestar-notifications:UpdateNotificationRule",
                        "codestar-notifications:Subscribe",
                        "codestar-notifications:Unsubscribe"
                    ],
                    "Resource":
                    "*",
                    "Condition": {
                        "StringLike": {
                            "codestar-notifications:NotificationsForResource":
                            "arn:aws:codebuild:*"
                        }
                    }
                }, {
                    "Sid":
                    "CodeStarNotificationsListAccess",
                    "Effect":
                    "Allow",
                    "Action": [
                        "codestar-notifications:ListNotificationRules",
                        "codestar-notifications:ListEventTypes",
                        "codestar-notifications:ListTargets",
                        "codestar-notifications:ListTagsforResource"
                    ],
                    "Resource":
                    "*"
                }, {
                    "Sid":
                    "SNSTopicListAccess",
                    "Effect":
                    "Allow",
                    "Action": ["sns:ListTopics", "sns:GetTopicAttributes"],
                    "Resource":
                    "*"
                }],
                "Version":
                "2012-10-17"
            }))

    # Codepipeline role
    CodePipelineRole = t.add_resource(
        Role("CodePipelineRole",
             RoleName="CodePipelineRole",
             AssumeRolePolicyDocument={
                 "Version":
                 "2012-10-17",
                 "Statement": [{
                     "Effect": "Allow",
                     "Principal": {
                         "Service": "codepipeline.amazonaws.com"
                     },
                     "Action": "sts:AssumeRole",
                 }],
             }))

    t.add_resource(
        PolicyType(
            'CodePipelineRolePolicy',
            PolicyName="CodePipelineRolePolicy",
            Roles=[Ref(CodePipelineRole)],
            PolicyDocument={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Action": [
                        "cloudformation:CreateStack",
                        "cloudformation:DeleteStack",
                        "cloudformation:DescribeStacks",
                        "cloudformation:UpdateStack",
                        "cloudformation:CreateChangeSet",
                        "cloudformation:DeleteChangeSet",
                        "cloudformation:DescribeChangeSet",
                        "cloudformation:ExecuteChangeSet",
                        "cloudformation:SetStackPolicy",
                        "cloudformation:ValidateTemplate",
                        "iam:PassRole",
                        "s3:*",
                    ],
                    "Resource":
                    "*",
                    "Effect":
                    "Allow"
                }, {
                    "Action":
                    ["codebuild:BatchGetBuilds", "codebuild:StartBuild"],
                    "Resource":
                    "*",
                    "Effect":
                    "Allow"
                }, {
                    "Action": ["ecr:*"],
                    "Resource": "*",
                    "Effect": "Allow"
                }, {
                    "Action": [
                        "ecs:DescribeServices", "ecs:DescribeTaskDefinition",
                        "ecs:DescribeTasks", "ecs:ListTasks",
                        "ecs:RegisterTaskDefinition", "ecs:UpdateService"
                    ],
                    "Resource":
                    "*",
                    "Effect":
                    "Allow"
                }, {
                    "Action": [
                        "codedeploy:CreateDeployment",
                        "codedeploy:GetDeployment",
                        "codedeploy:GetApplication",
                        "codedeploy:GetApplicationRevision",
                        "codedeploy:RegisterApplicationRevision",
                        "codedeploy:GetDeploymentConfig",
                        "ecs:RegisterTaskDefinition", "iam:PassRole"
                    ],
                    "Resource":
                    "*",
                    "Effect":
                    "Allow"
                }]
            }))
    # Outputs

    # ListenerArnHTTP
    t.add_output(
        Output(
            "ListenerArnHTTP",
            Description="Listener Arn (HTTP) of the newly created Listener",
            Export=Export(Sub("${AWS::StackName}-ListenerArnHTTP")),
            Value=Ref(listener80),
        ))

    t.add_output(
        Output(
            "ECSClusterRole",
            Description="ECS Cluster role with managed policy",
            Export=Export(Sub("${AWS::StackName}-ECSClusterRole")),
            Value=GetAtt(ECSClusterRole, "Arn"),
        ))

    t.add_output(
        Output(
            "CodePipelineRole",
            Description="CodePipeline role with managed policy",
            Export=Export(Sub("${AWS::StackName}-CodePipelineRole")),
            Value=GetAtt(CodePipelineRole, "Arn"),
        ))

    t.add_output(
        Output(
            "CodebuildDeveloperRole",
            Description="Codebuild role with managed policy",
            Export=Export(Sub("${AWS::StackName}-CodebuildDeveloperRole")),
            Value=GetAtt(CodebuildDeveloperRole, "Arn"),
        ))

    t.add_output(
        Output(
            "ECSClusterName",
            Description="ECS cluster name.",
            Export=Export(Sub("${AWS::StackName}-ECSClusterName")),
            # Value=GetAtt(ECSCluster, "Arn"),
            Value=Ref(ECSCluster),
        ))

    t.add_output(
        Output(
            "ALB",
            Description="ALB name.",
            Export=Export(Sub("${AWS::StackName}-ALBName")),
            Value=GetAtt(ALB, "LoadBalancerName"),
        ))

    t.add_output(
        Output(
            "ECSClusterSG",
            Description="ECS Cluster SG name.",
            Export=Export(Sub("${AWS::StackName}-ECSClusterSG")),
            Value=Ref(ClusterSG),
        ))

    return t
Esempio n. 13
0
def build_template(sierrafile):
    template = Template()

    template.add_version('2010-09-09')

    template.add_metadata(build_interface(sierrafile.extra_params))

    parameters = AttrDict(

        # Network Parameters

        vpc_cidr=template.add_parameter(Parameter(
            'VpcCidr',
            Type='String',
            Default='192.172.0.0/16',
        )),
        subnet1_cidr=template.add_parameter(Parameter(
            'Subnet1Cidr',
            Type='String',
            Default='192.172.1.0/24',
        )),
        subnet2_cidr=template.add_parameter(Parameter(
            'Subnet2Cidr',
            Type='String',
            Default='192.172.2.0/24',
        )),

        # ECS Parameters

        cluster_size=template.add_parameter(Parameter(
            'ClusterSize',
            Type='Number',
            Default=2,
        )),
        instance_type=template.add_parameter(Parameter(
            'InstanceType',
            Type='String',
            Default='t2.medium'
        )),
        key_name=template.add_parameter(Parameter(
            'KeyName',
            Type='AWS::EC2::KeyPair::KeyName',
        )),
        image_id=template.add_parameter(Parameter(
            'ImageId',
            Type='AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>',
            Default=(
                '/aws/service/ecs/optimized-ami'
                '/amazon-linux/recommended/image_id'
            ),
            Description=(
              'An SSM parameter that resolves to a valid AMI ID.'
              ' This is the AMI that will be used to create ECS hosts.'
              ' The default is the current recommended ECS-optimized AMI.'
            )
        )),

        # Other Parameters

        github_token=template.add_parameter(Parameter(
            'GitHubToken',
            Type='String',
            NoEcho=True,
        )),
    )

    # Environment Variable Parameters

    for env_var_param, env_var_name in sierrafile.extra_params:
        template.add_parameter(Parameter(
            env_var_param,
            Type='String',
            NoEcho=True,
        ))

    # Resource Declarations

    # # Network

    network_vpc = template.add_resource(VPC(
        'NetworkVpc',
        CidrBlock=Ref(parameters.vpc_cidr),
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    network_ig = template.add_resource(InternetGateway(
        'NetworkInternetGateway',
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    vpc_attach = template.add_resource(VPCGatewayAttachment(
        'NetworkInternetGatewayAttachment',
        InternetGatewayId=Ref(network_ig),
        VpcId=Ref(network_vpc),
    ))

    route_table = template.add_resource(RouteTable(
        'NetworkRouteTable',
        VpcId=Ref(network_vpc),
        Tags=Tags(Name=Ref('AWS::StackName')),
    ))

    template.add_resource(Route(
        'NetworkDefaultRoute',
        DependsOn=[vpc_attach.title],
        RouteTableId=Ref(route_table),
        DestinationCidrBlock='0.0.0.0/0',
        GatewayId=Ref(network_ig),
    ))

    subnet1 = template.add_resource(Subnet(
        'NetworkSubnet1',
        VpcId=Ref(network_vpc),
        AvailabilityZone=Select(0, GetAZs()),
        MapPublicIpOnLaunch=True,
        CidrBlock=Ref(parameters.subnet1_cidr),
        Tags=Tags(Name=Sub('${AWS::StackName} (Public)')),
    ))

    subnet2 = template.add_resource(Subnet(
        'NetworkSubnet2',
        VpcId=Ref(network_vpc),
        AvailabilityZone=Select(1, GetAZs()),
        MapPublicIpOnLaunch=True,
        CidrBlock=Ref(parameters.subnet2_cidr),
        Tags=Tags(Name=Sub('${AWS::StackName} (Public)')),
    ))

    template.add_resource(SubnetRouteTableAssociation(
        'NetworkSubnet1RouteTableAssociation',
        RouteTableId=Ref(route_table),
        SubnetId=Ref(subnet1),
    ))

    template.add_resource(SubnetRouteTableAssociation(
        'NetworkSubnet2RouteTableAssociation',
        RouteTableId=Ref(route_table),
        SubnetId=Ref(subnet2),
    ))

    elb = template.add_resource(LoadBalancer(
        ELB_NAME,
        Name=Sub('${AWS::StackName}-elb'),
        Type='network',
        Subnets=[Ref(subnet1), Ref(subnet2)],
    ))

    # # Cluster

    ecs_host_role = template.add_resource(Role(
        'EcsHostRole',
        AssumeRolePolicyDocument=PolicyDocument(
            Statement=[Statement(
                Effect=Allow,
                Principal=Principal('Service', 'ec2.amazonaws.com'),
                Action=[awacs.sts.AssumeRole]
            )],
        ),
        ManagedPolicyArns=[
            'arn:aws:iam::aws:policy/'
            'service-role/AmazonEC2ContainerServiceforEC2Role'
        ]
    ))

    ecs_host_profile = template.add_resource(InstanceProfile(
        'EcsHostInstanceProfile',
        Roles=[Ref(ecs_host_role)]
    ))

    ecs_host_sg = template.add_resource(SecurityGroup(
        'EcsHostSecurityGroup',
        GroupDescription=Sub('${AWS::StackName}-hosts'),
        VpcId=Ref(network_vpc),
        SecurityGroupIngress=[SecurityGroupRule(
            CidrIp='0.0.0.0/0',
            IpProtocol='-1'
        )]
    ))

    cluster = template.add_resource(Cluster(
        'EcsCluster',
        ClusterName=Ref('AWS::StackName')
    ))

    autoscaling_name = 'EcsHostAutoScalingGroup'
    launch_conf_name = 'EcsHostLaunchConfiguration'

    launch_conf = template.add_resource(LaunchConfiguration(
        launch_conf_name,
        ImageId=Ref(parameters.image_id),
        InstanceType=Ref(parameters.instance_type),
        IamInstanceProfile=Ref(ecs_host_profile),
        KeyName=Ref(parameters.key_name),
        SecurityGroups=[Ref(ecs_host_sg)],
        UserData=Base64(Sub(
            '#!/bin/bash\n'
            'yum install -y aws-cfn-bootstrap\n'
            '/opt/aws/bin/cfn-init -v'
            ' --region ${AWS::Region}'
            ' --stack ${AWS::StackName}'
            f' --resource {launch_conf_name}\n'
            '/opt/aws/bin/cfn-signal -e $?'
            ' --region ${AWS::Region}'
            ' --stack ${AWS::StackName}'
            f' --resource {autoscaling_name}\n'
        )),
        Metadata={
            'AWS::CloudFormation::Init': {
                'config': {
                    'commands': {
                        '01_add_instance_to_cluster': {
                            'command': Sub(
                                f'echo ECS_CLUSTER=${{{cluster.title}}}'
                                f' > /etc/ecs/ecs.config'
                            ),
                        }
                    },
                    'files': {
                        '/etc/cfn/cfn-hup.conf': {
                            'mode': 0o400,
                            'owner': 'root',
                            'group': 'root',
                            'content': Sub(
                                '[main]\n'
                                'stack=${AWS::StackId}\n'
                                'region=${AWS::Region}\n'
                            ),
                        },
                        '/etc/cfn/hooks.d/cfn-auto-reloader.conf': {
                            'content': Sub(
                                '[cfn-auto-reloader-hook]\n'
                                'triggers=post.update\n'
                                'path=Resources.ContainerInstances.Metadata'
                                '.AWS::CloudFormation::Init\n'
                                'action=/opt/aws/bin/cfn-init -v'
                                ' --region ${AWS::Region}'
                                ' --stack ${AWS::StackName}'
                                f' --resource {launch_conf_name}\n'
                            ),
                        },
                    },
                    'services': {
                        'sysvinit': {
                            'cfn-hup': {
                                'enabled': True,
                                'ensureRunning': True,
                                'files': [
                                    '/etc/cfn/cfn-hup.conf',
                                    '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
                                ]
                            }
                        }
                    }
                }
            }
        }
    ))

    autoscaling_group = template.add_resource(AutoScalingGroup(
        autoscaling_name,
        VPCZoneIdentifier=[Ref(subnet1), Ref(subnet2)],
        LaunchConfigurationName=Ref(launch_conf),
        DesiredCapacity=Ref(parameters.cluster_size),
        MinSize=Ref(parameters.cluster_size),
        MaxSize=Ref(parameters.cluster_size),
        Tags=[{
            'Key': 'Name',
            'Value': Sub('${AWS::StackName} - ECS Host'),
            'PropagateAtLaunch': True,
        }],
        CreationPolicy=CreationPolicy(
            ResourceSignal=ResourceSignal(Timeout='PT15M'),
        ),
        UpdatePolicy=UpdatePolicy(
            AutoScalingRollingUpdate=AutoScalingRollingUpdate(
                MinInstancesInService=1,
                MaxBatchSize=1,
                PauseTime='PT5M',
                WaitOnResourceSignals=True,
            ),
        ),
    ))

    # # Services

    task_role = template.add_resource(Role(
        'TaskExecutionRole',
        AssumeRolePolicyDocument=PolicyDocument(
            Statement=[Statement(
                Effect=Allow,
                Principal=Principal('Service', 'ecs-tasks.amazonaws.com'),
                Action=[awacs.sts.AssumeRole],
            )],
        ),
        ManagedPolicyArns=[
            'arn:aws:iam::aws:policy/'
            'service-role/AmazonECSTaskExecutionRolePolicy'
        ],
    ))

    artifact_bucket = template.add_resource(Bucket(
        'ArtifactBucket',
        DeletionPolicy='Retain',
    ))

    codebuild_role = template.add_resource(Role(
        'CodeBuildServiceRole',
        Path='/',
        AssumeRolePolicyDocument=PolicyDocument(
            Version='2012-10-17',
            Statement=[
                Statement(
                    Effect=Allow,
                    Principal=Principal(
                        'Service', 'codebuild.amazonaws.com'
                    ),
                    Action=[
                        awacs.sts.AssumeRole,
                    ],
                ),
            ],
        ),
        Policies=[Policy(
            PolicyName='root',
            PolicyDocument=PolicyDocument(
                Version='2012-10-17',
                Statement=[
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.ssm.GetParameters,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.s3.GetObject,
                            awacs.s3.PutObject,
                            awacs.s3.GetObjectVersion,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.logs.CreateLogGroup,
                            awacs.logs.CreateLogStream,
                            awacs.logs.PutLogEvents,
                        ],
                    ),
                ],
            ),
        )],
    ))

    codepipeline_role = template.add_resource(Role(
        'CodePipelineServiceRole',
        Path='/',
        AssumeRolePolicyDocument=PolicyDocument(
            Version='2012-10-17',
            Statement=[
                Statement(
                    Effect=Allow,
                    Principal=Principal(
                        'Service', 'codepipeline.amazonaws.com'
                    ),
                    Action=[
                        awacs.sts.AssumeRole,
                    ],
                ),
            ],
        ),
        Policies=[Policy(
            PolicyName='root',
            PolicyDocument=PolicyDocument(
                Version='2012-10-17',
                Statement=[
                    Statement(
                        Resource=[
                            Sub(f'${{{artifact_bucket.title}.Arn}}/*')
                        ],
                        Effect=Allow,
                        Action=[
                            awacs.s3.GetBucketVersioning,
                            awacs.s3.GetObject,
                            awacs.s3.GetObjectVersion,
                            awacs.s3.PutObject,
                        ],
                    ),
                    Statement(
                        Resource=['*'],
                        Effect=Allow,
                        Action=[
                            awacs.ecs.DescribeServices,
                            awacs.ecs.DescribeTaskDefinition,
                            awacs.ecs.DescribeTasks,
                            awacs.ecs.ListTasks,
                            awacs.ecs.RegisterTaskDefinition,
                            awacs.ecs.UpdateService,
                            awacs.codebuild.StartBuild,
                            awacs.codebuild.BatchGetBuilds,
                            awacs.iam.PassRole,
                        ],
                    ),
                ],
            ),
        )],
    ))

    log_group = template.add_resource(LogGroup(
        'LogGroup',
        LogGroupName=Sub('/ecs/${AWS::StackName}'),
    ))

    if any(conf.pipeline.enable for conf in sierrafile.services.values()):
        project = template.add_resource(Project(
            'CodeBuildProject',
            Name=Sub('${AWS::StackName}-build'),
            ServiceRole=Ref(codebuild_role),
            Artifacts=Artifacts(Type='CODEPIPELINE'),
            Source=Source(Type='CODEPIPELINE'),
            Environment=Environment(
                ComputeType='BUILD_GENERAL1_SMALL',
                Image='aws/codebuild/docker:17.09.0',
                Type='LINUX_CONTAINER',
            ),
        ))

    for name, settings in sierrafile.services.items():
        task_definition = template.add_resource(TaskDefinition(
            f'{name}TaskDefinition',
            RequiresCompatibilities=['EC2'],
            Cpu=str(settings.container.cpu),
            Memory=str(settings.container.memory),
            NetworkMode='bridge',
            ExecutionRoleArn=Ref(task_role.title),
            ContainerDefinitions=[
                ContainerDefinition(
                    Name=f'{name}',
                    Image=settings.container.image,
                    Memory=str(settings.container.memory),
                    Essential=True,
                    PortMappings=[
                        PortMapping(
                            ContainerPort=settings.container.port,
                            Protocol='tcp',
                        ),
                    ],
                    Environment=[
                        troposphere.ecs.Environment(Name=k, Value=v)
                        for k, v in sierrafile.env_vars.items()
                        if k in settings.get('environment', [])
                    ],
                    LogConfiguration=LogConfiguration(
                        LogDriver='awslogs',
                        Options={
                            'awslogs-region': Ref('AWS::Region'),
                            'awslogs-group': Ref(log_group.title),
                            'awslogs-stream-prefix': Ref('AWS::StackName'),
                        },
                    ),
                ),
            ],
        ))

        target_group = template.add_resource(TargetGroup(
            f'{name}TargetGroup',
            Port=settings.container.port,
            Protocol='TCP',
            VpcId=Ref(network_vpc),
            Tags=Tags(Name=Sub(f'${{AWS::StackName}}-{name}')),
        ))

        listener = template.add_resource(Listener(
            f'{name}ElbListener',
            LoadBalancerArn=Ref(elb),
            Port=settings.container.port,
            Protocol='TCP',
            DefaultActions=[
                Action(TargetGroupArn=Ref(target_group), Type='forward')
            ],
        ))

        service = template.add_resource(Service(
            f'{name}Service',
            Cluster=Ref(cluster),
            ServiceName=f'{name}-service',
            DependsOn=[autoscaling_group.title, listener.title],
            DesiredCount=settings.container.count,
            TaskDefinition=Ref(task_definition),
            LaunchType='EC2',
            LoadBalancers=[
                troposphere.ecs.LoadBalancer(
                    ContainerName=f'{name}',
                    ContainerPort=settings.container.port,
                    TargetGroupArn=Ref(target_group),
                ),
            ],
        ))

        if settings.pipeline.enable:
            pipeline = template.add_resource(Pipeline(
                f'{name}Pipeline',
                RoleArn=GetAtt(codepipeline_role, 'Arn'),
                ArtifactStore=ArtifactStore(
                    Type='S3',
                    Location=Ref(artifact_bucket),
                ),
                Stages=[
                    Stages(
                        Name='Source',
                        Actions=[Actions(
                            Name='Source',
                            ActionTypeId=ActionTypeId(
                                Category='Source',
                                Owner='ThirdParty',
                                Version='1',
                                Provider='GitHub',
                            ),
                            OutputArtifacts=[
                                OutputArtifacts(Name=f'{name}Source'),
                            ],
                            RunOrder='1',
                            Configuration={
                                'Owner': settings.pipeline.user,
                                'Repo': settings.pipeline.repo,
                                'Branch': settings.pipeline.branch,
                                'OAuthToken': Ref(parameters.github_token),
                            },
                        )],
                    ),
                    Stages(
                        Name='Build',
                        Actions=[Actions(
                            Name='Build',
                            ActionTypeId=ActionTypeId(
                                Category='Build',
                                Owner='AWS',
                                Version='1',
                                Provider='CodeBuild',
                            ),
                            InputArtifacts=[
                                InputArtifacts(Name=f'{name}Source'),
                            ],
                            OutputArtifacts=[
                                OutputArtifacts(Name=f'{name}Build'),
                            ],
                            RunOrder='1',
                            Configuration={
                                'ProjectName': Ref(project),
                            },
                        )],
                    ),
                    Stages(
                        Name='Deploy',
                        Actions=[Actions(
                            Name='Deploy',
                            ActionTypeId=ActionTypeId(
                                Category='Deploy',
                                Owner='AWS',
                                Version='1',
                                Provider='ECS',
                            ),
                            InputArtifacts=[
                                InputArtifacts(Name=f'{name}Build')
                            ],
                            RunOrder='1',
                            Configuration={
                                'ClusterName': Ref(cluster),
                                'ServiceName': Ref(service),
                                'FileName': 'image.json',
                            },
                        )],
                    ),
                ],
            ))

            template.add_resource(Webhook(
                f'{name}CodePipelineWebhook',
                Name=Sub(f'${{AWS::StackName}}-{name}-webhook'),
                Authentication='GITHUB_HMAC',
                AuthenticationConfiguration=AuthenticationConfiguration(
                    SecretToken=Ref(parameters.github_token),
                ),
                Filters=[FilterRule(
                    JsonPath='$.ref',
                    MatchEquals=f'refs/heads/{settings.pipeline.branch}'
                )],
                TargetAction='Source',
                TargetPipeline=Ref(pipeline),
                TargetPipelineVersion=1,
                RegisterWithThirdParty=True,
            ))

    return template
    def add_ecs_fargate_cluster(self):
        ecs_cluster = Cluster("Cluster")

        self.template.add_resource(ecs_cluster)
Esempio n. 15
0
    'ApplicationListener',
    Certificates=[elasticloadbalancingv2.Certificate(
        CertificateArn=acm_cluster_certificate_arn,
    )],
    LoadBalancerArn=Ref(application_load_balancer),
    Protocol='HTTPS',
    Port=443,
    DefaultActions=[Action(
        TargetGroupArn=Ref(application_target_group),
        Type='forward',
    )]
))

# ECS cluster
cluster = template.add_resource(Cluster(
    "Cluster",
))

# ECS container role
container_instance_role = template.add_resource(iam.Role(
    "ContainerInstanceRole",
    AssumeRolePolicyDocument=dict(Statement=[dict(
        Effect="Allow",
        Principal=dict(Service=["ec2.amazonaws.com"]),
        Action=["sts:AssumeRole"],
    )]),
    Path="/",
    Policies=[
        iam.Policy(
            PolicyName="AssetsManagementPolicy",
            PolicyDocument=dict(
Esempio n. 16
0
            "Value": Ref(parameters["Project"])
        }],
        TargetGroupAttributes=[
            TargetGroupAttribute(Key="deregistration_delay.timeout_seconds",
                                 Value="90"),
            TargetGroupAttribute(Key="stickiness.enabled", Value="true"),
            TargetGroupAttribute(Key="stickiness.type", Value="lb_cookie")
        ],
        TargetType="ip",
        UnhealthyThresholdCount=3,
        VpcId=ImportValue("VPC")))

### ECS Cluster ###

resources["HelloWorldECSCluster"] = template.add_resource(
    Cluster("HelloWorldECSCluster",
            ClusterName=Join("-", [Ref(parameters["Project"]), "cluster"])))

### ECS Task Definition IAM Role ###

resources["HelloWorldTaskExecutionRole"] = template.add_resource(
    Role(
        "HelloWorldTaskExecutionRole",
        AssumeRolePolicyDocument={
            "Version":
            "2008-10-17",
            "Statement": [{
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ecs-tasks.amazonaws.com"
                },
Esempio n. 17
0
    GroupId = GetAtt(security_group, "GroupId"),
    CidrIp = "0.0.0.0/0",
    IpProtocol = "tcp",
    FromPort = "443",
    ToPort = "443"
)

template.add_resource(alb_security_group)
template.add_resource(alb_security_group_ingress_http)
template.add_resource(alb_security_group_ingress_https)

cluster = Cluster(
    region.replace("-", "") + "ecslive",
    ClusterName = "live",
    ClusterSettings = [
        ClusterSetting(
            Name = "containerInsights",
            Value = "enabled"
        )
    ]
)

ecs_role = Role(
    region.replace("-", "") + "ecsrole",
    AssumeRolePolicyDocument = {
        "Statement": [{
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            }
        }]
Esempio n. 18
0
                           "Action": [
                               "s3:ListBucket",
                           ],
                           "Resource": ["arn:aws:s3:::status.ksp-ckan.space"],
                       },
                   ],
               }))

# Indexer Compute
# We could utilise an autoscaling group, but that is way
# more complicated for our use case. If at some point we'd
# to scale the service beyond a single instance (due to some
# infrastructure sponsorship) it wouldn't take more than
# adding an AutoScalingGroup + LoadBalancer to scale this.
netkan_ecs = t.add_resource(
    Cluster('NetKANCluster', ClusterName='NetKANCluster'))

netkan_userdata = Sub("""
#!/bin/bash -xe
echo ECS_CLUSTER=NetKANCluster > /etc/ecs/ecs.config
yum install -y aws-cfn-bootstrap
# Install the files and packages from the metadata
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} \
--resource NetKANCompute --region ${AWS::Region}

# ECS Volumes are a pain and I don't want to shave any more yaks
mkdir /mnt/letsencrypt
mkfs.ext4 -L CKANCACHE /dev/xvdh
mkdir -p /mnt/ckan_cache
echo "LABEL=CKANCACHE /mnt/ckan_cache ext4 defaults 0 2" >> /etc/fstab
mount -a
Esempio n. 19
0
                                     UnhealthyThreshold="2",
                                     Interval="100",
                                     Timeout="10",
                                 ),
                                 Scheme="internal")

template.add_output(
    Output("LoadBalancerDNSName",
           Description="Loadbalancer DNS",
           Value=Join("",
                      ["http://", GetAtt(load_balancer, "DNSName")])))

# ECS cluster
main_cluster = Cluster(
    "MainCluster",
    ClusterName=Join("", ["MainCluster-", Ref(AWS_STACK_NAME)]),
    template=template,
)

# ECS container role
container_instance_role = iam.Role(
    "ContainerInstanceRole",
    template=template,
    AssumeRolePolicyDocument=dict(Statement=[
        dict(
            Effect="Allow",
            Principal=dict(Service=["ec2.amazonaws.com"]),
            Action=["sts:AssumeRole"],
        )
    ]),
    Path="/",
Esempio n. 20
0
    def scaffold(self):
        """ Create long lived stack resources for the cluster """
        self.t.add_resource(
            Cluster("Cluster", ClusterName=self.cluster_vars['name']))
        OUTPUT_SG = ["ALB", "DB", "Cache", "Aux"]
        for sg in OUTPUT_SG:
            tmpsg = SecurityGroup(
                "{}BadgeSg".format(sg),
                GroupDescription=
                "SG for {} to wear in order to talk to ecs instances".format(
                    sg),
                VpcId=self.cluster_vars.get('vpc'))
            self.t.add_resource(tmpsg)
            self.t.add_output(
                Output("{}BadgeSg".format(sg),
                       Description="{} Security Group Badge".format(sg),
                       Export=Export(Sub("${AWS::StackName}:%sBadgeSg" % sg)),
                       Value=GetAtt(tmpsg, "GroupId")))
        # Refactor like this
        ### removing this because it's in the agent now
        add_asg_cleanup(self.t,
                        sanitize_cfn_resource_name(self.cluster_vars['name']))

        # add metric lambda
        self.t.add_resource(
            Function("ECSMetricLambda",
                     Code=Code(S3Bucket=Sub("${S3Bucket}"),
                               S3Key=Sub("${S3Prefix}/deployment.zip")),
                     Handler="metrics.cluster_metrics.lambda_handler",
                     Role=GetAtt("CronLambdaRole", "Arn"),
                     Runtime="python3.7",
                     MemorySize=128,
                     Timeout=300,
                     Environment=Environment(
                         Variables={
                             "CLUSTER": Sub("${ClusterName}"),
                             "ASGPREFIX": Sub("${ClusterName}-asg-"),
                             "REGION": Ref("AWS::Region")
                         })))

        self.t.add_resource(
            Role("CronLambdaRole",
                 AssumeRolePolicyDocument={
                     "Statement": [{
                         "Effect": "Allow",
                         "Action": "sts:AssumeRole",
                         "Principal": {
                             "Service": "lambda.amazonaws.com"
                         },
                     }]
                 },
                 Policies=[
                     Policy(PolicyName="logs-and-stuff",
                            PolicyDocument={
                                "Statement": [{
                                    "Effect": "Allow",
                                    "Action": ["logs:*"],
                                    "Resource": "arn:aws:logs:*:*:*"
                                }, {
                                    "Effect":
                                    "Allow",
                                    "Action": [
                                        "ec2:DescribeAutoScalingGroups",
                                        "ec2:UpdateAutoScalingGroup", "ecs:*",
                                        "cloudwatch:PutMetricData"
                                    ],
                                    "Resource":
                                    "*"
                                }]
                            })
                 ]))
        # run metrics every minute
        self.t.add_resource(
            Rule(
                "CronStats",
                ScheduleExpression="rate(1 minute)",
                Description="Cron for cluster stats",
                Targets=[Target(Id="1", Arn=GetAtt("ECSMetricLambda",
                                                   "Arn"))]))
        self.t.add_resource(
            Permission("StatPerm",
                       Action="lambda:InvokeFunction",
                       FunctionName=GetAtt("ECSMetricLambda", "Arn"),
                       Principal="events.amazonaws.com",
                       SourceArn=GetAtt("CronStats", "Arn")))
Esempio n. 21
0
t.add_description("""\
AWS CloudFormation ECS Cluster\
""")

# Parameters
ecsClusterName_param = t.add_parameter(Parameter(
    "ECSClusterName",
    Description="ECS Cluster Name",
    Default=data['ClusterInfo']['Name'],
    Type="String"
))


# Creating the ECS Cluster (using the name provided when running CloudFormation.
ECSCluster = t.add_resource(Cluster(
    'ECSCluster',
    ClusterName=Ref(ecsClusterName_param),
))


# Policy Amazon EC2 Container Registry - Enable our ECS Cluster to work with the ECR
PolicyEcr = t.add_resource(PolicyType(
    'PolicyEcr',
    PolicyName='EcrPolicy',
    PolicyDocument={'Version': '2012-10-17',
                    'Statement': [{'Action': ['ecr:GetAuthorizationToken'],
                                   'Resource': ['*'],
                                   'Effect': 'Allow'},
                                  {'Action': ['ecr:GetDownloadUrlForLayer',
                                              'ecr:BatchGetImage',
                                              'ecr:BatchCheckLayerAvailability'
                                              ],
Esempio n. 22
0
application_listener = Listener(
    'ApplicationListener',
    template=template,
    LoadBalancerArn=Ref(application_load_balancer),
    Protocol='HTTP',
    Port=8080,
    DefaultActions=[Action(
        TargetGroupArn=Ref(application_target_group),
        Type='forward',
    )]
)


# ECS cluster
cluster = Cluster(
    "Cluster",
    template=template,
)


# ECS container role
container_instance_role = iam.Role(
    "ContainerInstanceRole",
    template=template,
    AssumeRolePolicyDocument=dict(Statement=[dict(
        Effect="Allow",
        Principal=dict(Service=["ec2.amazonaws.com"]),
        Action=["sts:AssumeRole"],
    )]),
    Path="/",
    Policies=[
        iam.Policy(
Esempio n. 23
0
    NetworkConfiguration,
    PortMapping,
    Service,
    TaskDefinition,
)

t = Template()
t.set_version("2010-09-09")
t.add_parameter(
    Parameter(
        "Subnet",
        Type="AWS::EC2::Subnet::Id",
        Description="A VPC subnet ID for the container.",
    ))

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

task_definition = t.add_resource(
    TaskDefinition(
        "TaskDefinition",
        RequiresCompatibilities=["FARGATE"],
        Cpu="256",
        Memory="512",
        NetworkMode="awsvpc",
        ContainerDefinitions=[
            ContainerDefinition(
                Name="nginx",
                Image="nginx",
                Essential=True,
                PortMappings=[PortMapping(ContainerPort=80)],
            )
Esempio n. 24
0
from troposphere import Parameter, Ref, Template
from troposphere.ecs import (Cluster, Service, TaskDefinition,
                             ContainerDefinition, NetworkConfiguration,
                             AwsvpcConfiguration, PortMapping)

t = Template()
t.add_version('2010-09-09')
t.add_parameter(
    Parameter(
        'Subnet',
        Type='AWS::EC2::Subnet::Id',
        Description='A VPC subnet ID for the container.',
    ))

cluster = t.add_resource(Cluster('Cluster'))

task_definition = t.add_resource(
    TaskDefinition('TaskDefinition',
                   RequiresCompatibilities=['FARGATE'],
                   Cpu='256',
                   Memory='512',
                   NetworkMode='awsvpc',
                   ContainerDefinitions=[
                       ContainerDefinition(
                           Name='nginx',
                           Image='nginx',
                           Essential=True,
                           PortMappings=[PortMapping(ContainerPort=80)])
                   ]))

service = t.add_resource(
Esempio n. 25
0
                ],
            )
        ),
        ImageId="ami-13f84d60",
        KeyName="yourkey",
        SecurityGroups=["sg-96114ef2"],
        IamInstanceProfile=Ref("EC2InstanceProfile"),
        InstanceType="t2.micro",
        AssociatePublicIpAddress="true",
    )
)


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


ECSAutoScalingGroup = t.add_resource(
    AutoScalingGroup(
        "ECSAutoScalingGroup",
        DesiredCapacity="1",
        MinSize="1",
        MaxSize="1",
        VPCZoneIdentifier=["subnet-72849a0a", "subnet-72849a08"],
        AvailabilityZones=["eu-west-1a", "eu-west-1b"],
        LaunchConfigurationName=Ref("ContainerInstances"),
    )
)
Esempio n. 26
0
                          ec2.SecurityGroupRule(
                              IpProtocol="tcp",
                              FromPort=0,
                              ToPort=65535,
                              CidrIp="172.16.0.0/12",
                          ),
                          ec2.SecurityGroupRule(
                              IpProtocol="tcp",
                              FromPort="22",
                              ToPort="22",
                              CidrIp=PublicCidrIp,
                          ),
                      ],
                      VpcId=Ref("VpcId")))

t.add_resource(Cluster('ECSCluster', ))

t.add_resource(
    Role(
        'EcsClusterRole',
        ManagedPolicyArns=[
            'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM',
            'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly',
            'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role',
            'arn:aws:iam::aws:policy/CloudWatchFullAccess'
        ],
        AssumeRolePolicyDocument={
            'Version':
            '2012-10-17',
            'Statement': [{
                'Action': 'sts:AssumeRole',
Esempio n. 27
0
def __create_ecs():
    template = Template()

    desired_count = template.add_parameter(
        parameter=Parameter(title='DesiredCount', Default=1, Type='Number'))

    cpu = template.add_parameter(
        parameter=Parameter(title='Cpu', Default=256, Type='Number'))

    memory = template.add_parameter(
        parameter=Parameter(title='Memory', Default=512, Type='Number'))

    cluster = template.add_resource(resource=Cluster(title='SampleCluster', ))

    log_group = template.add_resource(resource=LogGroup(
        title='SampleLogGroup', LogGroupName='/aws/ecs/sample'))

    container_name = 'sample-nginx'

    task_definition = template.add_resource(resource=TaskDefinition(
        title='SampleTaskDefinition',
        Cpu=Ref(cpu),
        Family='sample-fargate-task',
        RequiresCompatibilities=['FARGATE'],
        Memory=Ref(memory),
        NetworkMode='awsvpc',
        ExecutionRoleArn=Sub(
            'arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole'),
        ContainerDefinitions=[
            ContainerDefinition(
                Image='nginx:latest',
                Name=container_name,
                PortMappings=[
                    PortMapping(ContainerPort=80, HostPort=80, Protocol='tcp')
                ],
                LogConfiguration=LogConfiguration(
                    LogDriver='awslogs',
                    Options={
                        'awslogs-region': Ref('AWS::Region'),
                        'awslogs-group': Ref(log_group),
                        'awslogs-stream-prefix': 'nginx'
                    }))
        ]))

    template.add_resource(resource=Service(
        title='SampleService',
        ServiceName='sample-fargate',
        Cluster=Ref(cluster),
        DesiredCount=Ref(desired_count),
        TaskDefinition=Ref(task_definition),
        LaunchType='FARGATE',
        NetworkConfiguration=NetworkConfiguration(
            AwsvpcConfiguration=AwsvpcConfiguration(
                AssignPublicIp='ENABLED',
                SecurityGroups=[
                    ImportValue(ExportName.TASK_SECURITY_GROUP.value)
                ],
                Subnets=[
                    ImportValue(
                        CommonResource.ExportName.PUBLIC_SUBNET_A_ID.value),
                    ImportValue(
                        CommonResource.ExportName.PUBLIC_SUBNET_B_ID.value),
                ])),
        LoadBalancers=[
            EcsLoadBalancer(ContainerName=container_name,
                            ContainerPort=80,
                            TargetGroupArn=ImportValue(
                                ExportName.TARGET_GROUP.value))
        ]))
    output_template_file(template, 'ecs.yml')