Skip to content

Instantly share code, notes, and snippets.

@jollyrojer
Created June 8, 2016 10:08
Show Gist options
  • Save jollyrojer/46814068ad954d1f86582c007c6bbe55 to your computer and use it in GitHub Desktop.
Save jollyrojer/46814068ad954d1f86582c007c6bbe55 to your computer and use it in GitHub Desktop.
application:
configuration:
input.image: {region: "us-west-2", ami: "ami-775e4f16", user: "ec2-user", type: "linux"}
input.instance-size: "m3.large"
input.quantity: {"seeds": 1, "nodes": 1}
interfaces:
input:
image: "bind(cassandra#input.image)"
instance-size: "bind(cassandra#input.instance-size)"
quantity: "bind(cassandra#input.quantity)"
endpoints:
"*": bind(cassandra#result.*, cassandra#actions.*)
bindings:
- [cassandra, props]
components:
props:
type: reference.Service
interfaces:
properties:
artifactory: publish-signal(object)
cassandra:
type: workflow.Instance
interfaces:
input:
image:
type: configuration(map<string,object>)
suggestions:
"centos-7 us-west-2": { region: "us-west-2", ami: "ami-d440a6e7", user: "centos", type: "linux"}
"rhel-7 us-west-2": {region: "us-west-2", ami: "ami-775e4f16", user: "ec2-user", type: "linux"}
instance-size:
type: configuration(string)
name: Server compatible hardware
suggestions:
"m3.large - 2 CPU, 7.5 Gb": m3.large
"i2.xlarge - 4 CPU, 31 Gb": i2.xlarge
"i2.2xlarge - 8 CPU, 61 Gb": i2.2xlarge
"c4.4xlarge - 16 CPU 30 Gb": c4.4xlarge
"c4.8xlarge - 36 CPU 60 Gb": c4.8xlarge
"r3.4xlarge - 16 CPU 122 Gb": r3.4xlarge
"c3.4xlarge - 16 CPU 30 Gb": c3.4xlarge
quantity:
type: configuration(map<string, int>)
name: Nodes quantity in Cassandra cluster
suggestions:
"2 nodes": {"seeds": 1, "nodes": 1}
"4 nodes": {"seeds": 3, "nodes": 1}
"8 nodes": {"seeds": 7, "nodes": 1}
"16 nodes": {"seeds": 15, "nodes": 1}
properties:
artifactory: consume-signal(object)
actions:
create-keyspaces:
type: receive-command(string worker-agent-url)
name: Create keyspace
arguments:
worker-agent-url:
name: Worker-agent source url
manage-user:
type: receive-command(string user-action, string user-name, string user-password, string keyspace)
name: Manage user
arguments:
user-action:
name: Perform action (create/delete)
default: create
user-name:
name: User
user-password:
name: User password
keyspace:
name: On keyspace
default: master_data_v3
add-client-cert:
type: receive-command(object client-pub-cert)
name: Add client public certificate
arguments:
client-pub-cert:
name: Client's public certificate
service-management:
type: receive-command(string service-action)
name: "Service management"
arguments:
service-action:
name: "Perform start/stop/restart"
result:
seeds-hosts: {type: publish-signal(list<string>), name: "Seeds Hosts"}
nodes-hosts: {type: publish-signal(list<string>), name: "Nodes Hosts"}
manage-host: {type: publish-signal(string), name: "Management Host"}
dba-password: {type: publish-signal(string), name: "DBA password"}
ssl-key-password: {type: publish-signal(string), name: "SSL password"}
nodes-pub-cert: {type: publish-signal(list<string>), name: "Public certificates"}
required: [properties]
configuration:
configuration.workflows:
launch:
steps:
- getContext:
action: getInstanceContext
output:
instanceId: instanceId
- provision-seeds:
action: provisionVms
parameters:
roleName: seeds
imageId: "{$.image.region}/{$.image.ami}"
hardwareId: "{$.instance-size}"
vmIdentity: "{$.image.user}"
jcloudsNodeNamePrefix: "Cassandra"
targetQuantity: "{$.quantity.seeds}"
blockDeviceMapping:
"/dev/sdb": ephemeral0
"/dev/sdc": ephemeral1
providerSettings:
userData: &uData
|
#cloud-config
yum_repos:
datastax:
name: DataStax Repo for Apache Cassandra
baseurl: http://rpm.datastax.com/community
enabled: true
gpgcheck: false
packages:
- unzip
- dsc22
- cassandra22-tools
runcmd:
- curl -O https://s3-us-west-2.amazonaws.com/ra-cookbooks/jdk-8u73-linux-x64.rpm
- yum install -y jdk-8u73-linux-x64.rpm
- curl -O https://s3-us-west-2.amazonaws.com/ra-cookbooks/jce_policy-8.zip
- unzip -o -j jce_policy-8.zip UnlimitedJCEPolicyJDK8/local_policy.jar -d /usr/java/latest/jre/lib/security/
- unzip -o -j jce_policy-8.zip UnlimitedJCEPolicyJDK8/US_export_policy.jar -d /usr/java/latest/jre/lib/security/
- service iptables stop
mounts:
- [ ephemeral0, /opt/cassandra/data/0, auto, "defaults,noexec" ]
- [ ephemeral1, /opt/cassandra/data/1, auto, "defaults,noexec" ]
output:
seeds-ips: ips
seeds-privateips: privateips
- provision-nodes:
action: provisionVms
parameters:
roleName: nodes
imageId: "{$.image.region}/{$.image.ami}"
hardwareId: "{$.instance-size}"
vmIdentity: "{$.image.user}"
jcloudsNodeNamePrefix: "Cassandra"
targetQuantity: "{$.quantity.nodes}"
blockDeviceMapping:
"/dev/sdb": ephemeral0
"/dev/sdc": ephemeral1
providerSettings:
userData: *uData
output:
nodes-ips: ips
nodes-privateips: privateips
- seeds2csv:
action: serialize
precedingPhases: [ provision-seeds ]
parameters:
format: CSV
input: [ "{$.seeds-privateips}" ]
output:
seedsCSV: serialized
- mount-drives:
action: execrun
precedingPhases: [ provision-nodes, provision-seeds ]
parameters:
roles: [ seeds, nodes ]
isSudo: true
command:
- |
mkdir -p /opt/cassandra/data/{{0,1}}
for i in /dev/xvd{{b,c,d,e}}; do [ -e $$i ] && mkfs.xfs -f $$i; mount $$i; done; exit 0;
- provision-manager-vm:
action: provisionVms
precedingPhases: [mount-drives, seeds2csv]
parameters:
roleName: manager
hardwareId: ""
vmIdentity: "{$.image.user}"
staticIps: ["{$.seeds-ips[0]}"]
output:
managerIp: ips
- generate-key-password:
action: execrun
precedingPhases: [provision-manager-vm]
parameters:
roles: [manager]
isSudo: true
command:
- |
key_pass=`openssl rand -hex 10`
>&2 echo $$key_pass
output:
key-password: stderr
- generate-cert:
action: execrun
precedingPhases: [generate-key-password]
parameters:
roles: [seeds, nodes]
isSudo: true
command:
- |
i=0
while [ \( $$i -le 12 \) -a \( `which keytoool &>/dev/null; echo $$?` -eq 1 \) ]; do
sleep 10
((i++))
done
if [ `which keytool &>/dev/null; echo $$?` -eq 1 ]; then
exit 1
else
cd /etc/cassandra/conf/
keytool -genkey -alias `hostname` -keyalg RSA -keystore .keystore -dname "CN=`hostname`" -keypass "{$.key-password[*][0]}" -storepass "{$.key-password[*][0]}" &>/dev/null
keytool -export -alias `hostname` -file `hostname`.crt -keystore .keystore -storepass "{$.key-password[*][0]}" -keyalg RSA -rfc &>/dev/null
cat `hostname`.crt
fi
output:
pub-cert: stdout
- public-certs:
action: serialize
precedingPhases: [generate-cert]
parameters:
format: YAML
input: "{$.pub-cert[*]}"
output:
yamlserialized: serialized
- import-public-certs:
action: execrun
precedingPhases: [public-certs]
parameters:
roles: [seeds, nodes]
isSudo: true
command:
- |
cd /etc/cassandra/conf/
cat <<EEND | sed 's/\\r\s*\\n/\n/g;s/\\n/\n/g;s/"//g;s/^- //' | awk '/BEGIN CERTIFICATE/{{i++}}{{print > "crts"i}}'
{$.yamlserialized}
EEND
for i in crts* ; do
CN=`openssl x509 -noout -subject -in $$i | sed 's/.*CN=//'`
keytool -import -v -trustcacerts -alias $$CN -file $$i -keystore .truststore -storepass "{$.key-password[*][0]}" -noprompt
done
keytool -importkeystore -srckeystore /etc/cassandra/conf/.keystore -destkeystore /etc/cassandra/conf/`hostname -i`.p12 -deststoretype PKCS12 -srcstorepass "{$.key-password[*][0]}" -deststorepass "{$.key-password[*][0]}"
openssl pkcs12 -in /etc/cassandra/conf/`hostname -i`.p12 -nokeys -out /etc/cassandra/conf/`hostname -i`.cer.pem -passin pass:"{$.key-password[*][0]}"
openssl pkcs12 -in /etc/cassandra/conf/`hostname -i`.p12 -nodes -nocerts -out /etc/cassandra/conf/`hostname -i`.key.pem -passin pass:"{$.key-password[*][0]}"
mkdir ~/.cassandra
hname=`hostname -i`
cat << EEND > ~/.cassandra/cqlshrc
[connection]
factory = cqlshlib.ssl.ssl_transport_factory
[ssl]
certfile = /etc/cassandra/conf/$$hname.cer.pem
validate = true
userkey = /etc/cassandra/conf/$$hname.key.pem
usercert = /etc/cassandra/conf/$$hname.cer.pem
EEND
- config:
action: serialize
precedingPhases: [ import-public-certs ]
parameters:
format: YAML
input:
cluster_name: "RA_Cluster_{$.instanceId}"
num_tokens: 256
endpoint_snitch: Ec2Snitch
#data_file_directories:
# - /var/lib/cassandra/data
commitlog_directory: /var/lib/cassandra/commitlog
saved_caches_directory: /var/lib/cassandra/saved_caches
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000
hinted_handoff_throttle_in_kb: 1024
max_hints_delivery_threads: 2
batchlog_replay_throttle_in_kb: 1024
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer
role_manager: CassandraRoleManager
roles_validity_in_ms: 2000
permissions_validity_in_ms: 2000
partitioner: org.apache.cassandra.dht.Murmur3Partitioner
disk_failure_policy: stop
commit_failure_policy: stop
key_cache_save_period: 14400
row_cache_size_in_mb: 4096
key_cache_size_in_mb: 4096
memory_allocator: NativeAllocator
row_cache_save_period: 0
counter_cache_save_period: 7200
commitlog_sync: periodic
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
concurrent_reads: 512
concurrent_writes: 256
concurrent_counter_writes: 32
memtable_allocation_type: heap_buffers
index_summary_resize_interval_in_minutes: 60
trickle_fsync: false
trickle_fsync_interval_in_kb: 10240
storage_port: 7000
ssl_storage_port: 7001
start_native_transport: true
native_transport_port: 9042
start_rpc: true
#rpc_address: 0.0.0.0
rpc_port: 9160
rpc_keepalive: true
rpc_server_type: sync
thrift_framed_transport_size_in_mb: 15
incremental_backups: false
snapshot_before_compaction: false
auto_snapshot: true
tombstone_warn_threshold: 1000
tombstone_failure_threshold: 100000
column_index_size_in_kb: 64
batch_size_warn_threshold_in_kb: 5
batch_size_fail_threshold_in_kb: 50
compaction_throughput_mb_per_sec: 16
compaction_large_partition_warning_threshold_mb: 100
sstable_preemptive_open_interval_in_mb: 50
read_request_timeout_in_ms: 60000
range_request_timeout_in_ms: 10000
write_request_timeout_in_ms: 60000
counter_write_request_timeout_in_ms: 5000
cas_contention_timeout_in_ms: 1000
truncate_request_timeout_in_ms: 60000
request_timeout_in_ms: 60000
cross_node_timeout: false
dynamic_snitch_update_interval_in_ms: 100
dynamic_snitch_reset_interval_in_ms: 600000
dynamic_snitch_badness_threshold: 0.1
request_scheduler: org.apache.cassandra.scheduler.NoScheduler
server_encryption_options:
internode_encryption: all
keystore: /etc/cassandra/conf/.keystore
keystore_password: "{$.key-password[*][0]}"
truststore: /etc/cassandra/conf/.truststore
truststore_password: "{$.key-password[*][0]}"
client_encryption_options:
enabled: true
keystore: /etc/cassandra/conf/.keystore
keystore_password: "{$.key-password[*][0]}"
truststore: /etc/cassandra/conf/.truststore
truststore_password: "{$.key-password[*][0]}"
require_client_auth: true
internode_compression: none
inter_dc_tcp_nodelay: false
tracetype_query_ttl: 86400
tracetype_repair_ttl: 604800
enable_user_defined_functions: false
windows_timer_interval: 1
output:
config: serialized
- put-config:
action: execrun
precedingPhases: [ config, seeds2csv ]
parameters:
roles: [ seeds, nodes ]
isSudo: true
command:
- |
while [ ! -e /etc/cassandra/conf/cassandra.yaml ]; do sleep 60; done; # Wait for Cloud-Init
cat <<EEND > /etc/cassandra/conf/cassandra.yaml
{$.config}
EEND
SEEDS=`echo -n {$.seedsCSV}`
cat <<EEND >> /etc/cassandra/conf/cassandra.yaml
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "$$SEEDS"
EEND
chown -R cassandra:cassandra /opt/cassandra/
echo -e "data_file_directories:" >> /etc/cassandra/conf/cassandra.yaml
mount | grep cassandra | cut -d' ' -f3 | xargs -n 1 echo " -" >> /etc/cassandra/conf/cassandra.yaml
echo 'export JVM_OPTS="-Xmx16g"' > /etc/default/cassandra
- start-seeds:
action: execrun
precedingPhases: [ put-config ]
parameters:
roles: [ seeds ]
isSudo: true
batchSize: 1
retryCount: 3
command:
- service cassandra start
- start-nodes:
action: execrun
precedingPhases: [ start-seeds ]
parameters:
roles: [ nodes ]
isSudo: true
batchSize: 1
retryCount: 3
command:
- service cassandra start
- wait-cassandra-cluster:
action: wait
precedingPhases: [start-nodes]
parameters:
delay: 3 minutes
- create-dba-user:
action: execrun
precedingPhases: [provision-manager-vm, wait-cassandra-cluster]
parameters:
roles: [manager]
isSudo: true
command:
- |
dba_password=`openssl rand -hex 10`
cassandra_password=`openssl rand -hex 10`
if [[ "{$.quantity.seeds}" -eq 1 ]]; then rf=2; else rf="{$.quantity.seeds}";fi
cqlsh "{$.seeds-privateips[0]}" --ssl -u cassandra -p cassandra -e "CREATE USER dba WITH PASSWORD '$$dba_password' SUPERUSER;"
cqlsh "{$.seeds-privateips[0]}" --ssl -u dba -p $$dba_password -e "ALTER USER cassandra WITH PASSWORD '$$cassandra_password' NOSUPERUSER;"
cqlsh "{$.seeds-privateips[0]}" --ssl -u dba -p $$dba_password -e "ALTER KEYSPACE system_auth WITH REPLICATION = {{'class' : 'SimpleStrategy', 'replication_factor' : $$rf}};"
nodetool repair
>&2 echo $$dba_password
output:
pwd: stderr
return:
manage-host:
value: "{$.seeds-ips[0]}"
seeds-hosts:
value: "{$.seeds-privateips}"
nodes-hosts:
value: "{$.nodes-privateips}"
dba-password:
value: "{$.pwd[*][0]}"
ssl-key-password:
value: "{$.key-password[*][0]}"
nodes-pub-cert:
value: "{$.pub-cert[*]}"
create-keyspaces:
steps:
- get-env-props:
action: getEnvironmentProperties
output:
props: result
- provision-manager-vm:
action: provisionVms
precedingPhases: [ get-env-props ]
parameters:
roleName: manager
hardwareId: ""
vmIdentity: centos
staticIps: ["{$.manage-host}"]
output:
managerIp: ips
- create-keyspaces:
action: execrun
precedingPhases: [provision-manager-vm]
parameters:
roles: [manager]
isSudo: true
command:
- |
mkdir -p /opt/cassandra/schema
cd /opt/cassandra/schema
rm -rf /opt/cassandra/schema/*
curl --insecure -u"{$.props.properties.artifactory.user}":"{$.props.properties.artifactory.password}" -O "{$.worker-agent-url}"
yum install -y unzip
filename=$$(basename "{$.worker-agent-url}")
unzip -j $$filename "cloud.worker.agent.dependencies/cloud.worker.data.access.cassandra-*.jar" -d /opt/cassandra/schema/
jar xf cloud.worker.data.access.cassandra-*.jar create_keyspaces_cloud.cql
jar xf cloud.worker.data.access.cassandra-*.jar create_tables.cql
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -f /opt/cassandra/schema/create_keyspaces_cloud.cql
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -f /opt/cassandra/schema/create_tables.cql
manage-user:
steps:
- get-env-props:
action: getEnvironmentProperties
output:
props: result
- provision-manager-vm:
action: provisionVms
precedingPhases: [ get-env-props ]
parameters:
roleName: manager
hardwareId: ""
vmIdentity: centos
staticIps: ["{$.manage-host}"]
output:
managerIp: ips
- manage-user:
action: execrun
precedingPhases: [provision-manager-vm]
parameters:
roles: [manager]
isSudo: true
command:
- |
if [[ "{$.user-action}" = "create" ]]; then
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -e "CREATE USER '{$.user-name}' WITH PASSWORD '{$.user-password}';"
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -e "GRANT ALL ON KEYSPACE {$.keyspace} TO '{$.user-name}';"
elif [[ "{$.user-action}" = "delete" ]]; then
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -e "REVOKE ALL ON KEYSPACE {$.keyspace} FROM '{$.user-name}';"
cqlsh "{$.seeds-hosts[0]}" --ssl -u dba -p "{$.dba-password}" -e "DROP USER '{$.user-name}';"
fi
add-client-cert:
steps:
- public-certs:
action: serialize
parameters:
format: YAML
input: "{$.client-pub-cert[*]}"
output:
yamlserialized: serialized
- import-public-certs:
action: execrun
precedingPhases: [public-certs]
parameters:
roles: [seeds, nodes]
isSudo: true
command:
- |
cd /etc/cassandra/conf/
rm -rf worker-crts*
cat <<EEND | sed 's/\\r\s*\\n/\n/g;s/\\n/\n/g;s/"//g;s/^- //' | awk '/BEGIN CERTIFICATE/{{i++}}{{print > "worker-crts"i}}'
{$.yamlserialized}
EEND
for i in worker-crts* ; do
CN=`openssl x509 -noout -subject -in $$i | sed 's/.*CN=//'`
keytool -list -keystore .truststore -storepass {$.ssl-key-password} -alias $$CN > /dev/null
if [[ $$? = 0 ]]; then
keytool -delete -alias $$CN -keystore .truststore -storepass {$.ssl-key-password}
fi
keytool -import -v -trustcacerts -alias $$CN -file $$i -keystore .truststore -storepass {$.ssl-key-password} -noprompt
done
service-management:
steps:
- manage-cassandra-service:
action: execrun
parameters:
roles: [seeds, nodes]
isSudo: true
command:
- /etc/init.d/cassandra "{$.service-action}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment