Skip to main content

Claude/ChatGPT Prompt to Automate Ubuntu Server Provisioning in Bash

Write an idempotent bash script to provision a hardened, production-ready Ubuntu VPS: users, SSH, firewall, runtimes, Docker, nginx.

Fill in the placeholders

Edit the values, then copy your finished prompt.

Your Prompt
prompt.txt

                                

What this prompt does

This prompt makes the model a senior Linux/DevOps engineer and asks for one complete, idempotent bash script safe to re-run — not a list of commands to paste by hand. You set [ubuntu_version], [admin_user], [runtimes], and [web_role], and it produces a script with set -euo pipefail and a root check, apt updates, a non-root sudo user, SSH hardening, a ufw firewall, unattended-upgrades, your runtimes plus Docker, and an nginx baseline, ending with a summary of what changed.

The structure works because idempotence is the whole point: re-running a hand-built setup is where drift and security holes creep in, so guarding every step means a second run fixes a half-configured box instead of breaking it. [admin_user] becomes the non-root sudo account, [web_role] decides which ufw ports open and the nginx baseline, [runtimes] lists what gets installed, and [ubuntu_version] pins the package and config choices to the right release. The set -euo pipefail header and root check at the top are not ceremony — they make the script fail loudly on the first error rather than ploughing ahead and leaving you with a box that's half-hardened and quietly broken. The closing summary echo gives you a checklist of exactly what changed and what to verify by hand.

When to use it

  • You're provisioning a fresh Ubuntu VPS and want it hardened from the first boot.
  • You want one idempotent script instead of a fragile copy-paste checklist.
  • You need SSH hardening — root login off, key-only auth, fail2ban — done correctly.
  • You want ufw opened to only the ports your web role actually needs.
  • You're installing specific runtimes plus Docker and the compose plugin.
  • You want unattended-upgrades and an nginx baseline configured in one pass.

Example output

Expect the full script in a single fenced bash block with brief inline comments at each section: the safety header and root check, apt update/upgrade, the non-root sudo user, the SSH hardening block, the ufw and unattended-upgrades setup, the runtime and Docker installs, the nginx baseline, and a final summary echo listing what changed and what to verify. Every step is guarded so a re-run is safe.

Pro tips

  • Set [web_role] precisely; it controls which ufw ports open, so a vague value risks closing a port you need or opening one you don't.
  • Match [ubuntu_version] to the actual target release so the package sources and config paths are right.
  • List exact [runtimes] with versions where it matters, so installs are pinned rather than whatever apt offers.
  • Lock SSH to key-only and confirm you can log in on a second session before closing the first — the script can't save you from a lockout.
  • Run it once, then run it again immediately to verify the idempotence guards actually hold.
  • Read the final summary echo and manually verify the items it flags, especially the firewall and SSH state.
  • Keep unattended-upgrades enabled so security patches land without you remembering to apply them, but watch for services that need a controlled restart.
  • Pin Docker and runtime versions in [runtimes] for anything where a surprise major upgrade could break your deploys.

Frequently Asked Questions

Is the script safe to run more than once?
Yes, idempotence is the core requirement. Every step is guarded so a second run repairs a half-configured server rather than breaking it or duplicating users, firewall rules, or installs. Running it twice is also a good way to confirm the guards hold.
Will SSH hardening lock me out?
It can if you're careless, so the script disables root login and password auth as part of hardening. Always keep a second SSH session open and confirm key-only login works before closing your first session, since no script can recover a lockout for you.
Which ports does the firewall open?
Only the ones your `[web_role]` needs. The default nginx reverse proxy role opens 80 and 443, but changing the web role changes the ufw rules, so set it precisely to avoid leaving a needed port closed or an unneeded one open.
Can I install any runtime I want?
Yes. List whatever you need in `[runtimes]`, such as Node.js and PHP, and the script installs them alongside Docker and the compose plugin. Pin versions in the field where they matter so you get specific releases rather than whatever apt defaults to.
Engr Mejba Ahmed

Need this built for real?

Engr Mejba Ahmed

AI Developer · Software Engineer

I'm Mejba — I design and ship production AI systems, automations, and full-stack apps. If you want this turned into a working solution for your team, let's talk.

More in Linux & Shell Scripting Prompts

Engr Mejba Ahmed

Engr Mejba Ahmed

Claude Code Expert · Online

👋

Hey there!

Quick Actions

WhatsApp Instant reply

Chat on WhatsApp

+880 1723 741224 · Instant reply

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

[email protected]

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support