Created
June 8, 2016 10:08
-
-
Save jollyrojer/46814068ad954d1f86582c007c6bbe55 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
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