AWSTemplateFormatVersion: 2010-09-09 Parameters: KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: 'AWS::EC2::KeyPair::KeyName' ConstraintDescription: Can contain only ASCII characters. SSHLocation: Description: The IP address range that can be used to SSH to the EC2 instances Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x DocDBUsername: Type: String Description: Username for the Amazon DocumentDB cluster DocDBPassword: Type: String Description: Password for the Amazon DocumentDB cluster NoEcho: true MinLength: 8 DocDBInstanceType: Type: String Description: Instance type for DocumentDB cluster Default: db.t3.medium AllowedValues: - db.t3.medium - db.r5.large - db.r5.xlarge - db.r5.2xlarge - db.r5.4xlarge - db.r5.12xlarge - db.r5.24xlarge EC2InstanceType: Type: String Description: Instance type for EC2 instance Default: m5.large AllowedValues: - m5.large - m5.xlarge - m5.2xlarge - m5.4xlarge - m5.8xlarge - m5.12xlarge - m5.16xlarge - m5.24xlarge MongoDBUsername: Type: String Description: Username for the MongoDB database MongoDBPassword: Type: String Description: Password for the MongoDB database NoEcho: true MinLength: 8 Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "DocumentDB Configuration" Parameters: - DocDBInstanceType - DocDBUsername - DocDBPassword - Label: default: "EC2 Configuration" Parameters: - EC2InstanceType - KeyName - SSHLocation - Label: default: "MongoDB Configuration" Parameters: - MongoDBUsername - MongoDBPassword Mappings: SubnetConfig: VPC: CIDR: 10.0.0.0/16 PublicOne: CIDR: 10.0.0.0/24 PrivateOne: CIDR: 10.0.1.0/24 PrivateTwo: CIDR: 10.0.2.0/24 PrivateThree: CIDR: 10.0.3.0/24 RegionAMI: ap-northeast-1: "AMI": "ami-0cc75a8978fbbc969" ap-northeast-2: "AMI": "ami-0bd7691bf6470fe9c" ap-south-1: "AMI": "ami-0ebc1ac48dfd14136" ap-southeast-1: "AMI": "ami-0cd31be676780afa7" ap-southeast-2: "AMI": "ami-0ded330691a314693" ca-central-1: "AMI": "ami-013d1df4bcea6ba95" eu-central-1: "AMI": "ami-0c115dbd34c69a004" eu-west-1: "AMI": "ami-07d9160fa81ccffb5" eu-west-2: "AMI": "ami-0a13d44dccf1f5cf6" eu-west-3: "AMI": "ami-093fa4c538885becf" us-east-1: "AMI": "ami-02354e95b39ca8dec" us-east-2: "AMI": "ami-07c8bc5c1ce9598c3" us-west-2: "AMI": "ami-0873b46c45c11058d" Resources: VPC: Type: 'AWS::EC2::VPC' Properties: EnableDnsSupport: true EnableDnsHostnames: true CidrBlock: !FindInMap - SubnetConfig - VPC - CIDR Tags: - Key: Name Value: !Sub ${AWS::StackName}-VPC PublicSubnetOne: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Select - 0 - !GetAZs Ref: 'AWS::Region' VpcId: !Ref VPC CidrBlock: !FindInMap - SubnetConfig - PublicOne - CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${AWS::StackName}-PublicSubnet PrivateSubnetOne: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Select - 0 - !GetAZs Ref: 'AWS::Region' VpcId: !Ref VPC CidrBlock: !FindInMap - SubnetConfig - PrivateOne - CIDR Tags: - Key: Name Value: !Sub ${AWS::StackName}-PrivateSubnetOne PrivateSubnetTwo: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Select - 1 - !GetAZs Ref: 'AWS::Region' VpcId: !Ref VPC CidrBlock: !FindInMap - SubnetConfig - PrivateTwo - CIDR Tags: - Key: Name Value: !Sub ${AWS::StackName}-PrivateSubnetTwo PrivateSubnetThree: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Select - 2 - !GetAZs Ref: 'AWS::Region' VpcId: !Ref VPC CidrBlock: !FindInMap - SubnetConfig - PrivateThree - CIDR Tags: - Key: Name Value: !Sub ${AWS::StackName}-PrivateSubnetThree InternetGateway: Type: 'AWS::EC2::InternetGateway' GatewayAttachement: Type: 'AWS::EC2::VPCGatewayAttachment' Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway PublicRouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PublicRoute: Type: 'AWS::EC2::Route' DependsOn: GatewayAttachement Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetOneRouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: SubnetId: !Ref PublicSubnetOne RouteTableId: !Ref PublicRouteTable PrivateRouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref VPC PrivateSubnetOneRouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnetOne PrivateSubnetTwoRouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnetTwo PrivateSubnetThreeRouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnetThree # DocumentDB DocumentDBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Amazon DocumentDB Security Group GroupName: !Sub ${AWS::StackName}-SG-DocumentDB VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp CidrIp: 10.0.0.0/16 FromPort: 27017 ToPort: 27017 Tags: - Key: Name Value: !Sub ${AWS::StackName}-SG-DocumentDB DocumentDBSubnetGroup: Type: AWS::DocDB::DBSubnetGroup Properties: DBSubnetGroupDescription: Subnet Group for DocumentDB DBSubnetGroupName: !Sub ${AWS::StackName}-SG-DocumentDB SubnetIds: - !Ref PrivateSubnetOne - !Ref PrivateSubnetTwo - !Ref PrivateSubnetThree Tags: - Key: Name Value: !Sub ${AWS::StackName}-SG-DocumentDB DocumentDBCluster: Type: AWS::DocDB::DBCluster Properties: DBClusterIdentifier: !Sub ${AWS::StackName}-DocumentDB MasterUsername: !Ref DocDBUsername MasterUserPassword: !Ref DocDBPassword DBSubnetGroupName : !Ref DocumentDBSubnetGroup StorageEncrypted: yes Tags: - Key: Name Value: !Sub ${AWS::StackName}-DocumentDB VpcSecurityGroupIds: - !Ref DocumentDBSecurityGroup DependsOn: VPC DocumentDBInstance1: Type: AWS::DocDB::DBInstance Properties: DBClusterIdentifier: !Ref DocumentDBCluster DBInstanceClass: !Ref DocDBInstanceType Tags: - Key: Name Value: !Sub ${AWS::StackName}-DocumentDBInstance1 DocumentDBInstance2: Type: AWS::DocDB::DBInstance Properties: DBClusterIdentifier: !Ref DocumentDBCluster DBInstanceClass: !Ref DocDBInstanceType Tags: - Key: Name Value: !Sub ${AWS::StackName}-DocumentDBInstance2 DocumentDBInstance3: Type: AWS::DocDB::DBInstance Properties: DBClusterIdentifier: !Ref DocumentDBCluster DBInstanceClass: !Ref DocDBInstanceType Tags: - Key: Name Value: !Sub ${AWS::StackName}-DocumentDBInstance3 DocDBSecret: Type: 'AWS::SecretsManager::Secret' Properties: Name: !Sub ${AWS::StackName}-DocDBSecret Description: This secret has the credentials for the DocumentDB cluster SecretString: !Join - '' - - '{"username":"' - !Ref DocDBUsername - '","password":"' - !Ref DocDBPassword - '", "ssl": true}' SecretDocDBClusterAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: !Ref DocDBSecret TargetId: !Ref DocumentDBCluster TargetType: AWS::DocDB::DBCluster # EC2 ClientInstanceSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable SSH access via port 22 VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SSHLocation ClientEC2Instance: Type: 'AWS::EC2::Instance' Properties: InstanceType: !Ref EC2InstanceType KeyName: !Ref KeyName IamInstanceProfile: !Ref EC2InstanceProfile AvailabilityZone: !Select - 0 - !GetAZs Ref: 'AWS::Region' SubnetId: !Ref PublicSubnetOne SecurityGroupIds: - !Ref ClientInstanceSecurityGroup - !Ref DocumentDBSecurityGroup ImageId: !FindInMap - RegionAMI - !Ref 'AWS::Region' - AMI Tags: - Key: Name Value: !Sub ${AWS::StackName}-ClientInstance UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y yum install python3.7 -y yum install java-1.8.0-openjdk-devel -y cd /home/ec2-user mkdir /home/ec2-user/setup cd /home/ec2-user/setup wget https://bootstrap.pypa.io/get-pip.py sudo python3.7 get-pip.py sudo python3.7 -m pip install boto3 pymongo echo "downloading mongondb-org 4.0 packages from https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/ ..." >>/tmp/mongosetup.log wget https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/mongodb-org-4.0.21-1.amzn1.x86_64.rpm wget https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/mongodb-org-server-4.0.21-1.amzn1.x86_64.rpm wget https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/mongodb-org-shell-4.0.21-1.amzn1.x86_64.rpm wget https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/mongodb-org-mongos-4.0.21-1.amzn1.x86_64.rpm wget https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/RPMS/mongodb-org-tools-4.0.21-1.amzn1.x86_64.rpm echo "running rpm for mongodb-org installation..." >>/tmp/mongosetup.log rpm -Uvh mongodb-org-tools-4.0.21-1.amzn1.x86_64.rpm >>/tmp/mongosetup.log rpm -Uvh mongodb-org-mongos-4.0.21-1.amzn1.x86_64.rpm >>/tmp/mongosetup.log rpm -Uvh mongodb-org-server-4.0.21-1.amzn1.x86_64.rpm >>/tmp/mongosetup.log rpm -Uvh mongodb-org-shell-4.0.21-1.amzn1.x86_64.rpm >>/tmp/mongosetup.log rpm -Uvh mongodb-org-4.0.21-1.amzn1.x86_64.rpm >>/tmp/mongosetup.log echo "starting mongo service... " >>/tmp/mongosetup.log service mongod start >>/tmp/mongosetup.log chkconfig mongod on >>/tmp/mongosetup.log echo "db = db.getSiblingDB('admin') " | tee -a file.js echo "db.createUser({ user: \"${MongoDBUsername}\" , pwd: \"${MongoDBPassword}\", roles: [{ role : \"read\", db : \"local\" },\"userAdminAnyDatabase\", \"dbAdminAnyDatabase\", \"readWriteAnyDatabase\", \"clusterManager\", \"clusterAdmin\"]})" | tee -a file.js echo "complete user creation and permissions" >>/tmp/mongosetup.log mongo file.js >>/tmp/mongosetup.log sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mongod.conf sed -i '/#security:/d' /etc/mongod.conf echo "security:" | tee -a /etc/mongod.conf echo " authorization: 'enabled'" | tee -a /etc/mongod.conf service mongod restart echo "db = db.getSiblingDB('admin') " | tee file2.js echo "rs.initiate( {_id : \"rs0\",members: [{ _id: 0, host: \"localhost:27017\" }]})" | tee -a file2.js echo "rs.conf()" | tee -a file2.js echo "setup replication configuration..." >>/tmp/mongosetup.log sed -i '/#replication:/d' /etc/mongod.conf echo "replication:" | tee -a /etc/mongod.conf echo " replSetName: "rs0"" | tee -a /etc/mongod.conf echo "restarting mongo service with replicaset.. " >>/tmp/mongosetup.log service mongod restart >>/tmp/mongosetup.log echo "setup replication..." >>/tmp/mongosetup.log mongo mongodb://${MongoDBUsername}:${MongoDBPassword}@localhost/admin file2.js >>/tmp/mongosetup.log cd /home/ec2-user wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem EC2Role: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' Effect: Allow Principal: Service: ec2.amazonaws.com Action: 'sts:AssumeRole' Path: / ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonS3FullAccess' Policies: - PolicyName: !Sub ${AWS::StackName}-DocumentDBSecretPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: !Ref DocDBSecret EC2InstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: InstanceProfileName: !Sub ${AWS::StackName}-EC2Profile Roles: - !Ref EC2Role Outputs: VPCId: Description: The ID of the VPC created Value: !Ref VPC PublicSubnetOne: Description: The name of the public subnet created Value: !Ref PublicSubnetOne PrivateSubnetOne: Description: The ID of private subnet one created Value: !Ref PrivateSubnetOne PrivateSubnetTwo: Description: The ID of private subnet two created Value: !Ref PrivateSubnetTwo PrivateSubnetThree: Description: The ID of private subnet three created Value: !Ref PrivateSubnetThree ClientEC2InstancePublicDNS: Description: The Public DNS for the MirrorMaker EC2 instance Value: !GetAtt - ClientEC2Instance - PublicDnsName DocumentDBClusterName: Value: !Ref DocumentDBCluster DocumentDBCluster: Value: !GetAtt DocumentDBCluster.Endpoint DocDBSecret: Value: !Ref DocDBSecret