---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'ElastiCache Redis'
Metadata:
  'AWS::CloudFormation::Interface':
    ParameterGroups:
    - Label:
        default: 'Parent Stacks'
      Parameters:
      - ParentVPCStack
    - Label:
        default: 'ElastiCache Parameters'
      Parameters:
      - EngineVersion
      - CacheNodeType
      - RedisAuthToken
Parameters:
  ParentVPCStack:
    Description: 'Stack name of parent VPC (created by eksctl command).'
    Type: String
  EngineVersion:
    Description: 'Redis version'
    Type: String
    Default: '6.2'
    AllowedValues:
    - '6.2'
    - '6.0'
    - '5.0.6'
  CacheNodeType:
    Description: 'The compute and memory capacity of the nodes in the node group (shard).'
    Type: String
    Default: 'cache.t3.micro'
  RedisAuthToken:
    Description: 'Authentication Token'
    Type: String
    MinLength: 16
    MaxLength: 128
    NoEcho: true
    AllowedPattern: '^[a-zA-Z0-9!&#$^<>-]+$'
Mappings:
  EngineVersionMap:
    '5.0.6':
      CacheParameterGroupFamily: 'redis5.0'
    '6.0':
      CacheParameterGroupFamily: 'redis6.x'
    '6.2':
      CacheParameterGroupFamily: 'redis6.x'
Resources:
  SecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: 'SG for GoodData.CN Redis'
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 6379
        ToPort: 6379
        SourceSecurityGroupId:
          'Fn::ImportValue':
            'Fn::Sub': '${ParentVPCStack}::SharedNodeSecurityGroup'
      VpcId:
        'Fn::ImportValue':
          'Fn::Sub': '${ParentVPCStack}::VPC'
  CacheParameterGroup:
    Type: 'AWS::ElastiCache::ParameterGroup'
    Properties:
      CacheParameterGroupFamily: !FindInMap [EngineVersionMap, !Ref EngineVersion, CacheParameterGroupFamily]
      Description: !Ref 'AWS::StackName'
      Properties:
        'cluster-enabled': 'yes'
        'maxmemory-policy': 'allkeys-lru'
  CacheSubnetGroup:
    Type: 'AWS::ElastiCache::SubnetGroup'
    Properties:
      Description: !Ref 'AWS::StackName'
      SubnetIds: !Split
      - ','
      - 'Fn::ImportValue': !Sub '${ParentVPCStack}::SubnetsPrivate'

  RedisCluster:
    Type: 'AWS::ElastiCache::ReplicationGroup'
    Properties:
      AtRestEncryptionEnabled: false
      AutomaticFailoverEnabled: true
      AutoMinorVersionUpgrade: true
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroup
      Engine: redis
      EngineVersion: !Ref EngineVersion
      NumCacheClusters: 3
      Port: 6379
      AuthToken: !Ref RedisAuthToken
      PreferredMaintenanceWindow: 'sun:23:00-mon:01:30'
      ReplicationGroupDescription: 'ElastiCache Redis'
      ReplicationGroupId: !Sub '${AWS::StackName}'
      SecurityGroupIds:
      - !Ref SecurityGroup
      TransitEncryptionEnabled: true

Outputs:
  StackName:
    Description: 'Stack name'
    Value: !Sub '${AWS::StackName}'
  ClusterName:
    Description: 'The name of the cluster'
    Value: !Sub '${AWS::StackName}'
    Export:
      Name: !Sub '${AWS::StackName}::ClusterName'
  RedisEndPointAddress:
    Description: 'The DNS address of the cache nodes.'
    Value: !GetAtt 'RedisCluster.ConfigurationEndPoint.Address'
    Export:
      Name: !Sub '${AWS::StackName}::ConfigurationEndPointAddress'
  RedisEndPointPort:
    Description: 'The port where the cache nodes are listening on.'
    Value: !GetAtt 'RedisCluster.ConfigurationEndPoint.Port'
    Export:
      Name: !Sub '${AWS::StackName}::ConfigurationEndPointPort'
