Skip to content

Instantly share code, notes, and snippets.

@alxndr42
Last active August 29, 2021 15:10
Show Gist options
  • Save alxndr42/fb5e151ee69b33f7900fd1bebf028753 to your computer and use it in GitHub Desktop.
Save alxndr42/fb5e151ee69b33f7900fd1bebf028753 to your computer and use it in GitHub Desktop.
Creates Debian-based LXD containers for Ansible management via SSH.
#!/bin/bash
# Creates Debian-based LXD containers for Ansible management via SSH.
#
# The user "ansible" is given password-less sudo access in the container
# and configured with the current user's Ed25519 or RSA key by default.
#
# Parameters:
# -k Use a different SSH key.
# -p Add the given profile.
# --nesting Enable "security.nesting".
export PATH="$PATH:/snap/bin"
usage_exit () {
echo "Usage: $(basename "$0") <image> <name> [-k public_key] [-p profile] [--nesting]"
exit 1
}
fail () {
echo "ERROR: $1"
exit 1
}
[ $# -ge 2 ] || usage_exit
IMAGE="$1"
NAME="$2"
shift 2
PUBLIC_KEY=""
PROFILE=""
NESTING="false"
C_USER="ansible"
C_HOME="/home/ansible"
# Parse command-line parameters
while [ -n "$1" ]; do
case "$1" in
-k)
PUBLIC_KEY="$2"
shift 2
;;
-p)
PROFILE="$2"
shift 2
;;
--nesting)
NESTING="true"
shift
;;
*)
usage_exit
;;
esac
done
# Ensure SSH public key
if [ -z "$PUBLIC_KEY" ]; then
if [ -f "$HOME/.ssh/id_ed25519.pub" ]; then
PUBLIC_KEY="$HOME/.ssh/id_ed25519.pub"
elif [ -f "$HOME/.ssh/id_rsa.pub" ]; then
PUBLIC_KEY="$HOME/.ssh/id_rsa.pub"
fi
fi
[ -f "$PUBLIC_KEY" ] || fail "No SSH public key"
echo "##### Launching container"
lxc launch "$IMAGE" "$NAME" || exit 1
if [ "$PROFILE" != "" ]; then
lxc profile add "$NAME" "$PROFILE" || exit 1
fi
echo "##### Creating Ansible user"
lxc exec "$NAME" -- adduser --home "$C_HOME" --shell /bin/bash --disabled-password --gecos '' "$C_USER" || exit 1
echo "##### Enabling SSH access"
lxc file push "$PUBLIC_KEY" "$NAME$C_HOME/.ssh/authorized_keys" -p --mode=600 || exit 1
lxc exec "$NAME" -- chmod 700 "$C_HOME/.ssh" || exit 1
lxc exec "$NAME" -- chown -R "$C_USER.$C_USER" "$C_HOME/.ssh" || exit 1
echo "##### Waiting for network"
WAIT=0
while [ "$(lxc exec "$NAME" -- ip a show scope global -tentative | grep -c inet)" -lt 1 ]; do
WAIT=$((WAIT + 1))
[ $WAIT -lt 60 ] || fail "Timeout while waiting for network"
sleep 1
done
echo "##### Waiting for cloud-init"
WAIT=0
while [ "$(lxc exec "$NAME" -- ps ax | grep -c cloud-init)" -gt 0 ]; do
WAIT=$((WAIT + 1))
[ $WAIT -lt 60 ] || fail "Timeout while waiting for cloud-init"
sleep 1
done
echo "##### Installing packages"
lxc exec "$NAME" -- apt-get -qy update || exit 1
lxc exec "$NAME" -- apt-get -qy install lsb-release openssh-server sudo || exit 1
lxc exec "$NAME" -- apt-get -qy install python3-minimal python3-apt || exit 1
lxc exec "$NAME" -- apt-get -qy autoremove --purge || exit 1
echo "##### Configuring sudo"
lxc exec "$NAME" -- mkdir -p /etc/sudoers.d || exit 1
lxc exec "$NAME" -- sh -c "echo \"$C_USER ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/99-$C_USER" || exit 1
if [ "$NESTING" = "true" ]; then
lxc config set "$NAME" security.nesting true
fi
echo "##### Finished!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment