Esempio n. 1
0
def create_cache_cluster(stack, name, cache_type, vpc, cidrs, subnet_ids,
                         instance_type, num_cache_clusters):
    """Add Elasticache Cache cluster Resource."""
    ports = {'redis': 6379, 'memcached': 11211}
    ingress = []

    for idx, cidr in enumerate(cidrs):
        ingress.append(
            SecurityGroupRule(
                '{0}{1}{2}'.format(name.replace('-', ''), cache_type, idx),
                CidrIp=cidr,
                FromPort=ports[cache_type],
                ToPort=ports[cache_type],
                IpProtocol='tcp',
            ))

    secgroup = stack.stack.add_resource(
        SecurityGroup(
            '{0}{1}SecurityGroup'.format(name.replace('-', ''), cache_type),
            GroupDescription='{0} {1} Security Group'.format(name, cache_type),
            SecurityGroupIngress=ingress,
            SecurityGroupEgress=[
                SecurityGroupRule('{0}egress'.format(name.replace('-', '')),
                                  CidrIp='0.0.0.0/0',
                                  IpProtocol='-1')
            ],
            VpcId=vpc,
        ))

    subnet_group = stack.stack.add_resource(
        elasticache.SubnetGroup(
            '{0}{1}cache'.format(name.replace('-', ''), cache_type),
            Description='{0}{1} cache'.format(name, cache_type),
            SubnetIds=subnet_ids,
        ))

    if num_cache_clusters > 1:
        stack.stack.add_resource(
            elasticache.ReplicationGroup(
                '{0}CacheCluster'.format(name.replace('-', '')),
                ReplicationGroupId='{0}'.format(name),
                ReplicationGroupDescription='{0}cluster'.format(name),
                Engine='{0}'.format(cache_type),
                EngineVersion='3.2.6',
                CacheNodeType=instance_type,
                NumCacheClusters=num_cache_clusters,
                CacheSubnetGroupName=Ref(subnet_group),
                SecurityGroupIds=[Ref(secgroup)],
                AtRestEncryptionEnabled=True))
    else:
        stack.stack.add_resource(
            elasticache.CacheCluster('{0}CacheCluster'.format(
                name.replace('-', '')),
                                     ClusterName='{0}'.format(name),
                                     Engine='{0}'.format(cache_type),
                                     EngineVersion='3.2.10',
                                     CacheNodeType=instance_type,
                                     NumCacheNodes=num_cache_clusters,
                                     VpcSecurityGroupIds=[Ref(secgroup)],
                                     CacheSubnetGroupName=Ref(subnet_group)))
Esempio n. 2
0
def create_redis_subnet_group_resource(template, subnets_parameter):
    return template.add_resource(
        elasticache.SubnetGroup(
            'RedisSubnetGroup',
            Description='Subnets available for the Redis cluster',
            SubnetIds=Ref(subnets_parameter)
        )
    )
Esempio n. 3
0
    def create_elasticache_replication_group(self):
        elasticache_security_group_name = 'sgCacheCluster'
        elasticache_security_group = self.add_resource(
            ec2.SecurityGroup(
                elasticache_security_group_name,
                GroupDescription='Enables access to the cache cluster',
                VpcId=Ref(self.vpc_id),
                SecurityGroupIngress=[
                    ec2.SecurityGroupRule(IpProtocol='tcp',
                                          CidrIp=VPC_CIDR,
                                          FromPort=p,
                                          ToPort=p) for p in [REDIS]
                ],
                SecurityGroupEgress=[
                    ec2.SecurityGroupRule(IpProtocol='tcp',
                                          CidrIp=VPC_CIDR,
                                          FromPort=p,
                                          ToPort=p) for p in [REDIS]
                ],
                Tags=self.get_tags(Name=elasticache_security_group_name)))

        elasticache_subnet_group = self.add_resource(
            ec.SubnetGroup(
                'ecsngCacheCluster',
                Description='Private subnets for the ElastiCache instances',
                SubnetIds=Ref(self.private_subnets)))

        elasticache_parameter_group = self.add_resource(
            ec.ParameterGroup(
                'ecpgCacheCluster',
                CacheParameterGroupFamily='redis2.8',
                Description='Parameter group for the ElastiCache instances',
                Properties={'maxmemory-policy': 'allkeys-lru'}))

        elasticache_group = self.add_resource(
            ec.ReplicationGroup(
                'CacheReplicationGroup',
                AutomaticFailoverEnabled=True,
                AutoMinorVersionUpgrade=True,
                CacheNodeType=Ref(self.elasticache_instance_type),
                CacheParameterGroupName=Ref(elasticache_parameter_group),
                CacheSubnetGroupName=Ref(elasticache_subnet_group),
                Engine='redis',
                EngineVersion='2.8.24',
                NotificationTopicArn=Ref(self.notification_topic_arn),
                NumCacheClusters=2,
                PreferredCacheClusterAZs=Ref(self.availability_zones),
                PreferredMaintenanceWindow=
                'sun:05:00-sun:06:00',  # NOQA SUN 01:00AM-02:00AM ET
                ReplicationGroupDescription='Redis replication group',
                SecurityGroupIds=[Ref(elasticache_security_group)],
                SnapshotRetentionLimit=30,
                SnapshotWindow='04:00-05:00'  # 12:00AM-01:00AM ET
            ))

        return elasticache_group, elasticache_security_group
Esempio n. 4
0
    def define_cache_subnet_group(self, subnet_group_config):
        sg = elasticache.SubnetGroup(subnet_group_config["name"],
                                     DeletionPolicy=self.deletion_policy)
        sg.Description = subnet_group_config["description"]
        s_ids = []
        for s in subnet_group_config["subnets"]:
            s_ids.append(Ref(s))
        sg.SubnetIds = s_ids

        self._add_resource(sg)

        return Ref(sg)
Esempio n. 5
0
def render_elasticache(context, template):
    ensure(context['elasticache']['engine'] == 'redis',
           'We only support Redis as ElastiCache engine at this time')

    cache_security_group = elasticache_security_group(context)
    template.add_resource(cache_security_group)

    subnet_group = elasticache.SubnetGroup(
        ELASTICACHE_SUBNET_GROUP_TITLE,
        Description="a group of subnets for this cache instance.",
        SubnetIds=context['elasticache']['subnets'])
    template.add_resource(subnet_group)

    parameter_group = elasticache.ParameterGroup(
        ELASTICACHE_PARAMETER_GROUP_TITLE,
        CacheParameterGroupFamily='redis2.8',
        Description='ElastiCache parameter group for %s' %
        context['stackname'],
        Properties=context['elasticache']['configuration'])
    template.add_resource(parameter_group)

    template.add_resource(
        elasticache.CacheCluster(
            ELASTICACHE_TITLE,
            CacheNodeType='cache.t2.small',
            CacheParameterGroupName=Ref(parameter_group),
            CacheSubnetGroupName=Ref(subnet_group),
            Engine='redis',
            EngineVersion=context['elasticache']['version'],
            PreferredAvailabilityZone=context['elasticache']['az'],
            # we only support Redis, and it only supports 1 node
            NumCacheNodes=1,
            Tags=Tags(**_generic_tags(context)),
            VpcSecurityGroupIds=[Ref(cache_security_group)],
        ))

    outputs = [
        mkoutput("ElastiCacheHost",
                 "The hostname on which the cache accepts connections",
                 (ELASTICACHE_TITLE, "RedisEndpoint.Address")),
        mkoutput("ElastiCachePort",
                 "The port number on which the cache accepts connections",
                 (ELASTICACHE_TITLE, "RedisEndpoint.Port")),
    ]
    map(template.add_output, outputs)
Esempio n. 6
0
 def redis_adder_replcation(self,
                            name,
                            tags,
                            instance_type='cache.m3.medium',
                            cache_clusters=2,
                            version='3.2.4'):
     rule = self.rule_adder(6379, cidr='10.0.0.0/16')
     subnetname = Join("", [name, Ref("DeploymentEnvironment")])
     self.group_adder("redissg", [rule])
     subnetgroup = self.template.add_resource(
         elasticache.SubnetGroup(
             "SubnetGroup",
             CacheSubnetGroupName=subnetname,
             Description='Subnet Group for ElasticCache Redis {0}'.format(
                 name),
             SubnetIds=self.config['subnets']))
     self.template.add_resource(
         elasticache.ReplicationGroup(
             'RedisReplicationGroup',
             ReplicationGroupId=name,
             Engine='redis',
             EngineVersion=version,
             CacheNodeType=instance_type,
             NumCacheClusters=cache_clusters,
             Tags=tags,
             CacheSubnetGroupName=Ref(subnetgroup),
             ReplicationGroupDescription="%s replication group" % name,
             SecurityGroupIds=[GetAtt('redissg', "GroupId")],
         ))
     redisdnsrecord = RecordSetType(
         "RedisDNSRecord",
         HostedZoneName=Join("", [Ref("RedisDNSDomain"), "."]),
         Name=Join("",
                   [Ref("RedisDNSName"), ".",
                    Ref("RedisDNSDomain"), "."]),
         Type="CNAME",
         TTL="900",
         ResourceRecords=[
             GetAtt("RedisReplicationGroup", "PrimaryEndPoint.Address")
         ],
     )
     self.template.add_resource(redisdnsrecord)
Esempio n. 7
0
def create_cache_cluster(stack, cache_type):
    """Add Elasticache Cache cluster Resource."""
    ports = {'redis': 6379, 'memcached': 11211}
    secgroup = stack.stack.add_resource(
        SecurityGroup(
            '{0}SecurityGroup'.format(cache_type),
            GroupDescription="{0} Security Group".format(cache_type),
            SecurityGroupIngress=[
                SecurityGroupRule(
                    "{0}".format(cache_type),
                    CidrIp=Ref(stack.vpc_address_param),
                    FromPort=ports[cache_type],
                    ToPort=ports[cache_type],
                    IpProtocol="tcp",
                )
            ],
            VpcId=Ref(stack.vpc),
        ))

    subnet_group = stack.stack.add_resource(
        elasticache.SubnetGroup(
            '{0}cache'.format(stack.env),
            Description='{0} cache'.format(stack.env),
            SubnetIds=[Ref(stack.backend1_subnet),
                       Ref(stack.backend2_subnet)],
        ))

    stack.stack.add_resource(
        elasticache.ReplicationGroup(
            'CacheCluster',
            ReplicationGroupId='{0}cluster'.format(stack.env),
            ReplicationGroupDescription='{0}cluster'.format(stack.env),
            Engine='{0}'.format(cache_type),
            CacheNodeType=Ref(stack.cache_instance_type_param),
            NumCacheClusters='2',
            CacheSubnetGroupName=Ref(subnet_group),
            SecurityGroupIds=[Ref(secgroup)]))
Esempio n. 8
0
def render_elasticache(context, template):
    ensure(context['elasticache']['engine'] == 'redis',
           'We only support Redis as ElastiCache engine at this time')

    cache_security_group = elasticache_security_group(context)
    template.add_resource(cache_security_group)

    subnet_group = elasticache.SubnetGroup(
        ELASTICACHE_SUBNET_GROUP_TITLE,
        Description="a group of subnets for this cache instance.",
        SubnetIds=context['elasticache']['subnets'])
    template.add_resource(subnet_group)

    parameter_group = elasticache_default_parameter_group(context)

    suppressed = context['elasticache'].get('suppressed', [])
    default_parameter_group_use = False
    for cluster in range(1, context['elasticache']['clusters'] + 1):
        if cluster in suppressed:
            continue

        cluster_context = overridden_component(
            context,
            'elasticache',
            index=cluster,
            allowed=['type', 'version', 'az', 'configuration'])

        if cluster_context['configuration'] != context['elasticache'][
                'configuration']:
            cluster_parameter_group = elasticache_overridden_parameter_group(
                context, cluster_context, cluster)
            template.add_resource(cluster_parameter_group)
            cluster_cache_parameter_group_name = Ref(cluster_parameter_group)
        else:
            cluster_cache_parameter_group_name = Ref(parameter_group)
            default_parameter_group_use = True

        cluster_title = ELASTICACHE_TITLE % cluster
        template.add_resource(
            elasticache.CacheCluster(
                cluster_title,
                CacheNodeType=cluster_context['type'],
                CacheParameterGroupName=cluster_cache_parameter_group_name,
                CacheSubnetGroupName=Ref(subnet_group),
                Engine='redis',
                EngineVersion=cluster_context['version'],
                PreferredAvailabilityZone=cluster_context['az'],
                # we only support Redis, and it only supports 1 node
                NumCacheNodes=1,
                Tags=Tags(**aws.generic_tags(context)),
                VpcSecurityGroupIds=[Ref(cache_security_group)],
            ))

        outputs = [
            mkoutput("ElastiCacheHost%s" % cluster,
                     "The hostname on which the cache accepts connections",
                     (cluster_title, "RedisEndpoint.Address")),
            mkoutput("ElastiCachePort%s" % cluster,
                     "The port number on which the cache accepts connections",
                     (cluster_title, "RedisEndpoint.Port")),
        ]
        lmap(template.add_output, outputs)

    if default_parameter_group_use:
        template.add_resource(parameter_group)
        Condition='CreateSecurityGroupCondition',
        VpcId=Ref(param_vpcid),
        GroupDescription='Enable cache access',
        SecurityGroupIngress=[
            ec2.SecurityGroupRule(
                IpProtocol='tcp',
                FromPort='6379',
                ToPort='6379',
                CidrIp=Ref(param_client_location),
            )
        ],
    ))

cache_subnet_group = t.add_resource(
    elasticache.SubnetGroup('CacheSubnetGroup',
                            Description='Cache subnet group',
                            SubnetIds=Ref(param_subnetids)))

cache_cluster = t.add_resource(
    elasticache.CacheCluster(
        'CacheCluster',
        Engine='redis',
        CacheNodeType=Ref(param_cache_node_type),
        NumCacheNodes=Ref(param_cache_node_num),
        CacheSubnetGroupName=Ref(cache_subnet_group),
        AutoMinorVersionUpgrade=True,
        VpcSecurityGroupIds=[
            If('CreateSecurityGroupCondition', Ref(cache_sg), Ref(param_sg))
        ],
    ))
Esempio n. 10
0
            ToPort=If(using_redis_condition, "6379", "11211"),
            CidrIp=container_a_subnet_cidr,
        ),
        ec2.SecurityGroupRule(
            IpProtocol="tcp",
            FromPort=If(using_redis_condition, "6379", "11211"),
            ToPort=If(using_redis_condition, "6379", "11211"),
            CidrIp=container_b_subnet_cidr,
        ),
    ],
)

cache_subnet_group = elasticache.SubnetGroup(
    "CacheSubnetGroup",
    template=template,
    Description="Subnets available for the cache instance",
    Condition=cache_condition,
    SubnetIds=[Ref(container_a_subnet),
               Ref(container_b_subnet)],
)

cache_cluster = elasticache.CacheCluster(
    "CacheCluster",
    template=template,
    Engine=Ref(cache_engine),
    CacheNodeType=Ref(cache_node_type),
    Condition=cache_condition,
    NumCacheNodes=1,  # Must be 1 for redis, but still required
    Port=If(using_redis_condition, 6379, 11211),
    VpcSecurityGroupIds=[Ref(cache_security_group)],
    CacheSubnetGroupName=Ref(cache_subnet_group),
)
Esempio n. 11
0
template.add_condition(
    secure_redis_condition,
    And(Condition(using_redis_condition),
        Condition(use_aes256_encryption_cond)))

using_either_cache_condition = "EitherCacheCondition"
template.add_condition(
    using_either_cache_condition,
    Or(Condition(using_memcached_condition), Condition(using_redis_condition)))

# Subnet and security group shared by both clusters

cache_subnet_group = elasticache.SubnetGroup(
    "CacheSubnetGroup",
    template=template,
    Description="Subnets available for the cache instance",
    Condition=using_either_cache_condition,
    SubnetIds=[Ref(private_subnet_a),
               Ref(private_subnet_b)],
)

cache_security_group = ec2.SecurityGroup(
    'CacheSecurityGroup',
    template=template,
    GroupDescription="Cache security group.",
    Condition=using_either_cache_condition,
    VpcId=Ref(vpc),
    SecurityGroupIngress=[
        If(
            using_memcached_condition,
            ec2.SecurityGroupRule(
                IpProtocol="tcp",
Esempio n. 12
0
        DBInstanceClass=Ref(database_class),
        Engine='MySQL',
        EngineVersion='5.7',
        MasterUsername=Ref(database_username),
        MasterUserPassword=Ref(database_password),
        VPCSecurityGroups=[GetAtt(database_security_group, 'GroupId')],
        DBSubnetGroupName=Ref(database_subnet_group),
        PubliclyAccessible=False
    )
)

# Create the Redis cluster.
redis_subnet_group = template.add_resource(
    elasticache.SubnetGroup(
        'RedisSubnetGroup',
        Description='Subnets available for the Redis cluster',
        SubnetIds=Ref(subnets)
    )
)

redis = template.add_resource(
    elasticache.CacheCluster(
        'Redis',
        Engine='redis',
        EngineVersion='4.0',
        CacheNodeType=Ref(redis_node_class),
        NumCacheNodes=Ref(redis_nodes_count),
        VpcSecurityGroupIds=[GetAtt(redis_security_group, 'GroupId')],
        CacheSubnetGroupName=Ref(redis_subnet_group)
    )
)
Esempio n. 13
0
 def add_elasticache_subnet_group(self, name, engine, private_subnets):
     return self.add_resource(
         elasticache.SubnetGroup(Description=name + engine + 'SubnetGroup',
                                 SubnetIds=private_subnets))
Esempio n. 14
0
    def configure(self):
        elasticache_metadata = constants.ENVIRONMENTS[self.env]['elasticache']
        self.name = 'elasticache'
        self.add_description('Sets up elasticache in VPC')
        self.get_standard_parameters()
        self.get_default_security_groups()

        for cache in elasticache_metadata:
            name = self.env + cache['name'].replace(
                '-', '').capitalize() + cache['engine'].capitalize()
            tags = self.get_tags(service_override=self.name,
                                 role_override=cache['name'])
            _port = 6379 if cache['engine'] == 'redis' else 11211
            security_group = self.add_resource(
                ec2.SecurityGroup(
                    '{}ElastiCacheSecurityGroup'.format(name),
                    VpcId=self.vpc_id,
                    GroupDescription='Security Group for {} Access'.format(
                        name),
                    SecurityGroupIngress=[{
                        'IpProtocol': 'tcp',
                        'FromPort': _port,
                        'ToPort': _port,
                        'CidrIp': self.vpc_cidr
                    }],
                    Tags=tags))
            # Default to true for preferred subnet unless using multi_az
            preferred_only = False if cache.get(
                'multi_az') is True else cache.get('preferred_only', True)
            subnet_group = self.add_resource(
                elasticache.SubnetGroup(
                    '{}SubnetGroup'.format(name),
                    Description='SubnetGroup for {} Elasticache'.format(name),
                    SubnetIds=list(
                        map(
                            lambda x: x['SubnetId'],
                            self.get_subnets(
                                'private', _preferred_only=preferred_only)))))
            if cache['engine'] == 'redis':
                cache_cluster = self.add_resource(
                    elasticache.ReplicationGroup(
                        '{}ReplicationGroup'.format(name),
                        AutomaticFailoverEnabled=False,
                        AutoMinorVersionUpgrade=True,
                        CacheNodeType=cache['instance_type'],
                        CacheSubnetGroupName=Ref(subnet_group),
                        Engine='redis',
                        EngineVersion=cache.get('engine_version', '5.0.6'),
                        NumCacheClusters=1,
                        ReplicationGroupDescription=
                        '{} RedisElasticache Cluster'.format(name),
                        SecurityGroupIds=[Ref(security_group)]))
                records = [GetAtt(cache_cluster, 'PrimaryEndPoint.Address')]
            else:
                cache_cluster = self.add_resource(
                    elasticache.CacheCluster(
                        '{}CacheCluster'.format(name),
                        AutoMinorVersionUpgrade=True,
                        CacheNodeType=cache['instance_type'],
                        CacheSubnetGroupName=Ref(subnet_group),
                        ClusterName=cache.get('cluster_name', name),
                        Engine='memcached',
                        EngineVersion='1.5.16',
                        NumCacheNodes=3,
                        VpcSecurityGroupIds=[Ref(security_group)]))
                records = [
                    GetAtt(cache_cluster, 'ConfigurationEndpoint.Address')
                ]

            if self.get_partition() != 'aws-us-gov':
                hosted_zone = constants.ENVIRONMENTS[self.env]['route53_zone']
                self.add_resource(
                    route53.RecordSetGroup(
                        '{}Route53'.format(name),
                        HostedZoneName=hosted_zone,
                        RecordSets=[
                            route53.RecordSet(
                                Name='{}.{}.{}'.format(cache['name'],
                                                       cache['engine'],
                                                       hosted_zone),
                                ResourceRecords=[
                                    GetAtt(cache_cluster,
                                           'PrimaryEndPoint.Address')
                                ],
                                Type='CNAME',
                                TTL=600)
                        ]))