Skip to content

Instantly share code, notes, and snippets.

@mjhong0708
Last active December 17, 2025 05:47
Show Gist options
  • Select an option

  • Save mjhong0708/c13c358a8eedabe433f8c64354657d89 to your computer and use it in GitHub Desktop.

Select an option

Save mjhong0708/c13c358a8eedabe433f8c64354657d89 to your computer and use it in GitHub Desktop.
#cloud-config
package_update: true
package_upgrade: false
packages:
- ca-certificates
- curl
- gnupg
- zip
- unzip
- xfsprogs
- git
- libssl-dev
- pkg-config
- build-essential
- htop
- tmux
- jq
- tree
- iputils-ping
- net-tools
- bind9-dnsutils
- nvtop
write_files:
# =======================
# Global config
# =======================
- path: /etc/ec2-bootstrap.conf
permissions: "0644"
content: |
REGION="ap-northeast-2"
EIP_ALLOC_ID="eipalloc-00e5b714a2ebad156"
VOLUME_ID="vol-0c11e130fcbe55de0"
MOUNT_POINT="/data"
# =======================
# AWS CLI v2
# =======================
- path: /usr/local/sbin/install-awscli-v2.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
command -v aws >/dev/null 2>&1 && exit 0
curl -s https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip
unzip -q /tmp/awscliv2.zip -d /tmp
/tmp/aws/install
# =======================
# Docker
# =======================
- path: /usr/local/sbin/install-docker.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
command -v docker >/dev/null 2>&1 && exit 0
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
cat > /etc/apt/sources.list.d/docker.sources <<'EOF'
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
DEFAULT_USER=$(getent passwd 1000 | cut -d: -f1 || true)
[ -n "$DEFAULT_USER" ] && usermod -aG docker "$DEFAULT_USER"
runcmd:
- [ bash, -lc, '/usr/local/sbin/install-awscli-v2.sh' ]
- [ bash, -lc, '/usr/local/sbin/install-docker.sh' ]
- [ bash, -lc, 'systemctl daemon-reload' ]
#cloud-config
package_update: true
package_upgrade: false
write_files:
# =======================
# Global config
# =======================
- path: /etc/ec2-bootstrap.conf
permissions: "0644"
content: |
REGION="ap-northeast-2"
EIP_ALLOC_ID="eipalloc-00e5b714a2ebad156"
VOLUME_ID="vol-0c11e130fcbe55de0"
MOUNT_POINT="/data"
# =======================
# Associate Elastic IP
# =======================
- path: /usr/local/sbin/associate-eip.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
source /etc/ec2-bootstrap.conf
command -v aws >/dev/null 2>&1 || exit 1
TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
[ -n "$TOKEN" ]
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id)
aws sts get-caller-identity --region "$REGION"
aws ec2 associate-address \
--instance-id "$INSTANCE_ID" \
--allocation-id "$EIP_ALLOC_ID" \
--allow-reassociation \
--region "$REGION"
# =======================
# EBS attach + mount
# =======================
- path: /usr/local/sbin/ebs-attach-and-mount.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
source /etc/ec2-bootstrap.conf
command -v aws >/dev/null 2>&1 || exit 1
# -----------------------
# Metadata (IMDSv2)
# -----------------------
TOKEN=$(curl -fsS -X PUT http://169.254.169.254/latest/api/token \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCE_ID=$(curl -fsS \
-H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id)
DEFAULT_USER=$(getent passwd 1000 | cut -d: -f1 || true)
DEVICE="/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_${VOLUME_ID//-/}"
STATE_FILE="/var/lib/ebs-${VOLUME_ID}.attached"
# -----------------------
# One-time guard
# -----------------------
if [ -f "$STATE_FILE" ]; then
echo "EBS volume already processed, skipping attach"
else
# -----------------------
# Check attachment state
# -----------------------
ATTACHED_INSTANCE=$(aws ec2 describe-volumes \
--volume-ids "$VOLUME_ID" \
--region "$REGION" \
--query 'Volumes[0].Attachments[0].InstanceId' \
--output text 2>/dev/null || true)
if [ "$ATTACHED_INSTANCE" = "$INSTANCE_ID" ]; then
echo "Volume already attached to this instance"
elif [ "$ATTACHED_INSTANCE" = "None" ] || [ -z "$ATTACHED_INSTANCE" ]; then
echo "Attaching volume $VOLUME_ID to $INSTANCE_ID"
aws ec2 attach-volume \
--volume-id "$VOLUME_ID" \
--instance-id "$INSTANCE_ID" \
--device /dev/sdf \
--region "$REGION"
else
echo "ERROR: Volume is attached to another instance: $ATTACHED_INSTANCE"
exit 1
fi
# -----------------------
# Wait for NVMe device
# -----------------------
echo "Waiting for device $DEVICE"
for i in {1..60}; do
[ -e "$DEVICE" ] && break
sleep 1
done
if [ ! -e "$DEVICE" ]; then
echo "ERROR: Device $DEVICE did not appear"
exit 1
fi
touch "$STATE_FILE"
fi
# -----------------------
# Filesystem
# -----------------------
mkdir -p "$MOUNT_POINT"
if ! blkid "$DEVICE" >/dev/null 2>&1; then
case "${FS_TYPE:-xfs}" in
xfs) mkfs.xfs -f "$DEVICE" ;;
ext4) mkfs.ext4 -F "$DEVICE" ;;
*) mkfs.xfs -f "$DEVICE" ;;
esac
fi
# -----------------------
# Mount
# -----------------------
mountpoint -q "$MOUNT_POINT" || mount "$DEVICE" "$MOUNT_POINT"
[ -n "$DEFAULT_USER" ] && chown "$DEFAULT_USER:$DEFAULT_USER" "$MOUNT_POINT"
runcmd:
- [ bash, -lc, '/usr/local/sbin/associate-eip.sh' ]
- [ bash, -lc, '/usr/local/sbin/ebs-attach-and-mount.sh' ]
- [ bash, -lc, 'systemctl daemon-reload' ]
- |
for i in {1..30}; do
mountpoint -q /data && break
sleep 1
done
- |
if systemctl is-active --quiet docker; then
docker rm -f dev-container >/dev/null 2>&1 || true
docker pull mjhong0708/dev-container:latest
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment