AwsUserDataSetEc2InstancePassword

nicolaw 13th May 2019 at 4:05pm
AWS bash CodeSnippets jq JSON
#!/usr/bin/env bash

set -veExo pipefail

aws_meta_data () {
  curl -sSL "http://169.254.169.254/latest/meta-data/$*"
}

aws_region () {
  declare az=""
  # shellcheck disable=SC2034
  az="$(aws_meta_data placement/availability-zone)"
  echo "$${az%[a-z]}"
}

aws_instance_id () {
  aws_meta_data instance-id
}

aws_ssm_get_parameter () {
  declare region=""; region="$(aws_region)"
  aws --region "$region" ssm get-parameter --with-decryption --name "$*"
}

aws_ec2_get_tags () {
  # Requires ec2:DescribeTags IAM action to be granted via instance profile.
  declare instance_id="$1"; shift
  aws ec2 describe-tags --filters "Name=resource-id,Values=$instance_id" "$@"
}

main () {
  declare password="" region="" function="${function}" instance_id=""

  instance_id="$(aws_instance_id)"
  if [[ -z "$${function:-}" ]]
  then
    # Optionally allow function to be templated by Terraform or CloudFormation.
    if ! function="$(aws_meta_data iam/security-credentials)" || [[ -z "$function" ]]
    then
      # Otherwise try to determine our function from our instance role, or from
      # the function tag on the instance.
      yum install -y jq
      # FIXME: Can we craft a query with awscli such that jq is unnecessary?
      function="$(aws_ec2_get_tags "$instance_id" | jq -r '.Tags[]|select(.Key=="function")|.Value')"
    fi
  fi

  # Keep a record of this instance function.
  jq -r ".+{function: \\"$function\\"}" /etc/myconfig.json | tee -a /etc/myconfig.json.new
  mv -v /etc/myconfig.json.new /etc/myconfig.json

  if password="$(aws_ssm_get_parameter "/myconfig/$function/instance/password/ec2-user/encrypted")"
  then
    # Set password to encrypted string stored in SSM.
    chpasswd -e <<< "ec2-user:$password"
  else
    # Otherwise set password to concatination of function and instance ID.
    chpasswd <<< "ec2-user:$function$instance_id"
  fi

  # Enable SSH password authentication.
  sed -i r 's/^(PasswordAuthentication)[[:space:]]+.*/\1 yes/' /etc/ssh/sshd_config
  service sshd restart
}