<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jas</title>
    <description>The latest articles on DEV Community by Jas (@jas_dev).</description>
    <link>https://dev.to/jas_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3961807%2Fa710d35f-67c4-4fa6-9c39-9b1a7c22f66b.jpg</url>
      <title>DEV Community: Jas</title>
      <link>https://dev.to/jas_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jas_dev"/>
    <language>en</language>
    <item>
      <title>Day 0 of a Linux Challenge and the Prompt I Almost Got Wrong</title>
      <dc:creator>Jas</dc:creator>
      <pubDate>Sat, 12 Sep 2026 18:45:07 +0000</pubDate>
      <link>https://dev.to/jas_dev/day-0-of-a-linux-challenge-and-the-prompt-i-almost-got-wrong-2m36</link>
      <guid>https://dev.to/jas_dev/day-0-of-a-linux-challenge-and-the-prompt-i-almost-got-wrong-2m36</guid>
      <description>&lt;p&gt;I signed up for the Black IT Academy Linux Upskill Challenge. Twenty lessons, one server, a cohort in Slack, and a rule that you keep a public journal of what you did every day. Day 0 was today. The only goal was to have a server I could log into and to post a screenshot proving it.&lt;/p&gt;

&lt;p&gt;That took about ten minutes. Then a purple box showed up in my terminal and I sat there for a while.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I went with a DigitalOcean droplet. Ubuntu 24.04, the cheapest Basic plan, [password / SSH key] for auth. The challenge guide says do not spend Day 0 comparing hosting providers, and after my AWS bill situation I did not need convincing. First thing I did after the droplet came up was set a $10 billing alert. That is a habit now.&lt;/p&gt;

&lt;p&gt;Connected with &lt;code&gt;ssh root@&lt;/code&gt; and the IP. Said yes to the fingerprint prompt. Ran &lt;code&gt;whoami&lt;/code&gt; and &lt;code&gt;uptime&lt;/code&gt; and felt good about myself. Then I ran the standard &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y&lt;/code&gt; because that is what you do on a fresh box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Halfway through the upgrade everything stopped and I got this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A new version of configuration file /etc/ssh/sshd_config is available, but the version installed currently has been locally modified.&lt;/p&gt;

&lt;p&gt;What do you want to do about modified configuration file sshd_config?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With a menu. Install the package maintainer's version. Keep the local version currently installed. Show the differences. A three way merge option.&lt;/p&gt;

&lt;p&gt;My first reaction was confusion. Locally modified by who? I had owned this server for four minutes. I had not opened a single config file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What was actually going on&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sshd_config&lt;/code&gt; is the file that controls how the SSH server behaves. Which port it listens on, whether root can log in, whether passwords are allowed or only keys. It is the file that decides if you can get back into your own server.&lt;/p&gt;

&lt;p&gt;The reason it was "locally modified" is that DigitalOcean modified it. When a droplet gets built, their provisioning process writes SSH settings into that file so you can log in the way you chose in their dashboard. From apt's point of view, that file no longer matches what the openssh package shipped, so when a new version of openssh came down in the upgrade, it stopped and asked me what to do.&lt;/p&gt;

&lt;p&gt;That is not a bug. That is apt being careful. It will not silently overwrite a config file that someone changed on purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the wrong answer is dangerous&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If I had picked the maintainer's version, apt would have replaced the file with the stock Ubuntu default. The settings DigitalOcean put there to let me log in would be gone. Depending on what they set, that can mean password login is off and I never uploaded a key, or root login is blocked and I have no other user yet. The SSH session I was sitting in would keep working right up until I disconnected, and then I would be locked out of a server I had owned for four minutes.&lt;/p&gt;

&lt;p&gt;Recovery is possible through the DigitalOcean web console, but that is a bad way to spend your first day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I did&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I kept the local version. It was already highlighted, which I suspect is not an accident.&lt;/p&gt;

&lt;p&gt;The part I did not know until I looked it up is that keeping local does not throw the new version away. apt drops the package's copy right next to yours, usually as &lt;code&gt;/etc/ssh/sshd_config.dpkg-dist&lt;/code&gt; or &lt;code&gt;.ucf-dist&lt;/code&gt;. So you lose nothing. You can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;diff /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;later and pull in anything that looks useful by hand, on your own schedule, with a plan for what happens if it breaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I took away&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rule I wrote in my journal is simple. If that prompt appears on a machine I am SSH'd into, keep local, then diff. Never let a package manager rewrite the file that controls my access while I am relying on that access.&lt;/p&gt;

&lt;p&gt;The bigger lesson is the same one the AWS audit taught me. The scary part of infrastructure is not the commands. It is the things that got set up for you that you did not know about. A provider edited a file on my behalf, and the first time I found out was when the system asked me to make a decision about it. The challenge apparently gets to hardening SSH in a later lesson. I am going to be reading that file very carefully when it does.&lt;/p&gt;

&lt;p&gt;[Anything else that broke on Day 0, or cut this line.]&lt;/p&gt;

&lt;p&gt;Server is alive. Screenshot is posted. Day 1 is Monday.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>devops</category>
      <category>career</category>
    </item>
    <item>
      <title>I Spent Three Hours Fighting CloudFront. Here's What I Actually Learned.</title>
      <dc:creator>Jas</dc:creator>
      <pubDate>Mon, 29 Jun 2026 04:57:46 +0000</pubDate>
      <link>https://dev.to/jas_dev/i-spent-three-hours-fighting-cloudfront-heres-what-i-actually-learned-2ao2</link>
      <guid>https://dev.to/jas_dev/i-spent-three-hours-fighting-cloudfront-heres-what-i-actually-learned-2ao2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Today was supposed to be simple.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm working through the Cloud Resume Challenge, a project that has you build a resume site on AWS using S3, CloudFront, Lambda, DynamoDB, and a handful of other services, wired together by hand. The point isn't the resume. The point is proving you can actually use the infrastructure, not just talk about it.&lt;/p&gt;

&lt;p&gt;Stage one: static site on S3. Done. Stage two: CloudFront with HTTPS.&lt;/p&gt;

&lt;p&gt;Three hours later, I was staring at the same error message for the sixth time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Went Wrong
&lt;/h2&gt;

&lt;p&gt;The error was this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;404 Not Found
Code: NoSuchBucket
BucketName: d2aoai2y8wmb9h.cloudfront.net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;S3 was receiving requests and trying to find a bucket named after my CloudFront domain. Which doesn't exist. Which will never exist. That's not how any of this works.&lt;/p&gt;

&lt;p&gt;Here's what was actually happening: CloudFront was forwarding the wrong Host header to S3. Instead of telling S3 "hey, I'm looking for content from resume.jasmineallen.dev.s3-website.us-east-2.amazonaws.com," it was sending its own domain name as the host. S3 saw that, tried to find a matching bucket, couldn't, and threw a 404.&lt;/p&gt;

&lt;p&gt;The root cause was the AWS console's new simplified CloudFront UI. When I selected "Amazon S3" as my origin type during setup, it locked in S3-specific origin behavior under the hood. Behavior I couldn't fully override by just editing the origin domain afterward. The UI was abstracting away the exact setting I needed to change.&lt;/p&gt;

&lt;p&gt;What I needed was a custom origin configured with CustomOriginConfig, which tells CloudFront to treat S3 as a plain HTTP server rather than an S3 bucket. That distinction matters because S3 static website hosting works differently from the S3 REST API, and CloudFront handles them differently.&lt;/p&gt;

&lt;p&gt;The console wouldn't let me set it. Every path I tried hit a wall: blocked Host header overrides, stale cached errors, a distribution I couldn't delete because of a billing plan lock. I tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Editing the origin domain&lt;/li&gt;
&lt;li&gt;Creating a second origin and swapping the behavior&lt;/li&gt;
&lt;li&gt;Invalidating the cache&lt;/li&gt;
&lt;li&gt;Disabling and re-enabling the distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of it worked.&lt;/p&gt;

&lt;p&gt;What finally worked was bypassing the UI entirely and using the AWS CLI to create a new distribution with the exact config I needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bashaws cloudfront create-distribution &lt;span class="nt"&gt;--distribution-config&lt;/span&gt; &lt;span class="s1"&gt;'{
  "Origins": {
    "Items": [{
      "DomainName": "resume.jasmineallen.dev.s3-website.us-east-2.amazonaws.com",
      "CustomOriginConfig": {
        "HTTPPort": 80,
        "OriginProtocolPolicy": "http-only"
      }
    }]
  }
  ...
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First try. Site loaded. HTTPS working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;The console UI hides things that matter.&lt;/p&gt;

&lt;p&gt;Simplified UIs are useful until they're not. The new CloudFront setup wizard made the wrong choice for my use case, S3 REST origin instead of custom HTTP origin, and then made it very hard to correct that choice after the fact. If I hadn't known to look for CustomOriginConfig as a concept, I would have been completely stuck.&lt;/p&gt;

&lt;p&gt;This is true of a lot of AWS tooling. The console is great for exploration. For production configuration, the CLI or IaC gives you precision the UI sometimes can't.&lt;/p&gt;

&lt;p&gt;Error messages are clues, not just complaints.&lt;/p&gt;

&lt;p&gt;The BucketName: d2aoai2y8wmb9h.cloudfront.net in the error response was telling me exactly what was wrong. CloudFront was sending the wrong host. I just had to slow down and read it instead of treating it as noise.&lt;/p&gt;

&lt;p&gt;Cache invalidation is not a magic fix.&lt;/p&gt;

&lt;p&gt;I created two invalidations today trying to clear errors that weren't caused by caching. Invalidation tells CloudFront to stop serving stale content. It doesn't fix a misconfigured origin. Reaching for invalidation before diagnosing the actual problem just adds waiting time.&lt;/p&gt;

&lt;p&gt;Sometimes you have to go lower in the stack.&lt;/p&gt;

&lt;p&gt;The UI abstracted away the problem. The CLI solved it in one command. Knowing that the CLI exists and how to use it isn't optional knowledge. It's the fallback when the pretty interface runs out of options.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why This Matters Beyond the Challenge&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This exact class of problem shows up in real projects all the time.&lt;/p&gt;

&lt;p&gt;A team sets up a CDN for a client-facing application using the console's default settings. Everything looks fine in the UI. Then traffic starts behaving strangely. Some requests are slow, some are returning stale content, some are failing entirely. Nobody can figure out why because nobody looked at the actual origin configuration. The UI said it was set up correctly.&lt;/p&gt;

&lt;p&gt;Or a startup moves their static marketing site to CloudFront to improve global performance. The engineer who set it up used the wizard. Six months later a different engineer needs to debug a caching issue and finds the origin type is wrong, with the distribution locked into a billing plan that makes it hard to recreate cleanly.&lt;/p&gt;

&lt;p&gt;Understanding what's actually happening underneath the UI isn't just useful for passing certifications. It's the difference between being able to debug your own infrastructure and being stuck with whatever the wizard decided for you.&lt;/p&gt;

&lt;p&gt;A few concrete takeaways for anyone building on AWS:&lt;/p&gt;

&lt;p&gt;For S3 static website hosting + CloudFront: always use the S3 website endpoint (bucket-name.s3-website.region.amazonaws.com) as a custom HTTP origin, not the S3 REST endpoint. The website endpoint handles index documents and error routing correctly. The REST endpoint doesn't.&lt;/p&gt;

&lt;p&gt;Before reaching for cache invalidation: confirm the origin is actually returning what you expect by hitting the origin URL directly. If the origin is broken, no amount of invalidation will fix it.&lt;/p&gt;

&lt;p&gt;Learn the CLI early. Not everything, just the services you're actively using. aws cloudfront create-distribution, aws s3 sync, aws lambda update-function-code. These give you a level of control and repeatability the console can't match.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I Am Now
&lt;/h2&gt;

&lt;p&gt;S3 static site: done&lt;br&gt;
CloudFront with HTTPS: done (via CLI, not the wizard)&lt;br&gt;
DNS: pointing resume.jasmineallen.dev at CloudFront&lt;br&gt;
Visitor counter: JavaScript to API Gateway to Lambda to DynamoDB&lt;br&gt;
IaC&lt;br&gt;
CI/CD&lt;br&gt;
This post&lt;/p&gt;

&lt;p&gt;The debugging was frustrating in the moment. Looking back, it was the most useful part of the day, more useful than if everything had worked on the first try.&lt;/p&gt;

&lt;p&gt;That's the thing about infrastructure work. The happy path teaches you the steps. The broken path teaches you how it actually works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next up: DNS and the visitor counter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Provisioning Jas is a series about building real things on AWS, written in real time, mistakes included.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>aws</category>
      <category>cloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Audited My AWS Account and Here's What I Found</title>
      <dc:creator>Jas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 17:01:02 +0000</pubDate>
      <link>https://dev.to/jas_dev/i-audited-my-aws-account-and-heres-what-i-found-3278</link>
      <guid>https://dev.to/jas_dev/i-audited-my-aws-account-and-heres-what-i-found-3278</guid>
      <description>&lt;p&gt;I finally sat down and did a proper audit of my AWS account. I knew I had projects running and services connected to my domains, but I had never actually gone line by line through the bill. When I did, I found $13.16 in charges across four separate services, some of which I did not even know were running.&lt;/p&gt;

&lt;p&gt;Here is what I found and what I did about it.&lt;br&gt;
AWS is not one bill. It is a lot of meters running at the same time.&lt;br&gt;
Every service you spin up has its own pricing. I had four separate things billing me and I only really understood one of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2&lt;/strong&gt; — $8.25&lt;/p&gt;

&lt;p&gt;A virtual Linux server running in US East Ohio. I spun this up for a study group project and forgot about it. EC2 charges by the hour whether anyone is using it or not. It does not care about traffic. It is a server and it is on until you turn it off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC Public IP&lt;/strong&gt; — $3.67&lt;/p&gt;

&lt;p&gt;This one surprised me the most. AWS started charging for public IPv4 addresses in 2024. My EC2 instance had one attached and I had no idea it was a separate charge. It was just sitting there costing money.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route 53&lt;/strong&gt; — $1.01&lt;/p&gt;

&lt;p&gt;This is AWS's DNS service. I have two domains and each one has its own hosted zone. Fifty cents per hosted zone per month plus a small amount for DNS queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amplify&lt;/strong&gt; — $0.23&lt;/p&gt;

&lt;p&gt;This was actually a good surprise. I did not realize I was using Amplify at all. Turns out one of my sites runs through it. Because it is a static site with low traffic, the cost was almost nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I did&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The EC2 instance was for a study group project that is on hold right now. It was not serving any live site. I confirmed my actual portfolio still loaded fine without it, so I stopped it. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stopping and terminating are not the same thing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stop&lt;/em&gt; powers it off and saves your work. A small storage charge still runs. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminate&lt;/em&gt; deletes everything permanently and stops all charges.&lt;br&gt;
I stopped it.&lt;/p&gt;

&lt;p&gt;My bill goes from $13.16 to about $1.64 next month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I took away from this&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The money was not even the main thing. It was realizing I had services running that I did not fully understand. Now I know that EC2 is a full virtual server and it is overkill for a static site. Amplify is the better tool for that because it is built on S3 and CloudFront and handles the deployment for you. Public IP addresses cost money now even when nothing is running. And reading your bill line by line is actually a skill worth building early.&lt;/p&gt;

&lt;p&gt;I am working through the Cloud Resume Challenge and building toward my AWS certifications. This was not a planned lesson but it ended up being one of the more useful things I have done.&lt;/p&gt;

&lt;p&gt;If you are early in your cloud learning go open your bill. You might be surprised by what you find.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>career</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
