{"id":"l-aws-1-3","courseId":"aws-cloud-foundations","lang":"en","kind":"lesson","summary":"Say which security tasks belong to AWS and which to you for EC2, RDS and Lambda, then lock down a new account with root MFA, an everyday admin and a budget alert.","html":"<p>Lantern’s old host had a short answer to “who keeps this secure?”: the maintainers did everything above the power socket. AWS splits the job. Knowing exactly where the split falls tells you what you can stop worrying about, and what you can never hand off.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Security of the cloud, security in the cloud</h2>\n<p>AWS calls this the <strong>shared responsibility model</strong>. AWS is responsible for security <strong>of</strong> the cloud: data centres, guards, hardware, the global network, the virtualisation layer, and the software that runs each managed service. You are responsible for security <strong>in</strong> the cloud: your data, who can access it, how you configure each service, and the code you deploy.</p>\n<p>The line is not fixed. It moves with how managed the service is.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 660 290\" role=\"img\" aria-labelledby=\"l-aws-1-3-t1\"><defs><marker id=\"arrow-l-aws-1-3-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-aws-1-3-t1\">Three columns. For EC2 you own data, access, app code, runtime and guest OS. For RDS you own data, access and schema while AWS runs the engine and OS. For Lambda you own data, access and code including dependencies while AWS runs the runtime and OS. AWS owns hardware and facilities in all three.</title>\n  <text class=\"d-label-strong\" x=\"130\" y=\"26\" text-anchor=\"middle\">Amazon EC2</text>\n  <text class=\"d-label-strong\" x=\"330\" y=\"26\" text-anchor=\"middle\">Amazon RDS</text>\n  <text class=\"d-label-strong\" x=\"530\" y=\"26\" text-anchor=\"middle\">AWS Lambda</text>\n  <rect class=\"d-box-primary\" x=\"50\" y=\"40\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"130\" y=\"62\" text-anchor=\"middle\">Data + access</text>\n  <rect class=\"d-box-primary\" x=\"50\" y=\"80\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"130\" y=\"102\" text-anchor=\"middle\">App code</text>\n  <rect class=\"d-box-primary\" x=\"50\" y=\"120\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"130\" y=\"142\" text-anchor=\"middle\">Runtime</text>\n  <rect class=\"d-box-primary\" x=\"50\" y=\"160\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"130\" y=\"182\" text-anchor=\"middle\">Guest OS</text>\n  <rect class=\"d-box-success\" x=\"50\" y=\"200\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"130\" y=\"222\" text-anchor=\"middle\">Hardware + sites</text>\n  <rect class=\"d-box-primary\" x=\"250\" y=\"40\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"330\" y=\"62\" text-anchor=\"middle\">Data + access</text>\n  <rect class=\"d-box-primary\" x=\"250\" y=\"80\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"330\" y=\"102\" text-anchor=\"middle\">Schema + queries</text>\n  <rect class=\"d-box-success\" x=\"250\" y=\"120\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"330\" y=\"142\" text-anchor=\"middle\">DB engine</text>\n  <rect class=\"d-box-success\" x=\"250\" y=\"160\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"330\" y=\"182\" text-anchor=\"middle\">OS</text>\n  <rect class=\"d-box-success\" x=\"250\" y=\"200\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"330\" y=\"222\" text-anchor=\"middle\">Hardware + sites</text>\n  <rect class=\"d-box-primary\" x=\"450\" y=\"40\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"530\" y=\"62\" text-anchor=\"middle\">Data + access</text>\n  <rect class=\"d-box-primary\" x=\"450\" y=\"80\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"530\" y=\"102\" text-anchor=\"middle\">Code + deps</text>\n  <rect class=\"d-box-success\" x=\"450\" y=\"120\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"530\" y=\"142\" text-anchor=\"middle\">Runtime</text>\n  <rect class=\"d-box-success\" x=\"450\" y=\"160\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"530\" y=\"182\" text-anchor=\"middle\">OS</text>\n  <rect class=\"d-box-success\" x=\"450\" y=\"200\" width=\"160\" height=\"34\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"530\" y=\"222\" text-anchor=\"middle\">Hardware + sites</text>\n  <rect class=\"d-box-primary\" x=\"150\" y=\"256\" width=\"24\" height=\"18\" rx=\"4\"/>\n  <text class=\"d-label\" x=\"182\" y=\"270\">You</text>\n  <rect class=\"d-box-success\" x=\"260\" y=\"256\" width=\"24\" height=\"18\" rx=\"4\"/>\n  <text class=\"d-label\" x=\"292\" y=\"270\">AWS</text>\n</svg><figcaption>Where the line falls for EC2, RDS and Lambda</figcaption></figure>\n<p>On EC2 you patch the operating system, exactly as on Lantern’s old server. On RDS, AWS patches the database engine and OS during a maintenance window you choose, but your schema, users and network access are yours. On Lambda, AWS keeps the runtime and OS patched, and you own the code and every package you bundle with it. The top row never moves: <strong>your data and who can reach it are always your job.</strong></p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Lock down the account before you build</h2>\n<p>A new account is the most dangerous moment, because the only identity is the all-powerful root user. Here is the setup Lantern uses, in order.</p>\n<h3 id=\"sec-3\" tabindex=\"-1\">1. Choose the right account plan</h3>\n<p>At sign-up, AWS (as of 2026) offers a <strong>Free plan</strong> and a <strong>Paid plan</strong>. Both start with promotional credits, and both include monthly free usage for over thirty services. The Free plan guarantees no charges, but limits you to selected services and closes the account after six months or when the credits run out, unless you upgrade. The Paid plan unlocks everything and bills you for usage beyond the credits. Use the Free plan to learn; Lantern’s production account is on the Paid plan, which is exactly why the budget in step 4 matters.</p>\n<h3 id=\"sec-4\" tabindex=\"-1\">2. Protect the root user</h3>\n<p>The root user is the email address you signed up with. It can change billing details and close the account, and IAM policies cannot restrict it. AWS requires MFA on root users; register a <strong>passkey or security key</strong> if you can, because they resist phishing in a way that six-digit codes do not. Never create access keys for root. After setup, you sign in as root only for the handful of root-only tasks, such as turning on <strong>IAM user and role access to billing information</strong> in the account settings, so that your admin identity can see costs.</p>\n<h3 id=\"sec-5\" tabindex=\"-1\">3. Create an everyday admin</h3>\n<p>Daily work happens as a separate identity. For a single standalone account like Lantern’s first one, that is an IAM user with console access, a strong password, its own MFA, and membership of an <code dir=\"ltr\">Admins</code> group that has the <code dir=\"ltr\">AdministratorAccess</code> managed policy. Section two explains every one of those words, and how teams with several accounts use IAM Identity Center instead.</p>\n<h3 id=\"sec-6\" tabindex=\"-1\">4. Set a budget before anything else</h3>\n<p>In <strong>AWS Budgets</strong>, create a monthly cost budget at an amount that would worry you, say 20 USD, with email alerts at 80% of actual spend and at 100% of forecasted spend. The forecast alert matters: it fires early in the month when the trend says you will overshoot. Under the hood a budget is a small JSON document:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">budget.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"BudgetName\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"lantern-monthly\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"BudgetLimit\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"Amount\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"20\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"Unit\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"USD\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"TimeUnit\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"MONTHLY\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"BudgetType\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"COST\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Thinking a budget is a spending cap</span></p>\n<p>A budget sends an alert; it does not switch anything off. If nobody reads the email, the forgotten instance keeps running. Send alerts to an address someone actually watches, and when one fires, find and delete the cause the same day.</p>\n</aside>\n<h3 id=\"sec-7\" tabindex=\"-1\">5. Fill in the alternate contacts</h3>\n<p>Under account settings, add a <strong>security</strong> contact and a <strong>billing</strong> contact. When AWS detects something suspicious, such as leaked credentials, it emails them. On a one-person project those emails easily land in a forgotten inbox.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Ten minutes that pay for themselves</span></p>\n<p>Root MFA, an admin user, a budget and alternate contacts take about ten minutes. Most horror stories you read about surprise bills and hijacked accounts skipped at least two of them.</p>\n</aside>\n<p>The account is safe to use. Next you will drive it from the terminal with the AWS CLI v2 and prove which identity you are using.</p>\n","toc":[{"id":"sec-1","text":"Security of the cloud, security in the cloud","level":2},{"id":"sec-2","text":"Lock down the account before you build","level":2},{"id":"sec-3","text":"1. Choose the right account plan","level":3},{"id":"sec-4","text":"2. Protect the root user","level":3},{"id":"sec-5","text":"3. Create an everyday admin","level":3},{"id":"sec-6","text":"4. Set a budget before anything else","level":3},{"id":"sec-7","text":"5. Fill in the alternate contacts","level":3}],"takeaways":["AWS is responsible for security of the cloud (buildings, hardware, network, service software); you are responsible for security in the cloud (data, access, configuration, code).","The more managed the service, the more of the stack AWS patches, but your data, permissions and code are always yours.","The root user can do anything, including closing the account, so give it a passkey or security key, never create access keys for it, and use it only for root-only tasks.","Do daily work as a separate admin identity with its own MFA, not as root.","An AWS Budgets alert warns you before a bill surprises you, but it does not stop spending on its own."],"further":[{"title":"Shared Responsibility Model","url":"https://aws.amazon.com/compliance/shared-responsibility-model/"},{"title":"Root user best practices for your AWS account","url":"https://docs.aws.amazon.com/IAM/latest/UserGuide/root-user-best-practices.html"},{"title":"Choosing a Free Tier account plan","url":"https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/free-tier-plans.html"},{"title":"Managing your costs with AWS Budgets","url":"https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-managing-costs.html"}],"quiz":[{"q":"<p>Lantern’s API runs on AWS Lambda. A security advisory lands for an npm package bundled in the function. Who patches it?</p>","options":[{"text":"AWS, because Lambda is a managed service and applies runtime updates.","why":"AWS patches the managed runtime (Node.js itself and the OS underneath). Dependencies you bundle are part of your code."},{"text":"Lantern, because packages bundled with the function code are part of the customer’s code.","why":"Correct. Under the shared responsibility model your code and its dependencies are always yours, on every service."},{"text":"Nobody needs to, because Lambda functions run in isolated environments.","why":"Isolation limits the blast radius between customers. It does not stop a vulnerable library from being exploited through your own API."}],"answer":1},{"q":"<p>Which task should you do while signed in as the root user?</p>","options":[{"text":"Creating the Lantern S3 bucket, since the root user owns the account.","why":"Any admin identity can create buckets. Using root for daily work exposes the most powerful credential for no gain."},{"text":"Creating root access keys so scripts can manage the account.","why":"Root access keys are the worst credential to leak because nothing can restrict them. AWS recommends never creating them."},{"text":"Turning on IAM user and role access to billing information so your admin user can see costs.","why":"Correct. That account setting is one of the few tasks only the root user can perform."},{"text":"Deploying Lambda functions, because root avoids permission errors.","why":"Avoiding permission errors by using unlimited access hides design problems and makes every mistake bigger."}],"answer":2},{"q":"<p>Lantern has a monthly AWS Budgets cost budget of 20 USD with an email alert at 100%. A forgotten instance pushes spend to 35 USD. What happens?</p>","options":[{"text":"AWS stops the instance when spend reaches 20 USD.","why":"A plain budget only notifies. Stopping resources needs a budget action or automation that you configure separately."},{"text":"The account is suspended until you raise the budget.","why":"Budgets never suspend an account. They are a monitoring tool, not a spending cap."},{"text":"You get an email when spend crosses 20 USD, and the instance keeps running and costing money until someone acts.","why":"Correct. The alert buys you reaction time. Someone still has to read it and delete the resource."}],"answer":2}],"exercise":{"kind":"choice","multiple":true,"options":["ec2-os","disk-swap","sg-port","lambda-runtime","bucket-policy","rds-engine-hw"],"correct":["ec2-os","sg-port","bucket-policy"],"title":"Whose job is it?","prompt":"<p>During the migration Lantern runs a worker on Amazon EC2, the events database on Amazon RDS, the RSVP API on AWS Lambda, and posters in Amazon S3. Select every task that is <strong>Lantern’s</strong> responsibility under the shared responsibility model.</p>\n","hints":["Picture the stacks from the lesson’s figure. Which layers are purple (yours) for each service?","Physical hardware is never yours. Who can reach your data always is.","Three tasks belong to Lantern: one is an operating system, two are about access."],"explanation":"<p>On EC2 you own the guest operating system, so applying security updates to it is Lantern’s job. Network access rules, such as which addresses can reach the database port, are configuration and therefore yours on every service. Who may read the posters bucket is also configuration, so the bucket policy is yours. AWS replaces failed physical disks, keeps Lambda’s managed runtime patched, and runs the hardware under RDS.</p>\n","checkLabels":{},"optionText":{"ec2-os":{"text":"Installing security updates on the EC2 instance’s Linux operating system.","why":"Yours. On EC2 the guest OS sits above the line; AWS only runs the hardware and the hypervisor underneath it."},"disk-swap":{"text":"Replacing a failed physical drive in the data centre that hosts the RDS database.","why":"AWS’s. Physical hardware and facilities are always security of the cloud. You will never touch a data-centre drive."},"sg-port":{"text":"Making sure the database port only accepts connections from Lantern’s app, not the whole internet.","why":"Yours. Network access is configuration you control through security groups, covered in section three."},"lambda-runtime":{"text":"Patching the Node.js runtime that the Lambda function runs on.","why":"AWS’s, for managed runtimes with the default automatic updates. Your bundled npm packages, however, stay yours."},"bucket-policy":{"text":"Deciding who is allowed to read objects in the posters bucket.","why":"Yours. AWS gives safe defaults such as Block Public Access, but every access decision on your data is your responsibility."},"rds-engine-hw":{"text":"Keeping the servers under the RDS database powered and cooled.","why":"AWS’s. Power, cooling and physical security are the clearest example of security of the cloud."}}},"words":729,"readMinutes":3}