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)))
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) ) )
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
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)
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)
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)
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)]))
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)) ], ))
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), )
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",
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) ) )
def add_elasticache_subnet_group(self, name, engine, private_subnets): return self.add_resource( elasticache.SubnetGroup(Description=name + engine + 'SubnetGroup', SubnetIds=private_subnets))
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) ]))