Browse code
(root)
Ed Langley authored on 21/02/2020 03:33:43
Showing 5 changed files
Showing 5 changed files
... | ... |
@@ -6,7 +6,8 @@ |
6 | 6 |
:dependencies '[[org.clojure/clojure "RELEASE"] |
7 | 7 |
[samestep/boot-refresh "0.1.0"] |
8 | 8 |
[adzerk/boot-test "RELEASE" :scope "test"] |
9 |
- [amazonica "0.3.120"]]) |
|
9 |
+ [amazonica "0.3.120"] |
|
10 |
+ [funcool/cuerdas "2.0.5"]]) |
|
10 | 11 |
|
11 | 12 |
(task-options! |
12 | 13 |
aot {:namespace #{'my-infra.core}} |
... | ... |
@@ -65,8 +65,8 @@ |
65 | 65 |
:vpc-id (id ::vpc vpc))) |
66 | 66 |
result)) |
67 | 67 |
|
68 |
-(def cred {:profile "personal" |
|
69 |
- :endpoint "us-west-2"}) |
|
68 |
+(def cred {:profile "default" |
|
69 |
+ :endpoint "us-east-1"}) |
|
70 | 70 |
|
71 | 71 |
(defmethod params ::my-vpc [thing & r] |
72 | 72 |
{:cidr-block "172.16.234.0/24"}) |
... | ... |
@@ -96,9 +96,12 @@ |
96 | 96 |
:subnet-id (id ::subnet subnet)) |
97 | 97 |
route-table) |
98 | 98 |
|
99 |
+ |
|
99 | 100 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
100 | 101 |
;; new-api |
101 | 102 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
103 |
+#_ |
|
104 |
+(begin |
|
102 | 105 |
|
103 | 106 |
(def vpc (create {::type ::vpc |
104 | 107 |
:cidr-block "10.1.0.0/16"} |
... | ... |
@@ -117,6 +120,7 @@ |
117 | 120 |
(def route-table (make-routes {::type ::my-route-table} |
118 | 121 |
cred vpc subnet |
119 | 122 |
["0.0.0.0/0" ::internet-gateway internet-gateway])) |
123 |
+) |
|
120 | 124 |
|
121 | 125 |
(defn -main |
122 | 126 |
"I don't do a whole lot ... yet." |
123 | 127 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,396 @@ |
1 |
+(ns my-infra.template |
|
2 |
+ (:require [cuerdas.core :as str])) |
|
3 |
+ |
|
4 |
+(defn process-lines [cb s] |
|
5 |
+ ((comp #(str/join "\n" %) |
|
6 |
+ cb |
|
7 |
+ #(str/split % "\n")) |
|
8 |
+ s)) |
|
9 |
+ |
|
10 |
+(defn remove-margin |
|
11 |
+ ([s] (remove-margin s "|")) |
|
12 |
+ ([s margin-indicator] (process-lines (fn [it] |
|
13 |
+ (eduction (map str/trim) |
|
14 |
+ (map #(str/trim % margin-indicator)) |
|
15 |
+ it)) |
|
16 |
+ s))) |
|
17 |
+ |
|
18 |
+(defmacro demargin [str] |
|
19 |
+ (if (and (seq? str) (= (first str) 'str)) |
|
20 |
+ (cons (first str) |
|
21 |
+ (map (fn [it] |
|
22 |
+ (cond |
|
23 |
+ (string? it) (remove-margin it) |
|
24 |
+ true it)) |
|
25 |
+ (rest str))) |
|
26 |
+ (remove-margin str))) |
|
27 |
+ |
|
28 |
+(demargin "cluster_name: ${CassandraCluster} |
|
29 |
+ |num_tokens: 256 |
|
30 |
+ |hinted_handoff_enabled: true |
|
31 |
+ |max_hint_window_in_ms: 10800000 |
|
32 |
+ |hinted_handoff_throttle_in_kb: 1024 |
|
33 |
+ |max_hints_delivery_threads: 2 |
|
34 |
+ |authenticator: AllowAllAuthenticator |
|
35 |
+ |authorizer: AllowAllAuthorizer |
|
36 |
+ |permissions_validity_in_ms: 2000 |
|
37 |
+ |partitioner: org.apache.cassandra.dht.Murmur3Partitioner |
|
38 |
+ |data_file_directories: |
|
39 |
+ | - /var/lib/cassandra/data |
|
40 |
+ |commitlog_directory: /var/lib/cassandra/commitlog |
|
41 |
+ |disk_failure_policy: stop |
|
42 |
+ |key_cache_size_in_mb: |
|
43 |
+ |key_cache_save_period: 14400 |
|
44 |
+ |row_cache_size_in_mb: 0 |
|
45 |
+ |row_cache_save_period: 0 |
|
46 |
+ |saved_caches_directory: /var/lib/cassandra/saved_caches |
|
47 |
+ |commitlog_sync: periodic |
|
48 |
+ |commitlog_sync_period_in_ms: 10000 |
|
49 |
+ |commitlog_segment_size_in_mb: 32 |
|
50 |
+ |seed_provider: |
|
51 |
+ | - class_name: org.apache.cassandra.locator.SimpleSeedProvider |
|
52 |
+ | parameters: |
|
53 |
+ | - seeds: cassandra-seed-1.${AWS::StackName}.${AWS::Region}.cjconfig,cassandra-seed-2.${AWS::StackName}.${AWS::Region}.cjconfig |
|
54 |
+ |concurrent_reads: 32 |
|
55 |
+ |concurrent_writes: 32 |
|
56 |
+ |trickle_fsync: false |
|
57 |
+ |trickle_fsync_interval_in_kb: 10240 |
|
58 |
+ |storage_port: 7000 |
|
59 |
+ |ssl_storage_port: 7001 |
|
60 |
+ |listen_address: ${CassandraSeedNetworkInterfaceAz1.PrimaryPrivateIpAddress} |
|
61 |
+ |start_native_transport: true |
|
62 |
+ |native_transport_port: 9042 |
|
63 |
+ |start_rpc: true |
|
64 |
+ |rpc_address: ${CassandraSeedNetworkInterfaceAz1.PrimaryPrivateIpAddress} |
|
65 |
+ |rpc_port: 9160 |
|
66 |
+ |rpc_keepalive: true |
|
67 |
+ |rpc_server_type: sync |
|
68 |
+ |thrift_framed_transport_size_in_mb: 15 |
|
69 |
+ |incremental_backups: false |
|
70 |
+ |snapshot_before_compaction: false |
|
71 |
+ |auto_snapshot: true |
|
72 |
+ |tombstone_warn_threshold: 1000 |
|
73 |
+ |tombstone_failure_threshold: 100000 |
|
74 |
+ |column_index_size_in_kb: 64 |
|
75 |
+ |compaction_throughput_mb_per_sec: 16 |
|
76 |
+ |read_request_timeout_in_ms: 5000 |
|
77 |
+ |range_request_timeout_in_ms: 10000 |
|
78 |
+ |write_request_timeout_in_ms: 2000 |
|
79 |
+ |cas_contention_timeout_in_ms: 1000 |
|
80 |
+ |truncate_request_timeout_in_ms: 60000 |
|
81 |
+ |request_timeout_in_ms: 10000 |
|
82 |
+ |cross_node_timeout: false |
|
83 |
+ |endpoint_snitch: Ec2Snitch |
|
84 |
+ |dynamic_snitch_update_interval_in_ms: 100 |
|
85 |
+ |dynamic_snitch_reset_interval_in_ms: 600000 |
|
86 |
+ |dynamic_snitch_badness_threshold: 0.1 |
|
87 |
+ |request_scheduler: org.apache.cassandra.scheduler.NoScheduler |
|
88 |
+ |server_encryption_options: |
|
89 |
+ | internode_encryption: none |
|
90 |
+ | keystore: conf/.keystore |
|
91 |
+ | keystore_password: cassandra |
|
92 |
+ | truststore: conf/.truststore |
|
93 |
+ | truststore_password: cassandra |
|
94 |
+ |client_encryption_options: |
|
95 |
+ | enabled: false |
|
96 |
+ | keystore: conf/.keystore |
|
97 |
+ | keystore_password: cassandra |
|
98 |
+ |internode_compression: all |
|
99 |
+ |inter_dc_tcp_nodelay: false |
|
100 |
+ |hints_directory: /var/lib/cassandra/hints |
|
101 |
+ |auto_bootstrap: false") |
|
102 |
+ |
|
103 |
+#_ |
|
104 |
+(drop-while #(and (not= % \|) |
|
105 |
+ (while) " |") ) |
|
106 |
+(defn cassandra-seed-instance [name dns-resource network-interface-id key-pair other-seed] |
|
107 |
+ {"Type" "AWS::EC2::Instance", |
|
108 |
+ "DependsOn" dns-resource, |
|
109 |
+ "Properties" |
|
110 |
+ {"Tags" [{"Key" "Name", "Value" name}], |
|
111 |
+ "NetworkInterfaces" [{"DeviceIndex" 0,"NetworkInterfaceId" network-interface-id}], |
|
112 |
+ "InstanceType" {"Ref" "InstanceType"}, |
|
113 |
+ "KeyName" key-pair, |
|
114 |
+ "ImageId" {"Fn::FindInMap" ["AMI" {"Ref" "AWS::Region"} "ami"]}, |
|
115 |
+ "BlockDeviceMappings" [{"DeviceName" "/dev/sdb","Ebs" {"VolumeSize" 2048,"VolumeType" "gp2","DeleteOnTermination" false}} |
|
116 |
+ {"DeviceName" "/dev/sdg","Ebs" {"VolumeSize" 512,"VolumeType" "gp2","DeleteOnTermination" false}}], |
|
117 |
+ "UserData" {"Fn::Base64" |
|
118 |
+ {"Fn::Sub" |
|
119 |
+ (demargin |
|
120 |
+ (str "#!/usr/bin/env bash\nset -evx -u -o pipefail\n\nyum update -y\n\n/opt/aws/bin/cfn-init -v \\ |
|
121 |
+ | --stack=${AWS::StackId} \\ |
|
122 |
+ | --resource=" name " \\ |
|
123 |
+ | --region=${AWS::Region} \\ |
|
124 |
+ | |
|
125 |
+ | -c cassandra_setup\n\nsleep 20\nservice cassandra status\nCASS_EXIT=$?\n\n/opt/aws/bin/cfn-signal \\ |
|
126 |
+ | --stack=${AWS::StackId} \\ |
|
127 |
+ | --resource=" name "\\ |
|
128 |
+ | --region=${AWS::Region} \\ |
|
129 |
+ | --exit-code=$CASS_EXIT \\ |
|
130 |
+ | --reason='" name " initialization complete'"))}}}, |
|
131 |
+ "CreationPolicy" {"ResourceSignal" {"Timeout" "PT15M"}}, |
|
132 |
+ "Metadata" {"AWS::CloudFormation::Init" |
|
133 |
+ {"configSets" |
|
134 |
+ {"cassandra_setup" ["configure_yum" "install_packages" "configure_hosts" "configure_hard_drive" "configure_cassandra"]}, |
|
135 |
+ "configure_yum" {"files" |
|
136 |
+ {"/etc/yum.repos.d/cassandra.repo" |
|
137 |
+ {"content" |
|
138 |
+ "[cassandra]\nname=Apache Cassandra\nbaseurl=https://www.apache.org/dist/cassandra/redhat/311x/\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://www.apache.org/dist/cassandra/KEYS\n"}}}, |
|
139 |
+ "install_packages" {"commands" |
|
140 |
+ {"01-install-java-8" {"command" "yum install -y java-1.8.0"}, |
|
141 |
+ "02-remove-java-7" {"command" "yum remove -y java-1.7.0-openjdk"}, |
|
142 |
+ "03-install-cassandra" {"command" "yum install -y cassandra"}}}, |
|
143 |
+ "configure_hosts" {"commands" |
|
144 |
+ {"01-create-hosts-entry-on-boot" {"command" "echo \"`curl -s http://169.254.169.254/latest/meta-data/local-ipv4` `hostname`\" >> /etc/hosts","test" "test ! -f .create-hosts-entry-semaphore"}, |
|
145 |
+ "02-signal_startup_complete" {"command" "touch .create-hosts-entry-semaphore"}}}, |
|
146 |
+ "configure_hard_drive" {"commands" |
|
147 |
+ {"00-install-xfs-programs" {"command" "yum install -y xfsprogs"}, |
|
148 |
+ "01-create-file-system-on-ebs-volume-1" {"command" "mkfs.xfs -s size=4096 /dev/sdb"}, |
|
149 |
+ "01-create-file-system-on-ebs-volume-2" {"command" "mkfs.xfs -s size=4096 /dev/sdg"}, |
|
150 |
+ "02-setup-fstab-1" {"command" "echo \"/dev/sdb /var/lib/cassandra/data xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
151 |
+ "02-setup-fstab-2" {"command" "echo \"/dev/sdg /var/lib/cassandra/commitlog xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
152 |
+ "03-mount-all" {"command" "mount -a"}}}, |
|
153 |
+ "configure_cassandra" {"files" |
|
154 |
+ {"/etc/cassandra/default.conf/cassandra.yaml" |
|
155 |
+ {"content" {"Fn::Sub" (demargin (str "TODO"))}, |
|
156 |
+ "mode" 420, |
|
157 |
+ "owner" "cassandra", |
|
158 |
+ "group" "cassandra"}}, |
|
159 |
+ "commands" {"00-chown-for-cassandra-data" {"command" "chown -R cassandra:cassandra /var/lib/cassandra/data"}, |
|
160 |
+ "01-chown-for-cassandra-commitlog" {"command" "chown -R cassandra:cassandra /var/lib/cassandra/commitlog"}}, |
|
161 |
+ "services" {"sysvinit" {"cassandra" {"enabled" true, "ensureRunning" true}}}}}}}) |
|
162 |
+ |
|
163 |
+(def cassandra-seed-az-1 |
|
164 |
+ {:instance (cassandra-seed-instance "CassandraSeedAz1" |
|
165 |
+ "CassandraSeedAz1DNS" |
|
166 |
+ {"Ref" "CassandraSeedNetworkInterfaceAz1"} |
|
167 |
+ {"Ref" "Ec2KeyPair"} |
|
168 |
+ "CassandraSeedAz2") |
|
169 |
+ |
|
170 |
+ :dns |
|
171 |
+ {"Type" "AWS::Route53::RecordSet", |
|
172 |
+ "Properties" |
|
173 |
+ {"HostedZoneId" {"Ref" "CassandraHostedZone"}, |
|
174 |
+ "Comment" "Cassandra Seed Az1 Record", |
|
175 |
+ "Name" |
|
176 |
+ {"Fn::Sub" |
|
177 |
+ "cassandra-seed-1.${AWS::StackName}.${AWS::Region}.cjconfig"}, |
|
178 |
+ "Type" "A", |
|
179 |
+ "TTL" 30, |
|
180 |
+ "ResourceRecords" |
|
181 |
+ [{"Fn::GetAtt" |
|
182 |
+ ["CassandraSeedNetworkInterfaceAz1" |
|
183 |
+ "PrimaryPrivateIpAddress"]}]}}}) |
|
184 |
+ |
|
185 |
+(def cassandra-seed-az-2 |
|
186 |
+ {:instance |
|
187 |
+ {"Type" "AWS::EC2::Instance", |
|
188 |
+ "DependsOn" "CassandraSeedAz2DNS", |
|
189 |
+ "Properties" |
|
190 |
+ {"NetworkInterfaces" |
|
191 |
+ [{"DeviceIndex" 0,"NetworkInterfaceId" {"Ref" "CassandraSeedNetworkInterfaceAz2"}}], |
|
192 |
+ "InstanceType" {"Ref" "InstanceType"}, |
|
193 |
+ "KeyName" {"Ref" "Ec2KeyPair"}, |
|
194 |
+ "ImageId" {"Fn::FindInMap" ["AMI" {"Ref" "AWS::Region"} "ami"]}, |
|
195 |
+ "BlockDeviceMappings" [{"DeviceName" "/dev/sdb","Ebs" {"VolumeSize" 2048,"VolumeType" "gp2","DeleteOnTermination" false}} |
|
196 |
+ {"DeviceName" "/dev/sdg","Ebs" {"VolumeSize" 512,"VolumeType" "gp2","DeleteOnTermination" false}}], |
|
197 |
+ "Tags" [{"Key" "Name", "Value" "CassandraSeedAz2"}], |
|
198 |
+ "UserData" {"Fn::Base64" {"Fn::Sub" "#!/usr/bin/env bash\nset -evx -u -o pipefail\n\nyum update -y\n\n/opt/aws/bin/cfn-init -v \\\n --stack=${AWS::StackId} \\\n --resource=CassandraSeedAz2 \\\n --region=${AWS::Region} \\\n -c cassandra_setup\n\nsleep 20\nservice cassandra status\nCASS_EXIT=$?\n\n/opt/aws/bin/cfn-signal \\\n --stack=${AWS::StackId} \\\n --resource=CassandraSeedAz2 \\\n --region=${AWS::Region} \\\n --exit-code=$CASS_EXIT \\\n --reason='CassandraSeedAz2 initialization complete'\n"}}}, |
|
199 |
+ "CreationPolicy" {"ResourceSignal" {"Timeout" "PT15M"}}, |
|
200 |
+ "Metadata" {"AWS::CloudFormation::Init" |
|
201 |
+ {"configSets" {"cassandra_setup" ["configure_yum" "install_packages" "configure_hosts" "configure_hard_drive" "configure_cassandra"]}, |
|
202 |
+ "configure_yum" {"files" |
|
203 |
+ {"/etc/yum.repos.d/cassandra.repo" {"content" "[cassandra]\nname=Apache Cassandra\nbaseurl=https://www.apache.org/dist/cassandra/redhat/311x/\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://www.apache.org/dist/cassandra/KEYS\n"}}}, |
|
204 |
+ "install_packages" {"commands" |
|
205 |
+ {"01-install-java-8" {"command" "yum install -y java-1.8.0"}, |
|
206 |
+ "02-remove-java-7" {"command" "yum remove -y java-1.7.0-openjdk"}, |
|
207 |
+ "03-install-cassandra" {"command" "yum install -y cassandra"}}}, |
|
208 |
+ "configure_hosts" {"commands" |
|
209 |
+ {"01-create-hosts-entry-on-boot" {"command" "echo \"`curl -s http://169.254.169.254/latest/meta-data/local-ipv4` `hostname`\" >> /etc/hosts","test" "test ! -f .create-hosts-entry-semaphore"}, |
|
210 |
+ "02-signal_startup_complete" {"command" "touch .create-hosts-entry-semaphore"}}}, |
|
211 |
+ "configure_hard_drive" {"commands" |
|
212 |
+ {"00-install-xfs-programs" {"command" "yum install -y xfsprogs"}, |
|
213 |
+ "01-create-file-system-on-ebs-volume-1" {"command" "mkfs.xfs -s size=4096 /dev/sdb"}, |
|
214 |
+ "01-create-file-system-on-ebs-volume-2" {"command" "mkfs.xfs -s size=4096 /dev/sdg"}, |
|
215 |
+ "02-setup-fstab-1" {"command" "echo \"/dev/sdb /var/lib/cassandra/data xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
216 |
+ "02-setup-fstab-2" {"command" "echo \"/dev/sdg /var/lib/cassandra/commitlog xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
217 |
+ "03-mount-all" {"command" "mount -a"}}}, |
|
218 |
+ "configure_cassandra" {"files" |
|
219 |
+ {"/etc/cassandra/default.conf/cassandra.yaml" |
|
220 |
+ {"content" |
|
221 |
+ {"Fn::Sub" |
|
222 |
+ "cluster_name: ${CassandraCluster}\nnum_tokens: 256\nhinted_handoff_enabled: true\nmax_hint_window_in_ms: 10800000\nhinted_handoff_throttle_in_kb: 1024\nmax_hints_delivery_threads: 2\nauthenticator: AllowAllAuthenticator\nauthorizer: AllowAllAuthorizer\npermissions_validity_in_ms: 2000\npartitioner: org.apache.cassandra.dht.Murmur3Partitioner\ndata_file_directories:\n - /var/lib/cassandra/data\ncommitlog_directory: /var/lib/cassandra/commitlog\ndisk_failure_policy: stop\nkey_cache_size_in_mb:\nkey_cache_save_period: 14400\nrow_cache_size_in_mb: 0\nrow_cache_save_period: 0\nsaved_caches_directory: /var/lib/cassandra/saved_caches\ncommitlog_sync: periodic\ncommitlog_sync_period_in_ms: 10000\ncommitlog_segment_size_in_mb: 32\nseed_provider:\n - class_name: org.apache.cassandra.locator.SimpleSeedProvider\n parameters:\n - seeds: cassandra-seed-1.${AWS::StackName}.${AWS::Region}.cjconfig,cassandra-seed-2.${AWS::StackName}.${AWS::Region}.cjconfig\nconcurrent_reads: 32\nconcurrent_writes: 32\ntrickle_fsync: false\ntrickle_fsync_interval_in_kb: 10240\nstorage_port: 7000\nssl_storage_port: 7001\nlisten_address: ${CassandraSeedNetworkInterfaceAz2.PrimaryPrivateIpAddress}\nstart_native_transport: true\nnative_transport_port: 9042\nstart_rpc: true\nrpc_address: ${CassandraSeedNetworkInterfaceAz2.PrimaryPrivateIpAddress}\nrpc_port: 9160\nrpc_keepalive: true\nrpc_server_type: sync\nthrift_framed_transport_size_in_mb: 15\nincremental_backups: false\nsnapshot_before_compaction: false\nauto_snapshot: true\ntombstone_warn_threshold: 1000\ntombstone_failure_threshold: 100000\ncolumn_index_size_in_kb: 64\ncompaction_throughput_mb_per_sec: 16\nread_request_timeout_in_ms: 5000\nrange_request_timeout_in_ms: 10000\nwrite_request_timeout_in_ms: 2000\ncas_contention_timeout_in_ms: 1000\ntruncate_request_timeout_in_ms: 60000\nrequest_timeout_in_ms: 10000\ncross_node_timeout: false\nendpoint_snitch: Ec2Snitch\ndynamic_snitch_update_interval_in_ms: 100\ndynamic_snitch_reset_interval_in_ms: 600000\ndynamic_snitch_badness_threshold: 0.1\nrequest_scheduler: org.apache.cassandra.scheduler.NoScheduler\nserver_encryption_options:\n internode_encryption: none\n keystore: conf/.keystore\n keystore_password: cassandra\n truststore: conf/.truststore\n truststore_password: cassandra\nclient_encryption_options:\n enabled: false\n keystore: conf/.keystore\n keystore_password: cassandra\ninternode_compression: all\ninter_dc_tcp_nodelay: false\nhints_directory: /var/lib/cassandra/hints\nauto_bootstrap: false\n"}, |
|
223 |
+ "mode" 420,"owner" "cassandra","group" "cassandra"}}, |
|
224 |
+ "commands" |
|
225 |
+ {"00-chown-for-cassandra-data" {"command" "chown -R cassandra:cassandra /var/lib/cassandra/data"}, |
|
226 |
+ "01-chown-for-cassandra-commitlog" {"command" "chown -R cassandra:cassandra /var/lib/cassandra/commitlog"}}, |
|
227 |
+ "services" {"sysvinit" {"cassandra" {"enabled" true, "ensureRunning" true}}}}}}} |
|
228 |
+ |
|
229 |
+ :dns |
|
230 |
+ {"Type" "AWS::Route53::RecordSet", |
|
231 |
+ "Properties" |
|
232 |
+ {"HostedZoneId" {"Ref" "CassandraHostedZone"}, |
|
233 |
+ "Comment" "Cassandra Seed Az2 Record", |
|
234 |
+ "Name" {"Fn::Sub" "cassandra-seed-2.${AWS::StackName}.${AWS::Region}.cjconfig"}, |
|
235 |
+ "Type" "A", |
|
236 |
+ "TTL" 30, |
|
237 |
+ "ResourceRecords" [{"Fn::GetAtt" ["CassandraSeedNetworkInterfaceAz2" "PrimaryPrivateIpAddress"]}]}}}) |
|
238 |
+ |
|
239 |
+(def template |
|
240 |
+ {"AWSTemplateFormatVersion" "2010-09-09", |
|
241 |
+ "Description" "Insights Server Cassandra Database", |
|
242 |
+ "Parameters" |
|
243 |
+ {"Subnets" {"Type" "List<String>","Description" "The subnets where Cassandra nodes live"}, |
|
244 |
+ "DefaultSecurityGroup" {"Type" "String","MinLength" 1,"Description" "Security group for general access within VPC"}, |
|
245 |
+ "DatabaseSecurityGroup" {"Type" "String","MinLength" 1,"Description" "Database-allowed access"}, |
|
246 |
+ "Ec2KeyPair" {"Type" "String","Default" "insights","MinLength" 1,"MaxLength" 64,"AllowedPattern" "[-_ a-zA-Z0-9]*","ConstraintDescription" "can contain only alphanumeric characters, spaces, dashes and underscores.","Description" "Name of an EC2 KeyPair to enable SSH access to EC2 instances"}, |
|
247 |
+ "CassandraCluster" {"Type" "String","MinLength" 1,"Description" "The cassandra cluster name"}, |
|
248 |
+ "InstanceType" {"Type" "String","Default" "m4.2xlarge","Description" "Instance type"}, |
|
249 |
+ "Vpc" {"Type" "String","Description" "The VPC the cluster will be running in"}, |
|
250 |
+ "ClusterSize" {"Type" "Number","MinValue" 1,"Default" 6,"Description" "The number of nodes (in addition to the 2 seed nodes)"}}, |
|
251 |
+ "Resources" |
|
252 |
+ {"CassandraSeedAz1" (:instance cassandra-seed-az-1,) |
|
253 |
+ "CassandraSeedAz1DNS" (:dns cassandra-seed-az-1), |
|
254 |
+ "CassandraSeedAz2" (:instance cassandra-seed-az-2,) |
|
255 |
+ "CassandraSeedAz2DNS" (:dns cassandra-seed-az-2), |
|
256 |
+ |
|
257 |
+ "CassandraLaunchConfiguration" |
|
258 |
+ {"Type" "AWS::AutoScaling::LaunchConfiguration", |
|
259 |
+ "Properties" |
|
260 |
+ {"InstanceType" {"Ref" "InstanceType"}, |
|
261 |
+ "KeyName" {"Ref" "Ec2KeyPair"}, |
|
262 |
+ "ImageId" {"Fn::FindInMap" ["AMI" {"Ref" "AWS::Region"} "ami"]}, |
|
263 |
+ "SecurityGroups" |
|
264 |
+ [{"Ref" "DefaultSecurityGroup"} {"Ref" "DatabaseSecurityGroup"}], |
|
265 |
+ "BlockDeviceMappings" |
|
266 |
+ [{"DeviceName" "/dev/sdb", |
|
267 |
+ "Ebs" |
|
268 |
+ {"VolumeSize" 2048, |
|
269 |
+ "VolumeType" "gp2", |
|
270 |
+ "DeleteOnTermination" false}} |
|
271 |
+ {"DeviceName" "/dev/sdg", |
|
272 |
+ "Ebs" |
|
273 |
+ {"VolumeSize" 512, |
|
274 |
+ "VolumeType" "gp2", |
|
275 |
+ "DeleteOnTermination" false}}], |
|
276 |
+ "UserData" |
|
277 |
+ {"Fn::Base64" |
|
278 |
+ {"Fn::Sub" |
|
279 |
+ "#! /usr/bin/env bash\nset -evx\n\nyum update -y\n\n# start instance initialization\n/opt/aws/bin/cfn-init -v \\\n --stack=${AWS::StackId} \\\n --resource=CassandraLaunchConfiguration \\\n --region=${AWS::Region} \\\n -c cassandra_setup\n\nservice cassandra start\nsleep 20\nservice cassandra status\nCASS_EXIT=$?\n\n# all is well so signal success\n/opt/aws/bin/cfn-signal \\\n --stack=${AWS::StackId} \\\n --resource=CassandraAutoScalingGroup \\\n --region=${AWS::Region} \\\n --exit-code=$CASS_EXIT \\\n --reason='CassandraNodeA initialization complete'\n"}}}, |
|
280 |
+ "CreationPolicy" {"ResourceSignal" {"Timeout" "PT15M"}}, |
|
281 |
+ "Metadata" |
|
282 |
+ {"AWS::CloudFormation::Init" |
|
283 |
+ {"configSets" |
|
284 |
+ {"cassandra_setup" |
|
285 |
+ ["configure_yum" |
|
286 |
+ "install_packages" |
|
287 |
+ "configure_hosts" |
|
288 |
+ "configure_hard_drive" |
|
289 |
+ "configure_cassandra"]}, |
|
290 |
+ "configure_yum" |
|
291 |
+ {"files" |
|
292 |
+ {"/etc/yum.repos.d/cassandra.repo" |
|
293 |
+ {"content" |
|
294 |
+ "[cassandra]\nname=Apache Cassandra\nbaseurl=https://www.apache.org/dist/cassandra/redhat/311x/\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://www.apache.org/dist/cassandra/KEYS\n"}}}, |
|
295 |
+ "install_packages" |
|
296 |
+ {"commands" |
|
297 |
+ {"01-install-java-8" {"command" "yum install -y java-1.8.0"}, |
|
298 |
+ "02-remove-java-7" |
|
299 |
+ {"command" "yum remove -y java-1.7.0-openjdk"}, |
|
300 |
+ "03-install-cassandra" {"command" "yum install -y cassandra"}}}, |
|
301 |
+ "configure_hosts" |
|
302 |
+ {"commands" |
|
303 |
+ {"01-create-hosts-entry-on-boot" |
|
304 |
+ {"command" |
|
305 |
+ "echo \"`curl -s http://169.254.169.254/latest/meta-data/local-ipv4` `hostname`\" >> /etc/hosts", |
|
306 |
+ "test" "test ! -f .create-hosts-entry-semaphore"}, |
|
307 |
+ "02-signal_startup_complete" |
|
308 |
+ {"command" "touch .create-hosts-entry-semaphore"}}}, |
|
309 |
+ "configure_hard_drive" |
|
310 |
+ {"commands" |
|
311 |
+ {"00-install-xfs-programs" {"command" "yum install -y xfsprogs"}, |
|
312 |
+ "01-create-file-system-on-ebs-volume-1" |
|
313 |
+ {"command" "mkfs.xfs -s size=4096 /dev/sdb"}, |
|
314 |
+ "01-create-file-system-on-ebs-volume-2" |
|
315 |
+ {"command" "mkfs.xfs -s size=4096 /dev/sdg"}, |
|
316 |
+ "02-setup-fstab-1" |
|
317 |
+ {"command" |
|
318 |
+ "echo \"/dev/sdb /var/lib/cassandra/data xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
319 |
+ "02-setup-fstab-2" |
|
320 |
+ {"command" |
|
321 |
+ "echo \"/dev/sdg /var/lib/cassandra/commitlog xfs defaults,nofail 0 0\" >> /etc/fstab"}, |
|
322 |
+ "03-mount-all" {"command" "mount -a"}}}, |
|
323 |
+ "configure_cassandra" |
|
324 |
+ {"files" |
|
325 |
+ {"/etc/cassandra/default.conf/cassandra.yaml" |
|
326 |
+ {"content" |
|
327 |
+ {"Fn::Sub" |
|
328 |
+ "cluster_name: ${CassandraCluster}\nnum_tokens: 256\nhinted_handoff_enabled: true\nmax_hint_window_in_ms: 10800000\nhinted_handoff_throttle_in_kb: 1024\nmax_hints_delivery_threads: 2\nauthenticator: AllowAllAuthenticator\nauthorizer: AllowAllAuthorizer\npermissions_validity_in_ms: 2000\npartitioner: org.apache.cassandra.dht.Murmur3Partitioner\ndata_file_directories:\n - /var/lib/cassandra/data\ncommitlog_directory: /var/lib/cassandra/commitlog\ndisk_failure_policy: stop\nkey_cache_size_in_mb:\nkey_cache_save_period: 14400\nrow_cache_size_in_mb: 0\nrow_cache_save_period: 0\nsaved_caches_directory: /var/lib/cassandra/saved_caches\ncommitlog_sync: periodic\ncommitlog_sync_period_in_ms: 10000\ncommitlog_segment_size_in_mb: 32\nseed_provider:\n - class_name: org.apache.cassandra.locator.SimpleSeedProvider\n parameters:\n - seeds: cassandra-seed-1.${AWS::StackName}.${AWS::Region}.cjconfig,cassandra-seed-2.${AWS::StackName}.${AWS::Region}.cjconfig\nconcurrent_reads: 32\nconcurrent_writes: 32\ntrickle_fsync: false\ntrickle_fsync_interval_in_kb: 10240\nstorage_port: 7000\nssl_storage_port: 7001\nlisten_address: __NODE_IP\nstart_native_transport: true\nnative_transport_port: 9042\nstart_rpc: true\nrpc_address: __NODE_IP\nrpc_port: 9160\nrpc_keepalive: true\nrpc_server_type: sync\nthrift_framed_transport_size_in_mb: 15\nincremental_backups: false\nsnapshot_before_compaction: false\nauto_snapshot: true\ntombstone_warn_threshold: 1000\ntombstone_failure_threshold: 100000\ncolumn_index_size_in_kb: 64\ncompaction_throughput_mb_per_sec: 16\nread_request_timeout_in_ms: 5000\nrange_request_timeout_in_ms: 10000\nwrite_request_timeout_in_ms: 2000\ncas_contention_timeout_in_ms: 1000\ntruncate_request_timeout_in_ms: 60000\nrequest_timeout_in_ms: 10000\ncross_node_timeout: false\nendpoint_snitch: Ec2Snitch\ndynamic_snitch_update_interval_in_ms: 100\ndynamic_snitch_reset_interval_in_ms: 600000\ndynamic_snitch_badness_threshold: 0.1\nrequest_scheduler: org.apache.cassandra.scheduler.NoScheduler\nserver_encryption_options:\n internode_encryption: none\n keystore: conf/.keystore\n keystore_password: cassandra\n truststore: conf/.truststore\n truststore_password: cassandra\nclient_encryption_options:\n enabled: false\n keystore: conf/.keystore\n keystore_password: cassandra\ninternode_compression: all\ninter_dc_tcp_nodelay: false\nhints_directory: /var/lib/cassandra/hints\nauto_bootstrap: false\n"}, |
|
329 |
+ "mode" 420, |
|
330 |
+ "owner" "cassandra", |
|
331 |
+ "group" "cassandra"}}, |
|
332 |
+ "commands" |
|
333 |
+ {"00-chown-for-cassandra-data" |
|
334 |
+ {"command" |
|
335 |
+ "chown -R cassandra:cassandra /var/lib/cassandra/data"}, |
|
336 |
+ "01-chown-for-cassandra-commitlog" |
|
337 |
+ {"command" |
|
338 |
+ "chown -R cassandra:cassandra /var/lib/cassandra/commitlog"}, |
|
339 |
+ "02-add-node-ip" |
|
340 |
+ {"command" |
|
341 |
+ "NODE_IP=`hostname -I` sed -i s/__NODE_IP/$NODE_IP/g /etc/cassandra/default.conf/cassandra.yaml"}}, |
|
342 |
+ "services" |
|
343 |
+ {"sysvinit" |
|
344 |
+ {"cassandra" {"enabled" true, "ensureRunning" true}}}}}}}, |
|
345 |
+ "CassandraSeedNetworkInterfaceAz1" |
|
346 |
+ {"Type" "AWS::EC2::NetworkInterface", |
|
347 |
+ "Properties" |
|
348 |
+ {"SubnetId" {"Fn::Select" [0 {"Ref" "Subnets"}]}, |
|
349 |
+ "GroupSet" |
|
350 |
+ [{"Ref" "DefaultSecurityGroup"} {"Ref" "DatabaseSecurityGroup"}]}}, |
|
351 |
+ "CassandraAutoScalingGroup" |
|
352 |
+ {"Type" "AWS::AutoScaling::AutoScalingGroup", |
|
353 |
+ "DependsOn" "CassandraSeedAz1", |
|
354 |
+ "Properties" |
|
355 |
+ {"MaxSize" {"Ref" "ClusterSize"}, |
|
356 |
+ "MinSize" {"Ref" "ClusterSize"}, |
|
357 |
+ "DesiredCapacity" {"Ref" "ClusterSize"}, |
|
358 |
+ "VPCZoneIdentifier" {"Ref" "Subnets"}, |
|
359 |
+ "LaunchConfigurationName" {"Ref" "CassandraLaunchConfiguration"}, |
|
360 |
+ "Tags" |
|
361 |
+ [{"Key" "Name", |
|
362 |
+ "Value" {"Fn::Sub" "Cassandra AutoScale ${AWS::StackName}"}, |
|
363 |
+ "PropagateAtLaunch" true}]}}, |
|
364 |
+ "CassandraSeedNetworkInterfaceAz2" |
|
365 |
+ {"Type" "AWS::EC2::NetworkInterface", |
|
366 |
+ "Properties" |
|
367 |
+ {"SubnetId" {"Fn::Select" [1 {"Ref" "Subnets"}]}, |
|
368 |
+ "GroupSet" |
|
369 |
+ [{"Ref" "DefaultSecurityGroup"} {"Ref" "DatabaseSecurityGroup"}]}}, |
|
370 |
+ "CassandraHostedZone" |
|
371 |
+ {"Type" "AWS::Route53::HostedZone", |
|
372 |
+ "Properties" |
|
373 |
+ {"Name" {"Fn::Sub" "${AWS::StackName}.${AWS::Region}.cjconfig"}, |
|
374 |
+ "HostedZoneConfig" |
|
375 |
+ {"Comment" "A hosted zone for our cjconfiguration"}, |
|
376 |
+ "VPCs" |
|
377 |
+ [{"VPCId" {"Ref" "Vpc"}, "VPCRegion" {"Ref" "AWS::Region"}}]}}}, |
|
378 |
+ "Mappings" |
|
379 |
+ {"AMI" |
|
380 |
+ {"us-east-1" {"ami" "ami-97785bed"}, |
|
381 |
+ "us-east-2" {"ami" "ami-f63b1193"}, |
|
382 |
+ "us-west-1" {"ami" "ami-824c4ee2"}, |
|
383 |
+ "us-west-2" {"ami" "ami-f2d3638a"}}, |
|
384 |
+ "NameMap" |
|
385 |
+ {"az1" {"name" "cassandra-seed-1"}, |
|
386 |
+ "az2" {"name" "cassandra-seed-2"}}}, |
|
387 |
+ "Conditions" |
|
388 |
+ {"T2InstanceFamily" |
|
389 |
+ {"Fn::Equals" |
|
390 |
+ [{"Fn::Select" [0 {"Fn::Split" ["." {"Ref" "InstanceType"}]}]} |
|
391 |
+ "t2"]}}, |
|
392 |
+ "Outputs" |
|
393 |
+ {"CassandraContactPoints" |
|
394 |
+ {"Value" |
|
395 |
+ {"Fn::Sub" |
|
396 |
+ "${CassandraSeedNetworkInterfaceAz1.PrimaryPrivateIpAddress},${CassandraSeedNetworkInterfaceAz2.PrimaryPrivateIpAddress}"}}}}) |