Changing The Default "ubuntu" Username On New EC2 Instances

configure your own ssh username in user-data

The official Ubuntu AMIs create a default user with the username ubuntu which is used for the initial ssh access, i.e.:

ssh ubuntu@<HOST>

You can create other users with your preferred usernames using standard Linux commands, but it is difficult to change the ubuntu username while you are logged in to that account since that is one of the checks made by usermod:

$ usermod -l myname ubuntu
usermod: user ubuntu is currently logged in

There are a couple ways to change the username of the default user on a new Ubuntu instance; both passing in special content for the user-data.

Approach 1: CloudInit cloud-config

The CloudInit package supports a special user-data format where you can pass in configuration parameters for the setup. Here is sample user-data (including the comment-like first line) that will set up the first user as ec2-user instead of the default ubuntu username.

#cloud-config
system_info:
  default_user:
    name: ec2-user

Here is a complete example using this cloud-config approach. It assumes you have already uploaded your default ssh key to EC2:

username=ec2-user
ami_id=ami-6d0c2204 # Ubuntu 13.10 Saucy
user_data_file=$(mktemp /tmp/user-data-XXXX.txt)

cat <<EOF >$user_data_file
#cloud-config
system_info:
  default_user:
    name: $username
EOF

instance_id=$(aws ec2 run-instances --user-data file://$user_data_file --key-name $USER --image-id $ami_id --instance-type t1.micro --output text --query 'Instances[*].InstanceId')
rm $user_data_file
echo instance_id=$instance_id

ip_address=$(aws ec2 describe-instances --instance-ids $instance_id --output text --query 'Reservations[*].Instances[*].PublicIpAddress')
echo ip_address=$ip_address

ssh ec2-user@$ip_address

The above cloud-config options do not seem to work for some older versions of Ubuntu including Ubuntu 12.05 LTS Precise, so here is another way to accomplish the same functionality…

Approach 2: user-data script

If you are using an older version of Ubuntu where the above cloud-config approach does not work, then you can change the default ubuntu user to a different username in a user-data script using standard Linux commands.

This approach is also useful if you are already using user-data scripts to do other initialization so you don’t have to mix shell commands and cloud-config directives.

Here’s a sample user-data script that renames the ubuntu user so that you ssh to ec2-user instead.

#!/bin/bash -ex
user=ec2-user
usermod  -l $user ubuntu
groupmod -n $user ubuntu
usermod  -d /home/$user -m $user
if [ -f /etc/sudoers.d/90-cloudimg-ubuntu ]; then
  mv /etc/sudoers.d/90-cloudimg-ubuntu /etc/sudoers.d/90-cloud-init-users
fi
perl -pi -e "s/ubuntu/$user/g;" /etc/sudoers.d/90-cloud-init-users

Here is a complete example using this user-data script approach. It assumes you have already uploaded your default ssh key to EC2:

username=ec2-user
ami_id=ami-6d0c2204 # Ubuntu 13.10 Saucy
user_data_file=$(mktemp /tmp/user-data-XXXX.txt)

cat <<EOF >$user_data_file
#!/bin/bash -ex
user=$username
usermod  -l \$user ubuntu
groupmod -n \$user ubuntu
usermod  -d /home/\$user -m \$user
if [ -f /etc/sudoers.d/90-cloudimg-ubuntu ]; then
  mv /etc/sudoers.d/90-cloudimg-ubuntu /etc/sudoers.d/90-cloud-init-users
fi
perl -pi -e "s/ubuntu/\$user/g;" /etc/sudoers.d/90-cloud-init-users
EOF

instance_id=$(aws ec2 run-instances --user-data file://$user_data_file --key-name $USER --image-id $ami_id --instance-type t1.micro --output text --query 'Instances[*].InstanceId')
rm $user_data_file
echo instance_id=$instance_id

ip_address=$(aws ec2 describe-instances --instance-ids $instance_id --output text --query 'Reservations[*].Instances[*].PublicIpAddress')
echo ip_address=$ip_address

ssh ec2-user@$ip_address

If you include this code in another user-data script, you may want to change the username towards the beginning of the script so that you can log in and monitor progress of the rest of the script.

Clean Up

When you’re done testing, terminate each demo instance.

aws ec2 terminate-instances --instance-ids "$instance_id" --output text --query 'TerminatingInstances[*].CurrentState.Name'

The sample commands in this demo require you to install the aws-cli tool.