Skip to content
koducathome

Bash User Data Script Generator for EC2

Build EC2 startup scripts for Linux and Windows, with pinned package versions.

How to use this tool

Steps for using the EC2 User Data Generator.

  1. Bash script is selected under Script Format.
  2. Pick the Operating System — the generator uses the right package manager (dnf, yum, apt or zypper) and checks for it at the start of the script.
  3. Turn on Setup Tasks — packages, a user with an SSH key, environment variables, Docker, a web server, the AWS CLI, an extra volume, CloudWatch or your own commands — and adjust them under Configure Options.
  4. Read the Generated User Data Script, edit it if you like, then copy or download it. Warnings flag problems such as a script over EC2's 16 KB limit.
  5. Paste it into Advanced details → User data when launching the instance (or pass it with --user-data in the AWS CLI). It runs once, as root, on the first boot.

Example

The default script for Amazon Linux 2023

Amazon Linux 2023 · Bash
Defaults: refresh package index, install git, jq and unzip, clean cache
User data
#!/bin/bash
# ─────────────────────────────────────────────────────────────
# EC2 user data · Amazon Linux 2023 · Bash script
# Generated by the Koducat EC2 User Data Script Generator.
# Runs once, on the first boot, through cloud-init, as root.
# Logs: /var/log/user-data.log and /var/log/cloud-init-output.log
# ─────────────────────────────────────────────────────────────
set -euo pipefail
exec > >(tee -a /var/log/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1
trap 'echo "[user-data] FAILED at line $LINENO (exit code $?)" >&2' ERR
log() { printf '[user-data] %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*"; }
command -v dnf >/dev/null 2>&1 || { echo "This user data is for Amazon Linux 2023: dnf was not found." >&2; exit 1; }

log "Starting user data"

# ── Refresh the package index ──
log 'Refresh the package index'
dnf -y makecache

# ── Install 3 packages ──
log 'Install 3 packages'
dnf -y install git jq unzip

# ── Clean the package cache ──
log 'Clean the package cache'
dnf clean all

log "User data finished"

Common use cases

  • Bootstrapping web servers, Docker hosts and build agents at launch.
  • Launch templates and Auto Scaling groups that must configure every new instance the same way.
  • Installing agents (CloudWatch, SSM, monitoring) on first boot.
  • Quick experiments where a plain shell script is easier than YAML.

How a Bash user data script runs

On a Linux AMI, cloud-init reads the instance's user data on the first boot. If it starts with #!/bin/bash, cloud-init saves it as a script and runs it once, as root, near the end of the boot. Re-running needs a new instance (or clearing cloud-init's state), so test on a throwaway instance first.

The generated script starts with set -euo pipefail, so it stops at the first failing command instead of carrying on with a half-configured server, and a trap reports the failing line. Everything is written to /var/log/user-data.log and the system console, and also appears in /var/log/cloud-init-output.log.

Each package step is non-interactive for its package manager — dnf -y, yum -y, apt-get -y with DEBIAN_FRONTEND=noninteractive, or zypper --non-interactive — and the script checks that the expected package manager exists, so a script meant for Amazon Linux fails clearly on Ubuntu instead of misbehaving.

Bash is the most flexible format: anything you can type in a shell can go in. For a declarative alternative that cloud-init validates for you, use the Cloud-Init generator; for Windows, use the PowerShell (Windows) generator.

Limitations

  • EC2 accepts at most 16 KB of user data — download larger files from S3 in the script instead.
  • Runs only on the first boot by default; changes later need a new instance or a configuration tool.
  • Linux only — Windows instances need PowerShell user data.

Frequently asked questions

Where can I see whether my user data script worked?

On the instance, read /var/log/user-data.log (written by this script) and /var/log/cloud-init-output.log. Without SSH, use EC2 → Instance → Monitor and troubleshoot → Get system log.

Does user data run as root?

Yes. Bash user data runs as root, so sudo isn't needed inside the script.

Why does my script run only once?

cloud-init runs user data scripts once per instance. Changing user data on a stopped instance doesn't re-run it unless you also configure cloud-init to run on every boot, so launch a new instance to test changes.

Bash or Cloud-Init — which should I use?

Bash for anything procedural or unusual; Cloud-Init when you want declarative packages, users and files that cloud-init validates. Both run through cloud-init on Linux.