项目作者: devopsrepohq

项目描述 :
Use this CDK stack to create a redis cluster and allow bastion host to access it.
高级语言: TypeScript
项目地址: git://github.com/devopsrepohq/redis.git
创建时间: 2020-08-02T00:46:20Z
项目社区:https://github.com/devopsrepohq/redis

开源协议:

下载


Use this CDK stack to create a redis cluster and allow bastion host to access it.

Redis architecture

What is it?

Amazon ElastiCache allows you to seamlessly set up, run, and scale popular open-Source compatible in-memory data stores in the cloud.

Features

  • Deploy a redis clusters
  • Setup to allow bastion host to access it

Prerequisites

You will need the following before utilize this CDK stack:

Stack Explain

cdk.json

Define project-name, env and profile context variables in cdk.json

  1. {
  2. "context": {
  3. "project-name": "container",
  4. "env": "dev",
  5. "profile": "devopsrepo"
  6. }
  7. }

lib/vpc-stack.ts

Setup standard VPC with public, private, and isolated subnets.

  1. const vpc = new ec2.Vpc(this, 'Vpc', {
  2. maxAzs: 3,
  3. natGateways: 1,
  4. cidr: '10.0.0.0/16',
  5. subnetConfiguration: [
  6. {
  7. cidrMask: 24,
  8. name: 'ingress',
  9. subnetType: ec2.SubnetType.PUBLIC,
  10. },
  11. {
  12. cidrMask: 24,
  13. name: 'application',
  14. subnetType: ec2.SubnetType.PRIVATE,
  15. },
  16. {
  17. cidrMask: 28,
  18. name: 'rds',
  19. subnetType: ec2.SubnetType.ISOLATED,
  20. }
  21. ]
  22. });
  • maxAzs - Define 3 AZs to use in this region.
  • natGateways - Create only 1 NAT Gateways/Instances.
  • cidr - Use ‘10.0.0.0/16’ CIDR range for the VPC.
  • subnetConfiguration - Build the public, private, and isolated subnet for each AZ.

Create flowlog and log the vpc traffic into cloudwatch

  1. vpc.addFlowLog('FlowLog');

lib/security-stack.ts

Get vpc create from vpc stack

  1. const { vpc } = props;

Create security group for bastion host

  1. const bastionSecurityGroup = new ec2.SecurityGroup(this, 'BastionSecurityGroup', {
  2. vpc: vpc,
  3. allowAllOutbound: true,
  4. description: 'Security group for bastion host',
  5. securityGroupName: 'BastionSecurityGroup'
  6. });
  • vpc - Use vpc created from vpc stack.
  • allowAllOutbound - Allow outbound rules for access internet
  • description - Description for security group
  • securityGroupName - Define the security group name

Allow ssh access to bastion host

  1. bastionSecurityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(22), 'SSH access');

Create security group for redis

  1. const redisSecurityGroup = new ec2.SecurityGroup(this, 'RedisSecurityGroup', {
  2. vpc: vpc,
  3. allowAllOutbound: true,
  4. description: 'Security group for Redis Cluster',
  5. securityGroupName: 'RedisSecurityGroup'
  6. });

Allow access from bastion host

  1. redisSecurityGroup.addIngressRule(bastionSecurityGroup, ec2.Port.tcp(6379), 'Access from bastion host');

lib/bastion-stack.ts

Get the vpc and bastionSecurityGroup from vpc and security stacks.

  1. const { vpc, bastionSecurityGroup } = props;

Get profile from context variables

  1. const profile = this.node.tryGetContext('profile');

Create bastion host instance in public subnet

  1. const bastionHostLinux = new ec2.BastionHostLinux(this, 'BastionHostLinux', {
  2. vpc: vpc,
  3. securityGroup: bastionSecurityGroup,
  4. subnetSelection: {
  5. subnetType: ec2.SubnetType.PUBLIC
  6. }
  7. });
  • vpc - Use vpc created from vpc stack.
  • securityGroup - Use security group created from security stack.
  • subnetSelection - Create the instance in public subnet.

Display commands for connect bastion host using ec2 instance connect

  1. const createSshKeyCommand = 'ssh-keygen -t rsa -f my_rsa_key';
  2. const pushSshKeyCommand = `aws ec2-instance-connect send-ssh-public-key --region ${cdk.Aws.REGION} --instance-id ${bastionHostLinux.instanceId} --availability-zone ${bastionHostLinux.instanceAvailabilityZone} --instance-os-user ec2-user --ssh-public-key file://my_rsa_key.pub ${profile ? `--profile ${profile}` : ''}`;
  3. const sshCommand = `ssh -o "IdentitiesOnly=yes" -i my_rsa_key ec2-user@${bastionHostLinux.instancePublicDnsName}`;
  4. new cdk.CfnOutput(this, 'CreateSshKeyCommand', { value: createSshKeyCommand });
  5. new cdk.CfnOutput(this, 'PushSshKeyCommand', { value: pushSshKeyCommand });
  6. new cdk.CfnOutput(this, 'SshCommand', { value: sshCommand});

lib/redis-stack.ts

Get the vpc and redisSecurityGroup from vpc and security stack

  1. const { vpc, redisSecurityGroup } = props;

Get projectName and env from context variables

  1. const projectName = this.node.tryGetContext('project-name');
  2. const env = this.node.tryGetContext('env');

Get all private subnet ids

  1. const privateSubnets = vpc.privateSubnets.map((subnet) => {
  2. return subnet.subnetId
  3. });

Create redis subnet group from private subnet ids

  1. const redisSubnetGroup = new redis.CfnSubnetGroup(this, 'RedisSubnetGroup', {
  2. subnetIds: privateSubnets,
  3. description: "Subnet group for redis"
  4. });
  • subnetIds - Assign the subnet ids to redis subnet group
  • description - Define the description for redis subnet group

Create Redis Cluster

  1. const redisCluster = new redis.CfnCacheCluster(this, 'RedisCluster', {
  2. autoMinorVersionUpgrade: true,
  3. cacheNodeType: 'cache.t2.small',
  4. engine: 'redis',
  5. numCacheNodes: 1,
  6. cacheSubnetGroupName: redisSubnetGroup.ref,
  7. clusterName: `${projectName}${env}`,
  8. vpcSecurityGroupIds: [redisSecurityGroup.securityGroupId]
  9. });
  • autoMinorVersionUpgrade - Allow auto upgrade for minor version.
  • cacheNodeType - Use ‘cache.t2.small’ for node type.
  • engine: Use redis.
  • numCacheNodes: Use 1 cache node.
  • cacheSubnetGroupName: Use redisSubnetGroup for cacheSubnetGroupName.
  • clusterName: Define the clusterName using project and env name pattern.
  • vpcSecurityGroupIds: Define the array for security group ids.

Define this redis cluster is depends on redis subnet group created first

  1. redisCluster.addDependsOn(redisSubnetGroup);

Deploy all the stacks to your aws account.

  1. cdk deploy '*'
  2. or
  3. cdk deploy '*' --profile your_profile_name

Useful commands

NPM commands

  • npm run build compile typescript to js
  • npm run watch watch for changes and compile
  • npm run test perform the jest unit tests

Toolkit commands

  • cdk list (ls) Lists the stacks in the app
  • cdk synthesize (synth) Synthesizes and prints the CloudFormation template for the specified stack(s)
  • cdk bootstrap Deploys the CDK Toolkit stack, required to deploy stacks containing assets
  • cdk deploy Deploys the specified stack(s)
  • cdk deploy '*' Deploys all stacks at once
  • cdk destroy Destroys the specified stack(s)
  • cdk destroy '*' Destroys all stacks at once
  • cdk diff Compares the specified stack with the deployed stack or a local CloudFormation template
  • cdk metadata Displays metadata about the specified stack
  • cdk init Creates a new CDK project in the current directory from a specified template
  • cdk context Manages cached context values
  • cdk docs (doc) Opens the CDK API reference in your browser
  • cdk doctor Checks your CDK project for potential problems

Pricing

As this cdk stack will create aws elasticache service, please refer the following link for pricing