diff --git a/modules/run-consul/consul-bootstrap-ssm b/modules/run-consul/consul-bootstrap-ssm new file mode 100644 index 00000000..8c62cb53 --- /dev/null +++ b/modules/run-consul/consul-bootstrap-ssm @@ -0,0 +1,40 @@ +function read_acl_token { + local -r cluster_name="$1" + local -r token_name="${2:-bootstrap}" + local -r aws_region="$3" + local -r max_retries="${4:-50}" + local -r sleep_between_retries="${5:-4}" + local -r ignore_error="${6:-false}" + + local parameter_name=$(get_acl_token_ssm_parameter_name $cluster_name $token_name) + local parameters + local parameter_exists + local token + + for (( i=0; i<"$max_retries"; i++ )); do + parameters=$(aws ssm get-parameters --names $parameter_name --with-decryption --region $aws_region) + parameter_exists=$(echo $parameters | jq '[.Parameters[]] | length') + if [[ $parameter_exists -eq 1 ]]; then + token=$(echo $parameters | jq '.Parameters[0].Value' -r) + echo $token + return + else + log_info "Parameter $parameter_name does not yet exist." + sleep "$sleep_between_retries" + fi + done + log_error "Parameter $parameter_name still does not exist after exceeding maximum number of retries." + if [[ "$ignore_error" == "false" ]]; then + exit 1 + fi +} + +function write_acl_token { + local -r token="$1" + local -r cluster_name="$2" + local -r token_name="${3:-bootstrap}" + local -r aws_region="$4" + + local -r parameter_name=$(get_acl_token_ssm_parameter_name $cluster_name $token_name) + aws ssm put-parameter --name $parameter_name --value $token --type SecureString --region $aws_region +} diff --git a/modules/run-consul/consul-bootstrap-vault b/modules/run-consul/consul-bootstrap-vault new file mode 100644 index 00000000..6e198867 --- /dev/null +++ b/modules/run-consul/consul-bootstrap-vault @@ -0,0 +1,39 @@ +function get_acl_token_parameter_name { + echo "ims_kv/consul/$cluster_name/$token_name" +} + +function read_acl_token { + local -r cluster_name="$1" + local -r token_name="${2:-bootstrap}" + local -r aws_region="$3" + local -r max_retries="${4:-50}" + local -r sleep_between_retries="${5:-4}" + local -r ignore_error="${6:-false}" + + local parameter_name=$(get_acl_token_parameter_name $cluster_name $token_name) + local token + + for (( i=0; i<"$max_retries"; i++ )); do + token=$(vault kv get $parameter_name -format json -field token) + if [[ $? -eq 0 ]] && [[ -n $token ]]; then + echo $token + return + else + log_info "Vault KV path $parameter_name does not yet exist." + sleep "$sleep_between_retries" + fi + done + log_error "Parameter $parameter_name still does not exist after exceeding maximum number of retries." + if [[ "$ignore_error" == "false" ]]; then + exit 1 + fi +} + +function write_acl_token { + local -r token="$1" + local -r cluster_name="$2" + local -r token_name="${3:-bootstrap}" + + local -r parameter_name=$(get_acl_token_parameter_name $cluster_name $token_name) + vault kv put $parameter_name token=$token +} diff --git a/modules/run-consul/consul-common.sh b/modules/run-consul/consul-common.sh index ec5f1be2..b202f677 100644 --- a/modules/run-consul/consul-common.sh +++ b/modules/run-consul/consul-common.sh @@ -228,60 +228,6 @@ function get_acl_token_ssm_parameter_name { echo "/$cluster_name/token/$token_name" } -function read_acl_token { - local -r cluster_name="$1" - local -r token_name="${2:-bootstrap}" - local -r aws_region="$3" - local -r storage_type="$4" - local -r max_retries="${5:-60}" - local -r sleep_between_retries="${6:-5}" - local -r ignore_error="${7:-false}" - - if [[ $storage_type == "ssm" ]]; then - local parameter_name=$(get_acl_token_ssm_parameter_name $cluster_name $token_name) - local parameters - local parameter_exists - local token - - for (( i=0; i<"$max_retries"; i++ )); do - parameters=$(aws ssm get-parameters --names $parameter_name --with-decryption --region $aws_region) - parameter_exists=$(echo $parameters | jq '[.Parameters[]] | length') - if [[ $parameter_exists -eq 1 ]]; then - token=$(echo $parameters | jq '.Parameters[0].Value' -r) - echo $token - return - else - log_info "Parameter $parameter_name does not yet exist." - sleep "$sleep_between_retries" - fi - done - log_error "Parameter $parameter_name still does not exist after exceeding maximum number of retries." - if [[ "$ignore_error" == "false" ]]; then - exit 1 - fi - else - log_error "ACL storage type '${storage_type}' is not supported." - exit 1 - fi -} - -function write_acl_token { - local -r token="$1" - local -r cluster_name="$2" - local -r token_name="${3:-bootstrap}" - local -r aws_region="$4" - local -r storage_type="$5" - - if [[ $storage_type == "ssm" ]]; then - local -r parameter_name=$(get_acl_token_ssm_parameter_name $cluster_name $token_name) - aws ssm put-parameter --name $parameter_name --value $token --type SecureString --region $aws_region - else - log_error "ACL storage type '${storage_type}' is not supported." - exit 1 - fi - -} - function generate_consul_config { local -r server="${1}" local -r config_dir="${2}" @@ -482,6 +428,17 @@ function write_acl_policy { consul acl policy create -name $policy_name -rules "$policy_hcl" $token_arg } +function generate_agent_policy_and_token { + local -r node_name="$1" + local -r token="$2" + + local -r agent_policy=$(generate_node_acl_policy $node_name) + write_acl_policy "$node_name" "$agent_policy" "$token" + + local -r generated_token=$(generate_token "$node_name" "$node_name agent policy" $token) + echo $generated_token +} + function generate_token { local -r policy_name="$1" local -r description="$2" @@ -511,4 +468,4 @@ function set_agent_token { fi consul acl set-agent-token $token_arg agent "$token" -} \ No newline at end of file +} diff --git a/modules/run-consul/run-consul b/modules/run-consul/run-consul index 3b2e98de..7dad257d 100755 --- a/modules/run-consul/run-consul +++ b/modules/run-consul/run-consul @@ -328,6 +328,8 @@ function run { start_consul if [[ "$enable_acl" == "true" ]]; then + local -r storage_type = "ssm" + local -r asg_name=$(aws_wrapper_get_asg_name $MAX_RETRIES $SLEEP_BETWEEN_RETRIES_SEC) local -r aws_region=$(aws_get_instance_region) local -r instance_id=$(aws_get_instance_id) @@ -339,16 +341,34 @@ function run { log_info "Calculated rally point instance is $rally_point_hostname." local -r local_hostname=$(aws_wrapper_get_hostname) log_info "Local hostname is $local_hostname" - + + local storage_type_matched = false + case "$storage_type" in + 'ssm' | 'SSM') + storage_type_matched = true + source ${SCRIPT_DIR}/consul-bootstrap-ssm.sh;; + + 'vault' | 'VAULT') + storage_type_matched = true + source ${SCRIPT_DIR}/consul-bootstrap-vault.sh;; + + *) + if [$storage_type_matched = false]; then + log_error "ACL storage type '${storage_type}' is not supported." + exit 1 + fi;; + + esac + if [[ "$rally_point_hostname" == "$local_hostname" ]]; then log_info "Checking if bootstrap token already exists" - local -r existing_token=$(read_acl_token $cluster_tag_value "bootstrap" $aws_region "ssm" 1 0 "true") + local -r existing_token=$(read_acl_token $cluster_tag_value "bootstrap" $aws_region "1 0 "true") if [[ "$existing_token" == "" ]] && [ "${server}" == "true" ]; then log_info "Generating bootstrap ACL token" bootstrap_token=$(generate_bootstrap_acl_token $MAX_RETRIES $SLEEP_BETWEEN_RETRIES_SEC) - log_info "Persisting bootstrap token to SSM parameter" - write_acl_token $bootstrap_token $cluster_tag_value "bootstrap" $aws_region "ssm" + log_info "Persisting bootstrap token" + write_acl_token $bootstrap_token $cluster_tag_value "bootstrap" $aws_region else log_info "Bootstrap token already exists, skipping" fi @@ -358,16 +378,12 @@ function run { # then we need to read it. if [[ -z "$bootstrap_token" ]]; then log_info "Acquiring bootstrap token" - bootstrap_token=$(read_acl_token $cluster_tag_value "bootstrap" $aws_region "ssm") + bootstrap_token=$(read_acl_token $cluster_tag_value "bootstrap" $aws_region) fi # Generate agent policy dynamically and write it log_info "Creating agent policy and token" - local -r agent_policy=$(generate_node_acl_policy $local_hostname) - write_acl_policy "$instance_id" "$agent_policy" "$bootstrap_token" - - # Generate agent token and persist it - local -r agent_token=$(generate_token "$instance_id" "$instance_id agent policy" $bootstrap_token) + local -r agent_token=$(generate_agent_policy_and_token "$instance_id" $bootstrap_token) set_agent_token "$agent_token" "$bootstrap_token" fi