-
-
Save angryTit/7ee7f77995996f0a4a793a6ac38851dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"Description": "Neo4j on AWS", | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Mappings": { | |
"AWSRegionArch2AMI": { | |
"ap-northeast-1": { | |
"64": "ami-06302e6ac02fc6c3e" | |
}, | |
"ap-southeast-1": { | |
"64": "ami-0ae3b1104eed0d04c" | |
}, | |
"eu-central-1": { | |
"64": "ami-01c3d234360b93e5d" | |
}, | |
"eu-west-1": { | |
"64": "ami-0d7656f1b46ca9e7e" | |
}, | |
"sa-east-1": { | |
"64": "ami-06b4c3ac60b242457" | |
}, | |
"us-east-1": { | |
"64": "ami-0b7914d1dfef90465" | |
}, | |
"us-east-2": { | |
"64": "ami-0e8145923643f75ad" | |
}, | |
"us-west-1": { | |
"64": "ami-0babbbbf2f70e2683" | |
}, | |
"us-west-2": { | |
"64": "ami-0969943ae3ba4b7f4" | |
} | |
} | |
}, | |
"Parameters": { | |
"InstanceType": { | |
"Description": "EC2 instance type", | |
"Type": "String", | |
"Default": "t2.medium", | |
"AllowedValues": [ | |
"m4.large", | |
"m4.xlarge", | |
"m4.2xlarge", | |
"m4.4xlarge", | |
"m4.10xlarge", | |
"m4.16xlarge", | |
"m5.large", | |
"m5.xlarge", | |
"m5.2xlarge", | |
"m5.4xlarge", | |
"m5.12xlarge", | |
"m5.24xlarge", | |
"t2.medium", | |
"t2.large", | |
"t2.xlarge", | |
"t2.2xlarge", | |
"x1e.16xlarge", | |
"x1e.8xlarge", | |
"x1e.4xlarge", | |
"x1e.2xlarge", | |
"x1e.xlarge", | |
"x1.16xlarge", | |
"r5.large", | |
"r5.xlarge", | |
"r5.2xlarge", | |
"r5.4xlarge", | |
"r5.8xlarge", | |
"r5.16xlarge" | |
], | |
"ConstraintDescription": "Must be a valid EC2 instance type." | |
}, | |
"ClusterNodes": { | |
"Description": "Number of core cluster node VMs", | |
"Type": "Number", | |
"Default": 3, | |
"MinValue": 1, | |
"MaxValue": 7 | |
}, | |
"ReadReplicas": { | |
"Description": "Number of read replicas in the cluster", | |
"Type": "Number", | |
"Default": 0, | |
"MinValue": 0, | |
"MaxValue": 5 | |
}, | |
"SSHKeyName": { | |
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances", | |
"Type": "AWS::EC2::KeyPair::KeyName", | |
"AllowedPattern": ".+" | |
}, | |
"NetworkWhitelist": { | |
"Description": " The IP address range that can be used to connect to Neo4j", | |
"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. For example, 0.0.0.0/0 for open internet access." | |
}, | |
"Password": { | |
"NoEcho": true, | |
"Description": "initial neo4j password (uppercase, lowercase, and numbers only)", | |
"Type": "String", | |
"MinLength": 8, | |
"MaxLength": 40, | |
"AllowedPattern": "^[a-zA-Z0-9\\.-]+$" | |
}, | |
"VolumeType": { | |
"Description": "What kind of storage to attach", | |
"Type": "String", | |
"Default": "gp2", | |
"AllowedValues": [ | |
"io1", | |
"gp2", | |
"st1" | |
] | |
}, | |
"EncryptDataVolume": { | |
"Description": "Should EBS storage be encrypted? Default is yes.", | |
"Type": "String", | |
"Default": "true", | |
"AllowedValues": [ | |
"true", | |
"false" | |
] | |
}, | |
"VolumeSizeGB": { | |
"Description": "How much EBS storage is allocated to each cluster node, in GiB", | |
"Type": "Number", | |
"Default": "100", | |
"MinValue": "10", | |
"MaxValue": "1000", | |
"ConstraintDescription": "Must be a valid EBS disk size in GiB." | |
} | |
}, | |
"Metadata": { | |
"AWS::CloudFormation::Interface": { | |
"ParameterGroups": [ | |
{ | |
"Label": { | |
"default": "Cluster Configuration" | |
}, | |
"Parameters": [ | |
"ClusterNodes", | |
"ReadReplicas" | |
] | |
}, | |
{ | |
"Label": { | |
"default": "Amazon EC2 Configuration" | |
}, | |
"Parameters": [ | |
"InstanceType", | |
"VolumeType", | |
"VolumeSizeGB", | |
"EncryptDataVolume" | |
] | |
}, | |
{ | |
"Label": { | |
"default": "Access Control" | |
}, | |
"Parameters": [ | |
"SSHKeyName", | |
"NetworkWhitelist", | |
"Password" | |
] | |
} | |
] | |
} | |
}, | |
"Conditions": { | |
"CreateNode0": { | |
"Fn::Equals": [ | |
true, | |
true | |
] | |
}, | |
"CreateNode1": { | |
"Fn::Equals": [ | |
true, | |
true | |
] | |
}, | |
"CreateNode2": { | |
"Fn::Equals": [ | |
true, | |
true | |
] | |
}, | |
"CreateNode3": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
4 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
5 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
6 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
7 | |
] | |
} | |
] | |
}, | |
"CreateNode4": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
5 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
6 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
7 | |
] | |
} | |
] | |
}, | |
"CreateNode5": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
6 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
7 | |
] | |
} | |
] | |
}, | |
"CreateNode6": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
0, | |
1 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ClusterNodes" | |
}, | |
7 | |
] | |
} | |
] | |
}, | |
"CreateReplica0": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
1 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
2 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
3 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
4 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
5 | |
] | |
} | |
] | |
}, | |
"CreateReplica1": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
2 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
3 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
4 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
5 | |
] | |
} | |
] | |
}, | |
"CreateReplica2": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
3 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
4 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
5 | |
] | |
} | |
] | |
}, | |
"CreateReplica3": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
4 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
5 | |
] | |
} | |
] | |
}, | |
"CreateReplica4": { | |
"Fn::Or": [ | |
{ | |
"Fn::Equals": [ | |
0, | |
1 | |
] | |
}, | |
{ | |
"Fn::Equals": [ | |
{ | |
"Ref": "ReadReplicas" | |
}, | |
5 | |
] | |
} | |
] | |
} | |
}, | |
"Resources": { | |
"VPC": { | |
"Type": "AWS::EC2::VPC", | |
"Properties": { | |
"EnableDnsSupport": "true", | |
"EnableDnsHostnames": "true", | |
"InstanceTenancy": "default", | |
"CidrBlock": "10.0.0.0/16", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jVPC", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
] | |
} | |
}, | |
"DNSZone": { | |
"Type": "AWS::Route53::HostedZone", | |
"DependsOn": "VPC", | |
"Properties": { | |
"HostedZoneConfig": { | |
"Comment": "Zone to define private DNS for neo4j nodes" | |
}, | |
"Name": "neo4j", | |
"VPCs": [ | |
{ | |
"VPCId": { | |
"Ref": "VPC" | |
}, | |
"VPCRegion": { | |
"Ref": "AWS::Region" | |
} | |
} | |
], | |
"HostedZoneTags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jPrivateZone", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
} | |
] | |
} | |
}, | |
"Subnet0": { | |
"Type": "AWS::EC2::Subnet", | |
"Properties": { | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"CidrBlock": "10.0.0.0/24", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jSubnet0", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
], | |
"MapPublicIpOnLaunch": "true" | |
} | |
}, | |
"SubnetRouteTableAssociation0": { | |
"Type": "AWS::EC2::SubnetRouteTableAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet0" | |
}, | |
"RouteTableId": { | |
"Ref": "RouteTable" | |
} | |
} | |
}, | |
"SubnetNetworkAclAssociation0": { | |
"Type": "AWS::EC2::SubnetNetworkAclAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet0" | |
}, | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
} | |
} | |
}, | |
"Subnet1": { | |
"Type": "AWS::EC2::Subnet", | |
"Properties": { | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
1, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"CidrBlock": "10.0.1.0/24", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jSubnet1", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
], | |
"MapPublicIpOnLaunch": "true" | |
} | |
}, | |
"SubnetRouteTableAssociation1": { | |
"Type": "AWS::EC2::SubnetRouteTableAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet1" | |
}, | |
"RouteTableId": { | |
"Ref": "RouteTable" | |
} | |
} | |
}, | |
"SubnetNetworkAclAssociation1": { | |
"Type": "AWS::EC2::SubnetNetworkAclAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet1" | |
}, | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
} | |
} | |
}, | |
"Subnet2": { | |
"Type": "AWS::EC2::Subnet", | |
"Properties": { | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
2, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"CidrBlock": "10.0.2.0/24", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jSubnet2", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
], | |
"MapPublicIpOnLaunch": "true" | |
} | |
}, | |
"SubnetRouteTableAssociation2": { | |
"Type": "AWS::EC2::SubnetRouteTableAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet2" | |
}, | |
"RouteTableId": { | |
"Ref": "RouteTable" | |
} | |
} | |
}, | |
"SubnetNetworkAclAssociation2": { | |
"Type": "AWS::EC2::SubnetNetworkAclAssociation", | |
"Properties": { | |
"SubnetId": { | |
"Ref": "Subnet2" | |
}, | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
} | |
} | |
}, | |
"InternetGateway": { | |
"Type": "AWS::EC2::InternetGateway", | |
"Properties": { | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jGateway", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
] | |
} | |
}, | |
"AttachGateway": { | |
"Type": "AWS::EC2::VPCGatewayAttachment", | |
"Properties": { | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"InternetGatewayId": { | |
"Ref": "InternetGateway" | |
} | |
} | |
}, | |
"RouteTable": { | |
"Type": "AWS::EC2::RouteTable", | |
"Properties": { | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"Neo4jRouteTable", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
] | |
} | |
}, | |
"Route": { | |
"Type": "AWS::EC2::Route", | |
"DependsOn": "AttachGateway", | |
"Properties": { | |
"RouteTableId": { | |
"Ref": "RouteTable" | |
}, | |
"DestinationCidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"GatewayId": { | |
"Ref": "InternetGateway" | |
} | |
} | |
}, | |
"NetworkAcl": { | |
"Type": "AWS::EC2::NetworkAcl", | |
"Properties": { | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"Tags": [ | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
} | |
] | |
} | |
}, | |
"SSHIngressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "101", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "22", | |
"To": "22" | |
} | |
} | |
}, | |
"SSHEgressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "102", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "22", | |
"To": "22" | |
} | |
} | |
}, | |
"BoltIngressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "102", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "7689", | |
"To": "7689" | |
} | |
} | |
}, | |
"BoltEgressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "104", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "7689", | |
"To": "7689" | |
} | |
} | |
}, | |
"Neo4jHTTPSIngressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "103", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "7473", | |
"To": "7473" | |
} | |
} | |
}, | |
"Neo4jHTTPSEgressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "106", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "7473", | |
"To": "7473" | |
} | |
} | |
}, | |
"HTTPSIngressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "104", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "443", | |
"To": "443" | |
} | |
} | |
}, | |
"HTTPSEgressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "108", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "443", | |
"To": "443" | |
} | |
} | |
}, | |
"HTTPIngressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "105", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "80", | |
"To": "80" | |
} | |
} | |
}, | |
"HTTPEgressNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "110", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "80", | |
"To": "80" | |
} | |
} | |
}, | |
"Int1NetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "201", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": "10.0.0.0/16", | |
"PortRange": { | |
"From": "5000", | |
"To": "5000" | |
} | |
} | |
}, | |
"Int2NetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "202", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": "10.0.0.0/16", | |
"PortRange": { | |
"From": "6000", | |
"To": "6000" | |
} | |
} | |
}, | |
"Int3NetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "203", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": "10.0.0.0/16", | |
"PortRange": { | |
"From": "7000", | |
"To": "7000" | |
} | |
} | |
}, | |
"InboundResponsePortsNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "300", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "false", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "1024", | |
"To": "65535" | |
} | |
} | |
}, | |
"OutBoundResponsePortsNetworkAclEntry": { | |
"Type": "AWS::EC2::NetworkAclEntry", | |
"Properties": { | |
"NetworkAclId": { | |
"Ref": "NetworkAcl" | |
}, | |
"RuleNumber": "301", | |
"Protocol": "6", | |
"RuleAction": "allow", | |
"Egress": "true", | |
"CidrBlock": { | |
"Ref": "NetworkWhitelist" | |
}, | |
"PortRange": { | |
"From": "1024", | |
"To": "65535" | |
} | |
} | |
}, | |
"ReadOwnTags": { | |
"Type": "AWS::IAM::Role", | |
"Properties": { | |
"RoleName": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"work-with-tags", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
}, | |
"AssumeRolePolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Principal": { | |
"Service": "ec2.amazonaws.com" | |
}, | |
"Action": "sts:AssumeRole" | |
} | |
] | |
}, | |
"Policies": [ | |
{ | |
"PolicyName": "root", | |
"PolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": "s3:*", | |
"Resource": "*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": "ec2:CreateTags", | |
"Resource": "*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": "ec2:Describe*", | |
"Resource": "*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": "elasticloadbalancing:Describe*", | |
"Resource": "*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"cloudwatch:ListMetrics", | |
"cloudwatch:GetMetricStatistics", | |
"cloudwatch:Describe*" | |
], | |
"Resource": "*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": "autoscaling:Describe*", | |
"Resource": "*" | |
} | |
] | |
} | |
} | |
] | |
} | |
}, | |
"instProfNeo4jEnterprise": { | |
"Type": "AWS::IAM::InstanceProfile", | |
"Properties": { | |
"Roles": [ | |
{ | |
"Ref": "ReadOwnTags" | |
} | |
], | |
"InstanceProfileName": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"read-own-tags-ip", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
} | |
}, | |
"sgNeo4jEnterprise": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"VpcId": { | |
"Ref": "VPC" | |
}, | |
"GroupDescription": "Neo4j Ports", | |
"SecurityGroupIngress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "5000", | |
"ToPort": "5000", | |
"CidrIp": "10.0.0.0/16" | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "6000", | |
"ToPort": "6000", | |
"CidrIp": "10.0.0.0/16" | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "7000", | |
"ToPort": "7000", | |
"CidrIp": "10.0.0.0/16" | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "22", | |
"ToPort": "22", | |
"CidrIp": { | |
"Ref": "NetworkWhitelist" | |
} | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "7687", | |
"ToPort": "7687", | |
"CidrIp": { | |
"Ref": "NetworkWhitelist" | |
} | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "7473", | |
"ToPort": "7473", | |
"CidrIp": { | |
"Ref": "NetworkWhitelist" | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer0DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode0", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 0.", | |
"Name": "node0.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer0", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer0": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode0", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet0" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-0", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"0" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer1DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode1", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 1.", | |
"Name": "node1.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer1", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer1": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode1", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
1, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet1" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-1", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"1" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer2DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode2", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 2.", | |
"Name": "node2.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer2", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer2": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode2", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
2, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet2" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-2", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"2" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer3DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode3", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 3.", | |
"Name": "node3.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer3", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer3": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode3", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet0" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-3", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"3" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer4DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode4", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 4.", | |
"Name": "node4.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer4", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer4": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode4", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
1, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet1" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-4", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"4" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer5DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode5", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 5.", | |
"Name": "node5.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer5", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer5": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode5", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
2, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet2" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-5", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"5" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jServer6DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateNode6", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j node 6.", | |
"Name": "node6.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer6", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jServer6": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateNode6", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet0" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-CORE-vm-6", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "CORE" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"6" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jReplica0DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateReplica0", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j replica 0.", | |
"Name": "replica0.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer0", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jReplica0": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateReplica0", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet0" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-READ_REPLICA-vm-0", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "READ_REPLICA" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"0" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jReplica1DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateReplica1", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j replica 1.", | |
"Name": "replica1.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer1", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jReplica1": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateReplica1", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
1, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet1" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-READ_REPLICA-vm-1", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "READ_REPLICA" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"1" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jReplica2DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateReplica2", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j replica 2.", | |
"Name": "replica2.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer2", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jReplica2": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateReplica2", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
2, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet2" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-READ_REPLICA-vm-2", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "READ_REPLICA" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"2" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jReplica3DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateReplica3", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j replica 3.", | |
"Name": "replica3.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer3", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jReplica3": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateReplica3", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
0, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet0" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-READ_REPLICA-vm-3", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "READ_REPLICA" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"3" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"Neo4jReplica4DNS": { | |
"Type": "AWS::Route53::RecordSet", | |
"Condition": "CreateReplica4", | |
"DependsOn": "DNSZone", | |
"Properties": { | |
"HostedZoneId": { | |
"Ref": "DNSZone" | |
}, | |
"Comment": "DNS names for neo4j replica 4.", | |
"Name": "replica4.neo4j.", | |
"Type": "A", | |
"TTL": "900", | |
"ResourceRecords": [ | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer4", | |
"PrivateIp" | |
] | |
} | |
] | |
} | |
}, | |
"Neo4jReplica4": { | |
"Type": "AWS::EC2::Instance", | |
"Condition": "CreateReplica4", | |
"Properties": { | |
"IamInstanceProfile": { | |
"Ref": "instProfNeo4jEnterprise" | |
}, | |
"AvailabilityZone": { | |
"Fn::Select": [ | |
1, | |
{ | |
"Fn::GetAZs": { | |
"Ref": "AWS::Region" | |
} | |
} | |
] | |
}, | |
"DisableApiTermination": "FALSE", | |
"ImageId": { | |
"Fn::FindInMap": [ | |
"AWSRegionArch2AMI", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
"64" | |
] | |
}, | |
"NetworkInterfaces": [ | |
{ | |
"GroupSet": [ | |
{ | |
"Ref": "sgNeo4jEnterprise" | |
} | |
], | |
"AssociatePublicIpAddress": "true", | |
"DeviceIndex": "0", | |
"DeleteOnTermination": "true", | |
"SubnetId": { | |
"Ref": "Subnet1" | |
} | |
} | |
], | |
"InstanceType": { | |
"Ref": "InstanceType" | |
}, | |
"KeyName": { | |
"Ref": "SSHKeyName" | |
}, | |
"Monitoring": "false", | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": { | |
"Fn::Join": [ | |
"-", | |
[ | |
"neo4j-READ_REPLICA-vm-4", | |
{ | |
"Ref": "AWS::StackName" | |
} | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "Application", | |
"Value": { | |
"Ref": "AWS::StackId" | |
} | |
}, | |
{ | |
"Key": "neo4j_mode", | |
"Value": "cluster" | |
}, | |
{ | |
"Key": "dbms_mode", | |
"Value": "READ_REPLICA" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_minimum_core_cluster_size_at_formation", | |
"Value": "3" | |
}, | |
{ | |
"Key": "causal_clustering_initial_discovery_members", | |
"Value": { | |
"Fn::Join": [ | |
",", | |
[ | |
"node0.neo4j:5000", | |
"node1.neo4j:5000", | |
"node2.neo4j:5000" | |
] | |
] | |
} | |
}, | |
{ | |
"Key": "initial_password", | |
"Value": { | |
"Ref": "Password" | |
} | |
}, | |
{ | |
"Key": "InstanceID", | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
"4" | |
] | |
] | |
} | |
} | |
], | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ | |
"", | |
[ | |
"#!/bin/bash\n", | |
"#\n", | |
"# This script starts at the launch of a VM, and handles final cluster coordination.\n", | |
"LOGFILE=/home/ubuntu/setup.log\n", | |
"echo `date` 'Preparing Causal Cluster' | tee -a $LOGFILE\n", | |
"\n", | |
"/bin/systemctl stop neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"export API=http://169.254.169.254/latest/\n", | |
"export EC2_AVAIL_ZONE=$(curl --silent $API/meta-data/placement/availability-zone)\n", | |
"export EC2_INSTANCE_ID=$(curl -s $API/meta-data/instance-id)\n", | |
"export EC2_REGION=$(curl -s $API/dynamic/instance-identity/document | jq -r .region)\n", | |
"export ROOT_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sda1 --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"export DATA_DISK_ID=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${EC2_INSTANCE_ID} Name=attachment.device,Values=/dev/sdb --query 'Volumes[*].[VolumeId]' --region=${EC2_REGION} --out text | cut -f 1)\n", | |
"env | tee -a $LOGFILE\n", | |
"# Tag volumes, which CloudFormation does not allow\n", | |
"# Root volume: /dev/sda, data volume /dev/sdb\n", | |
"aws ec2 create-tags --resources $ROOT_DISK_ID --tags Key=Name,Value=\"Root Neo4j Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"aws ec2 create-tags --resources $DATA_DISK_ID --tags Key=Name,Value=\"Neo4j Data Vol for $EC2_INSTANCE_ID\" --region ${EC2_REGION} 2>&1 | tee -a $LOGFILE\n", | |
"# Format EBS storage, and mount it in Neo4j directory\n", | |
"echo `date` 'Preparing neo4j volume...' | tee -a $LOGFILE\n", | |
"mkfs -t ext4 /dev/xvdb 2>&1 | tee -a $LOGFILE\n", | |
"mkdir /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"cp --preserve=all -r /var/lib/neo4j/* /tmpmount/ 2>&1 | tee -a $LOGFILE\n", | |
"umount /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"rm -rf /tmpmount 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Remounting new volume in place...' | tee -a $LOGFILE\n", | |
"mount /dev/xvdb /var/lib/neo4j 2>&1 | tee -a $LOGFILE\n", | |
"FSTAB_ENTRY='/dev/xvdb /var/lib/neo4j ext4 defaults,discard 0 2'\n", | |
"echo $FSTAB_ENTRY >> /etc/fstab\n", | |
"mount -a 2>&1 | tee -a $LOGFILE\n", | |
"echo `date` 'Preparing neo4j service...' | tee -a $LOGFILE\n", | |
"/bin/rm -rf /var/lib/neo4j/data/databases/graph.db/ 2>&1 | tee -a $LOGFILE\n", | |
"/bin/systemctl start neo4j.service 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
"sudo apt-get update\n", | |
"mkdir neo4jjars\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/graphaware-server-community-all-3.5.2.jar neo4jjars/graphaware-server-community-all-3.5.2.jar\n", | |
"aws s3 cp s3://prod-company-neo4j-jars/relationships-1.0-SNAPSHOT.jar neo4jjars/relationships-1.0-SNAPSHOT.jar\n", | |
"cp neo4jjars/graphaware-server-community-all-3.5.2.jar /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"cp neo4jjars/relationships-1.0-SNAPSHOT.jar /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/graphaware-server-community-all-3.5.2.jar\n", | |
"chown neo4j:neo4j /var/lib/neo4j/plugins/relationships-1.0-SNAPSHOT.jar\n", | |
"echo dbms.unmanaged_extension_classes=com.graphaware.server=/graphaware >> /etc/neo4j/neo4j.template\n", | |
"mkdir aws-cfn-bootstrap-latest\n", | |
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n", | |
"easy_install aws-cfn-bootstrap-latest\n", | |
"\n", | |
"echo Stack ID '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | tee -a $LOGFILE\n", | |
"export STACK_TOKEN=$(echo '", | |
{ | |
"Ref": "AWS::StackId" | |
}, | |
"' | base64 | tail -c 12)\n", | |
"# Loop waiting for neo4j service to start.\n", | |
"while true; do\n", | |
" if curl -s -I http://localhost:7474 | grep '200 OK'; then\n", | |
" echo `date` 'Neo4j is up; changing default password' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" curl -v -H 'Content-Type: application/json' \\n", | |
" -XPOST -d '{\"password\":\"", | |
{ | |
"Ref": "Password" | |
}, | |
"\"}' \\\n", | |
" -u neo4j:neo4j \\\n", | |
" http://localhost:7474/user/neo4j/password \\\n", | |
" 2>&1 | tee -a $LOGFILE\n", | |
" echo `date` 'Password reset; a graph user is you!' 2>&1 | tee -a $LOGFILE\n", | |
"\n", | |
" echo `date` 'Startup complete ' | tee -a $LOGFILE\n", | |
" break\n", | |
" fi\n", | |
"\n", | |
" echo `date` 'Waiting for neo4j to come up' 2>&1 | tee -a $LOGFILE\n", | |
" sleep 1\n", | |
"done\n", | |
"\n", | |
"echo Signaling stack success | tee -a $LOGFILE\n", | |
"/usr/local/bin/cfn-signal --stack ", | |
{ | |
"Ref": "AWS::StackName" | |
}, | |
" \\\n", | |
" --id $EC2_INSTANCE_ID \\\n", | |
" --region ", | |
{ | |
"Ref": "AWS::Region" | |
}, | |
" \\\n", | |
" --success true -d \"$STACK_TOKEN\" '", | |
{ | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"' 2>&1 | tee -a $LOGFILE \n" | |
] | |
] | |
} | |
}, | |
"BlockDeviceMappings": [ | |
{ | |
"DeviceName": "/dev/sda1", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": "10", | |
"DeleteOnTermination": "true" | |
} | |
}, | |
{ | |
"DeviceName": "/dev/sdb", | |
"Ebs": { | |
"VolumeType": { | |
"Ref": "VolumeType" | |
}, | |
"VolumeSize": { | |
"Ref": "VolumeSizeGB" | |
}, | |
"Encrypted": { | |
"Ref": "EncryptDataVolume" | |
} | |
} | |
} | |
] | |
} | |
}, | |
"StackTokenWaitHandle": { | |
"Type": "AWS::CloudFormation::WaitConditionHandle" | |
}, | |
"WaitOnPasswordReset": { | |
"Type": "AWS::CloudFormation::WaitCondition", | |
"DependsOn": "Neo4jServer0", | |
"Properties": { | |
"Handle": { | |
"Ref": "StackTokenWaitHandle" | |
}, | |
"Timeout": "900", | |
"Count": "1" | |
} | |
} | |
}, | |
"Outputs": { | |
"Neo4jWebadmin": { | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
"https://", | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer1", | |
"PublicIp" | |
] | |
}, | |
":7473/" | |
] | |
] | |
}, | |
"Description": "This is the address of your Neo4j server web administration console." | |
}, | |
"Username": { | |
"Value": "neo4j" | |
}, | |
"SSH": { | |
"Value": { | |
"Fn::Join": [ | |
"", | |
[ | |
"ssh -i ${HOME}/.ssh/", | |
{ | |
"Ref": "SSHKeyName" | |
}, | |
".pem -l ubuntu@", | |
{ | |
"Fn::GetAtt": [ | |
"Neo4jServer1", | |
"PublicIp" | |
] | |
} | |
] | |
] | |
}, | |
"Description": "This is how you gain remote access to the machine." | |
}, | |
"Node0Ip": { | |
"Value": { | |
"Fn::GetAtt": [ | |
"Neo4jServer0", | |
"PublicIp" | |
] | |
} | |
}, | |
"Node1Ip": { | |
"Value": { | |
"Fn::GetAtt": [ | |
"Neo4jServer1", | |
"PublicIp" | |
] | |
} | |
}, | |
"Node2Ip": { | |
"Value": { | |
"Fn::GetAtt": [ | |
"Neo4jServer2", | |
"PublicIp" | |
] | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment