1#!/bin/bash
2# This script is used to configure and run Consul on an AWS server.
3# SOURCE: GRUNTWORKS
4
5set -e
6
7readonly AWS_ASG_TAG_KEY="aws:autoscaling:groupName"
8
9readonly CONSUL_CONFIG_FILE="default.json"
10readonly CONSUL_GOSSIP_ENCRYPTION_CONFIG_FILE="gossip-encryption.json"
11readonly CONSUL_RPC_ENCRYPTION_CONFIG_FILE="rpc-encryption.json"
12readonly SYSTEMD_CONFIG_PATH="/etc/systemd/system/consul.service"
13
14readonly EC2_INSTANCE_METADATA_URL="http://169.254.169.254/latest/meta-data"
15readonly EC2_INSTANCE_DYNAMIC_DATA_URL="http://169.254.169.254/latest/dynamic"
16
17readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18readonly SCRIPT_NAME="$(basename "$0")"
19
20readonly MAX_RETRIES=30
21readonly SLEEP_BETWEEN_RETRIES_SEC=10
22
23readonly DEFAULT_AUTOPILOT_CLEANUP_DEAD_SERVERS="true"
24readonly DEFAULT_AUTOPILOT_LAST_CONTACT_THRESHOLD="200ms"
25readonly DEFAULT_AUTOPILOT_MAX_TRAILING_LOGS="250"
26readonly DEFAULT_AUTOPILOT_SERVER_STABILIZATION_TIME="10s"
27readonly DEFAULT_AUTOPILOT_REDUNDANCY_ZONE_TAG="az"
28readonly DEFAULT_AUTOPILOT_DISABLE_UPGRADE_MIGRATION="false"
29
30function print_usage {
31  echo
32  echo "Usage: run-consul [OPTIONS]"
33  echo
34  echo "This script is used to configure and run Consul on an AWS server."
35  echo
36  echo "Options:"
37  echo
38  echo -e "  --server\t\tIf set, run in server mode. Optional. Exactly one of --server or --client must be set."
39  echo -e "  --client\t\tIf set, run in client mode. Optional. Exactly one of --server or --client must be set."
40  echo -e "  --cluster-tag-key\tAutomatically form a cluster with Instances that have this tag key and the tag value in --cluster-tag-value. Optional."
41  echo -e "  --cluster-tag-value\tAutomatically form a cluster with Instances that have the tag key in --cluster-tag-key and this tag value. Optional."
42  echo -e "  --datacenter\t\tThe name of the datacenter Consul is running in. Optional. If not specified, will default to AWS region name."
43  echo -e "  --config-dir\t\tThe path to the Consul config folder. Optional. Default is the absolute path of '../config', relative to this script."
44  echo -e "  --data-dir\t\tThe path to the Consul data folder. Optional. Default is the absolute path of '../data', relative to this script."
45  echo -e "  --systemd-stdout\t\tThe StandardOutput option of the systemd unit.  Optional.  If not configured, uses systemd's default (journal)."
46  echo -e "  --systemd-stderr\t\tThe StandardError option of the systemd unit.  Optional.  If not configured, uses systemd's default (inherit)."
47  echo -e "  --bin-dir\t\tThe path to the folder with Consul binary. Optional. Default is the absolute path of the parent folder of this script."
48  echo -e "  --user\t\tThe user to run Consul as. Optional. Default is to use the owner of --config-dir."
49  echo -e "  --enable-gossip-encryption\t\tEnable encryption of gossip traffic between nodes. Optional. Must also specify --gossip-encryption-key."
50  echo -e "  --gossip-encryption-key\t\tThe key to use for encrypting gossip traffic. Optional. Must be specified with --enable-gossip-encryption."
51  echo -e "  --enable-rpc-encryption\t\tEnable encryption of RPC traffic between nodes. Optional. Must also specify --ca-file-path, --cert-file-path and --key-file-path."
52  echo -e "  --ca-path\t\tPath to the directory of CA files used to verify outgoing connections. Optional. Must be specified with --enable-rpc-encryption."
53  echo -e "  --cert-file-path\tPath to the certificate file used to verify incoming connections. Optional. Must be specified with --enable-rpc-encryption and --key-file-path."
54  echo -e "  --key-file-path\tPath to the certificate key used to verify incoming connections. Optional. Must be specified with --enable-rpc-encryption and --cert-file-path."
55  echo -e "  --environment\t\tA single environment variable in the key/value pair form 'KEY=\"val\"' to pass to Consul as environment variable when starting it up. Repeat this option for additional variables. Optional."
56  echo -e "  --skip-consul-config\tIf this flag is set, don't generate a Consul configuration file. Optional. Default is false."
57  echo -e "  --recursor\tThis flag provides address of upstream DNS server that is used to recursively resolve queries if they are not inside the service domain for Consul. Repeat this option for additional variables. Optional."
58  echo
59  echo "Options for Consul Autopilot:"
60  echo
61  echo -e "  --autopilot-cleanup-dead-servers\tSet to true or false to control the automatic removal of dead server nodes periodically and whenever a new server is added to the cluster. Defaults to $DEFAULT_AUTOPILOT_CLEANUP_DEAD_SERVERS. Optional."
62  echo -e "  --autopilot-last-contact-threshold\tControls the maximum amount of time a server can go without contact from the leader before being considered unhealthy. Must be a duration value such as 10s. Defaults to $DEFAULT_AUTOPILOT_LAST_CONTACT_THRESHOLD. Optional."
63  echo -e "  --autopilot-max-trailing-logs\t\tControls the maximum number of log entries that a server can trail the leader by before being considered unhealthy. Defaults to $DEFAULT_AUTOPILOT_MAX_TRAILING_LOGS. Optional."
64  echo -e "  --autopilot-server-stabilization-time\tControls the minimum amount of time a server must be stable in the 'healthy' state before being added to the cluster. Only takes effect if all servers are running Raft protocol version 3 or higher. Must be a duration value such as 30s. Defaults to $DEFAULT_AUTOPILOT_SERVER_STABILIZATION_TIME. Optional."
65  echo -e "  --autopilot-redundancy-zone-tag\t\t(Enterprise-only) This controls the -node-meta key to use when Autopilot is separating servers into zones for redundancy. Only one server in each zone can be a voting member at one time. If left blank, this feature will be disabled. Defaults to $DEFAULT_AUTOPILOT_REDUNDANCY_ZONE_TAG. Optional."
66  echo -e "  --autopilot-disable-upgrade-migration\t(Enterprise-only) If this flag is set, this will disable Autopilot's upgrade migration strategy in Consul Enterprise of waiting until enough newer-versioned servers have been added to the cluster before promoting any of them to voters. Defaults to $DEFAULT_AUTOPILOT_DISABLE_UPGRADE_MIGRATION. Optional."
67  echo -e "  --autopilot-upgrade-version-tag\t\t(Enterprise-only) That tag to be used to override the version information used during a migration. Optional."
68  echo
69  echo
70  echo "Example:"
71  echo
72  echo "  run-consul --server --config-dir /custom/path/to/consul/config"
73}
74
75function log {
76  local -r level="$1"
77  local -r message="$2"
78  local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S")
79  >&2 echo -e "${timestamp} [${level}] [$SCRIPT_NAME] ${message}"
80}
81
82function log_info {
83  local -r message="$1"
84  log "INFO" "$message"
85}
86
87function log_warn {
88  local -r message="$1"
89  log "WARN" "$message"
90}
91
92function log_error {
93  local -r message="$1"
94  log "ERROR" "$message"
95}
96
97# Based on code from: http://stackoverflow.com/a/16623897/483528
98function strip_prefix {
99  local -r str="$1"
100  local -r prefix="$2"
101  echo "${str#$prefix}"
102}
103
104function assert_not_empty {
105  local -r arg_name="$1"
106  local -r arg_value="$2"
107
108  if [[ -z "$arg_value" ]]; then
109    log_error "The value for '$arg_name' cannot be empty"
110    print_usage
111    exit 1
112  fi
113}
114
115function lookup_path_in_instance_metadata {
116  local -r path="$1"
117  curl --silent --show-error --location "$EC2_INSTANCE_METADATA_URL/$path/"
118}
119
120function lookup_path_in_instance_dynamic_data {
121  local -r path="$1"
122  curl --silent --show-error --location "$EC2_INSTANCE_DYNAMIC_DATA_URL/$path/"
123}
124
125function get_instance_ip_address {
126  lookup_path_in_instance_metadata "local-ipv4"
127}
128
129function get_instance_id {
130  lookup_path_in_instance_metadata "instance-id"
131}
132
133function get_instance_region {
134  lookup_path_in_instance_dynamic_data "instance-identity/document" | jq -r ".region"
135}
136
137function get_instance_tags {
138  local -r instance_id="$1"
139  local -r instance_region="$2"
140  local tags=""
141  local count_tags=""
142
143  log_info "Looking up tags for Instance $instance_id in $instance_region"
144  for (( i=1; i<="$MAX_RETRIES"; i++ )); do
145    tags=$(aws ec2 describe-tags \
146      --region "$instance_region" \
147      --filters "Name=resource-type,Values=instance" "Name=resource-id,Values=${instance_id}")
148    count_tags=$(echo $tags | jq -r ".Tags? | length")
149    if [[ "$count_tags" -gt 0 ]]; then
150      log_info "This Instance $instance_id in $instance_region has Tags."
151      echo "$tags"
152      return
153    else
154      log_warn "This Instance $instance_id in $instance_region does not have any Tags."
155      log_warn "Will sleep for $SLEEP_BETWEEN_RETRIES_SEC seconds and try again."
156      sleep "$SLEEP_BETWEEN_RETRIES_SEC"
157    fi
158  done
159
160  log_error "Could not find Instance Tags for $instance_id in $instance_region after $MAX_RETRIES retries."
161  exit 1
162}
163
164function get_asg_size {
165  local -r asg_name="$1"
166  local -r aws_region="$2"
167  local asg_json=""
168
169  log_info "Looking up the size of the Auto Scaling Group $asg_name in $aws_region"
170  asg_json=$(aws autoscaling describe-auto-scaling-groups --region "$aws_region" --auto-scaling-group-names "$asg_name")
171  echo "$asg_json" | jq -r '.AutoScalingGroups[0].DesiredCapacity'
172}
173
174function get_cluster_size {
175  local -r instance_tags="$1"
176  local -r aws_region="$2"
177
178  local asg_name=""
179  asg_name=$(get_tag_value "$instance_tags" "$AWS_ASG_TAG_KEY")
180  if [[ -z "$asg_name" ]]; then
181    log_warn "This EC2 Instance does not appear to be part of an Auto Scaling Group, so cannot determine cluster size. Setting cluster size to 1."
182    echo 1
183  else
184    get_asg_size "$asg_name" "$aws_region"
185  fi
186}
187
188# Get the value for a specific tag from the tags JSON returned by the AWS describe-tags:
189# https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-tags.html
190function get_tag_value {
191  local -r tags="$1"
192  local -r tag_key="$2"
193
194  echo "$tags" | jq -r ".Tags[] | select(.Key == \"$tag_key\") | .Value"
195}
196
197function assert_is_installed {
198  local -r name="$1"
199
200  if [[ ! $(command -v ${name}) ]]; then
201    log_error "The binary '$name' is required by this script but is not installed or in the system's PATH."
202    exit 1
203  fi
204}
205
206function split_by_lines {
207  local prefix="$1"
208  shift
209
210  for var in "$@"; do
211    echo "${prefix}${var}"
212  done
213}
214
215function generate_consul_config {
216  local -r server="${1}"
217  local -r config_dir="${2}"
218  local -r user="${3}"
219  local -r cluster_tag_key="${4}"
220  local -r cluster_tag_value="${5}"
221  local -r datacenter="${6}"
222  local -r enable_gossip_encryption="${7}"
223  local -r gossip_encryption_key="${8}"
224  local -r enable_rpc_encryption="${9}"
225  local -r ca_path="${10}"
226  local -r cert_file_path="${11}"
227  local -r key_file_path="${12}"
228  local -r cleanup_dead_servers="${13}"
229  local -r last_contact_threshold="${14}"
230  local -r max_trailing_logs="${15}"
231  local -r server_stabilization_time="${16}"
232  local -r redundancy_zone_tag="${17}"
233  local -r disable_upgrade_migration="${18}"
234  local -r upgrade_version_tag=${19}
235  local -r config_path="$config_dir/$CONSUL_CONFIG_FILE"
236
237  shift 19
238  local -r recursors=("$@")
239
240  local instance_id=""
241  local instance_ip_address=""
242  local instance_region=""
243  local ui="false"
244
245  instance_id=$(get_instance_id)
246  instance_ip_address=$(get_instance_ip_address)
247  instance_region=$(get_instance_region)
248
249  local retry_join_json=""
250  if [[ -z "$cluster_tag_key" || -z "$cluster_tag_value" ]]; then
251    log_warn "Either the cluster tag key ($cluster_tag_key) or value ($cluster_tag_value) is empty. Will not automatically try to form a cluster based on EC2 tags."
252  else
253    retry_join_json=$(cat <<EOF
254"retry_join": ["provider=aws region=$instance_region tag_key=$cluster_tag_key tag_value=$cluster_tag_value"],
255EOF
256)
257  fi
258
259  local recursors_config=""
260  if (( ${#recursors[@]} != 0 )); then
261        recursors_config="\"recursors\" : [ "
262        for recursor in ${recursors[@]}
263        do
264            recursors_config="${recursors_config}\"${recursor}\", "
265        done
266        recursors_config=$(echo "${recursors_config}"| sed 's/, $//')" ],"
267  fi
268
269  local bootstrap_expect=""
270  if [[ "$server" == "true" ]]; then
271    local instance_tags=""
272    local cluster_size=""
273
274    instance_tags=$(get_instance_tags "$instance_id" "$instance_region")
275    cluster_size=$(get_cluster_size "$instance_tags" "$instance_region")
276
277    bootstrap_expect="\"bootstrap_expect\": $cluster_size,"
278    ui="true"
279  fi
280
281  local autopilot_configuration=$(cat <<EOF
282"autopilot": {
283  "cleanup_dead_servers": $cleanup_dead_servers,
284  "last_contact_threshold": "$last_contact_threshold",
285  "max_trailing_logs": $max_trailing_logs,
286  "server_stabilization_time": "$server_stabilization_time",
287  "redundancy_zone_tag": "$redundancy_zone_tag",
288  "disable_upgrade_migration": $disable_upgrade_migration,
289  "upgrade_version_tag": "$upgrade_version_tag"
290},
291EOF
292)
293
294  local gossip_encryption_configuration=""
295  if [[ "$enable_gossip_encryption" == "true" && ! -z "$gossip_encryption_key" ]]; then
296    log_info "Creating gossip encryption configuration"
297    gossip_encryption_configuration="\"encrypt\": \"$gossip_encryption_key\","
298  fi
299
300  local rpc_encryption_configuration=""
301  if [[ "$enable_rpc_encryption" == "true" && ! -z "$ca_path" && ! -z "$cert_file_path" && ! -z "$key_file_path" ]]; then
302    log_info "Creating RPC encryption configuration"
303    rpc_encryption_configuration=$(cat <<EOF
304"verify_outgoing": true,
305"verify_incoming": true,
306"ca_path": "$ca_path",
307"cert_file": "$cert_file_path",
308"key_file": "$key_file_path",
309EOF
310)
311  fi
312
313  log_info "Creating default Consul configuration"
314  local default_config_json=$(cat <<EOF
315{
316  "advertise_addr": "$instance_ip_address",
317  "bind_addr": "$instance_ip_address",
318  $bootstrap_expect
319  "client_addr": "0.0.0.0",
320  "datacenter": "$datacenter",
321  "node_name": "$instance_id",
322  $recursors_config
323  $retry_join_json
324  "server": $server,
325  $gossip_encryption_configuration
326  $rpc_encryption_configuration
327  $autopilot_configuration
328  "ui": $ui
329}
330EOF
331)
332  log_info "Installing Consul config file in $config_path"
333  echo "$default_config_json" | jq '.' > "$config_path"
334  chown "$user:$user" "$config_path"
335}
336
337function generate_systemd_config {
338  local -r systemd_config_path="$1"
339  local -r consul_config_dir="$2"
340  local -r consul_data_dir="$3"
341  local -r consul_systemd_stdout="$4"
342  local -r consul_systemd_stderr="$5"
343  local -r consul_bin_dir="$6"
344  local -r consul_user="$7"
345  shift 7
346  local -r environment=("$@")
347  local -r config_path="$consul_config_dir/$CONSUL_CONFIG_FILE"
348
349  log_info "Creating systemd config file to run Consul in $systemd_config_path"
350
351  local -r unit_config=$(cat <<EOF
352[Unit]
353Description="HashiCorp Consul - A service mesh solution"
354Documentation=https://www.consul.io/
355Requires=network-online.target
356After=network-online.target
357ConditionFileNotEmpty=$config_path
358
359EOF
360)
361
362  local -r service_config=$(cat <<EOF
363[Service]
364Type=notify
365User=$consul_user
366Group=$consul_user
367ExecStart=$consul_bin_dir/consul agent -config-dir $consul_config_dir -data-dir $consul_data_dir
368ExecReload=$consul_bin_dir/consul reload
369KillMode=process
370Restart=on-failure
371TimeoutSec=300s
372LimitNOFILE=65536
373$(split_by_lines "Environment=" "${environment[@]}")
374
375EOF
376)
377
378  local log_config=""
379  if [[ ! -z $consul_systemd_stdout ]]; then
380    log_config+="StandardOutput=$consul_systemd_stdout\n"
381  fi
382  if [[ ! -z $consul_systemd_stderr ]]; then
383    log_config+="StandardError=$consul_systemd_stderr\n"
384  fi
385
386  local -r install_config=$(cat <<EOF
387[Install]
388WantedBy=multi-user.target
389EOF
390)
391
392  echo -e "$unit_config" > "$systemd_config_path"
393  echo -e "$service_config" >> "$systemd_config_path"
394  echo -e "$log_config" >> "$systemd_config_path"
395  echo -e "$install_config" >> "$systemd_config_path"
396}
397
398function start_consul {
399  log_info "Reloading systemd config and starting Consul"
400
401  sudo systemctl daemon-reload
402  sudo systemctl enable consul.service
403  sudo systemctl restart consul.service
404}
405
406# Based on: http://unix.stackexchange.com/a/7732/215969
407function get_owner_of_path {
408  local -r path="$1"
409  ls -ld "$path" | awk '{print $3}'
410}
411
412function run {
413  local server="false"
414  local client="false"
415  local config_dir=""
416  local data_dir=""
417  local systemd_stdout=""
418  local systemd_stderr=""
419  local bin_dir=""
420  local user=""
421  local cluster_tag_key=""
422  local cluster_tag_value=""
423  local datacenter=""
424  local upgrade_version_tag=""
425  local enable_gossip_encryption="false"
426  local gossip_encryption_key=""
427  local enable_rpc_encryption="false"
428  local ca_path=""
429  local cert_file_path=""
430  local key_file_path=""
431  local environment=()
432  local skip_consul_config="false"
433  local recursors=()
434  local all_args=()
435  local cleanup_dead_servers="$DEFAULT_AUTOPILOT_CLEANUP_DEAD_SERVERS"
436  local last_contact_threshold="$DEFAULT_AUTOPILOT_LAST_CONTACT_THRESHOLD"
437  local max_trailing_logs="$DEFAULT_AUTOPILOT_MAX_TRAILING_LOGS"
438  local server_stabilization_time="$DEFAULT_AUTOPILOT_SERVER_STABILIZATION_TIME"
439  local redundancy_zone_tag="$DEFAULT_AUTOPILOT_REDUNDANCY_ZONE_TAG"
440  local disable_upgrade_migration="$DEFAULT_AUTOPILOT_DISABLE_UPGRADE_MIGRATION"
441
442  while [[ $# > 0 ]]; do
443    local key="$1"
444
445    case "$key" in
446      --server)
447        server="true"
448        ;;
449      --client)
450        client="true"
451        ;;
452      --config-dir)
453        assert_not_empty "$key" "$2"
454        config_dir="$2"
455        shift
456        ;;
457      --data-dir)
458        assert_not_empty "$key" "$2"
459        data_dir="$2"
460        shift
461        ;;
462      --systemd-stdout)
463        assert_not_empty "$key" "$2"
464        systemd_stdout="$2"
465        shift
466        ;;
467      --systemd-stderr)
468        assert_not_empty "$key" "$2"
469        systemd_stderr="$2"
470        shift
471        ;;
472      --bin-dir)
473        assert_not_empty "$key" "$2"
474        bin_dir="$2"
475        shift
476        ;;
477      --user)
478        assert_not_empty "$key" "$2"
479        user="$2"
480        shift
481        ;;
482      --cluster-tag-key)
483        assert_not_empty "$key" "$2"
484        cluster_tag_key="$2"
485        shift
486        ;;
487      --cluster-tag-value)
488        assert_not_empty "$key" "$2"
489        cluster_tag_value="$2"
490        shift
491        ;;
492      --datacenter)
493        assert_not_empty "$key" "$2"
494        datacenter="$2"
495        shift
496        ;;
497      --autopilot-cleanup-dead-servers)
498        assert_not_empty "$key" "$2"
499        cleanup_dead_servers="$2"
500        shift
501        ;;
502      --autopilot-last-contact-threshold)
503        assert_not_empty "$key" "$2"
504        last_contact_threshold="$2"
505        shift
506        ;;
507      --autopilot-max-trailing-logs)
508        assert_not_empty "$key" "$2"
509        max_trailing_logs="$2"
510        shift
511        ;;
512      --autopilot-server-stabilization-time)
513        assert_not_empty "$key" "$2"
514        server_stabilization_time="$2"
515        shift
516        ;;
517      --autopilot-redundancy-zone-tag)
518        assert_not_empty "$key" "$2"
519        redundancy_zone_tag="$2"
520        shift
521        ;;
522      --autopilot-disable-upgrade-migration)
523        disable_upgrade_migration="true"
524        shift
525        ;;
526      --autopilot-upgrade-version-tag)
527        assert_not_empty "$key" "$2"
528        upgrade_version_tag="$2"
529        shift
530        ;;
531      --enable-gossip-encryption)
532        enable_gossip_encryption="true"
533        ;;
534      --gossip-encryption-key)
535        assert_not_empty "$key" "$2"
536        gossip_encryption_key="$2"
537        shift
538        ;;
539      --enable-rpc-encryption)
540        enable_rpc_encryption="true"
541        ;;
542      --ca-path)
543        assert_not_empty "$key" "$2"
544        ca_path="$2"
545        shift
546        ;;
547      --cert-file-path)
548        assert_not_empty "$key" "$2"
549        cert_file_path="$2"
550        shift
551        ;;
552      --key-file-path)
553        assert_not_empty "$key" "$2"
554        key_file_path="$2"
555        shift
556        ;;
557      --environment)
558        assert_not_empty "$key" "$2"
559        environment+=("$2")
560        shift
561        ;;
562      --skip-consul-config)
563        skip_consul_config="true"
564        ;;
565      --recursor)
566        assert_not_empty "$key" "$2"
567        recursors+=("$2")
568        shift
569        ;;
570      --help)
571        print_usage
572        exit
573        ;;
574      *)
575        log_error "Unrecognized argument: $key"
576        print_usage
577        exit 1
578        ;;
579    esac
580
581    shift
582  done
583
584  if [[ ("$server" == "true" && "$client" == "true") || ("$server" == "false" && "$client" == "false") ]]; then
585    log_error "Exactly one of --server or --client must be set."
586    exit 1
587  fi
588
589  assert_is_installed "systemctl"
590  assert_is_installed "aws"
591  assert_is_installed "curl"
592  assert_is_installed "jq"
593
594  if [[ -z "$config_dir" ]]; then
595    config_dir=$(cd "$SCRIPT_DIR/../config" && pwd)
596  fi
597
598  if [[ -z "$data_dir" ]]; then
599    data_dir=$(cd "$SCRIPT_DIR/../data" && pwd)
600  fi
601
602  # If $systemd_stdout and/or $systemd_stderr are empty, we leave them empty so that generate_systemd_config will use systemd's defaults (journal and inherit, respectively)
603
604  if [[ -z "$bin_dir" ]]; then
605    bin_dir=$(cd "$SCRIPT_DIR/../bin" && pwd)
606  fi
607
608  if [[ -z "$user" ]]; then
609    user=$(get_owner_of_path "$config_dir")
610  fi
611
612  if [[ -z "$datacenter" ]]; then
613    datacenter=$(get_instance_region)
614  fi
615
616  if [[ "$skip_consul_config" == "true" ]]; then
617    log_info "The --skip-consul-config flag is set, so will not generate a default Consul config file."
618  else
619    if [[ "$enable_gossip_encryption" == "true" ]]; then
620      assert_not_empty "--gossip-encryption-key" "$gossip_encryption_key"
621    fi
622    if [[ "$enable_rpc_encryption" == "true" ]]; then
623      assert_not_empty "--ca-path" "$ca_path"
624      assert_not_empty "--cert-file-path" "$cert_file_path"
625      assert_not_empty "--key_file_path" "$key_file_path"
626    fi
627
628    generate_consul_config "$server" \
629      "$config_dir" \
630      "$user" \
631      "$cluster_tag_key" \
632      "$cluster_tag_value" \
633      "$datacenter" \
634      "$enable_gossip_encryption" \
635      "$gossip_encryption_key" \
636      "$enable_rpc_encryption" \
637      "$ca_path" \
638      "$cert_file_path" \
639      "$key_file_path" \
640      "$cleanup_dead_servers" \
641      "$last_contact_threshold" \
642      "$max_trailing_logs" \
643      "$server_stabilization_time" \
644      "$redundancy_zone_tag" \
645      "$disable_upgrade_migration" \
646      "$upgrade_version_tag" \
647      "${recursors[@]}"
648  fi
649
650  generate_systemd_config "$SYSTEMD_CONFIG_PATH" "$config_dir" "$data_dir" "$systemd_stdout" "$systemd_stderr" "$bin_dir" "$user" "${environment[@]}"
651  start_consul
652}
653
654run "$@"
655