In this lecture, we are going to talk about Amazon EC2, and this is where we will create our first website on AWS.
❓ What is EC2?
EC2 — Elastic Compute Cloud — is one of AWS's flagship services. It's Infrastructure as a Service (IaaS): you rent virtual machines on demand, instead of buying and running physical servers.
🚀 EC2 isn't just one thing
<div class="infographic-ec2family">
<style>
.infographic-ec2family {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f6f4ef;
--accent: #d97706;
--accent-soft:#fdecd2;
--line: #ddd6c9;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: var(--ink);
background: var(--paper);
padding: 2rem 1.25rem 2.5rem;
max-width: 640px;
margin: 0 auto;
border-radius: 14px;
box-sizing: border-box;
}
.infographic-ec2family[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #f0a94e;
--accent-soft:#3a2b12;
--line: #2c313d;
}
.infographic-ec2family * { box-sizing: border-box; }
.ef-hub-wrap { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
gap: 0.6rem; max-width: 380px; margin: 0 auto 1.75rem; align-items: center; justify-items: center; }
.ef-hub { grid-column: 2; grid-row: 2; width: 84px; height: 84px; border-radius: 50%;
background: var(--accent-soft); border: 2px solid var(--accent); display: flex; align-items: center;
justify-content: center; font-weight: 800; color: var(--accent); font-size: 0.95rem; }
.ef-node { grid-column: auto; display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
cursor: pointer; padding: 0.4rem; border-radius: 10px; }
.ef-node .box { width: 56px; height: 56px; border-radius: 12px; border: 1.5px solid var(--line);
display: flex; align-items: center; justify-content: center; font-size: 1.6rem; background: var(--paper-alt);
transition: border-color 0.15s, background 0.15s; }
.ef-node.is-active .box { border-color: var(--accent); background: var(--accent-soft); }
.ef-node .lbl { font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); text-align: center; }
.ef-n-instances { grid-column: 2; grid-row: 1; }
.ef-n-ebs { grid-column: 1; grid-row: 2; }
.ef-n-elb { grid-column: 3; grid-row: 2; }
.ef-n-asg { grid-column: 2; grid-row: 3; }
@media (max-width: 420px) {
.ef-hub-wrap { max-width: 300px; gap: 0.3rem; }
.ef-hub { width: 66px; height: 66px; font-size: 0.72rem; }
.ef-node .box { width: 46px; height: 46px; font-size: 1.3rem; }
}
/* --- Stage: the illustrated animation area --- */
.ef-stage { border: 1.5px solid var(--line); border-radius: 12px; background: var(--paper-alt);
height: 130px; display: flex; align-items: center; justify-content: center; position: relative;
overflow: hidden; margin-bottom: 0.5rem; }
.ef-stage .placeholder { font-size: 0.78rem; color: var(--ink-soft); }
.ef-stage .cap { position: absolute; bottom: 6px; left: 0; right: 0; text-align: center; font-size: 0.68rem;
font-weight: 700; color: var(--ink-soft); }
.ef-scene { display: none; align-items: center; justify-content: center; gap: 0.8rem; font-size: 1.9rem; width: 100%; }
.ef-scene.show { display: flex; }
/* Instances scene: pulse */
.ef-scene.instances span { animation: ef-pulse 1.4s ease-in-out infinite; }
.ef-scene.instances span:nth-child(2) { animation-delay: 0.3s; }
@keyframes ef-pulse { 0%, 100% { transform: scale(1); opacity: 0.85; } 50% { transform: scale(1.15); opacity: 1; } }
/* EBS scene: drive slides in and attaches */
.ef-scene.ebs .drive { animation: ef-slide-in 1.6s ease-in-out infinite; }
@keyframes ef-slide-in {
0% { transform: translateX(-26px); opacity: 0.4; }
40%, 70% { transform: translateX(0); opacity: 1; }
100% { transform: translateX(-26px); opacity: 0.4; }
}
/* ELB scene: packets travel in, then split out to two instances */
.ef-scene.elb { position: relative; height: 100%; padding: 0; }
.lb-track { position: relative; width: 100%; height: 100%; }
.lb-hub { position: absolute; left: 42%; top: 50%; transform: translate(-50%, -50%); font-size: 1.7rem; z-index: 2; }
.lb-server { position: absolute; font-size: 1.4rem; transform: translate(-50%, -50%); }
.lb-server-top { left: 86%; top: 24%; }
.lb-server-bottom { left: 86%; top: 76%; }
.lb-packet { position: absolute; font-size: 1.05rem; opacity: 0; }
.lb-packet-in { animation: lb-in-move 1.8s ease-in-out infinite; }
.lb-packet-out1 { animation: lb-out1-move 1.8s ease-in-out infinite; }
.lb-packet-out2 { animation: lb-out2-move 1.8s ease-in-out infinite; }
@keyframes lb-in-move {
0% { left: 2%; top: 50%; opacity: 0; transform: translate(0, -50%); }
8% { opacity: 1; }
42% { left: 40%; top: 50%; opacity: 1; transform: translate(-50%, -50%); }
50% { opacity: 0; left: 40%; top: 50%; transform: translate(-50%, -50%); }
100% { opacity: 0; left: 40%; top: 50%; transform: translate(-50%, -50%); }
}
@keyframes lb-out1-move {
0%, 50% { left: 42%; top: 50%; opacity: 0; transform: translate(-50%, -50%); }
58% { opacity: 1; }
92% { left: 84%; top: 24%; opacity: 1; transform: translate(-50%, -50%); }
100% { opacity: 0; left: 84%; top: 24%; transform: translate(-50%, -50%); }
}
@keyframes lb-out2-move {
0%, 50% { left: 42%; top: 50%; opacity: 0; transform: translate(-50%, -50%); }
58% { opacity: 1; }
92% { left: 84%; top: 76%; opacity: 1; transform: translate(-50%, -50%); }
100% { opacity: 0; left: 84%; top: 76%; transform: translate(-50%, -50%); }
}
.lb-server { animation: lb-server-ping 1.8s ease-in-out infinite; }
.lb-server-top { animation-delay: 0.02s; }
.lb-server-bottom { animation-delay: 0.02s; }
@keyframes lb-server-ping {
0%, 86% { transform: translate(-50%, -50%) scale(1); }
92% { transform: translate(-50%, -50%) scale(1.25); }
100% { transform: translate(-50%, -50%) scale(1); }
}
/* ASG scene: instances popping in/out */
.ef-scene.asg span { transition: opacity 0.3s, transform 0.3s; }
.ef-scene.asg span.hidden { opacity: 0.15; transform: scale(0.7); }
@media (prefers-reduced-motion: reduce) {
.infographic-ec2family * { animation: none !important; transition-duration: 0.001ms !important; }
}
</style>
<div class="ef-hub-wrap">
<div class="ef-hub">EC2</div>
<div class="ef-node ef-n-instances is-active" data-n="instances">
<div class="box">🖥️</div><span class="lbl">Instances</span>
</div>
<div class="ef-node ef-n-ebs" data-n="ebs">
<div class="box">💾</div><span class="lbl">EBS</span>
</div>
<div class="ef-node ef-n-elb" data-n="elb">
<div class="box">⚖️</div><span class="lbl">Load Balancer</span>
</div>
<div class="ef-node ef-n-asg" data-n="asg">
<div class="box">📈</div><span class="lbl">Auto Scaling</span>
</div>
</div>
<div class="ef-stage">
<div class="ef-scene instances show" data-s="instances">
<span>🖥️</span><span>🖥️</span>
</div>
<div class="ef-scene ebs" data-s="ebs">
<span class="drive">💾</span><span>🖥️</span>
</div>
<div class="ef-scene elb" data-s="elb">
<div class="lb-track">
<span class="lb-server lb-server-top">🖥️</span>
<span class="lb-server lb-server-bottom">🖥️</span>
<span class="lb-hub">⚖️</span>
<span class="lb-packet lb-packet-in">📨</span>
<span class="lb-packet lb-packet-out1">📨</span>
<span class="lb-packet lb-packet-out2">📨</span>
</div>
</div>
<div class="ef-scene asg" data-s="asg">
<span>🖥️</span><span>🖥️</span><span>🖥️</span>
</div>
<span class="cap" id="ef-cap">the virtual machines</span>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-ec2family')
|| document.querySelector('.infographic-ec2family');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const caps = {
instances: 'the virtual machines',
ebs: 'attaches storage to an instance',
elb: 'splits traffic across instances',
asg: 'adds or removes instances automatically'
};
const cap = wrapper.querySelector('#ef-cap');
// ASG instances pop in/out
let asgTimer = null;
function startAsg() {
const spans = Array.from(wrapper.querySelectorAll('.ef-scene.asg span'));
let i = 0;
asgTimer = setInterval(() => {
spans.forEach((s, idx) => s.classList.toggle('hidden', idx > (i % 3)));
i++;
}, 700);
}
function stopAsg() { if (asgTimer) { clearInterval(asgTimer); asgTimer = null; } }
wrapper.querySelectorAll('.ef-node').forEach(node => {
node.addEventListener('click', () => {
const key = node.dataset.n;
wrapper.querySelectorAll('.ef-node').forEach(n => n.classList.remove('is-active'));
node.classList.add('is-active');
wrapper.querySelectorAll('.ef-scene').forEach(s => s.classList.remove('show'));
wrapper.querySelector('.ef-scene[data-s="' + key + '"]').classList.add('show');
cap.textContent = caps[key];
stopAsg();
if (key === 'asg') startAsg();
});
});
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});It's a family of related pieces:
🖥️ Instances — the virtual machines themselves
💾 EBS Volumes — attached storage
⚖️ Elastic Load Balancer — spreads traffic across instances
📈 Auto Scaling Group — adds or removes instances automatically
We'll dig into each of these later — for now, just know they exist.
🧐 Why EC2 Matters
EC2 is the clearest example of what "cloud computing" actually means: rent compute power, use it when you need it, scale it up or down as demand changes.
🤖 What you configure when launching an instance
<div class="infographic-ec2config">
<style>
.infographic-ec2config {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f6f4ef;
--accent: #d97706;
--accent-soft:#fdecd2;
--line: #ddd6c9;
--ok: #1e8e5a;
--ok-soft: #e2f6ec;
--bad: #c0392b;
--bad-soft: #fbe9e7;
--mono-font: 'SF Mono', Menlo, Consolas, monospace;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: var(--ink);
background: var(--paper);
padding: 2rem 1.25rem 2.5rem;
max-width: 800px;
margin: 0 auto;
border-radius: 14px;
box-sizing: border-box;
}
.infographic-ec2config[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #f0a94e;
--accent-soft:#3a2b12;
--line: #2c313d;
--ok: #4fbf87;
--ok-soft: #143024;
--bad: #e57373;
--bad-soft: #3a2222;
}
.infographic-ec2config * { box-sizing: border-box; }
.ec-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; margin-bottom: 1.5rem; }
@media (max-width: 560px) { .ec-grid { grid-template-columns: 1fr; } }
.ec-card { border: 1.5px solid var(--line); border-radius: 12px; padding: 0.9rem 1rem; background: var(--paper-alt); }
.ec-card-icon { font-size: 1.2rem; margin-bottom: 0.5rem; }
/* OS picker */
.ec-os { display: flex; gap: 0.5rem; justify-content: center; }
.ec-os button { flex: 1; font-size: 1.5rem; padding: 0.5rem 0; border-radius: 8px; border: 1.5px solid var(--line);
background: var(--paper); cursor: pointer; transition: border-color 0.15s, background 0.15s; }
.ec-os button.is-active { border-color: var(--accent); background: var(--accent-soft); }
/* Stepper */
.ec-stepper { display: flex; align-items: center; justify-content: center; gap: 0.7rem; }
.ec-stepper button { width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid var(--line);
background: var(--paper); font-size: 1rem; font-weight: 700; cursor: pointer; color: var(--ink); }
.ec-stepper button:hover { border-color: var(--accent); }
.ec-cores { display: flex; gap: 3px; flex-wrap: wrap; justify-content: center; max-width: 130px; }
.ec-cores span { width: 12px; height: 12px; border-radius: 3px; background: var(--line); }
.ec-cores span.on { background: var(--accent); }
/* RAM slider */
.ec-ram-val { text-align: center; font-family: var(--mono-font); font-weight: 700; color: var(--accent);
font-size: 0.95rem; margin-bottom: 0.3rem; }
.ec-ram-bar { height: 10px; border-radius: 999px; background: var(--line); overflow: hidden; margin-bottom: 0.4rem; }
.ec-ram-fill { height: 100%; background: var(--accent); width: 25%; transition: width 0.15s; }
.ec-ram input[type="range"] { width: 100%; accent-color: var(--accent); }
/* Storage toggle */
.ec-storage { display: flex; gap: 0.5rem; }
.ec-storage button { flex: 1; text-align: center; padding: 0.6rem 0.3rem; border-radius: 8px;
border: 1.5px solid var(--line); background: var(--paper); cursor: pointer; font-size: 1.4rem; }
.ec-storage button.is-active { border-color: var(--accent); background: var(--accent-soft); }
.ec-storage .lbl { display: block; font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); margin-top: 0.2rem; }
/* Networking */
.ec-net { display: flex; align-items: center; justify-content: center; gap: 1rem; }
.ec-net-item { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.ec-globe { font-size: 1.7rem; opacity: 0.3; transition: opacity 0.2s; }
.ec-globe.on { opacity: 1; }
.ec-switch { position: relative; width: 40px; height: 22px; }
.ec-switch input { opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; position: absolute; z-index: 2; }
.ec-switch .track { position: absolute; inset: 0; background: var(--line); border-radius: 999px; transition: background 0.15s; }
.ec-switch .thumb { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
background: var(--paper); box-shadow: 0 1px 2px rgba(0,0,0,0.25); transition: transform 0.15s; }
.ec-switch input:checked ~ .track { background: var(--accent); }
.ec-switch input:checked ~ .thumb { transform: translateX(18px); }
.ec-net .lbl { font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); }
/* Security */
.ec-sec { display: flex; align-items: center; justify-content: center; gap: 0.8rem; }
.ec-shield { font-size: 1.7rem; }
.ec-ports { display: flex; gap: 0.4rem; }
.ec-port { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; cursor: pointer; }
.ec-port .dot { width: 30px; height: 30px; border-radius: 8px; border: 1.5px solid var(--line);
display: flex; align-items: center; justify-content: center; font-size: 0.85rem; background: var(--paper);
color: var(--ink-soft); font-family: var(--mono-font); transition: all 0.15s; }
.ec-port.open .dot { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); }
.ec-port .lbl { font-size: 0.58rem; color: var(--ink-soft); }
.ec-card-title { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
color: var(--ink-soft); text-align: center; margin-bottom: 0.6rem; }
@media (prefers-reduced-motion: reduce) {
.infographic-ec2config * { transition-duration: 0.001ms !important; }
}
</style>
<div class="ec-grid">
<div class="ec-card">
<p class="ec-card-title">🖥️ Operating System</p>
<div class="ec-os">
<button class="is-active" data-os="linux">🐧</button>
<button data-os="windows">🪟</button>
<button data-os="mac">🍎</button>
</div>
</div>
<div class="ec-card">
<p class="ec-card-title">🧠 Compute — cores</p>
<div class="ec-stepper">
<button id="ec-cpu-minus">−</button>
<div class="ec-cores" id="ec-cores"></div>
<button id="ec-cpu-plus">+</button>
</div>
</div>
<div class="ec-card ec-ram">
<p class="ec-card-title">🧬 Memory</p>
<div class="ec-ram-val" id="ec-ram-val">4 GB</div>
<div class="ec-ram-bar"><div class="ec-ram-fill" id="ec-ram-fill"></div></div>
<input type="range" id="ec-ram-slider" min="1" max="64" value="4">
</div>
<div class="ec-card">
<p class="ec-card-title">💾 Storage</p>
<div class="ec-storage">
<button class="is-active" data-st="network">☁️<span class="lbl">EBS / EFS</span></button>
<button data-st="instance">🗄️<span class="lbl">Instance Store</span></button>
</div>
</div>
<div class="ec-card">
<p class="ec-card-title">🌐 Networking</p>
<div class="ec-net">
<div class="ec-net-item">
<span class="ec-globe on" id="ec-globe">🌍</span>
<label class="ec-switch"><input type="checkbox" id="ec-ip-toggle" checked><span class="track"></span><span class="thumb"></span></label>
<span class="lbl">Public IP</span>
</div>
</div>
</div>
<div class="ec-card">
<p class="ec-card-title">🔥 Security Group</p>
<div class="ec-sec">
<span class="ec-shield">🛡️</span>
<div class="ec-ports">
<div class="ec-port open" data-port="22"><div class="dot">22</div><span class="lbl">SSH</span></div>
<div class="ec-port open" data-port="80"><div class="dot">80</div><span class="lbl">HTTP</span></div>
<div class="ec-port" data-port="443"><div class="dot">443</div><span class="lbl">HTTPS</span></div>
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-ec2config')
|| document.querySelector('.infographic-ec2config');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
// OS picker
wrapper.querySelectorAll('.ec-os button').forEach(btn => {
btn.addEventListener('click', () => {
wrapper.querySelectorAll('.ec-os button').forEach(b => b.classList.remove('is-active'));
btn.classList.add('is-active');
});
});
// CPU stepper
const coresEl = wrapper.querySelector('#ec-cores');
let cpu = 2;
const MAX_CORES = 8;
function renderCores() {
coresEl.innerHTML = '';
for (let i = 0; i < MAX_CORES; i++) {
const s = document.createElement('span');
if (i < cpu) s.classList.add('on');
coresEl.appendChild(s);
}
}
renderCores();
wrapper.querySelector('#ec-cpu-minus').addEventListener('click', () => {
cpu = Math.max(1, cpu - 1);
renderCores();
});
wrapper.querySelector('#ec-cpu-plus').addEventListener('click', () => {
cpu = Math.min(MAX_CORES, cpu + 1);
renderCores();
});
// RAM slider
const ramSlider = wrapper.querySelector('#ec-ram-slider');
const ramVal = wrapper.querySelector('#ec-ram-val');
const ramFill = wrapper.querySelector('#ec-ram-fill');
function renderRam() {
const v = Number(ramSlider.value);
ramVal.textContent = v + ' GB';
ramFill.style.width = (v / 64 * 100) + '%';
}
ramSlider.addEventListener('input', renderRam);
renderRam();
// Storage toggle
wrapper.querySelectorAll('.ec-storage button').forEach(btn => {
btn.addEventListener('click', () => {
wrapper.querySelectorAll('.ec-storage button').forEach(b => b.classList.remove('is-active'));
btn.classList.add('is-active');
});
});
// Networking
const ipToggle = wrapper.querySelector('#ec-ip-toggle');
const globe = wrapper.querySelector('#ec-globe');
ipToggle.addEventListener('input', () => globe.classList.toggle('on', ipToggle.checked));
// Security ports
wrapper.querySelectorAll('.ec-port').forEach(port => {
port.addEventListener('click', () => port.classList.toggle('open'));
});
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Operating system — Linux (most common), Windows, or macOS
Compute power — number of CPU cores
Memory — how much RAM
Storage — network-based (EBS/EFS) or hardware-attached (Instance Store)
Networking — speed, public IP, network setup
Security — Security Groups, which act as your instance's firewall
🧮 User Data — the bootstrap script
<div class="infographic-userdata">
<style>
.infographic-userdata {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f6f4ef;
--accent: #d97706;
--accent-soft:#fdecd2;
--line: #ddd6c9;
--root: #7c3aed;
--root-soft: #efe7fd;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
color: var(--ink);
background: var(--paper);
padding: 2rem 1.25rem 2.5rem;
max-width: 720px;
margin: 0 auto;
border-radius: 14px;
box-sizing: border-box;
}
.infographic-userdata[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #f0a94e;
--accent-soft:#3a2b12;
--line: #2c313d;
--root: #b18cf5;
--root-soft: #2a2140;
}
.infographic-userdata * { box-sizing: border-box; }
.ud-run { display: flex; justify-content: center; margin-bottom: 2rem; }
.ud-run button { font: inherit; font-size: 0.85rem; font-weight: 700; padding: 0.55rem 1.2rem;
border-radius: 999px; border: none; background: var(--ink); color: var(--paper); cursor: pointer; }
.ud-run button:hover { opacity: 0.85; }
.ud-instance { display: flex; flex-direction: column; align-items: center; margin-bottom: 1.4rem; }
.ud-instance .icon { font-size: 2.6rem; transition: transform 0.3s; }
.ud-instance.is-on .icon { transform: scale(1.1); }
.ud-bolt { font-size: 1.2rem; opacity: 0; transition: opacity 0.25s; color: var(--accent); }
.ud-bolt.show { opacity: 1; }
.ud-once { display: flex; justify-content: center; align-items: center; gap: 0.4rem; margin: 0.4rem 0 1.6rem;
opacity: 0; transition: opacity 0.3s; }
.ud-once.show { opacity: 1; }
.ud-once .script { font-size: 1.8rem; }
.ud-once .badge { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em; color: var(--accent);
border: 1.5px solid var(--accent); border-radius: 999px; padding: 0.15rem 0.5rem; text-transform: uppercase; }
.ud-tasks { display: flex; justify-content: center; gap: 1.1rem; flex-wrap: wrap; margin-bottom: 1.75rem; }
.ud-task { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; opacity: 0.15;
transform: translateY(6px); transition: opacity 0.35s, transform 0.35s; }
.ud-task.show { opacity: 1; transform: translateY(0); }
.ud-task .box { width: 54px; height: 54px; border-radius: 12px; border: 1.5px solid var(--line);
display: flex; align-items: center; justify-content: center; font-size: 1.5rem; background: var(--paper-alt); }
.ud-task.show .box { border-color: var(--accent); background: var(--accent-soft); }
.ud-task .lbl { font-size: 0.62rem; font-weight: 700; color: var(--ink-soft); }
.ud-root { display: flex; justify-content: center; }
.ud-root-badge { display: flex; align-items: center; gap: 0.5rem; padding: 0.55rem 1rem; border-radius: 999px;
border: 1.5px solid var(--line); background: var(--paper-alt); opacity: 0.2; transform: scale(0.9);
transition: opacity 0.35s, transform 0.35s, border-color 0.35s, background 0.35s; }
.ud-root-badge.show { opacity: 1; transform: scale(1); border-color: var(--root); background: var(--root-soft); }
.ud-root-badge .icon { font-size: 1.3rem; }
.ud-root-badge .lbl { font-size: 0.72rem; font-weight: 800; color: var(--root); }
@media (prefers-reduced-motion: reduce) {
.infographic-userdata * { transition-duration: 0.001ms !important; }
}
</style>
<div class="ud-run"><button id="ud-run-btn">▶ Launch instance</button></div>
<div class="ud-instance" id="ud-instance">
<span class="icon">🖥️</span>
<span class="ud-bolt" id="ud-bolt">⚡</span>
</div>
<div class="ud-once" id="ud-once">
<span class="script">📜</span>
<span class="badge">runs once</span>
</div>
<div class="ud-tasks">
<div class="ud-task" data-t="1"><div class="box">🔄</div><span class="lbl">updates</span></div>
<div class="ud-task" data-t="2"><div class="box">📦</div><span class="lbl">software</span></div>
<div class="ud-task" data-t="3"><div class="box">⬇️</div><span class="lbl">files</span></div>
<div class="ud-task" data-t="4"><div class="box">⚙️</div><span class="lbl">config</span></div>
</div>
<div class="ud-root">
<div class="ud-root-badge" id="ud-root-badge">
<span class="icon">🔓</span>
<span class="lbl">root · sudo</span>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-userdata')
|| document.querySelector('.infographic-userdata');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const instance = wrapper.querySelector('#ud-instance');
const bolt = wrapper.querySelector('#ud-bolt');
const once = wrapper.querySelector('#ud-once');
const tasks = Array.from(wrapper.querySelectorAll('.ud-task'));
const rootBadge = wrapper.querySelector('#ud-root-badge');
const btn = wrapper.querySelector('#ud-run-btn');
let running = false;
function reset() {
instance.classList.remove('is-on');
bolt.classList.remove('show');
once.classList.remove('show');
tasks.forEach(t => t.classList.remove('show'));
rootBadge.classList.remove('show');
}
btn.addEventListener('click', () => {
if (running) return;
running = true;
reset();
const steps = [
() => { instance.classList.add('is-on'); bolt.classList.add('show'); },
() => once.classList.add('show'),
() => tasks[0].classList.add('show'),
() => tasks[1].classList.add('show'),
() => tasks[2].classList.add('show'),
() => tasks[3].classList.add('show'),
() => { rootBadge.classList.add('show'); running = false; }
];
steps.forEach((fn, i) => setTimeout(fn, i * 420));
});
})();
</script>
</div>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});This is a script that runs once, automatically, the moment the instance launches — a way to set things up without doing it by hand.
Bootstrapping just means: running commands automatically at startup.
What people typically use it for:
Installing updates
Installing software
Downloading files
Configuring the application
More steps in the script means more time before the instance is ready.
⚠️ One important detail: User Data scripts run as root — full sudo access, no restrictions.
The short version
EC2 lets you rent virtual machines on demand. You control the OS, CPU, RAM, storage, and networking. It bundles in storage, scaling, and load balancing. User Data lets you automate first-boot setup. And understanding EC2 is basically understanding the core idea of the cloud.