{"id":"l-aws-4-3","courseId":"aws-cloud-foundations","lang":"en","kind":"lesson","summary":"Watch Lantern in production with CloudWatch metrics, logs and alarms, then review the whole design against the six Well-Architected pillars with cost optimisation in mind.","html":"<p>Lantern is live: the site on CloudFront, RSVPs on Lambda and DynamoDB, events in RDS. On the old server, “monitoring” meant a volunteer noticing that the site was down. This lesson gives Lantern eyes, with <strong>Amazon CloudWatch</strong>, and then steps back to review the whole design with the <strong>AWS Well-Architected Framework</strong>.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Metrics: what is happening</h2>\n<p>AWS services publish <strong>metrics</strong> to CloudWatch automatically. Each lives in a namespace and has dimensions, such as <code dir=\"ltr\">AWS/Lambda</code> with <code dir=\"ltr\">FunctionName=lantern-rsvp</code>. The handful that matter most for Lantern:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"Scrollable table\" tabindex=\"0\"><table><thead>\n<tr>\n<th>Service</th>\n<th>Metric</th>\n<th>Tells you</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Lambda</td>\n<td><code dir=\"ltr\">Errors</code>, <code dir=\"ltr\">Throttles</code>, <code dir=\"ltr\">Duration</code></td>\n<td>Failures, capacity limits hit, slowness</td>\n</tr>\n<tr>\n<td>API Gateway</td>\n<td><code dir=\"ltr\">5xx</code>, <code dir=\"ltr\">4xx</code>, <code dir=\"ltr\">Latency</code></td>\n<td>What users actually experienced</td>\n</tr>\n<tr>\n<td>DynamoDB</td>\n<td><code dir=\"ltr\">ThrottledRequests</code></td>\n<td>Requests the table refused</td>\n</tr>\n<tr>\n<td>CloudFront</td>\n<td><code dir=\"ltr\">5xxErrorRate</code>, <code dir=\"ltr\">CacheHitRate</code> (an additional metric you turn on)</td>\n<td>Edge health and how well caching works</td>\n</tr>\n</tbody>\n</table></div><h2 id=\"sec-2\" tabindex=\"-1\">Logs: why it happened</h2>\n<p>Anything a Lambda function writes to stdout lands in <strong>CloudWatch Logs</strong>, in the log group <code dir=\"ltr\">/aws/lambda/lantern-rsvp</code>. Switch the function’s log format to JSON in its logging configuration, log objects rather than sentences, and you can query them later with <strong>CloudWatch Logs Insights</strong>:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Text</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>fields @timestamp, level, message, eventId\n| filter level = &quot;ERROR&quot;\n| sort @timestamp desc\n| limit 20</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>Logs that never expire</span></p>\n<p>New log groups keep everything forever, and you pay for every gigabyte ingested and stored. Set a retention period on each log group the day it appears, and never log full request bodies: they inflate the bill and put names and email addresses in places your privacy policy didn’t plan for.</p>\n</aside>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Terminal</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:#953800;--shiki-dark:#FFA657\">aws</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> logs</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> put-retention-policy</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --log-group-name</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> /aws/lambda/lantern-rsvp</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --retention-in-days</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 30</span></span></code></pre></div>\n<h2 id=\"sec-3\" tabindex=\"-1\">Alarms: tell a human</h2>\n<p>A metric nobody looks at is trivia. An <strong>alarm</strong> watches one metric against a threshold and changes state when it is crossed, notifying an <strong>Amazon SNS</strong> topic that emails the maintainers:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Terminal</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:#953800;--shiki-dark:#FFA657\">aws</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> cloudwatch</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> put-metric-alarm</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --alarm-name</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> lantern-rsvp-errors</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --namespace</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> AWS/Lambda</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --metric-name</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> Errors</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --dimensions</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> Name=FunctionName,Value=lantern-rsvp</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --statistic</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> Sum</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --period</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 300</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --evaluation-periods</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --threshold</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 5</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --comparison-operator</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> GreaterThanOrEqualToThreshold</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --treat-missing-data</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> notBreaching</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> \\</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">  --alarm-actions</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> arn:aws:sns:eu-west-1:111122223333:lantern-alerts</span></span></code></pre></div>\n<p>Five errors in five minutes pages someone; an idle night, with no data at all, does not. Lantern starts with three alarms: Lambda errors, API Gateway 5xx responses, and DynamoDB throttles. Fewer, meaningful alarms beat many noisy ones that people learn to ignore.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">The Well-Architected review</h2>\n<p>The <strong>AWS Well-Architected Framework</strong> is AWS’s checklist of design questions, grouped into six <strong>pillars</strong>. The free <strong>AWS Well-Architected Tool</strong> in the console walks you through them. Here is Lantern’s first review, one finding per pillar:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"Scrollable table\" tabindex=\"0\"><table><thead>\n<tr>\n<th>Pillar</th>\n<th>Lantern finding</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Operational excellence</td>\n<td>Deploys are a sequence of manual commands</td>\n<td>Script them; then infrastructure as code</td>\n</tr>\n<tr>\n<td>Security</td>\n<td>One volunteer still uses an IAM user</td>\n<td>Move everyone to IAM Identity Center</td>\n</tr>\n<tr>\n<td>Reliability</td>\n<td>RDS is Multi-AZ; RSVP table has no point-in-time recovery</td>\n<td>Turn PITR on</td>\n</tr>\n<tr>\n<td>Performance efficiency</td>\n<td>RSVP function at 128 MB takes 900 ms</td>\n<td>Test 512 MB; often faster and similar cost</td>\n</tr>\n<tr>\n<td>Cost optimization</td>\n<td>Migration EC2 instance idle since cut-over</td>\n<td>Snapshot and terminate it</td>\n</tr>\n<tr>\n<td>Sustainability</td>\n<td>Function runs on x86</td>\n<td>Switch to <code dir=\"ltr\">arm64</code> (Graviton)</td>\n</tr>\n</tbody>\n</table></div><h2 id=\"sec-5\" tabindex=\"-1\">Cost optimisation as a habit</h2>\n<p>Cost runs through every lesson in this course; here it is as a checklist to run on every account:</p>\n<ol>\n<li><strong>Delete what is idle.</strong> Old instances, unattached EBS volumes, unused Elastic IPs, forgotten NAT gateways.</li>\n<li><strong>Right-size.</strong> Use metrics, not guesses, to choose instance and function sizes.</li>\n<li><strong>Use the right pricing model.</strong> Savings Plans for the steady baseline, Spot for interruptible batch, serverless for spiky work.</li>\n<li><strong>Let data age out.</strong> S3 lifecycle rules and log retention periods.</li>\n<li><strong>Keep traffic local.</strong> Gateway endpoints for S3 and DynamoDB; CloudFront in front of anything public.</li>\n<li><strong>Tag and look.</strong> Tag every resource <code dir=\"ltr\">project=lantern</code>, activate the tag for cost allocation, and open <strong>AWS Cost Explorer</strong> monthly. Your budget alert from lesson three is the safety net, not the plan.</li>\n</ol>\n<aside class=\"callout callout-why\" 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\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><circle cx=\"12\" cy=\"12\" r=\"6\"/><circle cx=\"12\" cy=\"12\" r=\"2\"/></svg><span><span class=\"callout-kind\">Why this matters</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>The review never finishes</span></p>\n<p>Well-Architected isn’t a certificate you earn once. Lantern’s maintainers repeat the review every six months, or after any big change, because the right answer for 500 RSVPs a week is not the right answer for 50,000.</p>\n</aside>\n<p>That is the whole move. Lantern went from one fragile server to a set of managed pieces, each with an owner, a permission boundary, an alarm and a price you can explain. You can now set up an account safely, read and write IAM policies, pick the right core services, and ship and run a real workload, with cost and security designed in rather than bolted on.</p>\n","toc":[{"id":"sec-1","text":"Metrics: what is happening","level":2},{"id":"sec-2","text":"Logs: why it happened","level":2},{"id":"sec-3","text":"Alarms: tell a human","level":2},{"id":"sec-4","text":"The Well-Architected review","level":2},{"id":"sec-5","text":"Cost optimisation as a habit","level":2}],"takeaways":["CloudWatch collects metrics, logs and alarms for AWS services automatically; Lambda writes to the /aws/lambda/<function-name> log group.","An alarm watches one metric against a threshold and notifies an Amazon SNS topic, which emails the people who can act.","New log groups keep data forever by default, so set a retention period on every log group to cap storage costs.","The Well-Architected Framework has six pillars, namely operational excellence, security, reliability, performance efficiency, cost optimization and sustainability.","Cost optimisation is a habit of deleting idle resources, right-sizing, using the right pricing model and tagging so you can see what each thing costs."],"further":[{"title":"What is Amazon CloudWatch?","url":"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html"},{"title":"Using Amazon CloudWatch alarms","url":"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html"},{"title":"Analyzing log data with CloudWatch Logs Insights","url":"https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html"},{"title":"AWS Well-Architected Framework","url":"https://docs.aws.amazon.com/wellarchitected/latest/framework/welcome.html"}],"quiz":[{"q":"<p>Lantern’s maintainers want to hear about RSVP failures before users complain. What should they set up?</p>","options":[{"text":"A CloudWatch dashboard that someone checks every Friday.","why":"Dashboards are good for looking around, but nobody watches them at 9 p.m. on festival night."},{"text":"A log group with a longer retention period.","why":"Keeping logs longer helps investigation afterwards. It does not tell anyone that something is failing now."},{"text":"An AWS Budgets alert on the Lambda service.","why":"A budget tracks spend, not errors. A broken function can fail cheaply for days."},{"text":"A CloudWatch alarm on the function’s <code dir=\"ltr\">Errors</code> metric that notifies an SNS topic with the maintainers’ email.","why":"Correct. An alarm turns a metric into a notification, so a spike in errors reaches a person within minutes."}],"answer":3},{"q":"<p>Six months in, CloudWatch is a surprisingly large line on Lantern’s bill. Which change most likely helps?</p>","options":[{"text":"Set a retention period on log groups and stop logging full request bodies.","why":"Correct. Log groups never expire data by default, and ingestion and storage are charged per gigabyte."},{"text":"Turn off the default Lambda metrics.","why":"The standard Lambda metrics are published automatically and are not what makes the bill grow."},{"text":"Delete the alarms, since each one costs money.","why":"Alarms have a small monthly cost and catch real problems. Removing them saves little and loses visibility."}],"answer":0},{"q":"<p>In a Well-Architected review, the finding “the old migration EC2 instance is still running, three weeks after cut-over” belongs mainly to which pillar?</p>","options":[{"text":"Performance efficiency","why":"Nothing is slow; the instance is simply not needed. Performance efficiency is about using resources effectively for the load."},{"text":"Reliability","why":"An idle server does not affect whether the site recovers from failures."},{"text":"Operational excellence","why":"Better operations would have caught it, but the direct impact is money spent for nothing."},{"text":"Cost optimization","why":"Correct. Paying for idle resources is the textbook cost finding, and the fix is to snapshot what you need and terminate the instance."}],"answer":3},{"q":"<p>Why tag every Lantern resource with <code dir=\"ltr\">project=lantern</code> and activate that tag for cost allocation?</p>","options":[{"text":"Cost Explorer can then break the bill down by project, so you see what Lantern costs separately from anything else in the account.","why":"Correct. Activated cost allocation tags become a dimension in Cost Explorer and in budgets."},{"text":"Tagged resources get a discount.","why":"Tags have no effect on price. They describe resources so you can group, filter and control them."},{"text":"AWS deletes untagged resources after 30 days.","why":"AWS never deletes your resources for missing tags. Untagged resources just become hard to attribute."}],"answer":0}],"exercise":{"kind":"fill","language":"bash","template":"# 1. Keep the RSVP function's logs for 30 days, then let them expire\naws logs {{0}} \\\n  --log-group-name /aws/lambda/lantern-rsvp --retention-in-days 30\n\n# 2. Email the maintainers when the function errors 5+ times in 5 minutes\naws cloudwatch {{1}} --alarm-name lantern-rsvp-errors \\\n  --namespace AWS/Lambda --metric-name {{2}} \\\n  --dimensions Name=FunctionName,Value=lantern-rsvp \\\n  --statistic Sum --period 300 --evaluation-periods 1 \\\n  --threshold 5 --comparison-operator GreaterThanOrEqualToThreshold \\\n  --alarm-actions arn:aws:{{3}}:eu-west-1:111122223333:lantern-alerts","blanks":[{"answers":["put-retention-policy"]},{"answers":["put-metric-alarm"]},{"answers":["Errors"]},{"answers":["sns"]}],"title":"Cap the logs, wire the alarm","prompt":"<p>Finish two commands from Lantern’s launch checklist. Step 1 sets a 30-day retention period on the RSVP function’s log group. Step 2 creates an alarm on the Lambda metric that counts failed invocations, and sends notifications to the <code dir=\"ltr\">lantern-alerts</code> topic in the notification service that emails the maintainers.</p>\n","hints":["Both subcommands start with <code dir=\"ltr\">put-</code>: one sets a retention policy, the other a metric alarm.","The Lambda metric for failed invocations is a plural noun with a capital letter.","Alarm actions point at a topic in Amazon Simple Notification Service; look at the service part of the ARN."],"explanation":"<p><code dir=\"ltr\">aws logs put-retention-policy</code> sets how long CloudWatch Logs keeps the log group’s data; without it, logs never expire and storage keeps growing on the bill. <code dir=\"ltr\">aws cloudwatch put-metric-alarm</code> creates or updates an alarm. The <code dir=\"ltr\">Errors</code> metric in the <code dir=\"ltr\">AWS/Lambda</code> namespace counts invocations that ended in an error, and summing it over a 300-second period gives errors per five minutes. The alarm action is an Amazon SNS topic ARN (<code dir=\"ltr\">arn:aws:sns:...</code>); subscribers to that topic, such as the maintainers’ email addresses, receive the notification when the alarm changes to the ALARM state.</p>\n","checkLabels":{}},"words":673,"readMinutes":3}