<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://h-minn.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://h-minn.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2025-09-07T01:27:54+00:00</updated><id>https://h-minn.github.io/feed.xml</id><title type="html">Min</title><subtitle>AWS Certified Solutions Architect | Full Stack Developer | Professional Scrum Master™ II (PSM II) | Japanese N1 | DevSecOps &amp; Cybersecurity Enthusiast</subtitle><entry><title type="html">Snapshots vs. Backups in the Cloud: AWS, Azure, and Google Cloud</title><link href="https://h-minn.github.io/posts/en-backup-vs-snapshots/" rel="alternate" type="text/html" title="Snapshots vs. Backups in the Cloud: AWS, Azure, and Google Cloud" /><published>2025-09-07T00:00:00+00:00</published><updated>2025-09-07T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/en-backup-vs-snapshots</id><content type="html" xml:base="https://h-minn.github.io/posts/en-backup-vs-snapshots/"><![CDATA[<p>Data protection is one of the most critical aspects of cloud infrastructure. Whether you’re hosting a small application or running enterprise-scale workloads, you need to safeguard against accidental deletions, hardware failures, ransomware, or misconfigurations.</p>

<p>Two common strategies are <strong>snapshots</strong> and <strong>backups</strong>. While they might sound similar, they serve different purposes and are implemented differently across cloud providers such as <strong>AWS, Google Cloud, and Azure</strong>.</p>

<hr />

<h2 id="snapshots">Snapshots</h2>

<p>A <strong>snapshot</strong> is a point-in-time copy of a disk or volume.</p>
<ul>
  <li><strong>Granularity</strong>: Typically at the disk/volume level.</li>
  <li><strong>Speed</strong>: Faster to create than a full backup.</li>
  <li><strong>Storage efficiency</strong>: Often incremental (only changes since the last snapshot are stored).</li>
  <li><strong>Use case</strong>: Quick rollback, testing, or temporary protection during risky operations.</li>
</ul>

<h3 id="cloud-examples">Cloud Examples</h3>
<ul>
  <li><strong>AWS</strong>:
    <ul>
      <li><strong>EBS Snapshots</strong> store block-level data on S3.</li>
      <li>Incremental by default and can be copied across regions for disaster recovery.</li>
    </ul>
  </li>
  <li><strong>Azure</strong>:
    <ul>
      <li><strong>Managed Disk Snapshots</strong> are full copies of managed disks.</li>
      <li>Can be used to create new VMs or restore disks.</li>
    </ul>
  </li>
  <li><strong>Google Cloud</strong>:
    <ul>
      <li><strong>Persistent Disk Snapshots</strong> are incremental, global resources.</li>
      <li>Useful for cloning environments and protecting workloads.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="backups">Backups</h2>

<p>A <strong>backup</strong> is a broader concept that ensures long-term data durability and recovery.</p>
<ul>
  <li><strong>Granularity</strong>: Can cover entire systems, databases, applications, or file-level data.</li>
  <li><strong>Durability</strong>: Often stored in cheaper, long-term storage classes (e.g., S3 Glacier, Azure Backup Vault, Google Archive Storage).</li>
  <li><strong>Retention policies</strong>: Supports compliance, archiving, and long-term storage requirements.</li>
  <li><strong>Use case</strong>: Business continuity, disaster recovery, compliance, and ransomware protection.</li>
</ul>

<h3 id="cloud-examples-1">Cloud Examples</h3>
<ul>
  <li><strong>AWS</strong>:
    <ul>
      <li><strong>AWS Backup</strong> centralizes and automates backups across EBS, RDS, DynamoDB, EFS, FSx, and more.</li>
      <li>Supports policies, compliance, and lifecycle management (transition to cold storage).</li>
    </ul>
  </li>
  <li><strong>Azure</strong>:
    <ul>
      <li><strong>Azure Backup</strong> provides app-consistent, secure backups for VMs, SQL, file shares, and Azure Kubernetes Service (AKS).</li>
      <li>Integrated with Recovery Services Vault for retention and policy enforcement.</li>
    </ul>
  </li>
  <li><strong>Google Cloud</strong>:
    <ul>
      <li><strong>Backup and DR Service</strong> automates backups for VMs, databases, and applications.</li>
      <li>Policy-driven with regional replication and rapid recovery options.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="snapshots-vs-backups-key-differences">Snapshots vs. Backups: Key Differences</h2>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Snapshots</th>
      <th>Backups</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Scope</strong></td>
      <td>Disk/volume level</td>
      <td>File, database, or system level</td>
    </tr>
    <tr>
      <td><strong>Speed</strong></td>
      <td>Fast creation, incremental</td>
      <td>Slower (full or incremental sets)</td>
    </tr>
    <tr>
      <td><strong>Retention</strong></td>
      <td>Short-term or mid-term</td>
      <td>Long-term, policy-based</td>
    </tr>
    <tr>
      <td><strong>Use case</strong></td>
      <td>Quick restore, testing, cloning</td>
      <td>Disaster recovery, compliance</td>
    </tr>
    <tr>
      <td><strong>Cost efficiency</strong></td>
      <td>Higher for long-term retention</td>
      <td>Optimized for long-term storage</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="choosing-the-right-approach">Choosing the Right Approach</h2>

<ul>
  <li><strong>Use Snapshots when</strong>:
    <ul>
      <li>You need a fast rollback point before making risky changes.</li>
      <li>You’re cloning environments for testing or scaling workloads.</li>
      <li>You want to capture incremental changes frequently.</li>
    </ul>
  </li>
  <li><strong>Use Backups when</strong>:
    <ul>
      <li>You need <strong>long-term retention</strong> (months to years).</li>
      <li>Compliance or regulatory requirements demand durable storage.</li>
      <li>You must protect entire applications, not just disks.</li>
      <li>You want cross-region or cross-account disaster recovery.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="hybrid-approach">Hybrid Approach</h2>

<p>In practice, organizations often use <strong>both</strong>:</p>
<ul>
  <li>Snapshots for <strong>short-term protection</strong> and operational agility.</li>
  <li>Backups for <strong>long-term durability</strong>, compliance, and disaster recovery.</li>
</ul>

<p>For example:</p>
<ul>
  <li><strong>Take daily EBS snapshots</strong> for quick recovery.</li>
  <li><strong>Schedule AWS Backup policies</strong> to store critical workloads in cold storage for years.</li>
</ul>

<hr />

<h2 id="conclusion">Conclusion</h2>

<p>Snapshots and backups are complementary, not interchangeable. Snapshots provide speed and convenience, while backups ensure compliance, durability, and resilience.</p>

<p>Whether you’re on <strong>AWS, Azure, or Google Cloud</strong>, the key is to align your data protection strategy with your business requirements—balancing <strong>performance, cost, and compliance</strong>.</p>]]></content><author><name></name></author><category term="Cloud" /><category term="Storage" /><category term="Backup" /><category term="Snapshots" /><category term="AWS" /><category term="Azure" /><category term="Google Cloud" /><category term="Snapshots" /><category term="Backups" /><summary type="html"><![CDATA[Data protection is one of the most critical aspects of cloud infrastructure. Whether you’re hosting a small application or running enterprise-scale workloads, you need to safeguard against accidental deletions, hardware failures, ransomware, or misconfigurations.]]></summary></entry><entry><title type="html">Types of Backup: Full, Incremental, and Differential</title><link href="https://h-minn.github.io/posts/en-types-of-backups/" rel="alternate" type="text/html" title="Types of Backup: Full, Incremental, and Differential" /><published>2025-09-07T00:00:00+00:00</published><updated>2025-09-07T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/en-types-of-backups</id><content type="html" xml:base="https://h-minn.github.io/posts/en-types-of-backups/"><![CDATA[<p>Data protection strategies are built around backups, and the method chosen can significantly affect recovery speed, storage costs, and operational efficiency. The three fundamental types of backups are <strong>Full</strong>, <strong>Incremental</strong>, and <strong>Differential</strong>. Understanding their differences helps in designing an effective backup policy, whether for on-premises systems or cloud-based workloads.</p>

<hr />

<h2 id="full-backup">Full Backup</h2>

<p>A <strong>full backup</strong> is a complete copy of all selected data at a specific point in time.</p>
<ul>
  <li><strong>Advantages</strong>:
    <ul>
      <li>Simplest to manage and restore.</li>
      <li>Provides a single, comprehensive data set.</li>
    </ul>
  </li>
  <li><strong>Disadvantages</strong>:
    <ul>
      <li>Time-consuming to create.</li>
      <li>Requires the most storage space.</li>
    </ul>
  </li>
</ul>

<p><strong>Use Cases</strong>:</p>
<ul>
  <li>Baseline backup before starting incremental or differential backups.</li>
  <li>Small datasets where storage and time overhead are not significant.</li>
  <li>Compliance-driven workloads requiring frequent complete copies.</li>
</ul>

<hr />

<h2 id="incremental-backup">Incremental Backup</h2>

<p>An <strong>incremental backup</strong> saves only the data that has changed since the last backup (full or incremental).</p>
<ul>
  <li><strong>Advantages</strong>:
    <ul>
      <li>Fast to create.</li>
      <li>Efficient use of storage.</li>
    </ul>
  </li>
  <li><strong>Disadvantages</strong>:
    <ul>
      <li>Slower restores, as you need the last full backup plus all subsequent incremental backups.</li>
      <li>Dependency chain increases risk; if one backup in the chain is missing or corrupted, recovery may fail.</li>
    </ul>
  </li>
</ul>

<p><strong>Use Cases</strong>:</p>
<ul>
  <li>Large datasets with frequent changes.</li>
  <li>Environments where reducing backup windows and storage costs is a priority.</li>
  <li>Cloud storage strategies where bandwidth is limited.</li>
</ul>

<hr />

<h2 id="differential-backup">Differential Backup</h2>

<p>A <strong>differential backup</strong> saves all data that has changed since the last full backup.</p>
<ul>
  <li><strong>Advantages</strong>:
    <ul>
      <li>Faster restores than incremental backups (only the last full backup and the most recent differential are needed).</li>
      <li>Provides a balance between speed and storage.</li>
    </ul>
  </li>
  <li><strong>Disadvantages</strong>:
    <ul>
      <li>Backup size grows over time until the next full backup is taken.</li>
      <li>Requires more storage than incrementals but less than multiple full backups.</li>
    </ul>
  </li>
</ul>

<p><strong>Use Cases</strong>:</p>
<ul>
  <li>Mid-sized environments where restore speed is important.</li>
  <li>Applications requiring frequent recovery point updates without the storage cost of full backups.</li>
</ul>

<hr />

<h2 id="comparison-table">Comparison Table</h2>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Full Backup</th>
      <th>Incremental Backup</th>
      <th>Differential Backup</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Backup Time</strong></td>
      <td>Long</td>
      <td>Short</td>
      <td>Moderate</td>
    </tr>
    <tr>
      <td><strong>Restore Time</strong></td>
      <td>Short</td>
      <td>Long (depends on chain length)</td>
      <td>Moderate</td>
    </tr>
    <tr>
      <td><strong>Storage Requirement</strong></td>
      <td>High</td>
      <td>Low</td>
      <td>Medium (grows over time)</td>
    </tr>
    <tr>
      <td><strong>Risk of Failure</strong></td>
      <td>Low (single file set)</td>
      <td>Higher (chain dependency)</td>
      <td>Lower than incremental</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="practical-strategy">Practical Strategy</h2>

<p>In real-world scenarios, organizations rarely rely on just one method. A <strong>hybrid strategy</strong> is common:</p>
<ul>
  <li>Take <strong>full backups weekly</strong> to establish a baseline.</li>
  <li>Use <strong>incremental backups daily</strong> to capture changes efficiently.</li>
  <li>Occasionally use <strong>differential backups</strong> when balancing restore speed and storage efficiency is critical.</li>
</ul>

<p>In cloud platforms such as <strong>AWS Backup, Azure Backup, and Google Cloud Backup and DR</strong>, these strategies are often automated, with policies allowing organizations to choose retention schedules, lifecycle management, and storage tiers.</p>

<hr />

<h2 id="conclusion">Conclusion</h2>

<p>Choosing between full, incremental, and differential backups depends on your <strong>recovery objectives, storage capacity, and operational constraints</strong>. A well-designed backup strategy typically combines all three methods to optimize cost, recovery speed, and data protection.</p>

<p>By understanding these backup types, you can align your backup policy with business requirements, regulatory needs, and cloud capabilities.</p>]]></content><author><name></name></author><category term="Cloud" /><category term="Storage" /><category term="Backup" /><category term="Data Protection" /><category term="Backup" /><category term="Full Backup" /><category term="Incremental Backup" /><category term="Differential Backup" /><category term="Cloud Storage" /><summary type="html"><![CDATA[Data protection strategies are built around backups, and the method chosen can significantly affect recovery speed, storage costs, and operational efficiency. The three fundamental types of backups are Full, Incremental, and Differential. Understanding their differences helps in designing an effective backup policy, whether for on-premises systems or cloud-based workloads.]]></summary></entry><entry><title type="html">Comparing GCP and AWS Application Load Balancers</title><link href="https://h-minn.github.io/posts/en-comparing-gcp-and-aws-albs/" rel="alternate" type="text/html" title="Comparing GCP and AWS Application Load Balancers" /><published>2025-08-17T00:00:00+00:00</published><updated>2025-08-17T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/en-comparing-gcp-and-aws-albs</id><content type="html" xml:base="https://h-minn.github.io/posts/en-comparing-gcp-and-aws-albs/"><![CDATA[<p>In modern distributed architectures, <strong>load balancing</strong> is not just a mechanism for spreading traffic. It is a <strong>foundational control plane</strong> that impacts latency, reliability, multi-region strategy, and even compliance. Two of the most widely used cloud platforms—<strong>AWS</strong> and <strong>GCP</strong>—both offer <em>Application Load Balancers (ALBs)</em>, but their approaches differ in scope, functionality, and global reach.</p>

<p>This post highlights the <strong>architectural differences between AWS and GCP Application Load Balancers</strong>, with a focus on real-world implications for senior engineers and architects.</p>

<hr />

<h2 id="1-scope-and-regionality">1. Scope and Regionality</h2>

<ul>
  <li><strong><a href="https://aws.amazon.com/elasticloadbalancing/application-load-balancer/">AWS Application Load Balancer (ALB)</a></strong>
    <ul>
      <li>Regional construct: an ALB lives entirely within a single AWS Region.</li>
      <li>Can span multiple Availability Zones (AZs) within that region.</li>
      <li>Does <strong>not natively support cross-region load balancing</strong>.</li>
      <li>To achieve global distribution, AWS customers layer services like <strong>Route 53</strong> (DNS-based) or <strong>Global Accelerator</strong> (Anycast IPs with routing policies).</li>
    </ul>
  </li>
  <li><strong><a href="https://cloud.google.com/load-balancing/docs/application-load-balancer">GCP External Application Load Balancer (Global HTTP(S))</a></strong>
    <ul>
      <li>Global construct: a single Anycast IP serves as the entry point worldwide.</li>
      <li>Native cross-region support: traffic is automatically directed to the closest healthy backend across regions.</li>
      <li>Simplifies deployment—no need to stitch DNS policies or external accelerators.</li>
    </ul>
  </li>
</ul>

<p><strong>Takeaway:</strong> AWS ALB is region-bound; GCP’s external ALB is inherently global.</p>

<hr />

<h2 id="2-traffic-management-and-protocol-support">2. Traffic Management and Protocol Support</h2>

<ul>
  <li><strong>AWS ALB</strong>
    <ul>
      <li>L7 load balancing with support for HTTP, HTTPS, and WebSocket.</li>
      <li>Advanced routing features: host/path-based routing, query string/method headers, weighted target groups.</li>
      <li>Tight integration with AWS services (e.g., Lambda as a backend target, WAF, Cognito authentication).</li>
    </ul>
  </li>
  <li><strong>GCP Application Load Balancer</strong>
    <ul>
      <li>Also operates at L7 with HTTP, HTTPS, and gRPC support.</li>
      <li>Provides URL maps for sophisticated routing (host/path-based).</li>
      <li>Global routing decisions leverage Google’s backbone to minimize latency.</li>
      <li>Integrates with Cloud Armor (WAF), Identity-Aware Proxy, and Cloud CDN.</li>
    </ul>
  </li>
</ul>

<p><strong>Takeaway:</strong> Both platforms offer robust L7 routing, but GCP embeds latency-aware global routing as a first-class feature.</p>

<hr />

<h2 id="3-cross-region--multi-cloud-strategy">3. Cross-Region &amp; Multi-Cloud Strategy</h2>

<ul>
  <li><strong>AWS</strong>
    <ul>
      <li>Requires additional services (Route 53, Global Accelerator, or CloudFront) for multi-region HA/DR scenarios.</li>
      <li>Operational overhead: architects must design failover policies, health checks, and DNS propagation strategies.</li>
      <li>More composable, but with added complexity.</li>
    </ul>
  </li>
  <li><strong>GCP</strong>
    <ul>
      <li>Cross-region support is native, reducing architectural complexity.</li>
      <li>Failover is automatic within the load balancer layer.</li>
      <li>Better suited for organizations seeking <strong>simplified global deployments</strong> without custom DNS routing.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="4-internal-load-balancing">4. Internal Load Balancing</h2>

<ul>
  <li><strong>AWS</strong>
    <ul>
      <li>Offers <strong>internal ALBs</strong> and <strong>NLBs</strong> scoped to a VPC within a region.</li>
      <li>Cross-region internal load balancing is not supported.</li>
    </ul>
  </li>
  <li><strong>GCP</strong>
    <ul>
      <li>Provides <strong>Cross-Region Internal Application Load Balancer</strong>, a global internal L7 load balancer.</li>
      <li>Allows private workloads to leverage Google’s backbone for cross-region HA.</li>
      <li>Distinct advantage for multi-region service meshes and hybrid workloads.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="5-pricing-and-cost-predictability">5. Pricing and Cost Predictability</h2>

<ul>
  <li><strong>AWS ALB</strong>
    <ul>
      <li>Pricing model: per-hour charge + per-LCU (Load Balancer Capacity Unit).</li>
      <li>LCU captures new connections, active connections, rule evaluations, and data processed.</li>
      <li>Cost scales with complexity of traffic patterns, not just bandwidth.</li>
    </ul>
  </li>
  <li><strong>GCP ALB</strong>
    <ul>
      <li>Pricing model: global forwarding rules + backend service charges + bandwidth.</li>
      <li>Generally simpler to estimate when workloads are global, though regional cost optimizations may be less granular.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="6-strategic-considerations">6. Strategic Considerations</h2>

<ul>
  <li><strong>AWS ALB</strong> excels when:
    <ul>
      <li>You operate primarily within a single AWS Region.</li>
      <li>You need deep integration with AWS ecosystem features (Lambda, ECS, Cognito).</li>
      <li>You value modularity and are comfortable managing DNS-based global distribution.</li>
    </ul>
  </li>
  <li><strong>GCP ALB</strong> excels when:
    <ul>
      <li>You need <strong>built-in global distribution</strong> with Anycast IPs.</li>
      <li>You want to reduce operational overhead for multi-region HA.</li>
      <li>You plan to integrate with Google’s CDN, Cloud Armor, or hybrid networking.</li>
    </ul>
  </li>
</ul>

<hr />

<h2 id="final-thoughts">Final Thoughts</h2>

<p>Both AWS and GCP offer world-class L7 load balancing, but their <strong>philosophies diverge</strong>:</p>

<ul>
  <li>AWS takes a <strong>modular approach</strong>: ALB for regional L7, Route 53 or Global Accelerator for global traffic distribution.</li>
  <li>GCP takes a <strong>converged approach</strong>: a single load balancer resource can span the globe.</li>
</ul>

<p>For architects, the decision often comes down to whether you prefer <strong>fine-grained control with composable services (AWS)</strong> or <strong>simplified global reach with fewer moving parts (GCP)</strong>.</p>

<hr />

<p><em>Let me know your thoughts or experiences with AWS and GCP load balancers—I’d love to hear how you approach multi-region architectures.</em></p>]]></content><author><name></name></author><category term="cloud" /><category term="load-balancing" /><category term="aws" /><category term="gcp" /><category term="architecture" /><category term="load-balancing" /><category term="aws" /><category term="gcp" /><category term="architecture" /><category term="application-load-balancer" /><summary type="html"><![CDATA[In modern distributed architectures, load balancing is not just a mechanism for spreading traffic. It is a foundational control plane that impacts latency, reliability, multi-region strategy, and even compliance. Two of the most widely used cloud platforms—AWS and GCP—both offer Application Load Balancers (ALBs), but their approaches differ in scope, functionality, and global reach.]]></summary></entry><entry><title type="html">Just Discovered GPUs for Math-Intensive Workloads</title><link href="https://h-minn.github.io/posts/en-gpu-for-ml/" rel="alternate" type="text/html" title="Just Discovered GPUs for Math-Intensive Workloads" /><published>2025-08-17T00:00:00+00:00</published><updated>2025-08-17T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/en-gpu-for-ml</id><content type="html" xml:base="https://h-minn.github.io/posts/en-gpu-for-ml/"><![CDATA[<p>I just recently discovered how much a <strong>GPU (Graphics Processing Unit)</strong> can impact math-intensive workloads like <strong>machine learning</strong>, and I’m genuinely impressed. I thought CPUs were the main workhorses, but GPUs are a game-changer.</p>

<h2 id="why-gpus-matter-for-math-intensive-workloads">Why GPUs Matter for Math-Intensive Workloads</h2>

<p>At their core, GPUs are designed to handle <strong>massively parallel computations</strong>. While a CPU might have a few cores optimized for sequential tasks, a GPU has thousands of smaller cores built to do many calculations <strong>simultaneously</strong>. This architecture is perfect for workloads that involve large matrices, vectors, and repetitive numerical operations—which are exactly what machine learning and scientific computing rely on.</p>

<p>For example:</p>

<ul>
  <li><strong>Training neural networks</strong> involves a lot of matrix multiplications. GPUs can compute these operations <strong>in parallel</strong>, drastically reducing training time.</li>
  <li><strong>Simulations and data analysis</strong> often require crunching massive datasets. A GPU can process multiple data points at once, making these tasks much faster than a CPU alone.</li>
</ul>

<h2 id="real-world-impact">Real-World Impact</h2>

<p>Switching from CPU-only computations to GPU-accelerated workflows can reduce training times from <strong>days to hours</strong>, depending on the model size and dataset. This efficiency not only speeds up experimentation but also enables more complex models that would otherwise be impractical.</p>

<h2 id="takeaway">Takeaway</h2>

<p>Discovering the power of GPUs has been eye-opening. If you’re diving into <strong>machine learning, deep learning, or any math-heavy computation</strong>, leveraging a GPU is not just a nice-to-have—it’s almost essential for efficiency.</p>

<p>Have you recently discovered the GPU advantage in your own projects? I’d love to hear your experiences in the comments!</p>]]></content><author><name></name></author><category term="technology" /><category term="machine-learning" /><category term="gpu" /><summary type="html"><![CDATA[I just recently discovered how much a GPU (Graphics Processing Unit) can impact math-intensive workloads like machine learning, and I’m genuinely impressed. I thought CPUs were the main workhorses, but GPUs are a game-changer.]]></summary></entry><entry><title type="html">Terraform for Beginners: From Zero to Infrastructure as Code</title><link href="https://h-minn.github.io/posts/terraform-for-beginners/" rel="alternate" type="text/html" title="Terraform for Beginners: From Zero to Infrastructure as Code" /><published>2025-07-19T00:00:00+00:00</published><updated>2025-07-19T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/terraform-for-beginners</id><content type="html" xml:base="https://h-minn.github.io/posts/terraform-for-beginners/"><![CDATA[<h1 id="terraform-for-beginners-from-zero-to-infrastructure-as-code">Terraform for Beginners: From Zero to Infrastructure as Code</h1>

<h2 id="what-is-terraform">What is Terraform?</h2>

<p><strong>Terraform</strong> is an open-source tool developed by HashiCorp that allows you to define, provision, and manage your infrastructure using code.</p>

<p>This concept is known as <strong>Infrastructure as Code (IaC)</strong> — treating your infrastructure (servers, databases, networks, etc.) the same way you treat your application code: version-controlled, automated, and reproducible.</p>

<hr />

<h2 id="why-use-terraform">Why Use Terraform?</h2>

<p>Here’s what makes Terraform powerful:</p>

<ul>
  <li><strong>Declarative Syntax</strong>: You define <em>what</em> you want, not <em>how</em> to get it.</li>
  <li><strong>Multi-Cloud Support</strong>: Use the same language for AWS, Azure, GCP, and others.</li>
  <li><strong>Immutable Infrastructure</strong>: Apply changes safely and predictably.</li>
  <li><strong>State Tracking</strong>: Maintains a snapshot of your infrastructure.</li>
  <li><strong>Version Control Friendly</strong>: Your <code class="language-plaintext highlighter-rouge">.tf</code> files can live in Git.</li>
</ul>

<hr />

<h2 id="real-world-use-case">Real-World Use Case</h2>

<p>Imagine you need:</p>

<ul>
  <li>An AWS EC2 instance</li>
  <li>With a specific security group</li>
  <li>And an attached EBS volume</li>
</ul>

<p>You can either:</p>

<ul>
  <li>Log in to AWS Console and click through a bunch of pages<br />
<strong>OR</strong></li>
  <li>Write a few lines of Terraform code and run one command: <code class="language-plaintext highlighter-rouge">terraform apply</code></li>
</ul>

<hr />

<h2 id="key-concepts">Key Concepts</h2>

<p>Before writing code, understand these basic concepts:</p>

<h3 id="1-providers">1. <strong>Providers</strong></h3>
<p>Providers are services Terraform interacts with — like AWS, Azure, GCP, Kubernetes.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nx">provider</span> <span class="s2">"aws"</span> <span class="p">{</span>
  <span class="nx">region</span> <span class="o">=</span> <span class="s2">"us-east-1"</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="2-resources">2. <strong>Resources</strong></h3>

<p>Resources are components of your infrastructure — EC2 instance, S3 bucket, etc.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="nx">resource</span> <span class="s2">"aws_instance"</span> <span class="s2">"web"</span> <span class="p">{</span>
  <span class="nx">ami</span>           <span class="o">=</span> <span class="s2">"ami-0c55b159cbfafe1f0"</span>
  <span class="nx">instance_type</span> <span class="o">=</span> <span class="s2">"t2.micro"</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="3-variables">3. <strong>Variables</strong></h3>

<p>Variables make your configuration dynamic and reusable.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nx">variable</span> <span class="s2">"instance_type"</span> <span class="p">{</span>
  <span class="nx">default</span> <span class="o">=</span> <span class="s2">"t2.micro"</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="4-outputs">4. <strong>Outputs</strong></h3>

<p>Outputs let you display values after applying infrastructure — like IP addresses or URLs.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nx">output</span> <span class="s2">"instance_ip"</span> <span class="p">{</span>
  <span class="nx">value</span> <span class="o">=</span> <span class="nx">aws_instance</span><span class="p">.</span><span class="nx">web</span><span class="p">.</span><span class="nx">public_ip</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="5-state">5. <strong>State</strong></h3>

<p>Terraform maintains the infrastructure’s current state in a file named <code class="language-plaintext highlighter-rouge">terraform.tfstate</code>.</p>

<hr />

<h2 id="installing-terraform">Installing Terraform</h2>

<h3 id="on-macos">On macOS:</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>brew tap hashicorp/tap
brew <span class="nb">install </span>hashicorp/tap/terraform
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="on-linux">On Linux:</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="nb">sudo </span>apt-get update <span class="o">&amp;&amp;</span> <span class="nb">sudo </span>apt-get <span class="nb">install</span> <span class="nt">-y</span> gnupg software-properties-common
wget <span class="nt">-O-</span> https://apt.releases.hashicorp.com/gpg | gpg <span class="nt">--dearmor</span> <span class="o">&gt;</span> hashicorp.gpg
<span class="nb">sudo install</span> <span class="nt">-o</span> root <span class="nt">-g</span> root <span class="nt">-m</span> 644 hashicorp.gpg /etc/apt/trusted.gpg.d/
<span class="nb">sudo </span>apt-add-repository <span class="s2">"deb [arch=amd64] https://apt.releases.hashicorp.com </span><span class="si">$(</span>lsb_release <span class="nt">-cs</span><span class="si">)</span><span class="s2"> main"</span>
<span class="nb">sudo </span>apt-get update <span class="o">&amp;&amp;</span> <span class="nb">sudo </span>apt-get <span class="nb">install </span>terraform
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="on-windows">On Windows:</h3>

<p>Download the binary from <a href="https://terraform.io/downloads">https://terraform.io/downloads</a> and add it to your system PATH.</p>

<hr />

<h2 id="writing-your-first-terraform-project">Writing Your First Terraform Project</h2>

<p>Let’s create a project from scratch.</p>

<h3 id="1-create-a-folder">1. Create a Folder</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="nb">mkdir </span>my-first-terraform
<span class="nb">cd </span>my-first-terraform
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="2-create-your-first-file-maintf">2. Create Your First File: <code class="language-plaintext highlighter-rouge">main.tf</code></h3>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="nx">provider</span> <span class="s2">"aws"</span> <span class="p">{</span>
  <span class="nx">region</span> <span class="o">=</span> <span class="s2">"us-east-1"</span>
<span class="p">}</span>

<span class="nx">resource</span> <span class="s2">"aws_instance"</span> <span class="s2">"my_ec2"</span> <span class="p">{</span>
  <span class="nx">ami</span>           <span class="o">=</span> <span class="s2">"ami-0c55b159cbfafe1f0"</span>
  <span class="nx">instance_type</span> <span class="o">=</span> <span class="s2">"t2.micro"</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<blockquote>
  <p>Replace the AMI ID with a valid one from your AWS region.</p>
</blockquote>

<h3 id="3-initialize-terraform">3. Initialize Terraform</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform init
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This downloads the AWS provider plugin.</p>

<h3 id="4-preview-the-plan">4. Preview the Plan</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform plan
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This shows what Terraform <em>would</em> do if you apply.</p>

<h3 id="5-apply-the-infrastructure">5. Apply the Infrastructure</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform apply
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Type <code class="language-plaintext highlighter-rouge">yes</code> when prompted.</p>

<p>Terraform will:</p>

<ul>
  <li>Create an EC2 instance</li>
  <li>Track it in the <code class="language-plaintext highlighter-rouge">terraform.tfstate</code> file</li>
</ul>

<hr />

<h2 id="adding-variables">Adding Variables</h2>

<p>Let’s refactor the code to make it more reusable.</p>

<h3 id="create-variablestf">Create <code class="language-plaintext highlighter-rouge">variables.tf</code></h3>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre><span class="nx">variable</span> <span class="s2">"region"</span> <span class="p">{</span>
  <span class="nx">default</span> <span class="o">=</span> <span class="s2">"us-east-1"</span>
<span class="p">}</span>

<span class="nx">variable</span> <span class="s2">"instance_type"</span> <span class="p">{</span>
  <span class="nx">default</span> <span class="o">=</span> <span class="s2">"t2.micro"</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="update-maintf">Update <code class="language-plaintext highlighter-rouge">main.tf</code></h3>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="nx">provider</span> <span class="s2">"aws"</span> <span class="p">{</span>
  <span class="nx">region</span> <span class="o">=</span> <span class="nx">var</span><span class="p">.</span><span class="nx">region</span>
<span class="p">}</span>

<span class="nx">resource</span> <span class="s2">"aws_instance"</span> <span class="s2">"my_ec2"</span> <span class="p">{</span>
  <span class="nx">ami</span>           <span class="o">=</span> <span class="s2">"ami-0c55b159cbfafe1f0"</span>
  <span class="nx">instance_type</span> <span class="o">=</span> <span class="nx">var</span><span class="p">.</span><span class="nx">instance_type</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Now you can override variables via:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform apply <span class="nt">-var</span><span class="o">=</span><span class="s2">"instance_type=t3.micro"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Or via <code class="language-plaintext highlighter-rouge">terraform.tfvars</code>.</p>

<hr />

<h2 id="output-the-ec2-ip-address">Output the EC2 IP Address</h2>

<p>Add an output:</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nx">output</span> <span class="s2">"ec2_ip"</span> <span class="p">{</span>
  <span class="nx">value</span> <span class="o">=</span> <span class="nx">aws_instance</span><span class="p">.</span><span class="nx">my_ec2</span><span class="p">.</span><span class="nx">public_ip</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Run <code class="language-plaintext highlighter-rouge">terraform apply</code> again and it will print the instance’s IP address.</p>

<hr />

<h2 id="destroying-infrastructure">Destroying Infrastructure</h2>

<p>When done, destroy everything created:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform destroy
</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="directory-structure">Directory Structure</h2>

<p>Here’s how a typical small project looks:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre>my-first-terraform/
├── main.tf
├── variables.tf
├── terraform.tfvars (optional)
├── outputs.tf
├── terraform.tfstate (generated)
</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="tips-and-best-practices">Tips and Best Practices</h2>

<ul>
  <li>Keep <strong>state files secure</strong> (use remote backends for teams)</li>
  <li>Use <strong>version control</strong> (Git) for your <code class="language-plaintext highlighter-rouge">.tf</code> files</li>
  <li>Group infrastructure into <strong>modules</strong> for reusability</li>
  <li>Don’t commit <code class="language-plaintext highlighter-rouge">.tfstate</code> or <code class="language-plaintext highlighter-rouge">.terraform/</code> directory</li>
  <li>Prefer <strong>Terraform Cloud</strong>, <strong>S3 backends</strong>, or <strong>Terraform Enterprise</strong> for collaboration</li>
</ul>

<hr />

<h2 id="where-to-go-from-here">Where to Go From Here</h2>

<p>Now that you can write and apply your own Terraform code:</p>

<ul>
  <li>Explore more AWS resources: S3 buckets, RDS databases, IAM roles</li>
  <li>Learn about <strong>Terraform modules</strong></li>
  <li>Try <strong>remote state</strong> and <strong>workspaces</strong></li>
  <li>Integrate with <strong>CI/CD pipelines</strong></li>
</ul>

<hr />

<h2 id="helpful-resources">Helpful Resources</h2>

<ul>
  <li><a href="https://developer.hashicorp.com/terraform/docs">Terraform Docs</a></li>
  <li><a href="https://learn.hashicorp.com/terraform">Learn Terraform - HashiCorp</a></li>
  <li><a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs">Terraform AWS Provider</a></li>
</ul>

<hr />

<h2 id="final-thoughts">Final Thoughts</h2>

<p>Terraform gives you <strong>control, automation, and repeatability</strong> for your infrastructure. By learning it early, you gain a foundational DevOps skill that applies across all cloud platforms and technologies.</p>

<p>Whether you’re deploying a single VM or orchestrating a multi-region Kubernetes cluster, Terraform is the glue that connects everything in code.</p>]]></content><author><name></name></author><category term="terraform" /><category term="devops" /><category term="infrastructure" /><category term="iac" /><summary type="html"><![CDATA[A complete introduction to Terraform — what it is, how it works, and how to write your own Terraform configurations]]></summary></entry><entry><title type="html">TLS Basics: Everything You Need to Know</title><link href="https://h-minn.github.io/posts/tls-basics/" rel="alternate" type="text/html" title="TLS Basics: Everything You Need to Know" /><published>2025-07-19T00:00:00+00:00</published><updated>2025-07-19T06:15:16+00:00</updated><id>https://h-minn.github.io/posts/tls-basics</id><content type="html" xml:base="https://h-minn.github.io/posts/tls-basics/"><![CDATA[<h1 id="tls-basics-everything-you-need-to-know">TLS Basics: Everything You Need to Know</h1>

<h2 id="what-is-tls">What Is TLS?</h2>

<p><strong>TLS (Transport Layer Security)</strong> is a cryptographic protocol used to provide secure communication over a computer network. It ensures that data transferred between two parties (typically a client and a server) is:</p>

<ul>
  <li><strong>Confidential</strong>: Only the intended recipient can read the data.</li>
  <li><strong>Authenticated</strong>: You know who you’re talking to.</li>
  <li><strong>Tamper-proof</strong>: The data hasn’t been altered in transit.</li>
</ul>

<p>TLS is the successor to SSL (Secure Sockets Layer), and most modern systems use TLS 1.2 or TLS 1.3.</p>

<hr />

<h2 id="why-tls-matters">Why TLS Matters</h2>

<p>Without TLS, data such as passwords, credit card numbers, or personal information sent over the internet could be intercepted and read by attackers. TLS prevents this by encrypting the data and verifying the identity of the communicating parties.</p>

<hr />

<h2 id="the-building-blocks-of-tls">The Building Blocks of TLS</h2>

<p>TLS is composed of several core components:</p>

<h3 id="1-encryption">1. <strong>Encryption</strong></h3>
<p>This hides the content of messages using algorithms like AES (Advanced Encryption Standard), so that third parties cannot understand the communication.</p>

<h3 id="2-authentication">2. <strong>Authentication</strong></h3>
<p>Authentication ensures that the parties are who they say they are, usually through <strong>digital certificates</strong> and <strong>public key infrastructure (PKI)</strong>.</p>

<h3 id="3-integrity">3. <strong>Integrity</strong></h3>
<p>TLS uses <strong>message authentication codes (MACs)</strong> to ensure data hasn’t been tampered with.</p>

<hr />

<h2 id="tls-handshake-step-by-step">TLS Handshake: Step-by-Step</h2>

<p>The TLS handshake is the process that sets up the secure connection. Let’s go through it in <strong>TLS 1.2</strong>, then briefly touch on <strong>TLS 1.3</strong>, which simplifies some parts.</p>

<h3 id="step-1-client-hello">Step 1: Client Hello</h3>
<ul>
  <li>The client (browser) sends a <strong>ClientHello</strong> message to the server.</li>
  <li>It includes:
    <ul>
      <li>TLS version</li>
      <li>Supported cipher suites</li>
      <li>Random number (client_random)</li>
      <li>Session ID (optional)</li>
      <li>Supported compression methods</li>
    </ul>
  </li>
</ul>

<h3 id="step-2-server-hello">Step 2: Server Hello</h3>
<ul>
  <li>The server responds with a <strong>ServerHello</strong> message.</li>
  <li>It includes:
    <ul>
      <li>Selected TLS version and cipher suite</li>
      <li>Another random number (server_random)</li>
      <li>Server’s digital certificate (X.509)</li>
      <li>Optional: Session ID, parameters for key exchange</li>
    </ul>
  </li>
</ul>

<h3 id="step-3-certificate-validation">Step 3: Certificate Validation</h3>
<ul>
  <li>The client validates the server’s certificate by:
    <ul>
      <li>Verifying the certificate chain (up to a trusted root CA)</li>
      <li>Ensuring the certificate hasn’t expired or been revoked</li>
      <li>Checking the domain name</li>
    </ul>
  </li>
</ul>

<h3 id="step-4-key-exchange">Step 4: Key Exchange</h3>
<p>Depending on the cipher suite used, key exchange can happen using:</p>
<ul>
  <li><strong>RSA</strong> (now discouraged)</li>
  <li><strong>Diffie-Hellman</strong> (DH or ECDH)</li>
  <li><strong>Ephemeral Diffie-Hellman</strong> (DHE/ECDHE) for <strong>forward secrecy</strong></li>
</ul>

<h3 id="step-5-pre-master-secret-and-key-derivation">Step 5: Pre-Master Secret and Key Derivation</h3>
<ul>
  <li>The client and server compute a shared <strong>pre-master secret</strong>.</li>
  <li>They use the pre-master secret, along with the two random values (client_random and server_random), to derive:
    <ul>
      <li>Session keys for encryption</li>
      <li>MAC keys for integrity</li>
    </ul>
  </li>
</ul>

<h3 id="step-6-finished-messages">Step 6: Finished Messages</h3>
<ul>
  <li>Both sides send a <strong>Finished</strong> message encrypted with the newly established session key.</li>
  <li>This confirms that all further communication will be encrypted.</li>
</ul>

<hr />

<h2 id="tls-13-whats-new">TLS 1.3: What’s New?</h2>

<p>TLS 1.3 simplifies the handshake:</p>
<ul>
  <li>Removes support for outdated algorithms (e.g., RSA key exchange, static DH)</li>
  <li>Encrypts more of the handshake earlier</li>
  <li>Reduces the number of round trips:
    <ul>
      <li>A full handshake can be done in 1 round trip</li>
      <li>Supports 0-RTT for resumed sessions (with caveats)</li>
    </ul>
  </li>
</ul>

<p>Key differences:</p>
<ul>
  <li>No more MACs: uses AEAD (Authenticated Encryption with Associated Data)</li>
  <li>Key exchange is always ephemeral (forward secrecy by default)</li>
  <li>No support for renegotiation</li>
</ul>

<hr />

<h2 id="cipher-suites">Cipher Suites</h2>

<p>A cipher suite is a named set of algorithms used to:</p>
<ol>
  <li>Exchange keys</li>
  <li>Encrypt data</li>
  <li>Ensure data integrity</li>
</ol>

<p>Example (TLS 1.2):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
TLS\_ECDHE\_RSA\_WITH\_AES\_256\_GCM\_SHA384

</pre></td></tr></tbody></table></code></pre></div></div>

<p>Breakdown:</p>
<ul>
  <li><strong>ECDHE</strong>: Ephemeral Elliptic Curve Diffie-Hellman (key exchange)</li>
  <li><strong>RSA</strong>: For authentication (server certificate)</li>
  <li><strong>AES_256_GCM</strong>: Symmetric encryption algorithm</li>
  <li><strong>SHA384</strong>: For MAC and PRF (pseudorandom function)</li>
</ul>

<p>In <strong>TLS 1.3</strong>, cipher suites are simpler, e.g.:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
TLS\_AES\_128\_GCM\_SHA256

</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="certificates-and-pki">Certificates and PKI</h2>

<h3 id="what-is-a-certificate">What Is a Certificate?</h3>

<p>A <strong>digital certificate</strong> (e.g., an X.509 certificate) contains:</p>
<ul>
  <li>A public key</li>
  <li>Information about the entity (domain name, organization, etc.)</li>
  <li>Issuer (CA)</li>
  <li>Signature from the CA</li>
</ul>

<h3 id="role-of-certificate-authorities-cas">Role of Certificate Authorities (CAs)</h3>

<p>A <strong>Certificate Authority</strong> signs certificates to vouch for the identity of the subject. Browsers trust a list of CAs. If a certificate is signed by a trusted CA, it is accepted as valid.</p>

<hr />

<h2 id="forward-secrecy">Forward Secrecy</h2>

<p><strong>Forward Secrecy</strong> ensures that even if the server’s private key is compromised later, past sessions remain secure. This is achieved by using <strong>ephemeral key exchanges</strong> (like ECDHE) which generate unique session keys per connection.</p>

<hr />

<h2 id="session-resumption">Session Resumption</h2>

<p>TLS supports <strong>resuming sessions</strong> to avoid full handshakes:</p>
<ul>
  <li><strong>Session IDs</strong> (older method)</li>
  <li><strong>Session Tickets</strong> (TLS 1.2)</li>
  <li><strong>0-RTT Resumption</strong> (TLS 1.3): Faster but vulnerable to replay attacks</li>
</ul>

<hr />

<h2 id="tls-in-action">TLS in Action</h2>

<h3 id="https">HTTPS</h3>

<p>When you see <code class="language-plaintext highlighter-rouge">https://</code> in your browser, TLS is in use over HTTP.</p>

<h3 id="tls-in-email-vpn-and-more">TLS in Email, VPN, and More</h3>

<p>TLS isn’t just for web traffic:</p>
<ul>
  <li><strong>SMTP, IMAP, POP3</strong> can use TLS (STARTTLS)</li>
  <li><strong>VPNs</strong> like OpenVPN use TLS for key exchange</li>
  <li><strong>VoIP</strong>, messaging apps, etc., also rely on TLS</li>
</ul>

<hr />

<h2 id="common-tls-attacks-and-defenses">Common TLS Attacks and Defenses</h2>

<table>
  <thead>
    <tr>
      <th>Attack</th>
      <th>Description</th>
      <th>Defense</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Downgrade Attack</td>
      <td>Forcing a connection to a weaker protocol</td>
      <td>Disable SSLv2/3, use TLS 1.2+</td>
    </tr>
    <tr>
      <td>MITM</td>
      <td>Intercepting communication</td>
      <td>Certificate validation, HSTS</td>
    </tr>
    <tr>
      <td>BEAST, CRIME, POODLE</td>
      <td>Exploit old protocols</td>
      <td>Disable SSL, use TLS 1.2+</td>
    </tr>
    <tr>
      <td>Certificate Forgery</td>
      <td>Fake certificates</td>
      <td>Certificate pinning, CT logs</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="best-practices">Best Practices</h2>

<ul>
  <li>Use <strong>TLS 1.3</strong> or at least <strong>TLS 1.2</strong></li>
  <li>Enforce <strong>HTTPS</strong> with <strong>HSTS</strong></li>
  <li>Obtain certificates from trusted CAs (e.g., Let’s Encrypt)</li>
  <li>Regularly rotate certificates and keys</li>
  <li>Disable weak ciphers and protocols</li>
  <li>Implement <strong>OCSP Stapling</strong> and monitor for revocation</li>
</ul>

<hr />

<h2 id="conclusion">Conclusion</h2>

<p>TLS is foundational to modern internet security. From initial handshake to encrypted communication, understanding TLS helps developers, sysadmins, and security professionals ensure privacy and integrity across the web. As the protocol evolves, best practices must be kept up-to-date to stay protected.</p>

<hr />

<h2 id="further-reading">Further Reading</h2>

<ul>
  <li><a href="https://datatracker.ietf.org/doc/html/rfc8446">RFC 8446 – TLS 1.3 Specification</a></li>
  <li><a href="https://infosec.mozilla.org/guidelines/web_security">Mozilla TLS Guidelines</a></li>
  <li><a href="https://www.ssllabs.com/ssltest/">SSL Labs Server Test</a></li>
  <li><a href="https://www.internetsociety.org/deploy360/tls/basics/">TLS Basics by Internet Society</a></li>
</ul>

<hr />]]></content><author><name></name></author><category term="security" /><category term="tls" /><category term="encryption" /><category term="web" /><summary type="html"><![CDATA[A technical guide to understanding TLS from the ground up]]></summary></entry><entry><title type="html">Dive Deeper into TLS: Understanding TLS Certificates and Secure Communication</title><link href="https://h-minn.github.io/posts/tls-in-depth/" rel="alternate" type="text/html" title="Dive Deeper into TLS: Understanding TLS Certificates and Secure Communication" /><published>2025-07-19T00:00:00+00:00</published><updated>2025-07-19T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/tls-in-depth</id><content type="html" xml:base="https://h-minn.github.io/posts/tls-in-depth/"><![CDATA[<h1 id="understanding-tls-certificates-and-secure-communication">Understanding TLS Certificates and Secure Communication</h1>

<p>In this post, we’ll cover the absolute basics of <strong>TLS certificates</strong>, why you need them, and how they can be used to secure communication over SSH or web servers. Whether you’re new to security or brushing up on the fundamentals, this guide will walk you through each concept clearly and from the ground up.</p>

<hr />

<h2 id="what-is-a-tls-certificate">What is a TLS Certificate?</h2>

<p>A <strong>TLS certificate</strong> is used to establish <strong>trust</strong> between two parties during a network transaction. When a client (like a browser) connects to a web server, TLS certificates:</p>

<ul>
  <li><strong>Encrypt communication</strong> between client and server</li>
  <li><strong>Authenticate</strong> that the server is legitimate</li>
</ul>

<hr />

<h2 id="why-is-encryption-necessary">Why is Encryption Necessary?</h2>

<p>Let’s look at an example.</p>

<p>Imagine a user accessing their online banking site over an <strong>unsecured connection</strong>. Any credentials typed in (like username and password) would be sent in <strong>plain text</strong> over the network. A hacker sniffing the network could easily read these credentials and access the user’s account.</p>

<p>To prevent this, we need <strong>encryption</strong>.</p>

<hr />

<h2 id="what-is-encryption">What is Encryption?</h2>

<p>Encryption converts readable data into an unreadable format using a <strong>key</strong>. Only someone with the correct key can decrypt and understand the message.</p>

<p>The process involves:</p>
<ul>
  <li><strong>Encrypting</strong> data before transmission</li>
  <li><strong>Decrypting</strong> it on the receiving end using a key</li>
</ul>

<p>However, there’s more than one way to do this.</p>

<hr />

<h2 id="symmetric-encryption">Symmetric Encryption</h2>

<p>With <strong>symmetric encryption</strong>, the <strong>same key</strong> is used to both encrypt and decrypt the data.</p>

<ul>
  <li>The client encrypts data with a key</li>
  <li>The key must also be sent to the server to decrypt it</li>
</ul>

<h3 id="problem">Problem:</h3>
<p>The key itself is sent over the same network, making it vulnerable to interception. If an attacker gets the key, they can decrypt all messages.</p>

<hr />

<h2 id="asymmetric-encryption">Asymmetric Encryption</h2>

<p><strong>Asymmetric encryption</strong> uses two keys:</p>
<ul>
  <li>A <strong>public key</strong> (shared openly)</li>
  <li>A <strong>private key</strong> (kept secret)</li>
</ul>

<p>You encrypt data using the <strong>public key</strong>, but it can only be decrypted using the <strong>corresponding private key</strong>.</p>

<p>This way:</p>
<ul>
  <li>The server keeps the private key safe</li>
  <li>The client encrypts a message with the public key</li>
  <li>Only the server can decrypt it</li>
</ul>

<hr />

<h2 id="real-world-example-ssh-access-using-key-pairs">Real-World Example: SSH Access Using Key Pairs</h2>

<ol>
  <li>A user generates a <strong>public/private key pair</strong> using:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>ssh-keygen
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>The private key (<code class="language-plaintext highlighter-rouge">id_rsa</code>) stays on their machine.</li>
  <li>The public key (<code class="language-plaintext highlighter-rouge">id_rsa.pub</code>) is added to the server’s <code class="language-plaintext highlighter-rouge">~/.ssh/authorized_keys</code> file.</li>
  <li>Only users with the private key can access the server.</li>
</ol>

<p>You can copy the same public key to multiple servers and use your private key to securely connect to all of them.</p>

<p>Other users can generate their own key pairs and have their public keys added to the server.</p>

<hr />

<h2 id="https-and-tls-in-web-communication">HTTPS and TLS in Web Communication</h2>

<p>Let’s return to our web server example. How does TLS help?</p>

<h3 id="problem-1">Problem:</h3>

<p>If we use <strong>symmetric encryption</strong> alone, we must transmit the symmetric key over the network. A hacker could intercept it.</p>

<h3 id="solution">Solution:</h3>

<p>Use <strong>asymmetric encryption</strong> to <strong>securely exchange the symmetric key</strong>.</p>

<h3 id="how-it-works">How It Works:</h3>

<ol>
  <li>The server generates a <strong>public/private key pair</strong>.</li>
  <li>
    <p>When the client connects via <code class="language-plaintext highlighter-rouge">https://</code>, the server sends:</p>

    <ul>
      <li>Its <strong>public key</strong></li>
      <li>In a <strong>certificate</strong> that includes details like domain name, issuer, etc.</li>
    </ul>
  </li>
  <li>
    <p>The client (browser) uses the public key to:</p>

    <ul>
      <li><strong>Encrypt a symmetric key</strong></li>
      <li>Send the encrypted key to the server</li>
    </ul>
  </li>
  <li>The server decrypts the symmetric key with its private key.</li>
</ol>

<p>Now both sides share a symmetric key for efficient encrypted communication.</p>

<hr />

<h2 id="the-role-of-certificates">The Role of Certificates</h2>

<p>The <strong>TLS certificate</strong> sent by the server contains:</p>

<ul>
  <li>The <strong>public key</strong></li>
  <li>The <strong>domain name</strong></li>
  <li>The <strong>issuer’s identity</strong> (who signed it)</li>
</ul>

<p>Anyone can generate a certificate. But how do we verify it’s legitimate?</p>

<hr />

<h2 id="fake-certificates-and-the-role-of-cas">Fake Certificates and the Role of CAs</h2>

<p>A hacker could:</p>

<ul>
  <li>Create a fake version of a banking website</li>
  <li>Generate their own key pair</li>
  <li>Present a fake certificate</li>
</ul>

<p>Your browser may encrypt data and communicate securely — with the <strong>hacker’s server</strong>.</p>

<p>This is why <strong>certificate validation</strong> is crucial.</p>

<h3 id="the-solution">The Solution:</h3>

<ul>
  <li>Use a <strong>Certificate Authority (CA)</strong> to <strong>sign</strong> your certificate</li>
  <li>Browsers trust certificates <strong>signed by trusted CAs</strong></li>
</ul>

<h3 id="how-to-get-a-legitimate-certificate">How to Get a Legitimate Certificate:</h3>

<ol>
  <li>
    <p>Generate a <strong>Certificate Signing Request (CSR)</strong>:</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>openssl req <span class="nt">-new</span> <span class="nt">-key</span> server.key <span class="nt">-out</span> server.csr
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>Send the CSR to a <strong>CA</strong> like DigiCert or Let’s Encrypt</li>
  <li>The CA validates your identity</li>
  <li>The CA signs your certificate using its <strong>private key</strong></li>
  <li>The certificate is returned to you and installed on your server</li>
</ol>

<p>Browsers have the <strong>CA’s public keys</strong> built-in and can verify the certificate.</p>

<hr />

<h2 id="how-browsers-trust-certificates">How Browsers Trust Certificates</h2>

<ul>
  <li>All major browsers maintain a <strong>list of trusted CAs</strong></li>
  <li>
    <p>When a browser receives a certificate:</p>

    <ul>
      <li>It checks that it was <strong>signed by a trusted CA</strong></li>
      <li>It uses the CA’s <strong>public key</strong> to verify the signature</li>
      <li>If it passes validation, the connection proceeds</li>
    </ul>
  </li>
</ul>

<p>This process ensures that users are truly communicating with the <strong>intended server</strong>, not a malicious one.</p>

<hr />

<h2 id="private-cas-and-internal-websites">Private CAs and Internal Websites</h2>

<p>Public CAs don’t help with <strong>internal applications</strong> (e.g., company intranet, payroll portals).</p>

<p>For this, you can run your own <strong>Private CA</strong>:</p>

<ul>
  <li>Install the CA’s public key in your organization’s browsers</li>
  <li>Use it to issue certificates for internal apps</li>
</ul>

<hr />

<h2 id="summary-how-tls-works">Summary: How TLS Works</h2>

<ol>
  <li>
    <p><strong>Server</strong>:</p>

    <ul>
      <li>Generates a public/private key pair</li>
      <li>Requests a certificate from a trusted CA</li>
    </ul>
  </li>
  <li>
    <p><strong>CA</strong>:</p>

    <ul>
      <li>Validates the request</li>
      <li>Signs the certificate with its private key</li>
    </ul>
  </li>
  <li>
    <p><strong>Client</strong>:</p>

    <ul>
      <li>Receives the certificate</li>
      <li>Uses the CA’s public key to validate the certificate</li>
      <li>Extracts the server’s public key</li>
      <li>Generates a <strong>symmetric key</strong></li>
      <li>Encrypts it with the <strong>server’s public key</strong></li>
    </ul>
  </li>
  <li>
    <p><strong>Server</strong>:</p>

    <ul>
      <li>Decrypts the symmetric key using its <strong>private key</strong></li>
      <li>Now both client and server share the same symmetric key</li>
      <li>All further communication is encrypted using symmetric encryption</li>
    </ul>
  </li>
</ol>

<hr />

<h2 id="client-certificates-mutual-tls">Client Certificates (Mutual TLS)</h2>

<p>While servers present certificates to clients, sometimes <strong>clients must also present certificates</strong> to prove their identity.</p>

<p>This is called <strong>Mutual TLS</strong>.</p>

<ul>
  <li>The client generates a key pair and gets their certificate signed by a trusted CA</li>
  <li>The client presents the certificate during the handshake</li>
  <li>The server validates the client just as the client validates the server</li>
</ul>

<p>Most websites don’t require this, but it’s common in <strong>enterprise environments</strong> or <strong>API authentication</strong>.</p>

<hr />

<h2 id="what-is-pki">What is PKI?</h2>

<p><strong>Public Key Infrastructure (PKI)</strong> is the ecosystem that supports:</p>

<ul>
  <li>Certificate Authorities</li>
  <li>Certificates</li>
  <li>Key generation and management</li>
  <li>Validation and revocation processes</li>
</ul>

<p>It ensures trust and security in digital communication.</p>

<hr />

<h2 id="naming-conventions">Naming Conventions</h2>

<table>
  <thead>
    <tr>
      <th>File Type</th>
      <th>Description</th>
      <th>Example</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">.key</code></td>
      <td>Private key</td>
      <td><code class="language-plaintext highlighter-rouge">server.key</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">.crt</code>, <code class="language-plaintext highlighter-rouge">.pem</code></td>
      <td>Certificate with public key</td>
      <td><code class="language-plaintext highlighter-rouge">server.crt</code>, <code class="language-plaintext highlighter-rouge">client.pem</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">.csr</code></td>
      <td>Certificate Signing Request</td>
      <td><code class="language-plaintext highlighter-rouge">mydomain.csr</code></td>
    </tr>
  </tbody>
</table>

<blockquote>
  <p>A file with the word <code class="language-plaintext highlighter-rouge">key</code> in its name or extension is a private key.
If it does not include <code class="language-plaintext highlighter-rouge">key</code>, it’s usually a public certificate.</p>
</blockquote>

<hr />

<h2 id="final-notes">Final Notes</h2>

<ul>
  <li>Asymmetric encryption <strong>secures the key exchange</strong></li>
  <li>Symmetric encryption <strong>secures the data transfer</strong></li>
  <li>Certificates <strong>validate identity</strong></li>
  <li>CAs <strong>sign certificates</strong> to establish trust</li>
  <li>Browsers <strong>verify certificates</strong> using trusted root keys</li>
  <li>PKI <strong>manages the entire ecosystem</strong></li>
</ul>

<p>With this setup, TLS protects the integrity, confidentiality, and authenticity of web communications.</p>

<hr />

<p>Thank you for reading.</p>]]></content><author><name></name></author><category term="security" /><category term="tls" /><category term="certificates" /><category term="encryption" /><category term="web" /><summary type="html"><![CDATA[A complete beginner-friendly guide to TLS certificates, encryption, SSH, HTTPS, and public key infrastructure]]></summary></entry><entry><title type="html">Precision vs. Recall: Understanding the Basics for Machine Learning Beginners</title><link href="https://h-minn.github.io/posts/ml-precision-vs-recall/" rel="alternate" type="text/html" title="Precision vs. Recall: Understanding the Basics for Machine Learning Beginners" /><published>2025-07-06T00:00:00+00:00</published><updated>2025-07-06T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/ml-precision-vs-recall</id><content type="html" xml:base="https://h-minn.github.io/posts/ml-precision-vs-recall/"><![CDATA[<h1 id="precision-vs-recall--a-beginners-guide">Precision vs. Recall — A Beginner’s Guide</h1>

<p>When you’re starting your machine learning journey, you’ll quickly run into two key evaluation metrics: <strong>precision</strong> and <strong>recall</strong>.</p>

<p>But what do they really mean? And when should you care more about one than the other?</p>

<p>Let’s break it down in simple terms.</p>

<hr />

<h2 id="-imagine-a-real-world-problem-spam-email-detection">📬 Imagine a Real-World Problem: Spam Email Detection</h2>

<p>You’re building a model that predicts whether an email is <strong>spam</strong> or <strong>not spam</strong>.</p>

<p>The model can make four types of decisions:</p>

<table>
  <thead>
    <tr>
      <th>Prediction</th>
      <th>Actual</th>
      <th>Result</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Spam</td>
      <td>Spam</td>
      <td>✅ True Positive (TP)</td>
    </tr>
    <tr>
      <td>Spam</td>
      <td>Not Spam</td>
      <td>❌ False Positive (FP)</td>
    </tr>
    <tr>
      <td>Not Spam</td>
      <td>Spam</td>
      <td>❌ False Negative (FN)</td>
    </tr>
    <tr>
      <td>Not Spam</td>
      <td>Not Spam</td>
      <td>✅ True Negative (TN)</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-what-is-precision">🔍 What is Precision?</h2>

<blockquote>
  <p><strong>Precision</strong> tells you how many of the items your model said were “positive” (e.g., spam) are actually positive.</p>
</blockquote>

<p><strong>Formula:</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
Precision = True Positives / (True Positives + False Positives)

</pre></td></tr></tbody></table></code></pre></div></div>

<p><strong>Example:</strong><br />
Your model predicted 100 emails as spam.<br />
Only 60 were truly spam.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
Precision = 60 / 100 = 0.60 (60%)

</pre></td></tr></tbody></table></code></pre></div></div>

<p>✅ A <strong>high precision</strong> means the model rarely marks a good email as spam.</p>

<hr />

<h2 id="-what-is-recall">🎯 What is Recall?</h2>

<blockquote>
  <p><strong>Recall</strong> tells you how many of the actual positives your model successfully found.</p>
</blockquote>

<p><strong>Formula:</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
Recall = True Positives / (True Positives + False Negatives)

</pre></td></tr></tbody></table></code></pre></div></div>

<p><strong>Example:</strong><br />
There are 80 actual spam emails.<br />
Your model correctly found 60.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>
Recall = 60 / 80 = 0.75 (75%)

</pre></td></tr></tbody></table></code></pre></div></div>

<p>✅ A <strong>high recall</strong> means the model finds most of the spam — it <strong>doesn’t miss much</strong>.</p>

<hr />

<h2 id="️-precision-vs-recall-when-to-focus-on-which">⚖️ Precision vs. Recall: When to Focus on Which?</h2>

<table>
  <thead>
    <tr>
      <th>Scenario</th>
      <th>Focus On</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>You <strong>can’t afford to miss</strong> a positive case (e.g., disease, fraud)</td>
      <td>🟢 Recall</td>
    </tr>
    <tr>
      <td>You <strong>can’t afford false alarms</strong> (e.g., marking legit emails as spam)</td>
      <td>🔵 Precision</td>
    </tr>
    <tr>
      <td>You want a <strong>balance</strong> between the two</td>
      <td>⚖️ F1 Score</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-tldr-summary">💡 TL;DR Summary</h2>

<table>
  <thead>
    <tr>
      <th>Metric</th>
      <th>Measures</th>
      <th>Goal</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Precision</td>
      <td>Correctness of positive guesses</td>
      <td>Avoid false positives</td>
    </tr>
    <tr>
      <td>Recall</td>
      <td>Coverage of actual positives</td>
      <td>Avoid false negatives</td>
    </tr>
  </tbody>
</table>

<p>Both metrics are crucial — but depending on your use case, <strong>one will usually matter more</strong>.</p>

<hr />

<p><em>Happy learning!</em> 🚀</p>

<hr />]]></content><author><name></name></author><category term="machine-learning" /><category term="basics" /><category term="precision" /><category term="recall" /><category term="classification" /><category term="ml-metrics" /><category term="beginners" /><summary type="html"><![CDATA[Learn the difference between precision and recall using simple examples. A beginner-friendly guide to essential ML evaluation metrics.]]></summary></entry><entry><title type="html">Bash vs Zsh: What’s the Difference? Why Developers Love Zsh (and When to Avoid It)</title><link href="https://h-minn.github.io/posts/en-bash-vs-zsh/" rel="alternate" type="text/html" title="Bash vs Zsh: What’s the Difference? Why Developers Love Zsh (and When to Avoid It)" /><published>2025-06-07T00:00:00+00:00</published><updated>2025-06-07T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/en-bash-vs-zsh</id><content type="html" xml:base="https://h-minn.github.io/posts/en-bash-vs-zsh/"><![CDATA[<p>Starting with macOS Catalina, Apple changed the default shell from <strong>Bash</strong> to <strong>Zsh</strong>. Since then, many developers have wondered: <em>What’s the difference between Bash and Zsh?</em> and <em>Should I switch?</em></p>

<p>In this post, we’ll explore the <strong>key differences</strong>, <strong>what makes Zsh awesome</strong>, and also <strong>why it might not be perfect for everyone</strong>.</p>

<hr />

<h2 id="-what-is-bash">🐚 What Is Bash?</h2>

<p><strong>Bash</strong> (Bourne Again SHell) is a Unix shell developed by the GNU Project. It’s been the default shell on most Linux systems for decades and was also the default on macOS until 2019.</p>

<p>Key strengths:</p>

<ul>
  <li>Lightweight and stable</li>
  <li>POSIX-compliant scripting</li>
  <li>Universally supported, even on older servers</li>
</ul>

<hr />

<h2 id="-what-is-zsh">⚡ What Is Zsh?</h2>

<p><strong>Zsh</strong> (Z Shell) is a modern shell that builds on the traditional Bourne shell (sh), adding powerful features for usability, customization, and productivity.</p>

<p>Zsh became the <strong>default shell in macOS Catalina (2019)</strong> and is increasingly popular among developers.</p>

<hr />

<h2 id="-bash-vs-zsh-whats-the-difference">🔍 Bash vs Zsh: What’s the Difference?</h2>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Bash</th>
      <th>Zsh</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Auto-completion</td>
      <td>Basic</td>
      <td>Smart contextual suggestions</td>
    </tr>
    <tr>
      <td>Theme customization</td>
      <td>Minimal</td>
      <td>Full theme support via <code class="language-plaintext highlighter-rouge">oh-my-zsh</code></td>
    </tr>
    <tr>
      <td>Plugin support</td>
      <td>Requires manual setup</td>
      <td>Rich plugin system</td>
    </tr>
    <tr>
      <td>Scripting features</td>
      <td>POSIX standard</td>
      <td>More powerful arrays, globbing</td>
    </tr>
    <tr>
      <td>Setup simplicity</td>
      <td>Simple defaults</td>
      <td>Needs some initial customization</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-what-zsh-can-do-that-bash-struggles-with">✨ What Zsh Can Do (That Bash Struggles With)</h2>

<h3 id="-smarter-autocompletion">✅ Smarter Autocompletion</h3>

<p>Zsh offers rich autocompletion:</p>
<ul>
  <li>Supports commands like <code class="language-plaintext highlighter-rouge">git</code>, <code class="language-plaintext highlighter-rouge">docker</code>, <code class="language-plaintext highlighter-rouge">kubectl</code> with subcommands and options.</li>
  <li>Tab-completion suggests files, flags, even paths with typos.</li>
</ul>

<h3 id="-syntax-highlighting">✅ Syntax Highlighting</h3>

<ul>
  <li>With plugins like <code class="language-plaintext highlighter-rouge">zsh-syntax-highlighting</code>, you get real-time color feedback while typing.</li>
</ul>

<h3 id="-autosuggestions">✅ Autosuggestions</h3>

<ul>
  <li>With <code class="language-plaintext highlighter-rouge">zsh-autosuggestions</code>, Zsh predicts the next command based on history.</li>
</ul>

<h3 id="-flexible-globbing">✅ Flexible Globbing</h3>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="nb">ls</span> <span class="k">**</span>/<span class="k">*</span>.md
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This lists all Markdown files recursively — something not native in Bash.</p>

<h3 id="-customizable-prompt-themes">✅ Customizable Prompt Themes</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="c"># Set in ~/.zshrc</span>
<span class="nv">ZSH_THEME</span><span class="o">=</span><span class="s2">"agnoster"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Git branch, command status, and timers can be shown in your prompt.</p>

<hr />

<h2 id="️-why-developers-love-zsh">❤️ Why Developers Love Zsh</h2>

<ul>
  <li><strong>Faster workflows</strong>: Tab and history suggestions reduce keystrokes</li>
  <li><strong>Eye-friendly UI</strong>: Syntax colors and customizable themes</li>
  <li><strong>Highly extensible</strong>: Plugins for Git, Docker, AWS, fzf, etc.</li>
  <li><strong>Mac-friendly</strong>: Pre-installed and supported by default since macOS Catalina</li>
</ul>

<hr />

<h2 id="️-downsides-of-zsh">⚠️ Downsides of Zsh</h2>

<table>
  <thead>
    <tr>
      <th>Weakness</th>
      <th>Explanation</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Initial config setup</td>
      <td>Takes time to customize themes and plugins</td>
    </tr>
    <tr>
      <td>Script compatibility issues</td>
      <td>Bash scripts may not always run properly in Zsh</td>
    </tr>
    <tr>
      <td>Slight learning curve</td>
      <td>Power features come with some complexity</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-so-should-you-use-zsh-or-bash">🤔 So… Should You Use Zsh or Bash?</h2>

<table>
  <thead>
    <tr>
      <th>Use Bash if…</th>
      <th>Use Zsh if…</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>You write POSIX-compatible scripts</td>
      <td>You want a more modern, productive shell</td>
    </tr>
    <tr>
      <td>You work on legacy Linux systems</td>
      <td>You use macOS or work in modern dev tools</td>
    </tr>
    <tr>
      <td>You prefer simplicity over features</td>
      <td>You want rich suggestions and themes</td>
    </tr>
  </tbody>
</table>

<hr />

<p>Zsh is a modern, productivity-focused shell that significantly improves the CLI experience. If you haven’t tried it yet, now might be the perfect time to give your terminal superpowers.</p>]]></content><author><name></name></author><category term="shell" /><category term="bash" /><category term="zsh" /><category term="terminal" /><category term="bash" /><category term="zsh" /><category term="terminal" /><category term="shell" /><category term="linux" /><category term="mac" /><summary type="html"><![CDATA[Starting with macOS Catalina, Apple changed the default shell from Bash to Zsh. Since then, many developers have wondered: What’s the difference between Bash and Zsh? and Should I switch?]]></summary></entry><entry><title type="html">BashとZshの違いとは？Zshの魅力と注意点も含めて徹底解説</title><link href="https://h-minn.github.io/posts/jp-bash-vs-zsh/" rel="alternate" type="text/html" title="BashとZshの違いとは？Zshの魅力と注意点も含めて徹底解説" /><published>2025-06-07T00:00:00+00:00</published><updated>2025-06-07T00:00:00+00:00</updated><id>https://h-minn.github.io/posts/jp-bash-vs-zsh</id><content type="html" xml:base="https://h-minn.github.io/posts/jp-bash-vs-zsh/"><![CDATA[<p>macOS Catalina以降、Appleはデフォルトのシェルを<strong>Bash</strong>から<strong>Zsh</strong>に変更しました。それ以来、多くの開発者が「ZshってBashと何が違うの？」と感じるようになりました。</p>

<p>この記事では、<strong>BashとZshの違い</strong>に加えて、Zshの魅力、できること、そして意外な短所についてもわかりやすく紹介します。</p>

<hr />

<h2 id="-bashとは">🐚 Bashとは？</h2>

<p>Bash（Bourne Again SHell）は、GNUプロジェクトによって開発されたUnix系シェルで、Linuxや旧macOSで長らく標準となっていた実績あるシェルです。</p>

<ul>
  <li>軽量で安定</li>
  <li>スクリプト互換性が高い（POSIX準拠）</li>
  <li>古い環境でも動作</li>
</ul>

<hr />

<h2 id="-zshとは">⚡ Zshとは？</h2>

<p>Zsh（Z Shell）は、sh系のシェルをベースに<strong>モダンで高機能な拡張</strong>を多数取り込んだ人気のシェルです。</p>

<p>macOS Catalina（2019年）以降のmacOSでは<strong>標準シェル</strong>として採用されました。</p>

<hr />

<h2 id="-bashとzshの違い">🔍 BashとZshの違い</h2>

<table>
  <thead>
    <tr>
      <th>項目</th>
      <th>Bash</th>
      <th>Zsh</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>補完</td>
      <td>基本的</td>
      <td>スマート補完（gitなど対応）</td>
    </tr>
    <tr>
      <td>テーマサポート</td>
      <td>ほぼなし</td>
      <td><code class="language-plaintext highlighter-rouge">oh-my-zsh</code>で豊富にサポート</td>
    </tr>
    <tr>
      <td>プラグイン管理</td>
      <td>外部ツールが必要</td>
      <td><code class="language-plaintext highlighter-rouge">zinit</code>や<code class="language-plaintext highlighter-rouge">oh-my-zsh</code>で簡単</td>
    </tr>
    <tr>
      <td>配列/構文の柔軟性</td>
      <td>標準的</td>
      <td>より柔軟で多機能</td>
    </tr>
    <tr>
      <td>初期設定の手軽さ</td>
      <td>デフォルトで使いやすい</td>
      <td>機能豊富だがやや設定が必要</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-zshの主な特徴できること">✨ Zshの主な特徴・できること</h2>

<h3 id="-強力な補完システム">✅ 強力な補完システム</h3>

<ul>
  <li>サブコマンドやオプションの<strong>文脈補完</strong>が可能</li>
  <li><code class="language-plaintext highlighter-rouge">git</code>, <code class="language-plaintext highlighter-rouge">docker</code>, <code class="language-plaintext highlighter-rouge">kubectl</code>など多くのCLIツールと連携</li>
</ul>

<h3 id="-構文のハイライト">✅ 構文のハイライト</h3>

<ul>
  <li>入力中に<strong>コマンドの色付け</strong>が可能（<code class="language-plaintext highlighter-rouge">zsh-syntax-highlighting</code>）</li>
</ul>

<h3 id="-自動サジェスト">✅ 自動サジェスト</h3>

<ul>
  <li>履歴から<strong>自動的に次の入力を予測</strong></li>
  <li><code class="language-plaintext highlighter-rouge">zsh-autosuggestions</code>プラグインで強化</li>
</ul>

<h3 id="-パス補完の強化">✅ パス補完の強化</h3>

<ul>
  <li>タイポにも対応した補完</li>
  <li>ディレクトリ履歴を使った素早い移動</li>
</ul>

<h3 id="-スマートなグロブワイルドカード展開">✅ スマートなグロブ（ワイルドカード展開）</h3>

<div class="language-zsh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="nb">ls</span> <span class="k">**</span>/<span class="k">*</span>.md
</pre></td></tr></tbody></table></code></pre></div></div>

<p>→ サブディレクトリ含む全Markdownファイルを一覧</p>

<h3 id="-簡単にテーマ見た目を変更可能">✅ 簡単にテーマ・見た目を変更可能</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="c"># oh-my-zshでテーマを変更</span>
<span class="nv">ZSH_THEME</span><span class="o">=</span><span class="s2">"agnoster"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="️-zshの魅力">❤️ Zshの魅力</h2>

<ul>
  <li><strong>開発が捗る</strong>：補完や履歴サジェストでミスタイプ激減</li>
  <li><strong>カスタマイズ性</strong>：見た目や挙動を好みに合わせて調整できる</li>
  <li><strong>活発なコミュニティ</strong>：GitHub上に豊富なプラグインと情報が存在</li>
</ul>

<hr />

<h2 id="️-zshの短所cons">⚠️ Zshの短所（Cons）</h2>

<table>
  <thead>
    <tr>
      <th>短所</th>
      <th>解説</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>初期設定に少し手間がかかる</td>
      <td>Bashよりも設定ファイルが複雑。特にプラグイン導入時。</td>
    </tr>
    <tr>
      <td>スクリプト互換性が微妙な場合あり</td>
      <td>Bash用のシェルスクリプトがZshで動かないことがある。</td>
    </tr>
    <tr>
      <td>学習コスト</td>
      <td>カスタマイズが自由な分、初心者には戸惑いやすい部分も。</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-結論どっちを選ぶべき">🤔 結論：どっちを選ぶべき？</h2>

<ul>
  <li><strong>安定性重視・スクリプト中心</strong>なら Bash</li>
  <li><strong>補完と操作性重視・開発者体験重視</strong>なら Zsh</li>
</ul>

<p>特にMacユーザーやWeb開発者には、Zsh + <code class="language-plaintext highlighter-rouge">oh-my-zsh</code> の組み合わせは非常におすすめです。</p>

<hr />

<p>Zshを導入することで、ターミナル操作が一気に<strong>パワーアップ</strong>します。まだ使っていない人は、ぜひ一度試してみてください！</p>]]></content><author><name></name></author><category term="shell" /><category term="bash" /><category term="zsh" /><category term="terminal" /><category term="bash" /><category term="zsh" /><category term="terminal" /><category term="shell" /><category term="linux" /><category term="mac" /><summary type="html"><![CDATA[macOS Catalina以降、AppleはデフォルトのシェルをBashからZshに変更しました。それ以来、多くの開発者が「ZshってBashと何が違うの？」と感じるようになりました。]]></summary></entry></feed>